commandmate 0.30.2 → 0.31.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 +160 -160
- package/.next/app-path-routes-manifest.json +27 -27
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +9 -9
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route.js +1 -1
- package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route.js +3 -3
- package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/terminal/route.js +4 -4
- package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/tools/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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js +1 -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 +1 -1
- 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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/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_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_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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +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_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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/todos/route_client-reference-manifest.js +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_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_client-reference-manifest.js +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_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]/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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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/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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_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_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 -1
- 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 +4 -3
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route.js +4 -3
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +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 -1
- 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 +2 -2
- 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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -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_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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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/chat/page.js +2 -2
- package/.next/server/app/chat/page.js.nft.json +1 -1
- package/.next/server/app/chat/page_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.js +2 -2
- package/.next/server/app/more/page.js.nft.json +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.js +1 -1
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page.js +2 -2
- package/.next/server/app/repositories/page.js.nft.json +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page.js +1 -1
- package/.next/server/app/review/page.js.nft.json +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 +2 -2
- 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.js +2 -2
- package/.next/server/app/skills/installed/page.js.nft.json +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page.js +1 -1
- package/.next/server/app/skills/page.js.nft.json +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +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 +10 -10
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +27 -27
- package/.next/server/chunks/1058.js +1 -1
- package/.next/server/chunks/1068.js +1 -1
- package/.next/server/chunks/1262.js +1 -1
- package/.next/server/chunks/1886.js +3 -3
- package/.next/server/chunks/1990.js +103 -0
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2328.js +1 -1
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/261.js +1 -1
- package/.next/server/chunks/3123.js +1 -1
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3480.js +5 -4
- package/.next/server/chunks/4299.js +1 -1
- package/.next/server/chunks/4393.js +1 -1
- package/.next/server/chunks/4443.js +1 -5
- package/.next/server/chunks/5017.js +1 -1
- package/.next/server/chunks/5043.js +1 -1
- package/.next/server/chunks/5164.js +1 -1
- package/.next/server/chunks/552.js +2 -2
- package/.next/server/chunks/6072.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/663.js +4 -3
- package/.next/server/chunks/6894.js +2 -2
- package/.next/server/chunks/7187.js +1 -0
- package/.next/server/chunks/7472.js +1 -1
- package/.next/server/chunks/{880.js → 7859.js} +6 -6
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8800.js +2 -2
- package/.next/server/chunks/8918.js +7 -0
- package/.next/server/chunks/9123.js +2 -2
- package/.next/server/chunks/9130.js +4 -4
- package/.next/server/chunks/9627.js +1 -1
- package/.next/server/chunks/9696.js +1 -1
- package/.next/server/chunks/9798.js +1 -1
- 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/static/chunks/1783-11c9b4d8a52ebd91.js +1 -0
- package/.next/static/chunks/4718-de1224c9e8a6e7fc.js +1 -0
- package/.next/static/chunks/6022-2fa0b5a82d4ce7b6.js +1 -0
- package/.next/static/chunks/{5229-6c89475b61bd2c8b.js → 6170-951b9f5fe6b4b3b5.js} +1 -1
- package/.next/static/chunks/app/chat/{page-9aa2011410895b0d.js → page-37d7615d17d7e2a0.js} +1 -1
- package/.next/static/chunks/app/layout-4c2f21e3f653ee4c.js +1 -0
- package/.next/static/chunks/app/more/{page-333bba1c8bbc9c11.js → page-353a3924e6d7968e.js} +1 -1
- package/.next/static/chunks/app/{page-214f7ffa13a0cf10.js → page-c2bf871d953a1d6f.js} +1 -1
- package/.next/static/chunks/app/repositories/{page-4951cac905e50224.js → page-7d0f26df0537254c.js} +1 -1
- package/.next/static/chunks/app/review/{page-a0899b2d285318c3.js → page-e3f141b2829973e9.js} +1 -1
- package/.next/static/chunks/app/sessions/{page-fb36145ec732092a.js → page-53f188ed9ca49e5f.js} +1 -1
- package/.next/static/chunks/app/skills/[skillId]/{page-9099e26b60442873.js → page-80569b720aea59cc.js} +1 -1
- package/.next/static/chunks/app/skills/installed/{page-182e32368696d824.js → page-dbd2690ad72da95b.js} +1 -1
- package/.next/static/chunks/app/skills/{page-d3fdc88239ebe0ab.js → page-dacd36f9c11aa7da.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/page-97205088520255a5.js +1 -0
- package/.next/static/css/5c13ea243dfdcb66.css +1 -0
- package/.next/trace +13 -13
- package/README.md +37 -11
- package/dist/cli/commands/attach.d.ts +50 -0
- package/dist/cli/commands/attach.d.ts.map +1 -0
- package/dist/cli/commands/attach.js +204 -0
- package/dist/cli/commands/capture.d.ts.map +1 -1
- package/dist/cli/commands/capture.js +114 -0
- package/dist/cli/commands/instances.d.ts.map +1 -1
- package/dist/cli/commands/instances.js +23 -2
- package/dist/cli/commands/ls.d.ts.map +1 -1
- package/dist/cli/commands/ls.js +41 -1
- package/dist/cli/config/cli-dependencies.d.ts.map +1 -1
- package/dist/cli/config/cli-dependencies.js +34 -0
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +5 -0
- package/dist/cli/types/index.d.ts +36 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/config/tmux-pane-config.d.ts +153 -0
- package/dist/config/tmux-pane-config.d.ts.map +1 -0
- package/dist/config/tmux-pane-config.js +172 -0
- package/dist/lib/cli-tools/session-name.d.ts +44 -0
- package/dist/lib/cli-tools/session-name.d.ts.map +1 -0
- package/dist/lib/cli-tools/session-name.js +57 -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 +6 -1
- package/dist/lib/cli-tools/validation.d.ts +34 -0
- package/dist/lib/cli-tools/validation.d.ts.map +1 -0
- package/dist/lib/cli-tools/validation.js +41 -0
- package/dist/lib/detection/status-reason.d.ts +18 -0
- package/dist/lib/detection/status-reason.d.ts.map +1 -1
- package/dist/lib/detection/status-reason.js +18 -0
- package/dist/lib/detection/tools/verified-against.d.ts +57 -7
- package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
- package/dist/lib/detection/tools/verified-against.js +59 -8
- package/dist/lib/detection/version-probes.d.ts +26 -5
- package/dist/lib/detection/version-probes.d.ts.map +1 -1
- package/dist/lib/detection/version-probes.js +28 -6
- package/dist/lib/session/tmux-session-surface.d.ts +369 -0
- package/dist/lib/session/tmux-session-surface.d.ts.map +1 -0
- package/dist/lib/session/tmux-session-surface.js +525 -0
- package/dist/server/src/config/cli-tool-timing-config.js +12 -1
- package/dist/server/src/config/detection-evidence-config.js +5 -0
- package/dist/server/src/config/schedule-config.js +28 -1
- package/dist/server/src/lib/cli-tools/antigravity.js +2 -2
- package/dist/server/src/lib/cli-tools/base.js +13 -8
- package/dist/server/src/lib/cli-tools/claude.js +20 -0
- package/dist/server/src/lib/cli-tools/codex.js +205 -61
- package/dist/server/src/lib/cli-tools/command-code.js +349 -0
- package/dist/server/src/lib/cli-tools/composer-spec.js +6 -0
- package/dist/server/src/lib/cli-tools/copilot.js +2 -2
- package/dist/server/src/lib/cli-tools/gemini.js +2 -2
- package/dist/server/src/lib/cli-tools/graceful-exit.js +16 -1
- package/dist/server/src/lib/cli-tools/index.js +4 -1
- package/dist/server/src/lib/cli-tools/install-hints.js +131 -0
- package/dist/server/src/lib/cli-tools/liveness-spec.js +18 -0
- package/dist/server/src/lib/cli-tools/manager.js +2 -0
- package/dist/server/src/lib/cli-tools/opencode.js +2 -2
- package/dist/server/src/lib/cli-tools/start-availability.js +18 -11
- package/dist/server/src/lib/cli-tools/types.js +6 -1
- package/dist/server/src/lib/cli-tools/vibe-local.js +2 -2
- package/dist/server/src/lib/cmate-parser.js +6 -0
- package/dist/server/src/lib/detection/cli-patterns.js +441 -8
- package/dist/server/src/lib/detection/opencode-modal-overlay.js +66 -100
- package/dist/server/src/lib/detection/selection-shape.js +341 -0
- package/dist/server/src/lib/detection/sgr-background.js +210 -0
- package/dist/server/src/lib/detection/status-detector.js +6 -0
- package/dist/server/src/lib/detection/status-reason.js +18 -0
- package/dist/server/src/lib/detection/tools/antigravity/detect.js +38 -15
- package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +392 -0
- package/dist/server/src/lib/detection/tools/codex/detect.js +83 -2
- package/dist/server/src/lib/detection/tools/command-code/detect.js +159 -0
- package/dist/server/src/lib/detection/tools/registry.js +6 -4
- package/dist/server/src/lib/detection/tools/verified-against.js +59 -8
- package/dist/server/src/lib/detection/version-probes.js +28 -6
- package/dist/server/src/lib/hooks/sources/antigravity/history.js +77 -16
- package/dist/server/src/lib/hooks/sources/claude/history.js +94 -18
- package/dist/server/src/lib/hooks/sources/codex/history.js +84 -15
- package/dist/server/src/lib/hooks/sources/codex/hooks-config.js +130 -17
- package/dist/server/src/lib/hooks/sources/codex/relay-install.js +145 -0
- package/dist/server/src/lib/hooks/sources/command-code/history.js +865 -0
- package/dist/server/src/lib/hooks/sources/command-code/hooks-config.js +390 -0
- package/dist/server/src/lib/hooks/sources/command-code/source.js +290 -0
- package/dist/server/src/lib/hooks/sources/command-code/tool-id.js +18 -0
- package/dist/server/src/lib/hooks/sources/command-code/transcript.js +604 -0
- package/dist/server/src/lib/hooks/sources/index.js +3 -1
- package/dist/server/src/lib/hooks/sources/opencode/history.js +57 -3
- package/dist/server/src/lib/hooks/sources/opencode/transcript.js +24 -28
- package/dist/server/src/lib/hooks/sources/registry.js +4 -0
- package/dist/server/src/lib/hooks/sources/turn-body.js +77 -19
- package/dist/server/src/lib/job-executor.js +12 -0
- package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +6 -0
- package/dist/server/src/lib/polling/response-checker.js +112 -7
- package/dist/server/src/lib/polling/structured-history-gate.js +15 -8
- package/dist/server/src/lib/realtime/types.js +15 -5
- package/dist/server/src/lib/response-cleaner.js +24 -1
- package/dist/server/src/lib/response-extractor.js +11 -0
- package/dist/server/src/lib/session/claude-executor.js +223 -4
- package/dist/server/src/lib/session/cli-session.js +52 -0
- package/dist/server/src/lib/session/tmux-session-surface.js +525 -0
- package/dist/server/src/lib/skills/compatibility-matrix.js +117 -1
- package/dist/server/src/lib/tmux/geometry-delegation.js +143 -0
- package/dist/server/src/lib/tmux/read-mode-pager.js +76 -10
- package/dist/server/src/lib/tmux/read-mode.js +44 -2
- package/dist/server/src/lib/tmux/session-hook-scripts.js +249 -0
- package/dist/server/src/lib/tmux/session-hooks.js +122 -0
- package/dist/server/src/lib/tmux/session-status-options.js +213 -0
- package/dist/server/src/lib/tmux/tmux.js +79 -2
- package/dist/server/src/lib/version-checker.js +110 -0
- package/dist/server/src/lib/ws-server.js +16 -10
- package/dist/server/src/types/agent-transcript.js +73 -1
- package/dist/server/src/types/terminal-keys.js +131 -3
- package/dist/types/terminal-keys.d.ts +100 -3
- package/dist/types/terminal-keys.d.ts.map +1 -1
- package/dist/types/terminal-keys.js +131 -3
- package/package.json +1 -1
- package/.next/server/chunks/3099.js +0 -5
- package/.next/server/chunks/7824.js +0 -1
- package/.next/static/chunks/3916-0e929d089282dc5d.js +0 -1
- package/.next/static/chunks/6022-7a7d1760fc9814c7.js +0 -1
- package/.next/static/chunks/6381-147dde2a967e9458.js +0 -1
- package/.next/static/chunks/app/layout-6a26ea22d5cf03dc.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-2f73d69187936627.js +0 -1
- package/.next/static/css/23f9c40ecc458c77.css +0 -1
- /package/.next/static/{QXxQbXWoo7ldUyOcv7PCZ → nXW4dPkpE_9xUf_9ySRff}/_buildManifest.js +0 -0
- /package/.next/static/{QXxQbXWoo7ldUyOcv7PCZ → nXW4dPkpE_9xUf_9ySRff}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Command Code CLI tool implementation (Issue #2250, Epic #2249 Phase A).
|
|
4
|
+
*
|
|
5
|
+
* Integration with the Command Code CLI (`commandcode`, measured against
|
|
6
|
+
* v1.40.1). Command Code renders an INLINE TUI — `#{alternate_on}` is 0 and the
|
|
7
|
+
* pane keeps its scrollback, like codex and agy, unlike claude v2 / opencode /
|
|
8
|
+
* copilot — with a claude-shaped bottom-pinned composer:
|
|
9
|
+
*
|
|
10
|
+
* ```text
|
|
11
|
+
* ❯ <echoed prompt>
|
|
12
|
+
* ✻ Thought for 1 second [ctrl+o to expand]
|
|
13
|
+
* ⠶ <reply>
|
|
14
|
+
* ✻ Worked for 2s
|
|
15
|
+
* ──────────────────────── ← rule
|
|
16
|
+
* ❯ Ask your question... ← composer
|
|
17
|
+
* ──────────────────────── ← rule
|
|
18
|
+
* ? for shortcuts · taste on
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* ## The executable is `commandcode`, not `cmd`
|
|
22
|
+
*
|
|
23
|
+
* The package ships four bins — `cmd`, `cmdc`, `command-code`, `commandcode`.
|
|
24
|
+
* `cmd` collides with Windows' shell and reads as CommandMate's own name in a
|
|
25
|
+
* log line, so the unambiguous spelling is the one CommandMate launches
|
|
26
|
+
* (Epic #2249 決定 1).
|
|
27
|
+
*
|
|
28
|
+
* ## The launch line lives in one place
|
|
29
|
+
*
|
|
30
|
+
* {@link buildCommandCodeLaunchCommand} is the only thing that renders it, and
|
|
31
|
+
* since Phase B (#2251) its body is `buildAgentLaunchCommandLine` — so the line
|
|
32
|
+
* carries `CM_HOOK_URL` and the worktree's `.commandcode/settings.local.json`
|
|
33
|
+
* has been written by the time the pane sees it. The flags stay here rather than
|
|
34
|
+
* moving into the source, because which flags Command Code is launched with is
|
|
35
|
+
* this module's decision (Epic #2249 決定 2) and the hook source's business is
|
|
36
|
+
* only the correlation.
|
|
37
|
+
*/
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.CommandCodeTool = exports.COMMAND_CODE_EXIT_COMMAND = exports.COMMAND_CODE_LAUNCH_FLAGS = exports.COMMAND_CODE_COMMAND = void 0;
|
|
40
|
+
exports.buildCommandCodeLaunchCommand = buildCommandCodeLaunchCommand;
|
|
41
|
+
exports.isCommandCodeReady = isCommandCodeReady;
|
|
42
|
+
const base_1 = require("./base");
|
|
43
|
+
const terminal_keys_1 = require("../../types/terminal-keys");
|
|
44
|
+
const tmux_1 = require("../tmux/tmux");
|
|
45
|
+
const submit_verified_sender_1 = require("./submit-verified-sender");
|
|
46
|
+
const tmux_capture_cache_1 = require("../tmux/tmux-capture-cache");
|
|
47
|
+
const cli_patterns_1 = require("../detection/cli-patterns");
|
|
48
|
+
const errors_1 = require("../../lib/errors");
|
|
49
|
+
const logger_1 = require("../../lib/logger");
|
|
50
|
+
const tool_id_1 = require("../../lib/hooks/sources/command-code/tool-id");
|
|
51
|
+
const agent_session_lifecycle_1 = require("../../lib/session/agent-session-lifecycle");
|
|
52
|
+
const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
|
|
53
|
+
const install_hints_1 = require("./install-hints");
|
|
54
|
+
const logger = (0, logger_1.createLogger)('cli-tools/command-code');
|
|
55
|
+
/** The executable CommandMate launches. See the module docblock for why not `cmd`. */
|
|
56
|
+
exports.COMMAND_CODE_COMMAND = 'commandcode';
|
|
57
|
+
/**
|
|
58
|
+
* Launch flags, in the order Epic #2249 決定 2 fixed them.
|
|
59
|
+
*
|
|
60
|
+
* - `--trust` skips the first-run "do you trust this folder?" confirmation, so a
|
|
61
|
+
* worktree CommandMate just created does not park the session on a dialog no
|
|
62
|
+
* one is watching.
|
|
63
|
+
* - `--skip-onboarding` skips the taste-onboarding walkthrough, which is the
|
|
64
|
+
* same class of unattended-launch blocker (#2131's `wait` sat on claude's
|
|
65
|
+
* onboarding dialog for three hours).
|
|
66
|
+
* - `--no-auto-update` because a background self-update restarts the agent, and
|
|
67
|
+
* a restart is what killed Auto-Yes the last time an agent did it.
|
|
68
|
+
*/
|
|
69
|
+
exports.COMMAND_CODE_LAUNCH_FLAGS = [
|
|
70
|
+
'--trust',
|
|
71
|
+
'--skip-onboarding',
|
|
72
|
+
'--no-auto-update',
|
|
73
|
+
];
|
|
74
|
+
/** `/exit` — Command Code's own quit command. */
|
|
75
|
+
exports.COMMAND_CODE_EXIT_COMMAND = '/exit';
|
|
76
|
+
/**
|
|
77
|
+
* Render the shell line that starts Command Code in a pane (Issue #2251).
|
|
78
|
+
*
|
|
79
|
+
* Two things happen here, in this order, and the order is the point:
|
|
80
|
+
*
|
|
81
|
+
* 1. `buildAgentLaunchCommandLine` asks the tool's own {@link AgentEventSource}
|
|
82
|
+
* to write `<worktree>/.commandcode/settings.local.json` and to declare the
|
|
83
|
+
* environment the hooks need, then renders `CM_HOOK_URL='…' 'commandcode'`.
|
|
84
|
+
* Going through the shared helper rather than through
|
|
85
|
+
* `prepareAgentLaunch(...).command` is what keeps `env` from being silently
|
|
86
|
+
* dropped (#1846): the plan's environment is *data*, and this is the one
|
|
87
|
+
* function that turns it into shell assignments.
|
|
88
|
+
* 2. {@link COMMAND_CODE_LAUNCH_FLAGS} are appended **after** the rendered
|
|
89
|
+
* line, the shape `AntigravityTool` uses for `--model`. Appending keeps the
|
|
90
|
+
* assignments in front of the executable by construction instead of by the
|
|
91
|
+
* caller remembering to put them there.
|
|
92
|
+
*
|
|
93
|
+
* With `CM_AGENT_HOOKS_INJECT=0` the source returns the bare executable and an
|
|
94
|
+
* empty environment, so this renders the byte-identical Phase A line
|
|
95
|
+
* `commandcode --trust --skip-onboarding --no-auto-update`.
|
|
96
|
+
*
|
|
97
|
+
* @param context - The instance being started, its executable, and its worktree
|
|
98
|
+
* @returns The command line to type at the pane's shell prompt
|
|
99
|
+
*/
|
|
100
|
+
function buildCommandCodeLaunchCommand(context) {
|
|
101
|
+
return [(0, agent_session_lifecycle_1.buildAgentLaunchCommandLine)(context), ...exports.COMMAND_CODE_LAUNCH_FLAGS].join(' ');
|
|
102
|
+
}
|
|
103
|
+
/** Interval for polling composer readiness. */
|
|
104
|
+
const COMMAND_CODE_POLL_INTERVAL_MS = 1000;
|
|
105
|
+
/** Max attempts for initialization polling (30 * 1000ms = 30s window). */
|
|
106
|
+
const COMMAND_CODE_INIT_MAX_ATTEMPTS = 30;
|
|
107
|
+
/** Timeout for waiting for the composer before sending a message. */
|
|
108
|
+
const COMMAND_CODE_PROMPT_WAIT_TIMEOUT_MS = 15000;
|
|
109
|
+
/** Rows of pane tail the readiness probe reads. */
|
|
110
|
+
const COMMAND_CODE_READINESS_CAPTURE_LINES = 50;
|
|
111
|
+
/**
|
|
112
|
+
* Whether Command Code is sitting at a live, empty-of-work composer.
|
|
113
|
+
*
|
|
114
|
+
* Structural rather than textual, for the reason
|
|
115
|
+
* {@link findCommandCodeChromeStart} spells out: the composer block is drawn
|
|
116
|
+
* only when the agent is accepting input. While a permission dialog is up the
|
|
117
|
+
* whole block is replaced by the dialog (`dialog-create-file.txt` has one rule
|
|
118
|
+
* and no composer), and while a turn runs the status row sits above the block —
|
|
119
|
+
* hence the second condition.
|
|
120
|
+
*
|
|
121
|
+
* The footer's `? for shortcuts` is deliberately NOT the signal: it is only the
|
|
122
|
+
* DEFAULT permission mode's spelling of that row (see
|
|
123
|
+
* `COMMAND_CODE_MODE_INDICATOR_PATTERN`), so a session started in plan or
|
|
124
|
+
* auto-accept mode would never look ready.
|
|
125
|
+
*
|
|
126
|
+
* @param rawOutput - A captured pane, ANSI intact
|
|
127
|
+
* @returns True when the composer is on screen and no turn is in flight
|
|
128
|
+
*/
|
|
129
|
+
function isCommandCodeReady(rawOutput) {
|
|
130
|
+
const lines = rawOutput.split('\n');
|
|
131
|
+
const chromeStart = (0, cli_patterns_1.findCommandCodeChromeStart)(lines);
|
|
132
|
+
if (chromeStart < 0)
|
|
133
|
+
return false;
|
|
134
|
+
return !cli_patterns_1.COMMAND_CODE_THINKING_PATTERN.test((0, cli_patterns_1.stripAnsi)(rawOutput));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Command Code CLI tool implementation.
|
|
138
|
+
* Manages `commandcode` sessions using tmux.
|
|
139
|
+
*/
|
|
140
|
+
class CommandCodeTool extends base_1.BaseCLITool {
|
|
141
|
+
id = 'command-code';
|
|
142
|
+
name = 'Command Code CLI';
|
|
143
|
+
command = exports.COMMAND_CODE_COMMAND;
|
|
144
|
+
/**
|
|
145
|
+
* Declare the claude-family pad (Issue #2297).
|
|
146
|
+
*
|
|
147
|
+
* Command Code renders claude's inline overlay TUI, so it takes the same
|
|
148
|
+
* declaration rather than a copy of the base list — see
|
|
149
|
+
* {@link CLAUDE_NAVIGATION_KEY_VALUES}.
|
|
150
|
+
*
|
|
151
|
+
* **Its own `/model` picker does NOT use `s`.** Measured on v1.40.1 at
|
|
152
|
+
* 200x1000 for this Issue: a provider-grouped list of model NAMES with no
|
|
153
|
+
* option numbers, a `› Type to search models...` filter row, and the footer
|
|
154
|
+
* `type to search · ↑/↓ navigate · shift+↑/↓ jump provider · enter to select ·
|
|
155
|
+
* esc to cancel`. Nothing on it offers a session scope, so the chat surface
|
|
156
|
+
* draws no `s` button there: the button is gated on the footer being on
|
|
157
|
+
* screen (`readSelectionListShape`), not on the tool id. The key is declared
|
|
158
|
+
* anyway so the two halves of the claude family cannot drift apart, and
|
|
159
|
+
* declaring a key nobody draws sends nothing.
|
|
160
|
+
*/
|
|
161
|
+
navigationKeys() {
|
|
162
|
+
return { keys: terminal_keys_1.CLAUDE_NAVIGATION_KEY_VALUES, leaderKey: null };
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Check if a Command Code session is running for a worktree.
|
|
166
|
+
*
|
|
167
|
+
* @param worktreeId - Worktree ID
|
|
168
|
+
* @param instanceId - Agent instance ID (defaults to the primary instance)
|
|
169
|
+
* @returns True if session is running
|
|
170
|
+
*/
|
|
171
|
+
async isRunning(worktreeId, instanceId) {
|
|
172
|
+
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
173
|
+
return await (0, tmux_1.hasSession)(sessionName);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Start a new Command Code session for a worktree.
|
|
177
|
+
*
|
|
178
|
+
* @param worktreeId - Worktree ID
|
|
179
|
+
* @param worktreePath - Worktree path
|
|
180
|
+
* @param instanceId - Agent instance ID (defaults to the primary instance)
|
|
181
|
+
*/
|
|
182
|
+
async launchSession(worktreeId, worktreePath, instanceId) {
|
|
183
|
+
const available = await this.isInstalled();
|
|
184
|
+
if (!available) {
|
|
185
|
+
throw (0, install_hints_1.missingToolError)(this);
|
|
186
|
+
}
|
|
187
|
+
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
188
|
+
const exists = await (0, tmux_1.hasSession)(sessionName);
|
|
189
|
+
if (exists) {
|
|
190
|
+
await this.reconcileExistingSession(sessionName);
|
|
191
|
+
// Issue #2070's shape: a tmux session outlives the agent that was launched
|
|
192
|
+
// into it, and skipping the launch for a pane holding nothing but a shell
|
|
193
|
+
// prompt leaves `kill-session` by hand as the only recovery.
|
|
194
|
+
if (await this.isToolLive(sessionName, { confirm: true })) {
|
|
195
|
+
logger.info('command-code-session-exists');
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
logger.warn('command-code-session-relaunch', { sessionName });
|
|
199
|
+
}
|
|
200
|
+
// Issue #2251, seam S8: fence this instance's structured events off from the
|
|
201
|
+
// process that used to hold the same (worktree, tool, instance) key. On the
|
|
202
|
+
// creation path and on #2070's relaunch path — the reuse branch above has
|
|
203
|
+
// already returned — and before the pane exists, so there is no window in
|
|
204
|
+
// which a live pane is judged against a stale generation. Bumped even if the
|
|
205
|
+
// launch below then fails: falling back to the screen scraper is always safe
|
|
206
|
+
// and trusting a dead session's events is not.
|
|
207
|
+
(0, agent_session_lifecycle_1.beginAgentSession)({ worktreeId, cliToolId: tool_id_1.COMMAND_CODE_CLI_TOOL_ID, instanceId });
|
|
208
|
+
try {
|
|
209
|
+
if (!exists) {
|
|
210
|
+
// Inline-rendered, so the pane keeps scrollback; depth comes from the
|
|
211
|
+
// shared TMUX_HISTORY_LIMIT default (Issue #1624).
|
|
212
|
+
await (0, tmux_1.createSession)({
|
|
213
|
+
sessionName,
|
|
214
|
+
workingDirectory: worktreePath,
|
|
215
|
+
});
|
|
216
|
+
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_SESSION_CREATE_WAIT_MS));
|
|
217
|
+
}
|
|
218
|
+
await (0, tmux_1.sendKeys)(sessionName, buildCommandCodeLaunchCommand({
|
|
219
|
+
target: { worktreeId, cliToolId: tool_id_1.COMMAND_CODE_CLI_TOOL_ID, instanceId },
|
|
220
|
+
executablePath: this.command,
|
|
221
|
+
worktreePath,
|
|
222
|
+
}), true);
|
|
223
|
+
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.COMMAND_CODE_INIT_WAIT_MS));
|
|
224
|
+
await this.waitForReady(sessionName);
|
|
225
|
+
logger.info('started-command-code-session');
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
throw new Error(`Failed to start Command Code session: ${(0, errors_1.getErrorMessage)(error)}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Poll until the composer block is drawn.
|
|
233
|
+
*
|
|
234
|
+
* No dialog is answered here: `--trust` and `--skip-onboarding` are what
|
|
235
|
+
* remove the two startup dialogs Command Code has, so a launch that still
|
|
236
|
+
* parks on one is a launch whose flags did not take effect — and blind-firing
|
|
237
|
+
* Enter at an unmeasured dialog is how #1928 describes an Auto-Yes accident.
|
|
238
|
+
* A timeout logs and returns; the send path's own wait is what refuses.
|
|
239
|
+
*/
|
|
240
|
+
async waitForReady(sessionName) {
|
|
241
|
+
for (let i = 0; i < COMMAND_CODE_INIT_MAX_ATTEMPTS; i++) {
|
|
242
|
+
try {
|
|
243
|
+
const rawOutput = await (0, tmux_1.capturePane)(sessionName, COMMAND_CODE_READINESS_CAPTURE_LINES);
|
|
244
|
+
if (isCommandCodeReady(rawOutput)) {
|
|
245
|
+
logger.info('command-code-prompt-detected');
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// Capture may fail during initialization - continue polling
|
|
251
|
+
}
|
|
252
|
+
await new Promise((resolve) => setTimeout(resolve, COMMAND_CODE_POLL_INTERVAL_MS));
|
|
253
|
+
}
|
|
254
|
+
logger.info('command-code-prompt-detection-timeout');
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Wait for the composer before sending a message.
|
|
258
|
+
* Mirrors CodexTool.waitForPrompt: throws on timeout so a failed readiness
|
|
259
|
+
* check STOPS the send rather than typing into a non-ready TUI.
|
|
260
|
+
*
|
|
261
|
+
* @throws Error when the composer is not detected within the timeout
|
|
262
|
+
*/
|
|
263
|
+
async waitForPrompt(sessionName) {
|
|
264
|
+
const startTime = Date.now();
|
|
265
|
+
const pollInterval = 500;
|
|
266
|
+
while (Date.now() - startTime < COMMAND_CODE_PROMPT_WAIT_TIMEOUT_MS) {
|
|
267
|
+
try {
|
|
268
|
+
const rawOutput = await (0, tmux_1.capturePane)(sessionName, COMMAND_CODE_READINESS_CAPTURE_LINES);
|
|
269
|
+
if (isCommandCodeReady(rawOutput)) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
// Capture may fail - continue polling
|
|
275
|
+
}
|
|
276
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
277
|
+
}
|
|
278
|
+
logger.info('command-code-prompt-not-ready');
|
|
279
|
+
throw new Error('Command Code prompt not ready: timed out waiting for the composer before sending');
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Send a message to the Command Code session.
|
|
283
|
+
*
|
|
284
|
+
* @param worktreeId - Worktree ID
|
|
285
|
+
* @param message - Message to send
|
|
286
|
+
* @param instanceId - Agent instance ID (defaults to the primary instance)
|
|
287
|
+
*/
|
|
288
|
+
async sendMessage(worktreeId, message, instanceId) {
|
|
289
|
+
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
290
|
+
const exists = await (0, tmux_1.hasSession)(sessionName);
|
|
291
|
+
if (!exists) {
|
|
292
|
+
throw new Error(`Command Code session ${sessionName} does not exist. Start the session first.`);
|
|
293
|
+
}
|
|
294
|
+
// Issue #2070: the pane exists, but does the AGENT? Relaunches into the same
|
|
295
|
+
// pane when the tool is gone; costs one `capture-pane` when it is not.
|
|
296
|
+
await this.relaunchIfToolExited(worktreeId, instanceId);
|
|
297
|
+
try {
|
|
298
|
+
await this.waitForPrompt(sessionName);
|
|
299
|
+
// Issue #1471: body/Enter separation + read-back submit verification.
|
|
300
|
+
await (0, submit_verified_sender_1.sendMessageWithSubmitVerification)({
|
|
301
|
+
sessionName,
|
|
302
|
+
message,
|
|
303
|
+
cliToolId: 'command-code',
|
|
304
|
+
composer: this.describeComposer(),
|
|
305
|
+
});
|
|
306
|
+
// Required so the poller re-reads instead of answering from the 5s cache.
|
|
307
|
+
(0, tmux_capture_cache_1.invalidateCache)(sessionName);
|
|
308
|
+
logger.info('sent-message-to-command-code-session');
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
throw new Error(`Failed to send message to Command Code: ${(0, errors_1.getErrorMessage)(error)}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Kill the Command Code session.
|
|
316
|
+
*
|
|
317
|
+
* `/exit` typed and submitted as SEPARATE tmux commands, the shape #1905
|
|
318
|
+
* settled on for opencode: `/` opens Command Code's slash-command menu, and a
|
|
319
|
+
* `C-m` arriving inside the same `send-keys` is consumed by that menu rather
|
|
320
|
+
* than by the composer. Measured on 1.40.1 — the separated form exits the
|
|
321
|
+
* agent and drops the pane back to its shell.
|
|
322
|
+
*
|
|
323
|
+
* @param worktreeId - Worktree ID
|
|
324
|
+
* @param instanceId - Agent instance ID (defaults to the primary instance)
|
|
325
|
+
*/
|
|
326
|
+
async killSession(worktreeId, instanceId) {
|
|
327
|
+
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
328
|
+
try {
|
|
329
|
+
const exists = await (0, tmux_1.hasSession)(sessionName);
|
|
330
|
+
if (exists) {
|
|
331
|
+
await (0, tmux_1.sendKeys)(sessionName, exports.COMMAND_CODE_EXIT_COMMAND, false);
|
|
332
|
+
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_TEXT_INPUT_WAIT_MS));
|
|
333
|
+
await (0, tmux_1.sendSpecialKeys)(sessionName, ['Enter']);
|
|
334
|
+
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_EXIT_WAIT_MS));
|
|
335
|
+
}
|
|
336
|
+
const killed = await (0, tmux_1.killSession)(sessionName);
|
|
337
|
+
// So a later session reusing the name starts clean.
|
|
338
|
+
(0, tmux_capture_cache_1.invalidateCache)(sessionName);
|
|
339
|
+
if (killed) {
|
|
340
|
+
logger.info('stopped-command-code-session');
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
logger.error('session:stop-failed', { error: (0, errors_1.getErrorMessage)(error) });
|
|
345
|
+
throw error;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
exports.CommandCodeTool = CommandCodeTool;
|
|
@@ -65,6 +65,12 @@ const COMPOSER_SPECS = {
|
|
|
65
65
|
gemini: { ...exports.DEFAULT_COMPOSER_SPEC, clearBeforeSend: false },
|
|
66
66
|
copilot: { ...exports.DEFAULT_COMPOSER_SPEC, clearBeforeSend: false },
|
|
67
67
|
antigravity: { ...exports.DEFAULT_COMPOSER_SPEC, clearBeforeSend: false },
|
|
68
|
+
// Issue #2250. `input-line-marker` is right: Command Code draws a `❯` composer
|
|
69
|
+
// at the bottom of the pane, the shape the reader looks for. `clearBeforeSend`
|
|
70
|
+
// stays false because #1880's `C-e`+`C-u` was measured on claude's box and
|
|
71
|
+
// nobody has measured Command Code's -- the same reason gemini, copilot and
|
|
72
|
+
// agy carry the flag off.
|
|
73
|
+
'command-code': { ...exports.DEFAULT_COMPOSER_SPEC, clearBeforeSend: false },
|
|
68
74
|
// vibe-local's IME mode makes the first Enter insert a newline, so the
|
|
69
75
|
// initial submit is two presses (see VIBE_LOCAL_DOUBLE_ENTER_WAIT_MS).
|
|
70
76
|
'vibe-local': { ...exports.DEFAULT_COMPOSER_SPEC, clearBeforeSend: false, submitEnterCount: 2 },
|
|
@@ -31,7 +31,7 @@ const hook_settings_1 = require("../../lib/hooks/sources/copilot/hook-settings")
|
|
|
31
31
|
const tool_id_1 = require("../../lib/hooks/sources/copilot/tool-id");
|
|
32
32
|
const errors_1 = require("../../lib/errors");
|
|
33
33
|
const logger_1 = require("../../lib/logger");
|
|
34
|
-
const
|
|
34
|
+
const install_hints_1 = require("./install-hints");
|
|
35
35
|
const logger = (0, logger_1.createLogger)('cli-tools/copilot');
|
|
36
36
|
/** Interval for polling prompt detection */
|
|
37
37
|
const COPILOT_POLL_INTERVAL_MS = 1000;
|
|
@@ -168,7 +168,7 @@ class CopilotTool extends base_1.BaseCLITool {
|
|
|
168
168
|
// no copilot: the answer and the action have to come from one measurement.
|
|
169
169
|
const resolved = await (0, copilot_executable_1.resolveCopilotExecutable)();
|
|
170
170
|
if (!resolved) {
|
|
171
|
-
throw
|
|
171
|
+
throw (0, install_hints_1.missingToolError)(this);
|
|
172
172
|
}
|
|
173
173
|
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
174
174
|
// Check if session already exists
|
|
@@ -21,7 +21,7 @@ const sources_1 = require("../../lib/hooks/sources");
|
|
|
21
21
|
const agent_session_lifecycle_1 = require("../../lib/session/agent-session-lifecycle");
|
|
22
22
|
const logger_1 = require("../../lib/logger");
|
|
23
23
|
const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
|
|
24
|
-
const
|
|
24
|
+
const install_hints_1 = require("./install-hints");
|
|
25
25
|
const logger = (0, logger_1.createLogger)('cli-tools/gemini');
|
|
26
26
|
/**
|
|
27
27
|
* Extract error message from unknown error type (DRY)
|
|
@@ -66,7 +66,7 @@ class GeminiTool extends base_1.BaseCLITool {
|
|
|
66
66
|
// Check if Gemini is installed
|
|
67
67
|
const geminiAvailable = await this.isInstalled();
|
|
68
68
|
if (!geminiAvailable) {
|
|
69
|
-
throw
|
|
69
|
+
throw (0, install_hints_1.missingToolError)(this);
|
|
70
70
|
}
|
|
71
71
|
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
72
72
|
// Check if session already exists
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
* @module lib/cli-tools/graceful-exit
|
|
43
43
|
*/
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.DEFAULT_GRACEFUL_EXIT_SPEC = exports.GEMINI_EXIT_COMMAND_TEXT = exports.OPENCODE_EXIT_COMMAND_TEXT = exports.COPILOT_EXIT_COMMAND_TEXT = void 0;
|
|
45
|
+
exports.DEFAULT_GRACEFUL_EXIT_SPEC = exports.GEMINI_EXIT_COMMAND_TEXT = exports.COMMAND_CODE_EXIT_COMMAND_TEXT = exports.OPENCODE_EXIT_COMMAND_TEXT = exports.COPILOT_EXIT_COMMAND_TEXT = void 0;
|
|
46
46
|
exports.resolveGracefulExitSpec = resolveGracefulExitSpec;
|
|
47
47
|
exports.verifyGracefulExit = verifyGracefulExit;
|
|
48
48
|
const copilot_constants_1 = require("../../config/copilot-constants");
|
|
@@ -52,6 +52,8 @@ const cli_tool_contracts_1 = require("../../types/cli-tool-contracts");
|
|
|
52
52
|
exports.COPILOT_EXIT_COMMAND_TEXT = '/exit';
|
|
53
53
|
/** The graceful exit command opencode's TUI accepts. */
|
|
54
54
|
exports.OPENCODE_EXIT_COMMAND_TEXT = '/exit';
|
|
55
|
+
/** Command Code's own quit command (Issue #2250). */
|
|
56
|
+
exports.COMMAND_CODE_EXIT_COMMAND_TEXT = '/exit';
|
|
55
57
|
/** The graceful exit command gemini's TUI accepts. */
|
|
56
58
|
exports.GEMINI_EXIT_COMMAND_TEXT = '/quit';
|
|
57
59
|
/**
|
|
@@ -114,6 +116,19 @@ const GRACEFUL_EXIT_SPECS = {
|
|
|
114
116
|
exitWaitMs: cli_tool_timing_config_1.COPILOT_EXIT_WAIT_MS,
|
|
115
117
|
ownsLoopbackServer: false,
|
|
116
118
|
},
|
|
119
|
+
// `/exit` typed and submitted separately, the same shape as opencode's below
|
|
120
|
+
// and for the same measured reason: `/` opens Command Code's slash-command
|
|
121
|
+
// menu, so an Enter batched into the same `send-keys` is the menu's, not the
|
|
122
|
+
// composer's. The separated form exits 1.40.1 and returns the pane to its
|
|
123
|
+
// shell (Issue #2250).
|
|
124
|
+
'command-code': {
|
|
125
|
+
keys: [
|
|
126
|
+
(0, cli_tool_contracts_1.literalStep)(exports.COMMAND_CODE_EXIT_COMMAND_TEXT, cli_tool_timing_config_1.TUI_TEXT_INPUT_WAIT_MS),
|
|
127
|
+
(0, cli_tool_contracts_1.keyStep)('Enter'),
|
|
128
|
+
],
|
|
129
|
+
exitWaitMs: cli_tool_timing_config_1.TUI_EXIT_WAIT_MS,
|
|
130
|
+
ownsLoopbackServer: false,
|
|
131
|
+
},
|
|
117
132
|
// `/exit` typed and submitted separately, because the batched form does not
|
|
118
133
|
// exit at all: typing `/` opens the command palette and the `C-m` arriving in
|
|
119
134
|
// the same tmux command is consumed by it, leaving `/exit` in the composer
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @module cli-tools
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.CLIToolManager = exports.AntigravityTool = exports.GeminiTool = exports.CodexTool = exports.ClaudeTool = exports.BaseCLITool = exports.DEFAULT_GRACEFUL_EXIT_SPEC = exports.verifyGracefulExit = exports.resolveGracefulExitSpec = exports.GEMINI_PANE_HEIGHT = exports.resolveCaptureSpec = exports.DEFAULT_COMPOSER_SPEC = exports.resolveComposerSpec = exports.isImageCapableCLITool = void 0;
|
|
9
|
+
exports.CLIToolManager = exports.buildCommandCodeLaunchCommand = exports.CommandCodeTool = exports.AntigravityTool = exports.GeminiTool = exports.CodexTool = exports.ClaudeTool = exports.BaseCLITool = exports.DEFAULT_GRACEFUL_EXIT_SPEC = exports.verifyGracefulExit = exports.resolveGracefulExitSpec = exports.GEMINI_PANE_HEIGHT = exports.resolveCaptureSpec = exports.DEFAULT_COMPOSER_SPEC = exports.resolveComposerSpec = exports.isImageCapableCLITool = void 0;
|
|
10
10
|
var types_1 = require("./types");
|
|
11
11
|
Object.defineProperty(exports, "isImageCapableCLITool", { enumerable: true, get: function () { return types_1.isImageCapableCLITool; } });
|
|
12
12
|
var composer_spec_1 = require("./composer-spec");
|
|
@@ -31,6 +31,9 @@ var gemini_1 = require("./gemini");
|
|
|
31
31
|
Object.defineProperty(exports, "GeminiTool", { enumerable: true, get: function () { return gemini_1.GeminiTool; } });
|
|
32
32
|
var antigravity_1 = require("./antigravity");
|
|
33
33
|
Object.defineProperty(exports, "AntigravityTool", { enumerable: true, get: function () { return antigravity_1.AntigravityTool; } });
|
|
34
|
+
var command_code_1 = require("./command-code");
|
|
35
|
+
Object.defineProperty(exports, "CommandCodeTool", { enumerable: true, get: function () { return command_code_1.CommandCodeTool; } });
|
|
36
|
+
Object.defineProperty(exports, "buildCommandCodeLaunchCommand", { enumerable: true, get: function () { return command_code_1.buildCommandCodeLaunchCommand; } });
|
|
34
37
|
// Export CLI tool manager
|
|
35
38
|
var manager_1 = require("./manager");
|
|
36
39
|
Object.defineProperty(exports, "CLIToolManager", { enumerable: true, get: function () { return manager_1.CLIToolManager; } });
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* How to obtain each agent CLI CommandMate can drive (Issue #2301).
|
|
4
|
+
*
|
|
5
|
+
* ## Why this exists
|
|
6
|
+
*
|
|
7
|
+
* Every one of the eight tools already refuses to start when its binary is not
|
|
8
|
+
* on `PATH` — that gate is #2009's, and it is uniform. What was NOT uniform was
|
|
9
|
+
* what the refusal said. Seven of them said some spelling of
|
|
10
|
+
* `<tool> is not installed or not in PATH` and stopped there; only copilot went
|
|
11
|
+
* on to name the installer (`COPILOT_INSTALL_HINT`, #1907). So a reader who
|
|
12
|
+
* picked opencode or Command Code from the agent list got a sentence that told
|
|
13
|
+
* them the tool was missing and nothing about how to stop it being missing,
|
|
14
|
+
* while the reader who picked copilot got both. This module is the second half
|
|
15
|
+
* of that sentence, written once for all eight.
|
|
16
|
+
*
|
|
17
|
+
* ## Where the strings come from
|
|
18
|
+
*
|
|
19
|
+
* Measured against the npm registry and this machine's global install on
|
|
20
|
+
* 2026-09-05, not copied from an Issue body:
|
|
21
|
+
*
|
|
22
|
+
* | tool | binary | evidence |
|
|
23
|
+
* |---------------|---------------|---------------------------------------------|
|
|
24
|
+
* | claude | `claude` | `@anthropic-ai/claude-code` 2.1.261 |
|
|
25
|
+
* | codex | `codex` | `@openai/codex` — the package #2069 updates |
|
|
26
|
+
* | gemini | `gemini` | `@google/gemini-cli` 0.58.0 |
|
|
27
|
+
* | opencode | `opencode` | `opencode-ai` 1.18.28 |
|
|
28
|
+
* | copilot | `copilot` | {@link COPILOT_INSTALL_HINT} (#1907) |
|
|
29
|
+
* | command-code | `commandcode` | `command-code` 1.49.0 (four bins; #2250 |
|
|
30
|
+
* | | | picked `commandcode`) |
|
|
31
|
+
* | antigravity | `agy` | no package — the URL below is a string in |
|
|
32
|
+
* | | | the shipped `agy` binary itself |
|
|
33
|
+
* | vibe-local | `vibe-local` | a local script, not a published artifact |
|
|
34
|
+
*
|
|
35
|
+
* `@anthropic-ai/claude-cli` — the name `PreflightChecker.getInstallHint` still
|
|
36
|
+
* carries — is **not** a package that exists; `npm view` 404s it. The spelling
|
|
37
|
+
* here is the one that resolves.
|
|
38
|
+
*
|
|
39
|
+
* ## Why not `CLI_TOOL_DISPLAY_NAMES`' neighbour in `types.ts`
|
|
40
|
+
*
|
|
41
|
+
* A hint is advice about the world outside this repository, and it goes stale
|
|
42
|
+
* on someone else's release schedule. Keeping it out of `types.ts` keeps the
|
|
43
|
+
* module that every consumer of `CLIToolType` imports free of a table that has
|
|
44
|
+
* to be re-measured, and gives the re-measurement one file to land in.
|
|
45
|
+
*
|
|
46
|
+
* ## The one path this does not reach yet
|
|
47
|
+
*
|
|
48
|
+
* Seven tools ask `isInstalled()` inside their own `launchSession` and throw
|
|
49
|
+
* from there, so pointing that line at {@link missingToolError} is all it takes.
|
|
50
|
+
* claude does not: `ClaudeTool.launchSession` delegates to
|
|
51
|
+
* `lib/session/claude-session`, which owns the detection AND composes the
|
|
52
|
+
* sentence (`Claude CLI is not installed or not in PATH`, #1637). Enriching it
|
|
53
|
+
* means editing that module, and `tests/integration/api-send-cli-tool.test.ts`
|
|
54
|
+
* pins the sentence verbatim — both outside the scope this change was allowed to
|
|
55
|
+
* touch, so claude's tmux-launch wording is unchanged here.
|
|
56
|
+
*
|
|
57
|
+
* claude is NOT hintless, though: `assertToolStartable` and
|
|
58
|
+
* `reportToolUnavailable` (`./start-availability`) both build their refusal from
|
|
59
|
+
* this module, so the path Assistant Chat takes already carries the hint. What
|
|
60
|
+
* remains is one line in `claude-session.ts` plus the assertion that pins it.
|
|
61
|
+
*
|
|
62
|
+
* @module lib/cli-tools/install-hints
|
|
63
|
+
*/
|
|
64
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
65
|
+
exports.CLI_TOOL_INSTALL_HINTS = void 0;
|
|
66
|
+
exports.getCliToolInstallHint = getCliToolInstallHint;
|
|
67
|
+
exports.buildMissingToolMessage = buildMissingToolMessage;
|
|
68
|
+
exports.missingToolError = missingToolError;
|
|
69
|
+
const copilot_constants_1 = require("../../config/copilot-constants");
|
|
70
|
+
const session_start_error_1 = require("../session/session-start-error");
|
|
71
|
+
/**
|
|
72
|
+
* One sentence per tool, saying how to get it.
|
|
73
|
+
*
|
|
74
|
+
* Total rather than partial (`Record`, not `Partial<Record>`), so adding a
|
|
75
|
+
* ninth entry to `CLI_TOOL_IDS` fails `tsc` here instead of shipping a tool
|
|
76
|
+
* whose refusal says nothing — the shape #2009 used to make the gate itself
|
|
77
|
+
* impossible to forget.
|
|
78
|
+
*/
|
|
79
|
+
exports.CLI_TOOL_INSTALL_HINTS = {
|
|
80
|
+
claude: 'Install with: npm install -g @anthropic-ai/claude-code',
|
|
81
|
+
codex: 'Install with: npm install -g @openai/codex',
|
|
82
|
+
gemini: 'Install with: npm install -g @google/gemini-cli',
|
|
83
|
+
opencode: 'Install with: npm install -g opencode-ai',
|
|
84
|
+
copilot: copilot_constants_1.COPILOT_INSTALL_HINT,
|
|
85
|
+
'command-code': 'Install with: npm install -g command-code',
|
|
86
|
+
// No package to name: `agy` ships with Antigravity and updates itself. The
|
|
87
|
+
// URL is lifted from the binary on PATH rather than from a search result.
|
|
88
|
+
antigravity: 'Install the Antigravity CLI: https://antigravity.google/docs/cli/reference',
|
|
89
|
+
// Deliberately not an install command. `vibe-local` is a local shell script
|
|
90
|
+
// driving an Ollama model, which is also why `version-probes.ts` excludes it
|
|
91
|
+
// from staleness probing — there is no published artifact to point at.
|
|
92
|
+
'vibe-local': 'vibe-local is a local script rather than a published package: put your own `vibe-local` executable on PATH.',
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* How to obtain `id`.
|
|
96
|
+
*
|
|
97
|
+
* @param id - The tool whose binary is missing
|
|
98
|
+
* @returns The tool's install sentence
|
|
99
|
+
*/
|
|
100
|
+
function getCliToolInstallHint(id) {
|
|
101
|
+
return exports.CLI_TOOL_INSTALL_HINTS[id];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The whole sentence a missing binary earns: what is missing, what it is
|
|
105
|
+
* called on `PATH`, and how to get it.
|
|
106
|
+
*
|
|
107
|
+
* The binary name is inside the message because the display name is often not
|
|
108
|
+
* the thing to type — `Command Code CLI` is `commandcode`, `Antigravity CLI` is
|
|
109
|
+
* `agy` — and the two tools whose old wording already spelled it out were the
|
|
110
|
+
* two whose names diverge most.
|
|
111
|
+
*
|
|
112
|
+
* `is not installed` is load-bearing: `lib/push/failure-push-notifier` renders
|
|
113
|
+
* its own localized body, but the HTTP layer and three suites read this string,
|
|
114
|
+
* and #2009's contract is that the phrase survives.
|
|
115
|
+
*
|
|
116
|
+
* @param tool - The tool that could not be started
|
|
117
|
+
* @returns A sentence safe to hand back to an HTTP caller
|
|
118
|
+
*/
|
|
119
|
+
function buildMissingToolMessage(tool) {
|
|
120
|
+
return (`${tool.name} (${tool.command}) is not installed or not in PATH. ` +
|
|
121
|
+
`${getCliToolInstallHint(tool.id)}`);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The typed refusal, carrying {@link buildMissingToolMessage}.
|
|
125
|
+
*
|
|
126
|
+
* @param tool - The tool that could not be started
|
|
127
|
+
* @returns The error every launch path throws for a missing binary
|
|
128
|
+
*/
|
|
129
|
+
function missingToolError(tool) {
|
|
130
|
+
return new session_start_error_1.SessionStartUnavailableError(tool.name, buildMissingToolMessage(tool));
|
|
131
|
+
}
|
|
@@ -193,6 +193,24 @@ const LIVENESS_SPECS = {
|
|
|
193
193
|
cli_patterns_1.ANTIGRAVITY_THINKING_PATTERN,
|
|
194
194
|
],
|
|
195
195
|
},
|
|
196
|
+
/**
|
|
197
|
+
* Command Code 1.40.1 — measured live at 200x1000 (Issue #2250).
|
|
198
|
+
*
|
|
199
|
+
* The composer glyph, the footer's mode indicator and the status row. The
|
|
200
|
+
* footer is included as well as the composer because the two are drawn in the
|
|
201
|
+
* same block and a frame carrying either one is a frame Command Code owns;
|
|
202
|
+
* neither can be matched by a shell prompt, which is the only property this
|
|
203
|
+
* list has to keep.
|
|
204
|
+
*/
|
|
205
|
+
'command-code': {
|
|
206
|
+
...SHARED,
|
|
207
|
+
...ADDED_TOOL_DEFAULTS,
|
|
208
|
+
alivePatterns: [
|
|
209
|
+
cli_patterns_1.COMMAND_CODE_PROMPT_PATTERN,
|
|
210
|
+
cli_patterns_1.COMMAND_CODE_MODE_INDICATOR_PATTERN,
|
|
211
|
+
cli_patterns_1.COMMAND_CODE_THINKING_PATTERN,
|
|
212
|
+
],
|
|
213
|
+
},
|
|
196
214
|
/** vibe-local — patterns from `cli-patterns`; no live frames (needs Ollama). */
|
|
197
215
|
'vibe-local': {
|
|
198
216
|
...SHARED,
|
|
@@ -45,6 +45,7 @@ const vibe_local_1 = require("./vibe-local");
|
|
|
45
45
|
const opencode_1 = require("./opencode");
|
|
46
46
|
const copilot_1 = require("./copilot");
|
|
47
47
|
const antigravity_1 = require("./antigravity");
|
|
48
|
+
const command_code_1 = require("./command-code");
|
|
48
49
|
/**
|
|
49
50
|
* CLI Tool Manager (Singleton)
|
|
50
51
|
* Provides centralized access to all CLI tools (Issue #368: includes Vibe Local, Issue #379: includes OpenCode)
|
|
@@ -65,6 +66,7 @@ class CLIToolManager {
|
|
|
65
66
|
this.tools.set('opencode', new opencode_1.OpenCodeTool());
|
|
66
67
|
this.tools.set('copilot', new copilot_1.CopilotTool());
|
|
67
68
|
this.tools.set('antigravity', new antigravity_1.AntigravityTool());
|
|
69
|
+
this.tools.set('command-code', new command_code_1.CommandCodeTool());
|
|
68
70
|
}
|
|
69
71
|
/**
|
|
70
72
|
* Get singleton instance
|
|
@@ -72,7 +72,7 @@ const opencode_session_recall_1 = require("../../lib/session/opencode-session-re
|
|
|
72
72
|
const opencode_session_store_1 = require("../../lib/session/opencode-session-store");
|
|
73
73
|
const graceful_exit_1 = require("./graceful-exit");
|
|
74
74
|
const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
|
|
75
|
-
const
|
|
75
|
+
const install_hints_1 = require("./install-hints");
|
|
76
76
|
const logger = (0, logger_1.createLogger)('cli-tools/opencode');
|
|
77
77
|
const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
|
|
78
78
|
/**
|
|
@@ -244,7 +244,7 @@ class OpenCodeTool extends base_1.BaseCLITool {
|
|
|
244
244
|
async launchSession(worktreeId, worktreePath, instanceId) {
|
|
245
245
|
const opencodeAvailable = await this.isInstalled();
|
|
246
246
|
if (!opencodeAvailable) {
|
|
247
|
-
throw
|
|
247
|
+
throw (0, install_hints_1.missingToolError)(this);
|
|
248
248
|
}
|
|
249
249
|
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
250
250
|
const target = (0, runtime_1.opencodeTarget)(worktreeId, instanceId);
|