Commit Graph

241 Commits

Author SHA1 Message Date
Harsh Batheja 4e2144d99e
feat: OpenCode session lifecycle and CLI controls (#315)
* feat: refine OpenCode session reuse strategy and cleanup

* fix: harden OpenCode session selection and lint errors

* refactor: centralize OpenCode reuse resolution flow

* fix: return 404 for missing session in message route

* feat: replace force remap with terminal reload control

* fix: protect project path from session kill cleanup

* fix: preserve fullscreen alignment without reload action

* fix: harden OpenCode session id handling and title reuse selection

* fix: show OpenCode reload control and remap before restart

* fix: preserve title-only OpenCode reuse with fallback mapping persistence

* fix: resolve remaining PR315 Bugbot findings

* fix: keep OpenCode discovery title-based without timestamp sorting

* fix: avoid enrichment race fallout in session listing

* fix: guard OpenCode discovery parse with array check

* fix: stabilize Linear comment integration check

* fix: harden OpenCode discovery and prompt option flow

* ux: clarify OpenCode terminal restart action

* fix: remap OpenCode session fresh on each restart

* fix: validate remap session ids before reuse

* fix: clean archived metadata only after purge

* docs: align OpenCode remap selection with title-based behavior

* fix: harden opencode cleanup and ignore local sisyphus state

* test: add timeout cleanup coverage for session enrichment

* fix: harden Linear integration helper against transient non-JSON errors

* fix: make linear integration assertions resilient to eventual consistency

* fix: remove unused fs import after rebase

* fix: address remaining Bugbot blockers for opencode session handling

* fix: avoid stale metadata overwrite during restore post-launch

* fix: forward subagent in orchestrator flows and defer reuse lookup

* fix: apply configured subagent fallback for session spawn

* fix: scope archived cleanup by project and delay archive restore write

* fix: normalize orchestrator strategy aliases in start display logic

* fix: centralize orchestrator strategy normalization in core

* fix: derive orchestrator reuse display from spawn result

* fix: keep cleanup results consistent across project-id collisions

* fix: namespace cleanup results when session IDs collide

* fix: harden GitHub issue stateReason fallback

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: avoid false failing CI state mapping

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: add tmux command timeouts

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: bound session API enrichment latency

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: repair scm-github merge resolution

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: repair lifecycle-manager test merge

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: delay archive metadata recreation until restore passes

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* test: restore claim-pr session mocks

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: address review findings for OpenCode lifecycle PR

- Fix stripControlChars to preserve newlines for reload commands
- Add SessionNotFoundError and use instanceof checks in API routes
- Document orchestratorSessionStrategy in YAML example
- Validate existingSessionId with asValidOpenCodeSessionId()
- Extract inline Node script to buildSessionLookupScript helper
- Create OpenCodeSessionManager interface for remap capability
- Create OpenCodeAgentConfig type for agent-specific config
- Change default orchestratorSessionStrategy from delete to reuse

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: guard reused session display without metadata

* chore: add agent config files to .gitignore

Agent configuration files (CLAUDE.md, AGENTS.md, IMPROVEMENTS.md, etc.) are personal and project-specific. They should not be committed to the repository.

Changes:
- Remove CLAUDE.md from git tracking
- Add agent config files to .gitignore
- Create .gitignore-template for reference

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: update gitignore for agent config folder structure

Reorganized agent configuration files:
- CLAUDE.md and AGENTS.md stay in root (agents read them there)
- Tracking files move to .opencode/ (IMPROVEMENTS.md, etc.)
- Optional Claude files in .claude/

Updated .gitignore to ignore folders instead of individual files.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: tighten opencode remap and session discovery safeguards

* fix: address Bugbot findings in session manager

* fix: scope opencode discovery to opencode sessions

* fix: restore concurrent listing and strict permission literals

* fix: throw SessionNotFoundError, parallelize list enrichment, fix permissions type

- Session manager now throws SessionNotFoundError instead of plain Error
  for missing sessions, so web API routes correctly return 404 (not 500)
- Parallelize session enrichment in list() — was sequential, causing O(N)
  latency for N sessions with subprocess enrichment
- Fix AgentLaunchConfig.permissions type to accept legacy "skip" value
  (AgentPermissionInput instead of AgentPermissionMode)
- Add happy-path and validation tests for /api/sessions/:id/message route
- Update all test mocks to use SessionNotFoundError

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: route ao send through session manager

* feat: add purge option to orchestrator stop

* fix: register opencode agent in web services

* test: align web API missing-session coverage

* fix: match notifier config by plugin name

* refactor: dedupe session lookup and tmux buffer send flow

* test: update send lifecycle wait expectation

* fix: harden send routing and cleanup purge controls

---------

Co-authored-by: Harsh <harsh@Ubuntu-24-Forrest.lan>
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Prateek <karnalprateek@gmail.com>
2026-03-08 09:55:44 +05:30
prateek 025603e11e
Merge pull request #346 from ComposioHQ/fix/direct-terminal-reverse-proxy
fix: DirectTerminal WebSocket URL behind reverse proxy
2026-03-08 04:28:49 +05:30
Prateek 06011be6f0 test(web): cover direct terminal websocket URL selection 2026-03-08 04:21:41 +05:30
Prateek 40055eb0d1 fix(web): preserve host port for proxy websocket path 2026-03-08 04:16:04 +05:30
prateek 3db75e42f2
Merge pull request #343 from ComposioHQ/fix/341-gh-path-ordering
fix: prioritize /usr/local/bin in codex agent PATH for gh wrapper
2026-03-08 03:01:08 +05:30
Prateek b865549ea9 fix(codex): harden gh wrapper resolution with explicit GH_PATH 2026-03-08 02:55:31 +05:30
Prateek ca46607b69 Merge origin/main into fix/341-gh-path-ordering 2026-03-08 02:32:11 +05:30
prateek 91d0708a25
Merge pull request #339 from ComposioHQ/session/ao-5
chore: bump codex plugin version for npm publish
2026-03-08 02:21:29 +05:30
prateek 767495ff84
Merge pull request #338 from ComposioHQ/session/ao-3
fix: suppress codex update prompt in non-interactive agent sessions
2026-03-08 02:17:32 +05:30
Prateek db79ad9423 test: align codex plugin version checks and stabilize init port tests 2026-03-07 21:02:07 +05:30
Prateek cb2b386f99 test: align codex integration test with AgentPermissionMode 2026-03-07 21:01:32 +05:30
Prateek e81a8a4e27 test: add codex launch/env integration coverage 2026-03-07 20:37:36 +05:30
Prateek e90c7f7ff2 fix: disable codex startup update check via config override 2026-03-07 20:31:35 +05:30
Prateek 309bfbbc19 fix: DirectTerminal WebSocket URL behind reverse proxy
When the AO dashboard is served behind a reverse proxy (e.g. Caddy ->
FastAPI -> Next.js), the browser cannot reach the direct terminal
WebSocket server on port 14801. The connection attempt to
wss://hostname:14801/ws times out, leaving terminals stuck at
'Connecting...'.

Fix: detect when running on a standard port (443/80, indicating a
reverse proxy) and use a path-based WebSocket endpoint
(/ao-terminal-ws) instead of the direct port. This allows the proxy
to forward WebSocket connections to the terminal server.

Supports three modes:
1. NEXT_PUBLIC_TERMINAL_WS_PATH env var (explicit path override)
2. Auto-detect reverse proxy (standard port -> /ao-terminal-ws)
3. Direct port access (dev mode, non-standard port -> :14801)
2026-03-07 20:28:00 +05:30
prateek ef40c529f8
fix: handle permissions=skip correctly in codex plugin (#337)
* fix: handle permissions=skip correctly in codex plugin

* refactor: rename permission mode to permissionless and align agent mappings

---------

Co-authored-by: Jayesh Sharma <wjayesh@outlook.com>
2026-03-07 20:27:01 +05:30
Prateek 1bb68a3f2a fix(codex): prioritize /usr/local/bin ahead of linuxbrew in PATH 2026-03-07 15:15:41 +05:30
Prateek 79dcaa043f test: verify codex update check env var is set 2026-03-07 15:11:00 +05:30
Prateek 2cd1b02b49 fix: suppress codex update prompt in non-interactive agent sessions 2026-03-07 14:24:55 +05:30
Jayesh Sharma ea879773ec chore: bump codex plugin version for npm publish (fixes --system-prompt flag) 2026-03-07 14:13:29 +05:30
Jayesh Sharma 8801502871
feat: add PR claim flow for agent sessions (#326)
* feat: add PR claim flow for agent sessions

* feat: support PR claim during spawn

* fix: address PR review feedback

* feat: add lifecycle worker automation

* fix: prevent duplicate messages on unconfirmed delivery and deduplicate review prompt

sendWithConfirmation now treats unconfirmed delivery as a soft success
since the message was already sent, preventing the dispatch hash from
staying stale and causing duplicate sends on the next poll cycle.

review-check command now sources its prompt from the lifecycle reaction
config instead of hardcoding it, keeping both paths aligned.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: pass AO_CONFIG_PATH to spawned lifecycle worker and log duplicate-worker early exit

The spawned lifecycle worker now receives AO_CONFIG_PATH in its
environment so it finds the correct config regardless of CWD. Also
added a log message when exiting early due to an existing worker.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: prevent lifecycle worker from clearing metadata on SCM fetch failures

SCM methods (getPendingComments, getAutomatedComments) silently returned []
on error, causing maybeDispatchReviewBacklog to treat fetch failures as
"no comments" and clear all tracking metadata every poll cycle. The worker
appeared to do nothing because it kept resetting its own state.

- SCM methods now propagate errors instead of returning []
- maybeDispatchReviewBacklog distinguishes null (fetch failed, skip) from
  [] (confirmed empty, safe to clear)
- pollAll() logs errors instead of silently swallowing them
- Added heartbeat logging and stdout flush before process.exit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add debug breadcrumbs when review comment fetch fails

Logs a console.debug message when getPendingComments or
getAutomatedComments fails, making it clear the lifecycle loop is
preserving metadata due to a fetch failure rather than genuinely
having no comments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: scope lifecycle worker polling to its project and add missing test

pollAll() now passes the worker's projectId to sessionManager.list(),
so each per-project lifecycle worker only polls its own sessions. This
prevents duplicate SCM API calls and race conditions in multi-project
configs.

Also fixed misleading test name and added a test verifying that
--no-dashboard alone still starts the lifecycle worker.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: remove dead confirmation check and respect project-level reaction overrides

Removed the unreachable "could not be confirmed" guard from the retry
logic since sendWithConfirmation now returns silently on unconfirmed
delivery.

review-check now resolves the prompt per-session by checking
project-level reaction overrides before falling back to the global
config, matching lifecycle worker behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: close TOCTOU race in lifecycle worker spawn and unexport getRegistry

Write the child PID from the parent immediately after spawn, closing
the window where a concurrent ensureLifecycleWorker could pass the
"not running" check and spawn a duplicate worker.

Also removed the unnecessary export on getRegistry since it has no
external consumers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: always include ao base prompt on spawn

* fix: clear heartbeat on shutdown and add initial delay to confirmation loop

Clear the heartbeat interval in the shutdown handler to prevent it
firing during the stream-flush window after lifecycle.stop().

Move the sleep in sendWithConfirmation to before each check (including
the first), so the runtime has time to reflect the message before
the first confirmation attempt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve lint errors in lifecycle and session manager

- Replace dynamic delete with object reconstruction in lifecycle-manager
- Add { cause } to re-thrown errors in session-manager for preserve-caught-error rule

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 03:54:19 +05:30
Harsh Batheja 8a655e7625
Merge pull request #322 from ComposioHQ/fix/worktree-cleanup-safety-v2
fix: restrict cleanup to AO-managed worktree roots
2026-03-06 15:12:02 +05:30
Harsh bcc08cd229 fix: gate workspace cleanup to AO-managed worktree roots 2026-03-06 15:08:45 +05:30
Harsh Batheja 454931483f
Merge pull request #321 from ComposioHQ/fix/opencode-prune-worktree-safety-main
revert: undo PR #320 workspace cleanup changes
2026-03-06 14:58:44 +05:30
Harsh 71adbbfac1 Revert "fix: restrict cleanup to AO-managed worktrees"
This reverts commit 86b34c8923.
2026-03-06 14:52:58 +05:30
Harsh 51749d7e0a Revert "fix: preserve spawn cleanup while hardening kill path checks"
This reverts commit 1c9adba947.
2026-03-06 14:52:58 +05:30
Harsh 3f5707f079 Revert "fix: canonicalize missing worktree paths using real ancestor"
This reverts commit 79d97547c0.
2026-03-06 14:52:58 +05:30
Harsh Batheja a5b58aec46
Merge pull request #320 from ComposioHQ/fix/opencode-prune-worktree-safety-main
fix: restrict cleanup to AO-managed worktrees
2026-03-06 14:50:05 +05:30
Harsh 79d97547c0 fix: canonicalize missing worktree paths using real ancestor 2026-03-06 14:45:42 +05:30
Harsh 1c9adba947 fix: preserve spawn cleanup while hardening kill path checks 2026-03-06 14:37:38 +05:30
Harsh 86b34c8923 fix: restrict cleanup to AO-managed worktrees 2026-03-06 14:19:16 +05:30
Harsh Batheja 32fdbdb03a
Merge pull request #312 from ComposioHQ/chore/untrack-local-yaml
chore: untrack local agent-orchestrator config
2026-03-06 11:40:47 +05:30
Harsh 456ef3e951 chore: untrack local agent-orchestrator config 2026-03-05 22:21:21 +05:30
sujayjayjay 690bd9ee3a
Merge pull request #278 from ComposioHQ/preview-banner
Add Composio banner to README
2026-03-03 22:48:20 +05:30
Sujay Choubey 17c79b21a0 Add Composio banner to README 2026-03-03 22:43:23 +05:30
prateek a4a1a32e96
fix: auto-detect free port in ao start <url> config generation (#275)
* fix: auto-detect free port in ao start <url> config generation

When generating a new config via `ao start <url>`, auto-detect a free
port instead of hardcoding 3000. Reuses `findFreePort` (extracted to
shared web-dir.ts from init.ts). When port was auto-selected, skip the
strict preflight port check and silently find another free port if
needed (race condition).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add polling to listIssues integration test for Linear API consistency

The listIssues test was failing because Linear's API has eventual
consistency — a just-created issue may not appear in list queries
immediately. Other tests in this file already use pollUntilEqual for
the same reason. Use pollUntil to retry until the issue appears.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: restore coupling between MAX_PORT_SCAN and findFreePort

MAX_PORT_SCAN was decoupled from findFreePort after extraction to
web-dir.ts — init.ts kept a local constant only used in messages while
findFreePort had its own default, and start.ts hardcoded 99. Export
MAX_PORT_SCAN from web-dir.ts as the single source of truth, use it as
findFreePort's default parameter, and import it in both callers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 15:03:20 +05:30
prateek e503caeaa3
fix: don't show 'Ready to merge' badge on merged/closed PRs (#274)
Extract isPRMergeReady() helper that checks pr.state === "open" before
evaluating merge criteria, preventing the badge from appearing alongside
the 'Merged' chip on already-merged PRs.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:46:54 +05:30
prateek b5128cf69f
fix: use gh repo clone for private repo auth in ao start <url> (#273)
HTTPS clone fails on private repos without credentials. Now tries
three strategies in order:
1. gh repo clone (handles GitHub auth via gh auth token)
2. git clone with SSH URL (works with SSH keys)
3. git clone with HTTPS URL (public repos fallback)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:42:35 +05:30
prateek e72593d4f8
fix: URL start multi-project resolution and cross-platform browser open (#272)
* fix: URL start handles multi-project configs and cross-platform browser open

When `ao start <url>` loads an existing config with multiple projects,
resolve the correct project by matching the URL's owner/repo against
each project's `repo` field instead of failing with "Multiple projects".

Also fix browser open to use platform-appropriate command (open/xdg-open/start)
instead of hardcoded macOS `open`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use shallow clone (--depth 1) for faster repo onboarding

Full clones of large repos can take minutes. Shallow clone with
depth 1 fetches only the latest commit, making `ao start <url>`
near-instant for any repo size.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use cmd.exe /c start for Windows browser open

`start` is a cmd.exe builtin, not a standalone executable — spawn
would fail with ENOENT. Run via cmd.exe /c with empty title arg.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:26:41 +05:30
prateek 80a1d59999
feat: add `ao start <url>` one-command project onboarding (#267)
* feat: add `ao start <url>` one-command project onboarding

When `ao start` receives a repo URL instead of a project ID, it now:
1. Parses the URL (supports GitHub, GitLab, Bitbucket — HTTPS and SSH)
2. Clones the repo (or reuses if already present with matching remote)
3. Auto-generates agent-orchestrator.yaml with sensible defaults:
   - SCM/tracker plugins inferred from URL host
   - Default branch detected from local refs
   - Project type detected (language, package manager)
   - Post-create install commands set based on package manager
4. Starts the orchestrator + dashboard as usual

New core module `config-generator.ts` handles URL parsing, SCM detection,
project info detection, and config generation. All logic is in core (not
CLI) for reusability. 36 unit tests cover URL parsing, SCM detection,
default branch detection, project info, config generation, and clone
target resolution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address bugbot review feedback

1. Non-JS postCreate fix: Only set postCreate install commands for JS
   package managers (pnpm/yarn/bun/npm). Rust/Go/Python projects no
   longer get an incorrect "npm install" command.

2. Deduplicate startup logic: Extract shared `runStartup()` helper used
   by both URL-mode and normal-mode start flows. Eliminates ~100 lines
   of duplicated dashboard+orchestrator startup code.

3. SSH URL matching: Normalize SSH URLs to HTTPS format in
   `isRepoAlreadyCloned()` so repos cloned via SSH
   (git@github.com:owner/repo) are correctly detected as matching.

4. SCM/tracker always explicit: Always set scm and tracker fields in
   generated config so `applyProjectDefaults()` doesn't silently
   override with github defaults for non-GitHub repos.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: sanitize repo names for project IDs and session prefixes

Address remaining bugbot comments:
- Add sanitizeProjectId() to handle dots/special chars in repo names
  (e.g. "my.app" → "my-app" instead of failing Zod validation)
- Preserve original case for generateSessionPrefix() so CamelCase
  detection works (e.g. "DevOS" → prefix "dos", not "dev")
- Strip invalid chars before prefix generation to prevent dots
  leaking into sessionPrefix

Also update README and SETUP docs with `ao start <url>` quick
onboarding flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: auto-open browser to orchestrator page on `ao start`

Opens the orchestrator session page (/sessions/{id}) instead of the
root dashboard, since the Kanban board is empty on first startup
with no worker sessions yet.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: replace fixed 3s delay with port polling for browser open

Poll the dashboard port via TCP connection attempts (300ms intervals,
30s timeout) instead of a hardcoded setTimeout. Opens the browser only
once the server is actually accepting connections — deterministic
regardless of how long Next.js takes to compile.

Applied to both `ao start` and `ao dashboard` commands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add CLI tests for start/stop commands

12 new tests covering:
- Project resolution: single project, explicit arg, missing project,
  multi-project ambiguity, empty config
- URL argument: reuse existing clone, git clone flow, existing config
  detection, clone failure error handling
- Port polling: waitForPortAndOpen polls isPortAvailable before opening
  browser (proves deterministic behavior vs fixed delay)
- Stop command: session kill + dashboard stop, graceful missing session

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: deduplicate waitForPortAndOpen into shared utility

Move waitForPortAndOpen to lib/web-dir.ts (alongside isPortAvailable)
so both start.ts and dashboard.ts share a single cancellation-aware
implementation. start.ts now uses AbortSignal like dashboard.ts —
polling stops immediately if the dashboard process exits early.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 13:52:49 +05:30
suraj_markup d1bf5a5b03
Merge pull request #266 from suraj-markup/feat/issue-265
feat(mobile): React Native app for monitoring AO sessions
2026-03-03 05:21:20 +05:30
suraj-markup c9bf351481 fix: enable cleartext traffic on Android for local/Tailscale HTTP
Android blocks plain HTTP by default. Enable usesCleartextTraffic
so the app can connect to http://100.x.x.x:3000 (Tailscale) and
http://192.168.x.x:3000 (LAN) backends.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 05:17:03 +05:30
suraj-markup d6d5dd6642 fix: skip polling with empty session ID, use correct XDA parser API
- Add `enabled` option to useSession hook; OrchestratorScreen passes
  enabled: !!orchestratorId to avoid polling /api/sessions/ with an
  empty string when no orchestrator is running
- Replace term.onData XDA handler with term.parser.registerCsiHandler
  matching the web dashboard implementation — onData only fires for
  outgoing user input, not incoming WebSocket data where the CSI > q
  query actually arrives

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 05:07:27 +05:30
suraj-markup 0773137a65 feat: embed orchestrator session details inline, remove overview
Show orchestrator session details (status, activity, summary, timing,
terminal button, send message) directly on the Orchestrator page
instead of requiring navigation to a separate SessionDetail page.
Remove the Overview stats section. Commands remain in header button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 04:53:32 +05:30
suraj-markup b5e486ffd2 fix: robot button goes to Orchestrator page with Commands in header
Revert 🤖 to navigate to Orchestrator overview (zones, stats,
orchestrator status card). The "Commands" header button on that
page opens the CLI commands reference. Tapping the orchestrator
card navigates to its session detail.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 04:50:54 +05:30
suraj-markup 185dc97ede fix: add Commands button (📋) to HomeScreen header
The Commands button was on the Orchestrator page header which is
no longer visited when the orchestrator is running. Move it to the
HomeScreen header so it's always accessible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 04:49:43 +05:30
suraj-markup d733f107c3 feat: robot button opens orchestrator session, commands in header
- Robot button (🤖) on HomeScreen now navigates directly to the
  orchestrator's session detail when running, or to the Orchestrator
  overview when not running
- Move CLI commands to a new CommandsScreen, accessible via a
  "Commands" header button on the Orchestrator page
- Remove inline CLI commands from OrchestratorScreen body

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 04:47:12 +05:30
suraj-markup 170d54cd53 fix: move Tailscale details out of backend URL section into setup guide
Keep the backend URL hint clean — Tailscale/ngrok/LAN instructions
are already in the setup guide below.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 04:41:28 +05:30
suraj-markup 9bafd33cb3 feat: add Tailscale setup guide and hide test notifications in prod
- Add Tailscale as the recommended connection method in the setup guide
  with step-by-step instructions
- Add alternative sections for Local Wi-Fi and ngrok
- Wrap test notification buttons in __DEV__ so they only show during
  development and are stripped from production builds
- Update placeholder and hint text to show Tailscale IP format first

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 04:41:04 +05:30
suraj-markup 68a0ab1ded fix: stale fetch race condition and invalid test status
- Replace isMountedRef with generation counter (fetchGenRef) in
  useSessions and useSession hooks to prevent stale fetches from
  overwriting correct data when the backend URL changes mid-flight
- Fix test review notification using invalid "needs_review" status;
  correct value is "review_pending" per core types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 04:39:22 +05:30
suraj-markup 6c9f74a700 feat: add review notifications and notification tap-to-navigate
- Add "review" attention level to notification triggers (background task,
  foreground hook, and scheduleNotification)
- Add notification tap handling: tapping a notification navigates directly
  to the session detail screen via navigationRef
- Handle cold-start case (app killed) via getLastNotificationResponseAsync
- Add "review" test notification button in Settings screen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 04:21:34 +05:30