commandmate 0.42.2 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +176 -176
- package/.next/app-path-routes-manifest.json +34 -34
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +15 -15
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/update/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/versions/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/release-notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route.js +2 -2
- package/.next/server/app/api/app/update/route.js.nft.json +1 -1
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.js +1 -1
- package/.next/server/app/api/app/update-check/route.js.nft.json +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route.js +1 -1
- package/.next/server/app/api/daily-summary/route.js.nft.json +1 -1
- package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route.js +1 -1
- package/.next/server/app/api/daily-summary/status/route.js.nft.json +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route.js.nft.json +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/route.js.nft.json +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route.js.nft.json +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route.js.nft.json +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js +103 -1
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route.js.nft.json +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route.js +1 -1
- package/.next/server/app/api/push/escalation/route.js.nft.json +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route.js.nft.json +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route.js +1 -1
- package/.next/server/app/api/push/vapid/route.js.nft.json +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/route.js +1 -1
- package/.next/server/app/api/relays/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route.js.nft.json +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route.js +1 -1
- package/.next/server/app/api/skills/installations/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route.js +2 -2
- package/.next/server/app/api/skills/operations/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route.js +1 -1
- package/.next/server/app/api/skills/reindex/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route.js +1 -1
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route.js +1 -1
- package/.next/server/app/api/slash-commands/route.js.nft.json +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route.js.nft.json +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route.js.nft.json +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route.js.nft.json +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route.js.nft.json +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +3 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +3 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route.js +7 -7
- package/.next/server/app/api/worktrees/[id]/marp-render/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -103
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +3 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +3 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route.js +3 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -103
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +103 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +103 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +1 -1
- package/.next/server/app/sessions/page.js.nft.json +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page.js +1 -1
- package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +9 -9
- package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +34 -34
- package/.next/server/chunks/1068.js +1 -1
- package/.next/server/chunks/1210.js +1 -1
- package/.next/server/chunks/1501.js +3 -3
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/22.js +1 -1
- package/.next/server/chunks/2283.js +15 -0
- package/.next/server/chunks/2328.js +1 -1
- package/.next/server/chunks/2404.js +4 -3
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/252.js +1 -1
- package/.next/server/chunks/2816.js +1 -1
- package/.next/server/chunks/3543.js +1 -1
- package/.next/server/chunks/3730.js +1 -1
- package/.next/server/chunks/3945.js +1 -1
- package/.next/server/chunks/4207.js +3 -3
- package/.next/server/chunks/4802.js +1 -1
- package/.next/server/chunks/488.js +1 -0
- package/.next/server/chunks/5064.js +1 -1
- package/.next/server/chunks/5326.js +1 -1
- package/.next/server/chunks/5456.js +1 -1
- package/.next/server/chunks/5571.js +1 -1
- package/.next/server/chunks/5775.js +1 -1
- package/.next/server/chunks/611.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6285.js +1 -1
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/6474.js +14 -0
- package/.next/server/chunks/650.js +1 -1
- package/.next/server/chunks/6661.js +1 -1
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/6793.js +1 -1
- package/.next/server/chunks/6927.js +1 -0
- package/.next/server/chunks/7491.js +3 -0
- package/.next/server/chunks/7506.js +1 -1
- package/.next/server/chunks/7685.js +1 -1
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8543.js +1 -1
- package/.next/server/chunks/8581.js +2 -2
- package/.next/server/chunks/8728.js +2 -2
- package/.next/server/chunks/8782.js +1 -0
- package/.next/server/chunks/8791.js +1 -1
- package/.next/server/chunks/8800.js +4 -3
- package/.next/server/chunks/8918.js +108 -6
- package/.next/server/chunks/9130.js +3 -3
- package/.next/server/chunks/{8052.js → 9353.js} +4 -2
- package/.next/server/chunks/9390.js +3 -0
- package/.next/server/chunks/9627.js +3 -3
- package/.next/server/chunks/967.js +1 -0
- package/.next/server/chunks/9731.js +3 -3
- package/.next/server/chunks/9882.js +3 -3
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/server/src/middleware.js +2 -2
- package/.next/server/src/middleware.js.map +1 -1
- package/.next/static/chunks/2053-85a974ddfe7498fe.js +1 -0
- package/.next/static/chunks/{2407-6b9e12c099fa598c.js → 2407-340774f1a24f2b45.js} +1 -1
- package/.next/static/chunks/5449-6cb80bab2bd06b79.js +1 -0
- package/.next/static/chunks/5521-c358c31f60e5e689.js +1 -0
- package/.next/static/chunks/591-0a45801e83f26f24.js +1 -0
- package/.next/static/chunks/8165-3853772f6ae1299b.js +1 -0
- package/.next/static/chunks/{8566-a6a7c70558927410.js → 8566-aeda747542072ace.js} +1 -1
- package/.next/static/chunks/8811-29eaa24237f48558.js +1 -0
- package/.next/static/chunks/{9619-22adf5367c4b7080.js → 9619-84aced0846cbe3ac.js} +1 -1
- package/.next/static/chunks/app/{layout-5b95e1236dcd9ef6.js → layout-0fc249fb7de75a27.js} +1 -1
- package/.next/static/chunks/app/review/page-ff9efae3f86eb840.js +1 -0
- package/.next/static/chunks/app/sessions/page-55297155e7bf01b9.js +1 -0
- package/.next/static/chunks/app/skills/[skillId]/page-9ee7a381636e60cb.js +1 -0
- package/.next/static/chunks/app/skills/page-182e16168b2fc098.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-d2103e0c25be83c8.js +1 -0
- package/.next/static/css/38070d879efa1371.css +1 -0
- package/.next/trace +13 -13
- package/README.md +58 -620
- package/dist/cli/commands/ask.d.ts.map +1 -1
- package/dist/cli/commands/ask.js +23 -149
- package/dist/cli/commands/capture.d.ts.map +1 -1
- package/dist/cli/commands/capture.js +11 -1
- package/dist/cli/commands/docs.d.ts.map +1 -1
- package/dist/cli/commands/docs.js +5 -0
- package/dist/cli/commands/remote.d.ts +24 -1
- package/dist/cli/commands/remote.d.ts.map +1 -1
- package/dist/cli/commands/remote.js +155 -6
- package/dist/cli/commands/reply.d.ts +40 -0
- package/dist/cli/commands/reply.d.ts.map +1 -0
- package/dist/cli/commands/reply.js +133 -0
- package/dist/cli/commands/respond.d.ts.map +1 -1
- package/dist/cli/commands/respond.js +255 -112
- package/dist/cli/commands/stop.d.ts.map +1 -1
- package/dist/cli/commands/stop.js +53 -1
- package/dist/cli/commands/sync.js +3 -3
- package/dist/cli/commands/wait.d.ts +5 -0
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +10 -1
- package/dist/cli/docs/agent-operations.d.ts +2 -2
- package/dist/cli/docs/agent-operations.d.ts.map +1 -1
- package/dist/cli/docs/agent-operations.js +13 -0
- package/dist/cli/docs/setup-guide.d.ts +14 -0
- package/dist/cli/docs/setup-guide.d.ts.map +1 -0
- package/dist/cli/docs/setup-guide.js +366 -0
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +4 -0
- package/dist/cli/types/api-responses.d.ts +11 -0
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/types/index.d.ts +2 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/utils/daemon.d.ts +42 -2
- package/dist/cli/utils/daemon.d.ts.map +1 -1
- package/dist/cli/utils/daemon.js +222 -40
- package/dist/cli/utils/docs-reader.d.ts +6 -0
- package/dist/cli/utils/docs-reader.d.ts.map +1 -1
- package/dist/cli/utils/docs-reader.js +14 -13
- package/dist/cli/utils/npm-runner.d.ts +12 -0
- package/dist/cli/utils/npm-runner.d.ts.map +1 -1
- package/dist/cli/utils/npm-runner.js +36 -0
- package/dist/cli/utils/process-inspect.d.ts +55 -0
- package/dist/cli/utils/process-inspect.d.ts.map +1 -0
- package/dist/cli/utils/process-inspect.js +214 -0
- package/dist/cli/utils/remote-pairing.d.ts +68 -0
- package/dist/cli/utils/remote-pairing.d.ts.map +1 -0
- package/dist/cli/utils/remote-pairing.js +117 -0
- package/dist/cli/utils/reply-ledger.d.ts +95 -0
- package/dist/cli/utils/reply-ledger.d.ts.map +1 -0
- package/dist/cli/utils/reply-ledger.js +187 -0
- package/dist/cli/utils/server-identity.d.ts +50 -0
- package/dist/cli/utils/server-identity.d.ts.map +1 -0
- package/dist/cli/utils/server-identity.js +118 -0
- package/dist/cli/utils/server-ready.d.ts +13 -0
- package/dist/cli/utils/server-ready.d.ts.map +1 -1
- package/dist/cli/utils/server-ready.js +16 -0
- package/dist/lib/cli-tools/copilot-executable.d.ts +9 -0
- package/dist/lib/cli-tools/copilot-executable.d.ts.map +1 -1
- package/dist/lib/cli-tools/copilot-executable.js +21 -5
- package/dist/lib/cli-tools/opencode-executable.d.ts +103 -0
- package/dist/lib/cli-tools/opencode-executable.d.ts.map +1 -0
- package/dist/lib/cli-tools/opencode-executable.js +179 -0
- package/dist/lib/cli-tools/types.d.ts +1 -1
- package/dist/lib/cli-tools/types.d.ts.map +1 -1
- package/dist/lib/cli-tools/types.js +5 -1
- package/dist/lib/detection/tools/verified-against.d.ts +15 -0
- package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
- package/dist/lib/detection/tools/verified-against.js +17 -1
- package/dist/lib/detection/version-probes.d.ts.map +1 -1
- package/dist/lib/detection/version-probes.js +14 -1
- package/dist/lib/security/pairing-code.d.ts +2 -1
- package/dist/lib/security/pairing-code.d.ts.map +1 -1
- package/dist/lib/session/tmux-session-surface.d.ts.map +1 -1
- package/dist/lib/session/tmux-session-surface.js +1 -1
- package/dist/server/locales/en/worktree.json +72 -20
- package/dist/server/locales/ja/worktree.json +72 -20
- package/dist/server/server.js +23 -0
- package/dist/server/src/config/cli-tool-timing-config.js +19 -1
- package/dist/server/src/config/detection-evidence-config.js +3 -0
- package/dist/server/src/config/image-extensions.js +1 -0
- package/dist/server/src/config/schedule-config.js +55 -1
- package/dist/server/src/lib/auto-yes-poller.js +69 -4
- package/dist/server/src/lib/cli-tools/agent-mode-spec.js +54 -2
- package/dist/server/src/lib/cli-tools/base.js +6 -2
- package/dist/server/src/lib/cli-tools/command-code-plan-review.js +175 -0
- package/dist/server/src/lib/cli-tools/command-code.js +81 -2
- package/dist/server/src/lib/cli-tools/composer-spec.js +10 -0
- package/dist/server/src/lib/cli-tools/copilot-executable.js +21 -5
- package/dist/server/src/lib/cli-tools/graceful-exit.js +15 -1
- package/dist/server/src/lib/cli-tools/index.js +3 -1
- package/dist/server/src/lib/cli-tools/install-hints.js +9 -3
- package/dist/server/src/lib/cli-tools/liveness-spec.js +19 -0
- package/dist/server/src/lib/cli-tools/manager.js +2 -0
- package/dist/server/src/lib/cli-tools/opencode-executable.js +179 -0
- package/dist/server/src/lib/cli-tools/opencode-v2.js +369 -0
- package/dist/server/src/lib/cli-tools/opencode.js +29 -5
- package/dist/server/src/lib/cli-tools/types.js +5 -1
- package/dist/server/src/lib/cmate-cli-tool-parser.js +65 -7
- package/dist/server/src/lib/cmate-parser.js +12 -0
- package/dist/server/src/lib/cmate-validator.js +13 -1
- package/dist/server/src/lib/detection/cli-patterns.js +172 -3
- package/dist/server/src/lib/detection/model-info-extractor.js +79 -7
- package/dist/server/src/lib/detection/status-detector.js +10 -1
- package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +2 -1
- package/dist/server/src/lib/detection/tools/codex/detect.js +26 -0
- package/dist/server/src/lib/detection/tools/command-code/plan-review-state.js +75 -0
- package/dist/server/src/lib/detection/tools/opencode-v2/detect.js +253 -0
- package/dist/server/src/lib/detection/tools/opencode-v2/dialog-title.js +48 -0
- package/dist/server/src/lib/detection/tools/registry.js +2 -0
- package/dist/server/src/lib/detection/tools/run-detection.js +9 -0
- package/dist/server/src/lib/detection/tools/verified-against.js +17 -1
- package/dist/server/src/lib/detection/upstream-faults.js +8 -0
- package/dist/server/src/lib/detection/version-probes.js +14 -1
- package/dist/server/src/lib/hooks/agent-session-telemetry.js +36 -1
- package/dist/server/src/lib/hooks/sources/claude/transcript.js +33 -1
- package/dist/server/src/lib/hooks/sources/opencode/log-diagnosis.js +105 -0
- package/dist/server/src/lib/hooks/sources/opencode/source.js +7 -1
- package/dist/server/src/lib/hooks/sources/opencode-v2/client.js +422 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/decision-labels.js +24 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/history.js +421 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/ingest.js +271 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/mappers.js +165 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/payloads.js +351 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/ports.js +230 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/reattach.js +149 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/runtime.js +180 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/secrets.js +182 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/source.js +295 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/subscription.js +455 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/tool-id.js +18 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/usage.js +214 -0
- package/dist/server/src/lib/hooks/sources/registry.js +2 -0
- package/dist/server/src/lib/hooks/structured-decision-response.js +14 -5
- package/dist/server/src/lib/job-executor.js +2 -1
- package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +15 -1
- package/dist/server/src/lib/polling/structured-history-gate.js +19 -5
- package/dist/server/src/lib/relay/relay-delivery.js +4 -1
- package/dist/server/src/lib/session/agent-event-state.js +24 -0
- package/dist/server/src/lib/session/claude-executor.js +186 -12
- package/dist/server/src/lib/session/claude-session.js +131 -15
- package/dist/server/src/lib/session/current-output-builder.js +27 -3
- package/dist/server/src/lib/session/send-user-message.js +4 -0
- package/dist/server/src/lib/session/session-start-error.js +20 -0
- package/dist/server/src/lib/session/structured-prompt.js +54 -0
- package/dist/server/src/lib/session/tmux-session-surface.js +1 -1
- package/dist/server/src/lib/skills/agent-state-paths.js +39 -0
- package/dist/server/src/lib/skills/compatibility-matrix.js +65 -0
- package/dist/server/src/lib/skills/receipt-owned-paths.js +118 -0
- package/dist/server/src/lib/tmux/tmux.js +73 -2
- package/dist/server/src/lib/verification/env-clean-gate.js +281 -10
- package/dist/server/src/lib/verification/gate-runner.js +29 -2
- package/dist/server/src/lib/verification/scope-gate.js +58 -4
- package/dist/server/src/types/cli-tool-contracts.js +10 -2
- package/dist/types/cli-tool-contracts.d.ts +16 -5
- package/dist/types/cli-tool-contracts.d.ts.map +1 -1
- package/dist/types/cli-tool-contracts.js +10 -2
- package/docs/en/architecture.md +722 -0
- package/docs/en/user-guide/agents-guide.md +306 -0
- package/docs/en/user-guide/cli-setup-guide.md +676 -0
- package/docs/en/user-guide/cmate-schedules-guide.md +388 -0
- package/docs/en/user-guide/commands-guide.md +467 -0
- package/docs/en/user-guide/quick-start.md +231 -0
- package/docs/en/user-guide/webapp-guide.md +1020 -0
- package/docs/en/user-guide/workflow-examples.md +463 -0
- package/package.json +19 -7
- package/release-notes/0.43.0.json +130 -0
- package/release-notes/0.44.0.json +82 -0
- package/scripts/hooks/cmate-agent-event.sh +14 -0
- package/scripts/opencode-v2/launch.sh +226 -0
- package/.next/server/chunks/1990.js +0 -103
- package/.next/server/chunks/3707.js +0 -15
- package/.next/server/chunks/4443.js +0 -3
- package/.next/server/chunks/5164.js +0 -1
- package/.next/server/chunks/5742.js +0 -1
- package/.next/server/chunks/7004.js +0 -1
- package/.next/server/chunks/8673.js +0 -14
- package/.next/static/chunks/2039-117a361f795ddc4b.js +0 -1
- package/.next/static/chunks/2053-611dd27d42721b79.js +0 -1
- package/.next/static/chunks/3778-56f41fc2cecb8c43.js +0 -1
- package/.next/static/chunks/5449-550bd273dccc3ae4.js +0 -1
- package/.next/static/chunks/7705-2a2936551b0cf9a3.js +0 -1
- package/.next/static/chunks/8165-934ee7ff3b4ddfd4.js +0 -1
- package/.next/static/chunks/app/review/page-30616daa1dc595c2.js +0 -1
- package/.next/static/chunks/app/sessions/page-1a8ba152bbcb9efb.js +0 -1
- package/.next/static/chunks/app/skills/[skillId]/page-ab7e432b69fccb3b.js +0 -1
- package/.next/static/chunks/app/skills/page-56b4fa11223e0cbd.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-59f5337e031518c6.js +0 -1
- package/.next/static/css/b3f433d52b8ed5c8.css +0 -1
- /package/.next/static/{MXZXkcFAnpELZnxxHB4iJ → wu7SUiHTirFcrpo5teyZ3}/_buildManifest.js +0 -0
- /package/.next/static/{MXZXkcFAnpELZnxxHB4iJ → wu7SUiHTirFcrpo5teyZ3}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,1020 @@
|
|
|
1
|
+
[日本語版](../../user-guide/webapp-guide.md)
|
|
2
|
+
|
|
3
|
+
# Web App Guide
|
|
4
|
+
|
|
5
|
+
This guide explains the basic operations of the CommandMate web app.
|
|
6
|
+
It's a step-by-step guide for first-time users.
|
|
7
|
+
|
|
8
|
+
> **For developers**: See the [UI/UX Guide](../../UI_UX_GUIDE.md) for UI implementation details.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Table of Contents
|
|
13
|
+
|
|
14
|
+
1. [Launching and Accessing the App](#launching-and-accessing-the-app)
|
|
15
|
+
2. [Registering Repositories](#registering-repositories)
|
|
16
|
+
3. [Removing Repositories](#removing-repositories)
|
|
17
|
+
4. [Selecting a Worktree](#selecting-a-worktree)
|
|
18
|
+
5. [Sending Messages](#sending-messages)
|
|
19
|
+
6. [Auto Yes Mode](#auto-yes-mode)
|
|
20
|
+
7. [Viewing Chat History](#viewing-chat-history)
|
|
21
|
+
8. [Status Indicators](#status-indicators)
|
|
22
|
+
9. [Markdown Log Viewer](#markdown-log-viewer)
|
|
23
|
+
10. [Notes Feature](#notes-feature)
|
|
24
|
+
11. [Agent Settings](#agent-settings)
|
|
25
|
+
12. [Switching the Output Surface (Terminal / Chat)](#switching-the-output-surface-terminal--chat)
|
|
26
|
+
13. [The Default Output Surface (Terminal / Chat)](#the-default-output-surface-terminal--chat)
|
|
27
|
+
14. [Temporarily Maximizing One Split (Desktop)](#temporarily-maximizing-one-split-desktop)
|
|
28
|
+
15. [Execution Contract and Verification](#execution-contract-and-verification)
|
|
29
|
+
16. [Mobile Access](#mobile-access)
|
|
30
|
+
17. [Phone Notifications (Web Push)](#phone-notifications-web-push)
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Launching and Accessing the App
|
|
35
|
+
|
|
36
|
+
### 1. Starting the Server
|
|
37
|
+
|
|
38
|
+
#### npm Global Install (recommended)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Start in background
|
|
42
|
+
commandmate start --daemon
|
|
43
|
+
|
|
44
|
+
# Check status
|
|
45
|
+
commandmate status
|
|
46
|
+
|
|
47
|
+
# Stop
|
|
48
|
+
commandmate stop
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### Development Environment (git clone)
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
cd CommandMate
|
|
55
|
+
|
|
56
|
+
# Development server
|
|
57
|
+
npm run dev
|
|
58
|
+
|
|
59
|
+
# Production build
|
|
60
|
+
npm run build
|
|
61
|
+
npm start
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
> **Note**: If this is your first time, run `commandmate init` for initial setup. See the [CLI Setup Guide](./cli-setup-guide.md) for details.
|
|
65
|
+
|
|
66
|
+
### 2. Accessing via Browser
|
|
67
|
+
|
|
68
|
+
Open your browser and navigate to:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
http://127.0.0.1:3000
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
> **Port change**: Change the port with `commandmate start --port 3001` or set `CM_PORT=3001` in the `.env` file.
|
|
75
|
+
|
|
76
|
+
> **`127.0.0.1`, not `localhost`**: CommandMate binds `127.0.0.1` by default (`CM_BIND`).
|
|
77
|
+
> `localhost` can resolve to `::1` (IPv6) first, which CommandMate does not listen on — if
|
|
78
|
+
> another process holds that address, your browser silently talks to it instead.
|
|
79
|
+
|
|
80
|
+
### 3. Supported browsers
|
|
81
|
+
|
|
82
|
+
The web UI is built with Tailwind CSS 4, which targets modern browsers and relies on
|
|
83
|
+
`@property` and `color-mix()` for its color and theming layer. The minimum supported
|
|
84
|
+
versions are:
|
|
85
|
+
|
|
86
|
+
| Browser | Minimum version |
|
|
87
|
+
|---------|-----------------|
|
|
88
|
+
| Safari (macOS / iOS) | 16.4+ |
|
|
89
|
+
| Chrome / Edge | 111+ |
|
|
90
|
+
| Firefox | 128+ |
|
|
91
|
+
|
|
92
|
+
Older browsers will load the app but render it with degraded colors and spacing.
|
|
93
|
+
CommandMate is a local developer tool, so this matches the browsers a current
|
|
94
|
+
development machine or phone will already have.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Registering Repositories
|
|
99
|
+
|
|
100
|
+
To manage worktrees with CommandMate, you first need to register a repository.
|
|
101
|
+
There are two registration methods.
|
|
102
|
+
|
|
103
|
+
### Method 1: Scan from Local Path
|
|
104
|
+
|
|
105
|
+
Scan and register an existing repository on your PC.
|
|
106
|
+
|
|
107
|
+
1. Click the **"Add Repository"** button at the top right of the homepage
|
|
108
|
+
2. Select the **"Local Path"** tab
|
|
109
|
+
3. Enter the repository path (e.g., `/Users/yourname/projects/my-repo`)
|
|
110
|
+
4. Click **"Scan"**
|
|
111
|
+
5. Review the detected worktree list and click **"Register"**
|
|
112
|
+
|
|
113
|
+
### Method 2: Clone from URL
|
|
114
|
+
|
|
115
|
+
Clone and register from a remote repository like GitHub.
|
|
116
|
+
|
|
117
|
+
1. Click the **"Add Repository"** button at the top right of the homepage
|
|
118
|
+
2. Select the **"URL Clone"** tab
|
|
119
|
+
3. Enter the repository URL
|
|
120
|
+
- HTTPS: `https://github.com/username/repo.git`
|
|
121
|
+
- SSH: `git@github.com:username/repo.git`
|
|
122
|
+
4. Click **"Clone"**
|
|
123
|
+
5. After cloning completes, the worktree is automatically registered
|
|
124
|
+
|
|
125
|
+
> **Note**: When using SSH URLs, SSH keys must be set up.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Removing Repositories
|
|
130
|
+
|
|
131
|
+
You can remove repositories that are no longer needed.
|
|
132
|
+
|
|
133
|
+
1. In the repository list on the homepage, click the **"..."** menu for the repository you want to remove
|
|
134
|
+
2. Select **"Delete"**
|
|
135
|
+
3. Type `delete` in the confirmation dialog
|
|
136
|
+
4. Click the **"Delete"** button
|
|
137
|
+
|
|
138
|
+
> **Warning**: Removing a repository deletes all related worktree information, notes, and history. The repository's actual files are not deleted.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Selecting a Worktree
|
|
143
|
+
|
|
144
|
+
Select a worktree (branch) from registered repositories to operate on.
|
|
145
|
+
|
|
146
|
+
### Desktop
|
|
147
|
+
|
|
148
|
+
1. A list of worktrees is displayed in the left sidebar
|
|
149
|
+
2. Click the worktree you want to operate on
|
|
150
|
+
3. The detail view appears on the right
|
|
151
|
+
|
|
152
|
+
### Mobile
|
|
153
|
+
|
|
154
|
+
1. A list of worktrees is displayed on the homepage
|
|
155
|
+
2. Tap the worktree you want to operate on
|
|
156
|
+
3. Navigate to the worktree detail view
|
|
157
|
+
|
|
158
|
+

|
|
159
|
+
*Desktop: Two-column layout*
|
|
160
|
+
|
|
161
|
+

|
|
162
|
+
*Mobile: Tab-based layout*
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Sending Messages
|
|
167
|
+
|
|
168
|
+
Send messages to Claude Code to give instructions.
|
|
169
|
+
|
|
170
|
+
### How to Send
|
|
171
|
+
|
|
172
|
+
1. Select a worktree
|
|
173
|
+
2. Type your message in the input field at the bottom
|
|
174
|
+
3. Click the **"Send"** button (or press Enter)
|
|
175
|
+
|
|
176
|
+
### Responding to Claude's Confirmations
|
|
177
|
+
|
|
178
|
+
When Claude asks for yes/no or multiple-choice confirmations:
|
|
179
|
+
|
|
180
|
+
1. A confirmation dialog appears automatically
|
|
181
|
+
2. Click **"Yes"** or **"No"**
|
|
182
|
+
3. For multiple choices, click the options to respond
|
|
183
|
+
|
|
184
|
+

|
|
185
|
+
*Mobile: Sending messages in the Terminal tab*
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Auto Yes Mode
|
|
190
|
+
|
|
191
|
+
A mode that automatically approves Claude's confirmations.
|
|
192
|
+
Useful when you want to run continuous processes without interruption.
|
|
193
|
+
|
|
194
|
+
### How to Use
|
|
195
|
+
|
|
196
|
+
1. Open the worktree detail view
|
|
197
|
+
2. Turn on the **"Auto Yes"** toggle at the top of the screen
|
|
198
|
+
3. A confirmation dialog appears
|
|
199
|
+
4. **Select the active duration** (1 hour / 3 hours / 8 hours)
|
|
200
|
+
- Default is **1 hour**
|
|
201
|
+
- Select the minimum time needed for your work
|
|
202
|
+
5. The description text changes dynamically based on your selection (e.g., "Will automatically turn OFF after 3 hours.")
|
|
203
|
+
6. Click **"Agree and Enable"**
|
|
204
|
+
|
|
205
|
+
### Active Duration
|
|
206
|
+
|
|
207
|
+
| Option | Milliseconds | Intended Use Case |
|
|
208
|
+
|--------|-------------|-------------------|
|
|
209
|
+
| **1 hour** (default) | 3,600,000 | Normal development work, short tasks |
|
|
210
|
+
| **3 hours** | 10,800,000 | Medium-scale implementation work |
|
|
211
|
+
| **8 hours** | 28,800,000 | Long batch-processing tasks (regular progress checks recommended) |
|
|
212
|
+
|
|
213
|
+
A countdown timer always shows the remaining time.
|
|
214
|
+
- **Under 1 hour**: `MM:SS` format (e.g., `45:30`)
|
|
215
|
+
- **1 hour or more**: `H:MM:SS` format (e.g., `2:15:30`)
|
|
216
|
+
|
|
217
|
+
### API Specification (for developers)
|
|
218
|
+
|
|
219
|
+
The Auto-Yes activation API accepts the following parameters:
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
POST /api/worktrees/:id/auto-yes
|
|
223
|
+
|
|
224
|
+
{
|
|
225
|
+
"enabled": true,
|
|
226
|
+
"duration": 3600000 | 10800000 | 28800000 // Optional (default: 3600000)
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
- **When duration is omitted**: Defaults to 1 hour (3,600,000 ms) for backward compatibility
|
|
231
|
+
- **Invalid duration value**: Returns 400 error
|
|
232
|
+
- **Security**: 5-layer defense with worktreeId format validation -> JSON parse validation -> type validation -> whitelist validation
|
|
233
|
+
|
|
234
|
+
### Approval Routes Differ by Agent
|
|
235
|
+
|
|
236
|
+
There are two routes by which Auto Yes answers a confirmation, and **which one you get is a property
|
|
237
|
+
of the agent**, not of how you set the toggle.
|
|
238
|
+
|
|
239
|
+
| Route | What you see on screen | Agents |
|
|
240
|
+
|-------|------------------------|--------|
|
|
241
|
+
| **Hook approval** | The confirmation dialog **never appears**. The agent asks CommandMate before it runs the tool and proceeds straight away once allowed | Claude / Codex / Copilot / Antigravity (OpenCode does the same thing over SSE rather than hooks) |
|
|
242
|
+
| **Screen-based (TUI numbered response)** | The confirmation dialog **is drawn on the terminal surface**, then a few seconds later it is answered automatically and disappears | **Command Code** / Gemini / Vibe-Local |
|
|
243
|
+
|
|
244
|
+
**Command Code cannot use hook approval, structurally.** It tells CommandMate that it is about to run
|
|
245
|
+
a tool only **after** the permission dialog has been answered — by then the dialog is gone, so the
|
|
246
|
+
reply cannot be an approval. Command Code's Auto Yes therefore runs entirely on the route that reads
|
|
247
|
+
the terminal surface and sends back the option's number key.
|
|
248
|
+
|
|
249
|
+
This does not mean Auto Yes is broken on Command Code: in a live check both a file-creation
|
|
250
|
+
confirmation and a shell-command confirmation were answered automatically. What differs is how it
|
|
251
|
+
looks and what it depends on.
|
|
252
|
+
|
|
253
|
+
- **The dialog is visible for a few seconds** (measured: 3–4 seconds before it is answered and
|
|
254
|
+
disappears). On the four hook-approval tools no dialog appears at all as long as the request is
|
|
255
|
+
allowed
|
|
256
|
+
- **Nothing is answered while the terminal cannot be read.** Reading the terminal surface is this
|
|
257
|
+
route's only input, so a frame that cannot be read — or that slips past detection — leaves the
|
|
258
|
+
dialog standing. Click the option manually when that happens
|
|
259
|
+
- **Who answered is recorded.** In the prompt history on the terminal surface (or
|
|
260
|
+
`commandmate capture <worktree-id> --prompts` from the CLI), `answeredBy` is `auto` for the
|
|
261
|
+
server-side Auto Yes and `human` for a manual answer
|
|
262
|
+
|
|
263
|
+
See [Agent event hooks](./agent-event-hooks.md) for the per-route technical detail.
|
|
264
|
+
|
|
265
|
+
### Important Notes
|
|
266
|
+
|
|
267
|
+
- While Auto Yes is active, all confirmations are automatically answered with "Yes"
|
|
268
|
+
- Important changes (file deletions, etc.) are also auto-approved, so use with caution
|
|
269
|
+
- You can disable it by turning off the toggle
|
|
270
|
+
- Auto Yes automatically turns OFF after the selected duration
|
|
271
|
+
- **Security best practices**:
|
|
272
|
+
- Select the **minimum time** needed for your work (1 hour recommended when in doubt)
|
|
273
|
+
- Limit `CM_ROOT_DIR` to the target worktree directory
|
|
274
|
+
- Manually turn OFF when stepping away for extended periods, regardless of remaining time
|
|
275
|
+
- See [Trust & Safety](../../TRUST_AND_SAFETY.md#auto-yes-有効時間に関するリスクと推奨事項) for details
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Viewing Chat History
|
|
280
|
+
|
|
281
|
+
View past message history.
|
|
282
|
+
|
|
283
|
+
### Desktop
|
|
284
|
+
|
|
285
|
+
History is displayed in the **History column** on the left of each split.
|
|
286
|
+
- User messages and Claude's responses are shown chronologically
|
|
287
|
+
- Scroll to view past history
|
|
288
|
+
|
|
289
|
+
### Showing and hiding it (desktop)
|
|
290
|
+
|
|
291
|
+
The **[History]** and **[Open Files]** buttons on the right of the action bar
|
|
292
|
+
above the splits are the ONLY switches for their column / panel (Issue #2259).
|
|
293
|
+
Hiding the column used to leave a 36px vertical strip carrying a second copy of
|
|
294
|
+
the same button; that strip is **gone**, and the terminal takes the width back
|
|
295
|
+
(108px at three splits).
|
|
296
|
+
|
|
297
|
+
| Button | What it shows/hides | When it is disabled |
|
|
298
|
+
|--------|--------------------|---------------------|
|
|
299
|
+
| **[History]** | Each split's History column. **Applies to every split at once** | While every split shows the Chat surface (chat has no History column) |
|
|
300
|
+
| **[Open Files]** | The file panel on the right; the badge is the open tab count | With no tab open and no diff showing |
|
|
301
|
+
|
|
302
|
+
The arrow in the History column's header points the way it **folds** (left).
|
|
303
|
+
Bring it back with [History] in the action bar.
|
|
304
|
+
|
|
305
|
+
Note that the Activity Bar's **"File Tree"** (the icon column on the far left)
|
|
306
|
+
is for browsing the worktree, and is a different thing from the action bar's
|
|
307
|
+
**"Open Files"** (the panel showing files you opened).
|
|
308
|
+
|
|
309
|
+
### Mobile
|
|
310
|
+
|
|
311
|
+
Tap the **"History"** tab in the tab bar at the bottom.
|
|
312
|
+
- View a list of past interactions
|
|
313
|
+
- Tap for details
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Status Indicators
|
|
318
|
+
|
|
319
|
+
Indicators displayed on each worktree in the sidebar show the current state.
|
|
320
|
+
|
|
321
|
+
| Display | Status | Meaning |
|
|
322
|
+
|---------|--------|---------|
|
|
323
|
+
| Grey dot | idle | No active session |
|
|
324
|
+
| Green dot | ready | Waiting for input (ready to send a new message) |
|
|
325
|
+
| Blue spinner | running | Claude is processing |
|
|
326
|
+
| Yellow dot | waiting | Waiting for user input (yes/no confirmations, etc.) |
|
|
327
|
+
| Blue spinner | generating | Generating response |
|
|
328
|
+
|
|
329
|
+
> **Details**: See [Status Indicator Details](../../features/sidebar-status-indicator.md) for how status detection works.
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Markdown Log Viewer
|
|
334
|
+
|
|
335
|
+
View Claude's detailed output in Markdown format.
|
|
336
|
+
|
|
337
|
+
### Mobile
|
|
338
|
+
|
|
339
|
+
1. Tap the **"Logs"** tab in the tab bar at the bottom
|
|
340
|
+
2. Tap a log file from the list
|
|
341
|
+
3. View the content rendered in Markdown format
|
|
342
|
+
|
|
343
|
+
### Desktop
|
|
344
|
+
|
|
345
|
+
1. Click the **"Info"** button to open the modal
|
|
346
|
+
2. Select a log file from the list to view
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Notes Feature
|
|
351
|
+
|
|
352
|
+
Save notes for each worktree.
|
|
353
|
+
Useful for recording work details and TODOs.
|
|
354
|
+
|
|
355
|
+
### Editing Notes
|
|
356
|
+
|
|
357
|
+
#### Desktop
|
|
358
|
+
|
|
359
|
+
1. Click the **"Info"** button at the top right
|
|
360
|
+
2. Edit in the **"Notes"** section in the modal
|
|
361
|
+
3. Content is auto-saved
|
|
362
|
+
|
|
363
|
+
#### Mobile
|
|
364
|
+
|
|
365
|
+
1. Tap the **"Info"** tab in the tab bar at the bottom
|
|
366
|
+
2. Edit in the **"Notes"** section
|
|
367
|
+
3. Content is auto-saved
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Agent Settings
|
|
372
|
+
|
|
373
|
+
Select which CLI agents to use for each worktree.
|
|
374
|
+
|
|
375
|
+
### How to Configure
|
|
376
|
+
|
|
377
|
+
1. Select a worktree
|
|
378
|
+
2. Click the **"CMATE"** tab
|
|
379
|
+
3. Click the **"Agent"** sub-tab
|
|
380
|
+
4. Select **2** agents using the checkboxes
|
|
381
|
+
5. Settings are saved automatically
|
|
382
|
+
|
|
383
|
+
### Available Agents
|
|
384
|
+
|
|
385
|
+
| Agent | Description |
|
|
386
|
+
|-------|-------------|
|
|
387
|
+
| **Claude** | Claude Code CLI |
|
|
388
|
+
| **Codex** | OpenAI Codex CLI |
|
|
389
|
+
| **Gemini** | Google Gemini CLI |
|
|
390
|
+
| **Vibe-Local** | Ollama local LLM |
|
|
391
|
+
| **OpenCode** | OpenCode CLI |
|
|
392
|
+
| **OpenCode V2** | OpenCode 2.0 (`opencode2`, [OpenCode V2 guide](./opencode-v2.md)) |
|
|
393
|
+
| **Copilot** | GitHub Copilot CLI |
|
|
394
|
+
| **Antigravity** | Antigravity CLI (`agy`) |
|
|
395
|
+
| **Command Code** | Command Code CLI (`commandcode`, Issue #2250) |
|
|
396
|
+
|
|
397
|
+
- You must always select exactly **2** agents
|
|
398
|
+
- **Auto Yes behaves differently per agent.** Command Code / Gemini / Vibe-Local only have
|
|
399
|
+
the screen-based route (the dialog is drawn once, then answered automatically). See
|
|
400
|
+
[Approval Routes Differ by Agent](#approval-routes-differ-by-agent)
|
|
401
|
+
- The selected agents appear as tabs in the terminal header
|
|
402
|
+
|
|
403
|
+
### Ollama Model Selection (Vibe-Local)
|
|
404
|
+
|
|
405
|
+
When Vibe-Local is selected, you can specify which Ollama model to use.
|
|
406
|
+
|
|
407
|
+
1. Choose a model from the **"Ollama Model"** selector in the Agent settings
|
|
408
|
+
2. If Ollama is not running, "Ollama is not running" is displayed
|
|
409
|
+
|
|
410
|
+
> **Note**: The selected model is also used for scheduled executions (CMATE.md).
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
## Switching the Output Surface (Terminal / Chat)
|
|
415
|
+
|
|
416
|
+
A session's screen is split into an **output surface** (where you watch what the agent is
|
|
417
|
+
doing) and an **input surface** (the composer and the answer buttons). Only the **output
|
|
418
|
+
surface** switches — the input surface stays exactly the same in either mode
|
|
419
|
+
(Issue #2193 / #2194).
|
|
420
|
+
|
|
421
|
+
| Mode | What you see | When it helps |
|
|
422
|
+
|------|--------------|---------------|
|
|
423
|
+
| **Terminal** | The tmux screen as it is drawn (TUI borders, cursor and pagers included) | Working a dialog, TUI-specific screens, reading output in detail |
|
|
424
|
+
| **Chat** | A flat column of bubbles (one message per row; your messages as bubbles on the right, the agent's replies in full across the row) | Following what was exchanged, watching progress from a phone |
|
|
425
|
+
|
|
426
|
+
### How to switch
|
|
427
|
+
|
|
428
|
+
| Screen | Action |
|
|
429
|
+
|--------|--------|
|
|
430
|
+
| **Desktop** | Click the **Terminal / Chat toggle** in each split's header |
|
|
431
|
+
| **Mobile** | Tap the **round toggle** floating over the top-right corner of the output area |
|
|
432
|
+
| **Keyboard** | **`Cmd/Ctrl + Shift + M`** (press `?` for the shortcut list) |
|
|
433
|
+
|
|
434
|
+
`Cmd/Ctrl + Shift + M` acts on the **split that holds focus**. With focus outside every
|
|
435
|
+
split, the first split switches — except while you are typing in a field elsewhere on the
|
|
436
|
+
page, where the chord is left alone.
|
|
437
|
+
|
|
438
|
+
A switch is remembered **per split on desktop, and per tab on the phone**. Which surface a
|
|
439
|
+
session *opens* in is set in
|
|
440
|
+
[The Default Output Surface](#the-default-output-surface-terminal--chat).
|
|
441
|
+
|
|
442
|
+
You can also deep-link a surface with **`?view=terminal`** / **`?view=chat`** (for example
|
|
443
|
+
`/worktrees/<id>?pane=terminal&view=chat`). It is independent of `?pane=`, and the value is
|
|
444
|
+
written back to that surface's stored preference, so a shared `?view=chat` link does not
|
|
445
|
+
quietly revert on the next visit.
|
|
446
|
+
|
|
447
|
+
### What the chat surface shows
|
|
448
|
+
|
|
449
|
+
The chat surface is **its own column of bubbles, separate from the History column**
|
|
450
|
+
(Issue #2232). One message is one row: **your messages are bubbles on the right**, and
|
|
451
|
+
**the agent's replies take the full width of the row** and are shown **in full**. There is
|
|
452
|
+
no 100-character clamp and no "show more" here — that is the History column's shape.
|
|
453
|
+
|
|
454
|
+
- **A generating indicator** — "Responding…" / "Thinking…" while the agent is working
|
|
455
|
+
- **The reply as it is written** — on agents that support it, the in-progress answer streams
|
|
456
|
+
**in place at the end of the column** (Issue #2199 / #2233). When it is too long and the
|
|
457
|
+
head had to be dropped, it says "Showing the latest part only"
|
|
458
|
+
- **In-flight becomes settled without moving** — when the reply is finished, the body stays
|
|
459
|
+
in the **same place, in the same type**; the only thing that changes is the spinner going
|
|
460
|
+
away (Issue #2233). Until the settled row reaches the transcript, the body is held with
|
|
461
|
+
"Not saved to the conversation yet" beside it, so it never blinks out (Issue #2248)
|
|
462
|
+
- **Chips for tool calls, reasoning and approvals** — tool calls, the reasoning section and
|
|
463
|
+
approval dialogs are taken out of the reply body and become **one-line chips that are
|
|
464
|
+
folded by default** ("Tool calls · 3", "Tool approvals · 5"). Pressing a chip opens it in
|
|
465
|
+
place (Issue #2245 / #2272 / #2284). The **"Show / Hide tool activity"** toggle at the top
|
|
466
|
+
right of the column folds and unfolds the whole column at once
|
|
467
|
+
- **"Jump to latest"** — press it to return to the newest row while you are reading back
|
|
468
|
+
through the transcript; it reads "Jump to latest (still responding)" while a reply is
|
|
469
|
+
being written. At the tail it offers "Jump to the beginning" instead (Issue #2283)
|
|
470
|
+
- **The dialog card** — when a dialog or a selection list is up on the TUI side, a card that
|
|
471
|
+
shows the **tail of the terminal screen** as-is with the controls for it underneath
|
|
472
|
+
(Issue #2254). See the next section
|
|
473
|
+
|
|
474
|
+
> **Note**: the controls that **narrow the transcript** — the display-count select, "Show
|
|
475
|
+
> archived" and "User only" — **are not on the chat surface**. They belong to the History
|
|
476
|
+
> column; search is the only one of them chat keeps.
|
|
477
|
+
|
|
478
|
+
### The dialog card — answering a TUI without leaving chat
|
|
479
|
+
|
|
480
|
+
When something the chat surface **cannot drive** is on screen on the terminal side, this
|
|
481
|
+
surface used to raise an "Open terminal" banner and send you to the terminal. **That
|
|
482
|
+
behaviour was withdrawn by Issue #2254.** Below the banner there is now a card showing the
|
|
483
|
+
**tail of the terminal screen as it is** (12-20 rows; 12 on a phone), with the controls for
|
|
484
|
+
that kind of screen directly under it. You answer it without leaving chat.
|
|
485
|
+
|
|
486
|
+
| Kind of screen | What appears under the card |
|
|
487
|
+
|------|--------------------|
|
|
488
|
+
| A pager is open | Arrow keys plus PgUp / PgDn / Home / End / q |
|
|
489
|
+
| A selection list is open | Arrow keys plus Enter / Esc |
|
|
490
|
+
| A screen nothing could classify | Arrows and Esc (Navigate) plus the digits 1-9, y / n and Enter |
|
|
491
|
+
| Waiting, with options nobody could read | The digits 1-9, y / n and Enter |
|
|
492
|
+
|
|
493
|
+
**Press the number or y/n while reading the card.** Enter confirms whatever the CLI has
|
|
494
|
+
currently highlighted, so on a numbered dialog an Enter meant as "no" can land as an
|
|
495
|
+
approval (Issue #1681).
|
|
496
|
+
|
|
497
|
+
The "Open terminal" button **remains, as a secondary way out**. The card shows only the last
|
|
498
|
+
few rows, so switch to the terminal surface from here when you need scrollback or search.
|
|
499
|
+
|
|
500
|
+
While the card is up, **no control is duplicated**. The navigation buttons / Navigate pad
|
|
501
|
+
above the composer on desktop, and the navigation buttons docked above the composer on a
|
|
502
|
+
phone, defer to the card's copies while the chat surface is showing (on the terminal surface
|
|
503
|
+
they behave exactly as before).
|
|
504
|
+
|
|
505
|
+
**An ordinary yes/no or numbered prompt raises neither a card nor a banner.** The answer
|
|
506
|
+
panel on the input surface works as it is — the answer UI lives on the input surface rather
|
|
507
|
+
than the output one, so you can reply without leaving chat. Drawing a card there would put
|
|
508
|
+
two answer UIs on one dialog, so that one case is deliberately left alone.
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## The Default Output Surface (Terminal / Chat)
|
|
513
|
+
|
|
514
|
+
A session's **output** half switches between the terminal (the tmux screen as it is drawn)
|
|
515
|
+
and chat (the conversation transcript) from the header toggle (Issue #2193). A switch is
|
|
516
|
+
remembered per split and per phone tab, but that is "how you last left it", not "what it
|
|
517
|
+
opens as". If you want to **always start in chat**, pick `Terminal` or `Chat` under
|
|
518
|
+
**More screen → Settings → "Default output surface"** (Issue #2201). The setting is stored
|
|
519
|
+
server-wide, and it applies **only to surfaces you have not switched yet**: a split or phone
|
|
520
|
+
tab you already toggled by hand keeps the mode you left it in, and saving the setting never
|
|
521
|
+
pulls it back.
|
|
522
|
+
|
|
523
|
+
Each browser picks the value up in the background the first time it opens any session
|
|
524
|
+
surface, and what that request buys is the **next** surface opened — including, after a
|
|
525
|
+
reload, the first one. Opening the More screen seeds it immediately on that device. A
|
|
526
|
+
browser that has never reached the server starts on `Terminal`.
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
530
|
+
## Temporarily Maximizing One Split (Desktop)
|
|
531
|
+
|
|
532
|
+
Two or three splits side by side means each one is narrow. When you only need the room
|
|
533
|
+
while reading a long dialog or a diff, you can **blow one split up to the full width and
|
|
534
|
+
put it back with the same gesture** (Issue #2261).
|
|
535
|
+
|
|
536
|
+
| Action | Where |
|
|
537
|
+
|--------|-------|
|
|
538
|
+
| **Maximize / restore** | The button at the right end of each split's title bar (⤢ / ⤡) |
|
|
539
|
+
| **Maximize / restore** | The button in the action bar above the splits (acts on the focused split) |
|
|
540
|
+
| **Maximize / restore** | `Cmd/Ctrl + Shift + Enter` |
|
|
541
|
+
|
|
542
|
+
`Cmd/Ctrl + Shift + Enter` follows the same rule as `Cmd/Ctrl + Shift + M` (the output
|
|
543
|
+
surface switch): it acts on the **split that holds focus**. With focus outside every split,
|
|
544
|
+
the first split answers — except while you are typing in a field outside the splits.
|
|
545
|
+
|
|
546
|
+
The hidden splits **keep their sessions and keep polling** while they are off screen, so
|
|
547
|
+
restoring shows the output that arrived in the meantime. The action bar's `2 / 3 splits`
|
|
548
|
+
label reads "Split 2 maximized" while one is maximized.
|
|
549
|
+
|
|
550
|
+
Because it is **temporary**, the layout comes back on its own when you:
|
|
551
|
+
|
|
552
|
+
- add or remove a split,
|
|
553
|
+
- press the equalize-widths button in the action bar,
|
|
554
|
+
- switch to another worktree, or
|
|
555
|
+
- reload the page (the maximized state is not persisted; the width ratios you dragged are,
|
|
556
|
+
so restoring returns the exact proportions you had).
|
|
557
|
+
|
|
558
|
+
The file panel on the right is not part of this. Hide it with **[Open Files]** in the
|
|
559
|
+
action bar instead.
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
## Execution Contract and Verification
|
|
564
|
+
|
|
565
|
+
The **execution contract** handed to an agent with `commandmate send --contract`, and the
|
|
566
|
+
**gate verdicts** `commandmate verify` produced from it, are readable on screen — no CLI
|
|
567
|
+
stdout required (Issue #1816).
|
|
568
|
+
|
|
569
|
+
### The header status chip
|
|
570
|
+
|
|
571
|
+
A worktree that was delegated with a contract shows a status chip in its header, carrying
|
|
572
|
+
the task title, its `TaskStatus`, and the `RESULT` of the most recent verification run.
|
|
573
|
+
|
|
574
|
+
- A worktree with no task row shows **no chip at all**
|
|
575
|
+
- Hovering the chip (or reading it with a screen reader) gives the **reason** behind the
|
|
576
|
+
verdict, down to the ids of the gates that did not pass
|
|
577
|
+
- Clicking the chip opens the **Verification** pane
|
|
578
|
+
|
|
579
|
+
### The Verification pane
|
|
580
|
+
|
|
581
|
+
| Screen | How to open |
|
|
582
|
+
|---------|-------------|
|
|
583
|
+
| Desktop | The shield icon (Verification) in the left Activity Bar |
|
|
584
|
+
| Mobile | **Tools** tab in the bottom bar → **Verification** sub-tab |
|
|
585
|
+
|
|
586
|
+
The pane has three sections, top to bottom.
|
|
587
|
+
|
|
588
|
+
1. **Execution contract** — title, the start of `goal`, `scope.allow`, `verify.gates`,
|
|
589
|
+
`autoYes.mode`, and the contract file path. With no contract, it says how to create one
|
|
590
|
+
(`commandmate send --contract`, or the `cmate-task-contract` Skill)
|
|
591
|
+
2. **Verification runs** — newest first (start time, `RESULT`, run id, trigger), plus the
|
|
592
|
+
**Re-verify** button. Selecting a run switches the third section to it
|
|
593
|
+
3. **Gates** — the selected run's gate table: gate id, `PASS` / `FAIL` / `TIMEOUT` / `SKIP`,
|
|
594
|
+
exit code, duration, and the last 40 log lines. Gates that did not pass open with their
|
|
595
|
+
log already expanded
|
|
596
|
+
|
|
597
|
+
### The Re-verify button
|
|
598
|
+
|
|
599
|
+
It calls `POST /api/worktrees/:id/verify` and re-reads the list as soon as the route answers
|
|
600
|
+
202 with a run id. Gates are whole suites and builds, so the request returns **before** any
|
|
601
|
+
verdict exists; progress then arrives on the worktree detail screen's existing poll. When a
|
|
602
|
+
run is already going, the pane says so and names it.
|
|
603
|
+
|
|
604
|
+
> **This surface is read-only.** There is no contract editor. Edit
|
|
605
|
+
> `.commandmate/tasks/<name>.yaml` directly and re-send with `commandmate send --contract` —
|
|
606
|
+
> scope is judged against the **snapshot taken at send time**, so editing the YAML alone
|
|
607
|
+
> changes no verdict.
|
|
608
|
+
|
|
609
|
+
---
|
|
610
|
+
|
|
611
|
+
## Mobile Access
|
|
612
|
+
|
|
613
|
+
How to access CommandMate from your smartphone.
|
|
614
|
+
|
|
615
|
+
There are two routes. **Try `commandmate remote` first.** Use
|
|
616
|
+
[Method 2: connect directly on the same LAN](#method-2-connect-directly-on-the-same-lan-without-cloudflared)
|
|
617
|
+
only if you would rather not install a provider tool, or you want to stay inside the LAN.
|
|
618
|
+
|
|
619
|
+
| | Method 1: `commandmate remote` | Method 2: direct on the same LAN |
|
|
620
|
+
|---|---|---|
|
|
621
|
+
| **Authentication** | Yes (only the paired phone) | **None** |
|
|
622
|
+
| **Encryption** | Yes (HTTPS on the outside) | **None** (plain HTTP) |
|
|
623
|
+
| **Reach** | Also from away (over the internet or your tailnet) | Only inside the same Wi-Fi |
|
|
624
|
+
| **Requires** | `tailscale` or `cloudflared` | Nothing |
|
|
625
|
+
| **Using the PC at the same time** | No login needed with `--auth remote-only` (below) | Works as it is |
|
|
626
|
+
| **Server bind** | Stays `127.0.0.1` | `0.0.0.0` (every interface) |
|
|
627
|
+
|
|
628
|
+
### Method 1 (recommended): `commandmate remote` with QR pairing
|
|
629
|
+
|
|
630
|
+
`commandmate remote` **starts the server, publishes it, and pairs your phone** in one
|
|
631
|
+
command. A QR code is printed in the terminal; point your phone's camera at it.
|
|
632
|
+
|
|
633
|
+
```bash
|
|
634
|
+
commandmate remote
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
It does four things:
|
|
638
|
+
|
|
639
|
+
1. Detects the providers (the ways out) and picks one
|
|
640
|
+
2. **Asks you before creating a public tunnel** (see "Approval before publishing" below)
|
|
641
|
+
3. Starts a CommandMate server with authentication enabled
|
|
642
|
+
4. Prints a QR code for `https://<published URL>/login#code=<code>`, carrying a one-time
|
|
643
|
+
pairing code
|
|
644
|
+
|
|
645
|
+
Scanning that QR code on the phone completes the sign-in. **The pairing code is single-use
|
|
646
|
+
and expires after 10 minutes by default.** That is the only time the code is shown —
|
|
647
|
+
`commandmate remote status` shows the URL but never shows the code again.
|
|
648
|
+
|
|
649
|
+
#### Approval before publishing
|
|
650
|
+
|
|
651
|
+
`commandmate remote` can publish through either of two providers:
|
|
652
|
+
|
|
653
|
+
| Provider | `--provider` | What it publishes to |
|
|
654
|
+
|---|---|---|
|
|
655
|
+
| Tailscale Serve | `tailscale` | Your own tailnet — not the public internet. Tried first |
|
|
656
|
+
| Cloudflare Quick Tunnel | `cloudflare` | A temporary **public internet** address, `https://<random>.trycloudflare.com` |
|
|
657
|
+
|
|
658
|
+
Because the Cloudflare route puts this machine on the public internet, `commandmate remote`
|
|
659
|
+
prints a warning and asks y/n before creating that tunnel. In a non-interactive environment
|
|
660
|
+
(a script, CI) **there is no way to ask, so it refuses by default** and stops with
|
|
661
|
+
`CONFIG_ERROR` (exit 2). Pass `--yes` only when you mean to publish.
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
commandmate remote --yes # skip the confirmation and create the public tunnel
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
> **If no provider is ready, `remote` stops with `DEPENDENCY_ERROR` (exit 1).**
|
|
668
|
+
> It never switches to a public tunnel on its own because Tailscale was unavailable.
|
|
669
|
+
|
|
670
|
+
> **Fixed — the Cloudflare route used to die together with the command
|
|
671
|
+
> ([#2146](https://github.com/Kewton/CommandMate/issues/2146), now closed).** As measured on
|
|
672
|
+
> 2026-08-29, `cloudflared` exited the moment `commandmate remote` returned and the URL it
|
|
673
|
+
> had just printed started answering HTTP 530 within seconds, leaving no time to scan the QR
|
|
674
|
+
> code (defect **D-1**). The cause was the shape of the spawn: the child's stderr stayed on a
|
|
675
|
+
> pipe that closed with the parent.
|
|
676
|
+
> [**#2148**](https://github.com/Kewton/CommandMate/pull/2148) **points fd 2 at a file
|
|
677
|
+
> (`~/.commandmate/cloudflared.log`) instead of a pipe, together with `detached: true` and
|
|
678
|
+
> `unref()`**, and [#2149](https://github.com/Kewton/CommandMate/pull/2149) re-ran the check
|
|
679
|
+
> against the real `cloudflared` 2025.4.0: the published URL answered **non-530 at t+22.6 /
|
|
680
|
+
> +56.7 / +60.3 seconds after `up` returned**, and went **530 within 2.3 seconds of
|
|
681
|
+
> `remote stop`** — alive while published, revoked on teardown. Both measurements are in
|
|
682
|
+
> [`docs/qa/1937-remote-uat-record.md`](../../qa/1937-remote-uat-record.md) (D-1 in §3.6, its
|
|
683
|
+
> resolution in §6).
|
|
684
|
+
|
|
685
|
+
#### Using the PC at the same time (`--auth remote-only`)
|
|
686
|
+
|
|
687
|
+
Under the default `--auth all`, a remote session **also asks the browser on this machine to
|
|
688
|
+
log in** — and because the plaintext token is deleted the instant pairing succeeds, there is
|
|
689
|
+
no way to log in from the PC. The CLI on this machine (`commandmate ls` / `send` / `wait` /
|
|
690
|
+
`capture`) stops for the same reason. Pass `--auth remote-only` when you want the phone and
|
|
691
|
+
the PC at once.
|
|
692
|
+
|
|
693
|
+
```bash
|
|
694
|
+
commandmate remote --auth remote-only
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
| Value | Through the provider (your phone) | Local on this PC (`http://localhost:<port>`) |
|
|
698
|
+
|-------|----------------------------------|----------------------------------------------|
|
|
699
|
+
| `all` (default) | Authenticated | Authenticated |
|
|
700
|
+
| `remote-only` | Authenticated | **Not authenticated** |
|
|
701
|
+
|
|
702
|
+
In this mode the server opens **a second listener on a separate `127.0.0.1` port** alongside
|
|
703
|
+
the existing one, and the provider is pointed at that one alone. Authentication is decided by
|
|
704
|
+
which listener a request arrived on, so forging a source IP or a `Host` header cannot make
|
|
705
|
+
the provider route unauthenticated (a tunnel's upstream is `127.0.0.1` too, which is exactly
|
|
706
|
+
why the source address cannot tell the two apart).
|
|
707
|
+
|
|
708
|
+
- The provider route stays authenticated (before pairing: 307 for screens, 401 for the API, 401 for WebSocket)
|
|
709
|
+
- **IP restriction (`CM_ALLOWED_IPS`) is not exempt**
|
|
710
|
+
- A non-loopback `CM_BIND` (`0.0.0.0` and friends) is refused with exit 2
|
|
711
|
+
|
|
712
|
+
> **The trade-off.** Under `remote-only`, any process on this PC — including the agents
|
|
713
|
+
> CommandMate runs in tmux — can reach the API without a token. That is the same exposure as
|
|
714
|
+
> ordinary local use without `remote`, and weaker than `all`, so `all` remains the default.
|
|
715
|
+
|
|
716
|
+
#### Checking the state, and packing up
|
|
717
|
+
|
|
718
|
+
```bash
|
|
719
|
+
commandmate remote status # provider, URL, expiry, pairing state
|
|
720
|
+
commandmate remote stop # close the outward door
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
`remote stop` reverts **only the settings CommandMate itself created**. When the state file
|
|
724
|
+
cannot be read it does not guess which provider to tear down — it says it does not know
|
|
725
|
+
what to clean up and exits successfully.
|
|
726
|
+
|
|
727
|
+
**When the session expires, only the outward door closes; the server is not stopped.**
|
|
728
|
+
Stopping it would take your local use of the machine down with it.
|
|
729
|
+
|
|
730
|
+
> **With Tailscale, always pack up with `commandmate remote stop`.** After a successful
|
|
731
|
+
> `tailscale serve`, Tailscale itself suggests disabling the proxy by re-running `serve`
|
|
732
|
+
> with only the port and the word "off" and no path. That form removes **every** handler on
|
|
733
|
+
> that port, including mappings you set up yourself, silently and with exit status 0.
|
|
734
|
+
|
|
735
|
+
#### Main options
|
|
736
|
+
|
|
737
|
+
| Option | Default | Description |
|
|
738
|
+
|--------|---------|-------------|
|
|
739
|
+
| `--provider <tailscale\|cloudflare>` | Auto | Force a provider |
|
|
740
|
+
| `--expires <duration>` | `8h` | Remote session TTL (`1h`-`30d`) |
|
|
741
|
+
| `--pairing-expires <duration>` | `10m` | Pairing code TTL (`1m`-`24h`) |
|
|
742
|
+
| `-p, --port <number>` | Auto | Port of the server to expose |
|
|
743
|
+
| `--yes` | — | Approve a public tunnel (required when non-interactive) |
|
|
744
|
+
| `--auth <all\|remote-only>` | `all` | How far authentication reaches (see "Using the PC at the same time" above) |
|
|
745
|
+
| `--json` | — | JSON output |
|
|
746
|
+
|
|
747
|
+
Exit codes: `0` success / `1` DEPENDENCY_ERROR / `2` CONFIG_ERROR / `3` START_FAILED /
|
|
748
|
+
`4` STOP_FAILED / `99` UNEXPECTED_ERROR.
|
|
749
|
+
For the CLI in full, see the [CLI Operations Guide](./cli-operations-guide.md#commandmate-remote).
|
|
750
|
+
|
|
751
|
+
#### Worth knowing
|
|
752
|
+
|
|
753
|
+
- **`CM_BIND` does not change.** `remote` never writes it and the server stays bound to
|
|
754
|
+
`127.0.0.1`; it is **read** only under `--auth remote-only`, to decide whether that mode is
|
|
755
|
+
allowed at all. All `remote` adds is one door out.
|
|
756
|
+
- **Auto-Yes stays off by default.** `remote` has no flag that enables Auto-Yes.
|
|
757
|
+
- **No plaintext long-lived token is stored anywhere.** The server is handed only
|
|
758
|
+
`CM_AUTH_TOKEN_HASH`, `CM_AUTH_EXPIRE`, `CM_REMOTE_PAIRING_FILE` and `CM_AUTH_SCOPE` —
|
|
759
|
+
five with `CM_REMOTE_INGRESS_PORT` under `--auth remote-only` — and none of them is a
|
|
760
|
+
secret (`CM_REMOTE_PAIRING_FILE` is a file path). The pairing handoff file
|
|
761
|
+
`~/.commandmate/remote-pairing.json` is mode 0600 and is **deleted the instant pairing
|
|
762
|
+
succeeds**.
|
|
763
|
+
- **The login cookie carries no `Secure` attribute over a tunnel, and that is correct.**
|
|
764
|
+
Setting `Secure` would make the browser refuse the cookie during local use over
|
|
765
|
+
`http://127.0.0.1:3000`, breaking access from the PC. The outside of the tunnel is HTTPS,
|
|
766
|
+
so the eavesdropping risk on the wire is already addressed. See the
|
|
767
|
+
[Security Guide](../security-guide.md) for details.
|
|
768
|
+
|
|
769
|
+
#### OS support status
|
|
770
|
+
|
|
771
|
+
Measured as of 2026-08-29. **Read "measured" and "unverified" as the different things they
|
|
772
|
+
are.** The procedure and raw logs are under `dev-reports/issue/1937/u8-os-matrix.md`, and
|
|
773
|
+
the live acceptance run is in
|
|
774
|
+
[`docs/qa/1937-remote-uat-record.md`](../../qa/1937-remote-uat-record.md).
|
|
775
|
+
|
|
776
|
+
| OS | Provider detection | Approval flow | Reaching the published tunnel | Notes |
|
|
777
|
+
|----|--------------------|---------------|-------------------------------|-------|
|
|
778
|
+
| **macOS** (Darwin arm64) | ✅ Measured<br>`ready` once the provider tool is installed | ✅ Measured<br>non-interactive stops with exit 2 | ✅ Measured<br>Tailscale Serve passed; Cloudflare Quick Tunnel failed at first (**D-1**) and has passed since [#2148](https://github.com/Kewton/CommandMate/pull/2148), re-confirmed against the real `cloudflared` in [#2149](https://github.com/Kewton/CommandMate/pull/2149) | cloudflared 2025.4.0, Tailscale 1.102.3 |
|
|
779
|
+
| **Linux** (Debian 12 / aarch64) | ✅ Measured<br>`DEPENDENCY_ERROR` (exit 1) before install, `ready` after | ✅ Measured<br>identical to macOS | ⏭️ Not attempted | ⚠️ **Measured in a docker container, whose network setup can differ from bare-metal Linux** |
|
|
780
|
+
| **WSL2** | ❌ **Unverified** | ❌ **Unverified** | ❌ **Unverified** | **No test environment was available.** WSL2 varies widely in how `localhost` is forwarded, so **whether the tunnel's `127.0.0.1` upstream points inside WSL2 or at the Windows side is configuration-dependent** |
|
|
781
|
+
|
|
782
|
+
- ✅ **Measured** / ⏭️ **Not attempted** (deliberately skipped, to avoid creating a new
|
|
783
|
+
public tunnel) / ❌ **Unverified** (no environment to test in)
|
|
784
|
+
- The "measured" entries in the detection and approval columns are the part that can be
|
|
785
|
+
checked **without creating a public tunnel** (provider detection, the approval gate,
|
|
786
|
+
`status` and `stop`).
|
|
787
|
+
- **End-to-end use from a real phone (scanning the QR code, pairing, the PWA, push
|
|
788
|
+
notifications) is still outstanding on every OS.** The acceptance run covered the server
|
|
789
|
+
side only, and the phone pass is tracked in
|
|
790
|
+
[#2152](https://github.com/Kewton/CommandMate/issues/2152).
|
|
791
|
+
|
|
792
|
+
### Method 2: Connect directly on the same LAN (without `cloudflared`)
|
|
793
|
+
|
|
794
|
+
Use this if you would rather not install a provider tool, or you want nothing to leave the
|
|
795
|
+
LAN at all.
|
|
796
|
+
|
|
797
|
+
> ⚠️ **This method opens the server to the LAN with no authentication.**
|
|
798
|
+
> `CM_BIND=0.0.0.0` makes CommandMate listen on every network interface of your PC.
|
|
799
|
+
> **Anyone** on the same Wi-Fi who opens `http://<your PC's IP address>:3000` in a browser
|
|
800
|
+
> can operate your repositories, terminals and agents **without being asked to authenticate**.
|
|
801
|
+
> Do not use it on shared Wi-Fi (a cafe, a coworking space, a corporate guest network).
|
|
802
|
+
> If you need authentication and encryption, use
|
|
803
|
+
> [Method 1](#method-1-recommended-commandmate-remote-with-qr-pairing).
|
|
804
|
+
|
|
805
|
+
1. Connect your PC and smartphone to the same Wi-Fi
|
|
806
|
+
2. Edit the `.env` file:
|
|
807
|
+
```
|
|
808
|
+
CM_BIND=0.0.0.0
|
|
809
|
+
```
|
|
810
|
+
3. Restart the server
|
|
811
|
+
4. Open `http://<your PC's IP address>:3000` in your smartphone's browser
|
|
812
|
+
|
|
813
|
+
When you are done, set `CM_BIND` back to `127.0.0.1` (the default) and restart the server.
|
|
814
|
+
|
|
815
|
+
#### Finding Your PC's IP Address
|
|
816
|
+
|
|
817
|
+
```bash
|
|
818
|
+
# macOS
|
|
819
|
+
ifconfig | grep "inet " | grep -v 127.0.0.1
|
|
820
|
+
|
|
821
|
+
# Linux
|
|
822
|
+
ip addr | grep "inet " | grep -v 127.0.0.1
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
#### Exposing to an external network
|
|
826
|
+
|
|
827
|
+
If you publish the server yourself rather than through `commandmate remote`, always pair it
|
|
828
|
+
with authentication at a reverse proxy. See the [Security Guide](../security-guide.md) and
|
|
829
|
+
the [Deployment Guide](../../DEPLOYMENT.md) for details.
|
|
830
|
+
|
|
831
|
+
### Mobile UI
|
|
832
|
+
|
|
833
|
+
On mobile, a tab bar is displayed at the bottom:
|
|
834
|
+
|
|
835
|
+
| Tab | Content |
|
|
836
|
+
|-----|---------|
|
|
837
|
+
| **Terminal** | Real-time output + message input |
|
|
838
|
+
| **History** | Chat history |
|
|
839
|
+
| **Files** | File tree view |
|
|
840
|
+
| **CMATE** | Notes + execution logs |
|
|
841
|
+
| **Info** | Worktree information |
|
|
842
|
+
|
|
843
|
+

|
|
844
|
+
*Mobile: Homepage*
|
|
845
|
+
|
|
846
|
+
### Installing as an app (PWA)
|
|
847
|
+
|
|
848
|
+
CommandMate is a Progressive Web App. On a mobile browser, use **Add to Home Screen** to launch it
|
|
849
|
+
full-screen (standalone), which is ideal for monitoring agents on the go. A Service Worker precaches
|
|
850
|
+
static assets and shows an offline fallback screen; API responses, the login page, and WebSocket
|
|
851
|
+
traffic are never cached.
|
|
852
|
+
|
|
853
|
+
> **HTTPS is required for installation.** Browsers only register a Service Worker (and offer
|
|
854
|
+
> install) on `https://` or `http://127.0.0.1`. When accessing a self-hosted instance over plain HTTP
|
|
855
|
+
> on the LAN (e.g. `http://192.168.x.x:3000`), install and offline support are disabled by the
|
|
856
|
+
> browser — use `commandmate remote`, a tunnel or an HTTPS reverse proxy to enable them. The app
|
|
857
|
+
> itself remains fully usable without the PWA layer.
|
|
858
|
+
|
|
859
|
+
Once installed, the app can also receive push notifications while it is closed — see
|
|
860
|
+
[Phone Notifications (Web Push)](#phone-notifications-web-push).
|
|
861
|
+
|
|
862
|
+
---
|
|
863
|
+
|
|
864
|
+
## Phone Notifications (Web Push)
|
|
865
|
+
|
|
866
|
+
CommandMate can push a notification to your phone **while the app is closed** — when an
|
|
867
|
+
agent is waiting for you, when a verification gate fails, or when a session could not
|
|
868
|
+
start.
|
|
869
|
+
|
|
870
|
+
**No notification is sent until you finish every step in this section.** A fresh install
|
|
871
|
+
has no VAPID keys, and without them the whole push feature is off.
|
|
872
|
+
|
|
873
|
+
### 0. Prerequisites (check these first)
|
|
874
|
+
|
|
875
|
+
| Prerequisite | Why | How to check |
|
|
876
|
+
|---|---|---|
|
|
877
|
+
| **You reach the app over HTTPS** | Service Worker and PushManager require a secure context. `127.0.0.1` is exempt, but **your phone is not** — it is a different host. The subscribe button does not work over `http://<your PC's IP>:3000` on the same LAN | The address bar on the phone says `https://` |
|
|
878
|
+
| **iOS / iPadOS: add to Home Screen** | Web Push is unavailable in a Safari tab. You can only subscribe from an **installed** app, launched from the Home Screen icon | If you see "add this app to your Home Screen" instead of the subscribe button, this is why |
|
|
879
|
+
| **Android Chrome works in a normal tab** | No Home Screen install needed | — |
|
|
880
|
+
|
|
881
|
+
Three ways to get HTTPS:
|
|
882
|
+
|
|
883
|
+
- **`commandmate remote`** (simplest; recommended): the provider terminates TLS, so the
|
|
884
|
+
phone reaches the app over HTTPS and the secure-context requirement is met as-is. See
|
|
885
|
+
[Mobile Access](#method-1-recommended-commandmate-remote-with-qr-pairing)
|
|
886
|
+
- **A tunnel you set up yourself** (also works away from home): Cloudflare Tunnel and
|
|
887
|
+
friends — see the [Deployment Guide](../../DEPLOYMENT.md)
|
|
888
|
+
- **A self-signed certificate** (same LAN only):
|
|
889
|
+
```bash
|
|
890
|
+
brew install mkcert && mkcert -install && mkcert <your PC's IP address>
|
|
891
|
+
commandmate start --cert ./<cert>.pem --key ./<key>.pem
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
### 1. Generate the VAPID keys
|
|
895
|
+
|
|
896
|
+
`commandmate init` generates the key pair and writes it into `.env`.
|
|
897
|
+
**You never have to type a `node -e "require('web-push')..."` one-liner.**
|
|
898
|
+
|
|
899
|
+
```bash
|
|
900
|
+
commandmate init
|
|
901
|
+
```
|
|
902
|
+
|
|
903
|
+
If `.env` already exists, `--force` rewrites it — and **an existing key pair is carried
|
|
904
|
+
across**. The public key is baked into the `PushSubscription` every subscribed browser
|
|
905
|
+
holds, so replacing the pair would silently cut off every device that had subscribed.
|
|
906
|
+
|
|
907
|
+
```bash
|
|
908
|
+
commandmate init --force
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
### 2. Check the three variables in `.env`
|
|
912
|
+
|
|
913
|
+
```bash
|
|
914
|
+
CM_VAPID_PUBLIC_KEY=<base64url, 65 bytes>
|
|
915
|
+
CM_VAPID_PRIVATE_KEY=<base64url, 32 bytes>
|
|
916
|
+
CM_VAPID_SUBJECT=https://github.com/Kewton/CommandMate
|
|
917
|
+
```
|
|
918
|
+
|
|
919
|
+
`CM_VAPID_SUBJECT` is the VAPID `sub` claim: who to contact about pushes from this server.
|
|
920
|
+
RFC 8292 allows both a `mailto:` address and an `https:` URL.
|
|
921
|
+
|
|
922
|
+
> **Important (only Apple checks this)**: **APNs validates `sub`.** A host that cannot
|
|
923
|
+
> resolve — `localhost`, a bare hostname with no dot, a reserved TLD such as `.local` — is
|
|
924
|
+
> answered with **403, and iPhone/iPad receive nothing.** Google (FCM) is permissive here,
|
|
925
|
+
> so **testing on Android alone cannot see the problem.** If you want your own address,
|
|
926
|
+
> use a **real domain**: `mailto:you@your-domain.example.org`.
|
|
927
|
+
|
|
928
|
+
**`CM_VAPID_PRIVATE_KEY` is a secret.** `.env` is git-ignored via
|
|
929
|
+
[`.gitignore`](../../../.gitignore), but **a copy of it is not.** Never paste it into a
|
|
930
|
+
commit or a chat.
|
|
931
|
+
|
|
932
|
+
### 3. Restart the server
|
|
933
|
+
|
|
934
|
+
```bash
|
|
935
|
+
commandmate stop && commandmate start
|
|
936
|
+
```
|
|
937
|
+
|
|
938
|
+
### 4. Verify the server side
|
|
939
|
+
|
|
940
|
+
```bash
|
|
941
|
+
curl -s http://127.0.0.1:3000/api/push/vapid
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
```json
|
|
945
|
+
{"configured":true,"publicKey":"BN..."}
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
If it says `"configured": false`, the keys were not read. The startup log and
|
|
949
|
+
`commandmate status` both name the reason in one line:
|
|
950
|
+
|
|
951
|
+
```bash
|
|
952
|
+
commandmate status
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
```
|
|
956
|
+
Push notifications are disabled: no VAPID keys are configured.
|
|
957
|
+
Set CM_VAPID_PUBLIC_KEY and CM_VAPID_PRIVATE_KEY to enable them.
|
|
958
|
+
```
|
|
959
|
+
|
|
960
|
+
**A correctly configured server prints nothing here** — silence is the healthy state. A
|
|
961
|
+
`CM_VAPID_SUBJECT` that APNs will reject produces a line in the same two places.
|
|
962
|
+
|
|
963
|
+
### 5. Subscribe on the device
|
|
964
|
+
|
|
965
|
+
1. Open the **HTTPS URL** in the phone's browser
|
|
966
|
+
2. **iOS / iPadOS only**: Share menu -> "Add to Home Screen" -> **launch from that icon**
|
|
967
|
+
3. **More screen** (tab bar on mobile, sidebar on desktop) -> **Notifications**
|
|
968
|
+
4. Press **"Enable notifications"**
|
|
969
|
+
5. Answer "Allow" in the browser's permission dialog
|
|
970
|
+
|
|
971
|
+
> **The site does not appear in the OS notification list until you press that button.**
|
|
972
|
+
> Looking at iOS Settings -> Notifications, or Android's Apps & notifications, **before
|
|
973
|
+
> subscribing shows nothing** — it is easy to conclude "I already allowed it" from that.
|
|
974
|
+
|
|
975
|
+
> **Android note**: once you choose "Block", the permission dialog never appears again.
|
|
976
|
+
> Re-allow it from the browser's site settings.
|
|
977
|
+
|
|
978
|
+
After subscribing, the **Notifications** section of the More screen shows two switches:
|
|
979
|
+
|
|
980
|
+
| Switch | Covers | Default |
|
|
981
|
+
|---|---|---|
|
|
982
|
+
| When you need to act | Prompt waiting, failed verification gate, upstream API fault, session that could not start | On |
|
|
983
|
+
| Also tell me about completions | Ordinary completions that need nothing from you | **Off** |
|
|
984
|
+
|
|
985
|
+
### 6. When nothing arrives
|
|
986
|
+
|
|
987
|
+
The **Notifications** section shows a card saying this device is not receiving.
|
|
988
|
+
|
|
989
|
+
| Card | Meaning | What to do |
|
|
990
|
+
|---|---|---|
|
|
991
|
+
| **This device is not receiving notifications** | The push service is rejecting sends (HTTP 403 and similar). **Your subscription was not deleted** | On a 403, suspect `CM_VAPID_SUBJECT` first (see the Important note above) |
|
|
992
|
+
| **This device was dropped by the push service** | 404 / 410. The browser's subscription expired, so the server stopped sending to it | Press "Enable notifications" again to re-subscribe |
|
|
993
|
+
|
|
994
|
+
Server-side, with `CM_LOG_LEVEL=info`:
|
|
995
|
+
|
|
996
|
+
```
|
|
997
|
+
[WARN] [push/sender] push-send-failed {"statusCode":403,"consecutiveFailures":4}
|
|
998
|
+
[INFO] [push/sender] push-fanout-complete {"kind":"prompt","worktreeId":"my-feature","instanceId":"claude-2","delivered":1,"failed":1}
|
|
999
|
+
```
|
|
1000
|
+
|
|
1001
|
+
If `delivered` stays at 0, either no device is subscribed or every device is failing.
|
|
1002
|
+
|
|
1003
|
+
`worktreeId` and `instanceId` say **which worktree and which instance the fan-out was for**
|
|
1004
|
+
(`instanceId` is omitted when the producer named no instance). With several worktrees running at
|
|
1005
|
+
once their notifications interleave in the same second, so **filter by `worktreeId` whenever you
|
|
1006
|
+
count one worktree's pushes**:
|
|
1007
|
+
|
|
1008
|
+
```bash
|
|
1009
|
+
grep -a push-fanout-complete logs/server.log | grep -c '"worktreeId":"my-feature"'
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
---
|
|
1013
|
+
|
|
1014
|
+
## Related Documentation
|
|
1015
|
+
|
|
1016
|
+
- [CLI Setup Guide](./cli-setup-guide.md) - Installation and initial setup
|
|
1017
|
+
- [UI/UX Guide](../../UI_UX_GUIDE.md) - UI implementation technical details
|
|
1018
|
+
- [Status Indicator Details](../../features/sidebar-status-indicator.md) - How status detection works
|
|
1019
|
+
- [Deployment Guide](../../DEPLOYMENT.md) - Production environment setup
|
|
1020
|
+
- [Concept](../../concept.md) - CommandMate's vision
|