commandmate 0.30.1 → 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 +164 -164
- package/.next/app-path-routes-manifest.json +28 -28
- 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 +28 -28
- 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 +2 -2
- 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/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 +101 -21
- package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +39 -0
- package/dist/server/src/lib/hooks/sources/claude/history.js +245 -21
- package/dist/server/src/lib/hooks/sources/claude/transcript.js +175 -13
- 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/hooks/stop-history-capture.js +58 -25
- 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-dbf04a99647f6018.js +0 -1
- package/.next/static/chunks/app/layout-6a26ea22d5cf03dc.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-aac399392ec8c273.js +0 -1
- package/.next/static/css/23f9c40ecc458c77.css +0 -1
- /package/.next/static/{pcpB4K6KreMzu2qbhvuRY → nXW4dPkpE_9xUf_9ySRff}/_buildManifest.js +0 -0
- /package/.next/static/{pcpB4K6KreMzu2qbhvuRY → nXW4dPkpE_9xUf_9ySRff}/_ssgManifest.js +0 -0
|
@@ -28,6 +28,12 @@ const prompt_dedup_1 = require("./prompt-dedup");
|
|
|
28
28
|
const prompt_dedup_state_1 = require("./prompt-dedup-state");
|
|
29
29
|
const response_dedup_1 = require("./response-dedup");
|
|
30
30
|
const structured_history_gate_1 = require("./structured-history-gate");
|
|
31
|
+
// Issue #2317 Phase D: while a human holds the pane's geometry, the frame is
|
|
32
|
+
// their terminal (44 rows), not the 1000-row canvas every rule below was
|
|
33
|
+
// measured against. See the block in `checkForResponse` for what that changes.
|
|
34
|
+
const session_name_1 = require("../../lib/cli-tools/session-name");
|
|
35
|
+
const geometry_delegation_1 = require("../../lib/tmux/geometry-delegation");
|
|
36
|
+
const tmux_session_surface_1 = require("../../lib/session/tmux-session-surface");
|
|
31
37
|
const response_poller_core_1 = require("./response-poller-core");
|
|
32
38
|
const push_1 = require("../../lib/push");
|
|
33
39
|
// Issue #1790: imported by deep path, not through `@/lib/push`. Suites that
|
|
@@ -246,13 +252,21 @@ function extractResponse(output, lastCapturedLine, cliToolId, captureWindowLines
|
|
|
246
252
|
// silently delete another tool's boundary, and a boundary that stops existing
|
|
247
253
|
// does not fail loudly: it puts terminal furniture back into History.
|
|
248
254
|
const openCodeCleanLines = cliToolId === 'opencode' ? lines.map(cli_patterns_1.stripAnsi) : null;
|
|
255
|
+
// Issue #2250: Command Code is the fourth. Its landmark is its own — the
|
|
256
|
+
// `❯ Ask your question...` composer fenced by two full-pane rules, with the
|
|
257
|
+
// permission-mode row underneath — and it is load-bearing rather than tidy:
|
|
258
|
+
// that placeholder is drawn with the same `❯ <text>` shape as a transcript
|
|
259
|
+
// echo, so without the boundary `findRecentUserPromptIndex` anchors the turn
|
|
260
|
+
// on the FOOTER and every reply extracts as empty (#1289's defect, verbatim).
|
|
249
261
|
const chromeStart = cliToolId === 'claude'
|
|
250
262
|
? (0, cli_patterns_1.findClaudeChromeStart)(lines)
|
|
251
263
|
: cliToolId === 'copilot'
|
|
252
264
|
? (0, cli_patterns_1.findCopilotChromeStart)(lines)
|
|
253
|
-
:
|
|
254
|
-
? (0, cli_patterns_1.
|
|
255
|
-
:
|
|
265
|
+
: cliToolId === 'command-code'
|
|
266
|
+
? (0, cli_patterns_1.findCommandCodeChromeStart)(lines)
|
|
267
|
+
: openCodeCleanLines
|
|
268
|
+
? (0, cli_patterns_1.findOpenCodeChromeStart)(openCodeCleanLines)
|
|
269
|
+
: -1;
|
|
256
270
|
const contentEnd = chromeStart >= 0 ? chromeStart : totalLines;
|
|
257
271
|
const BUFFER_RESET_TOLERANCE = 25;
|
|
258
272
|
const bufferShrank = totalLines > 0 && lastCapturedLine > BUFFER_RESET_TOLERANCE && (totalLines + BUFFER_RESET_TOLERANCE) < lastCapturedLine;
|
|
@@ -330,7 +344,16 @@ function extractResponse(output, lastCapturedLine, cliToolId, captureWindowLines
|
|
|
330
344
|
return -1;
|
|
331
345
|
};
|
|
332
346
|
// Early check for interactive prompts (before extraction logic)
|
|
333
|
-
|
|
347
|
+
//
|
|
348
|
+
// Issue #2250: `command-code` must be here. Its permission dialog draws its
|
|
349
|
+
// highlighted option as `❯ 1. Yes` and keeps a full-pane rule above the block,
|
|
350
|
+
// so `hasPrompt && hasSeparator && !isThinking` below is TRUE while the dialog
|
|
351
|
+
// is waiting for an answer — the turn would be declared finished and the
|
|
352
|
+
// dialog saved as the reply.
|
|
353
|
+
if (cliToolId === 'claude' ||
|
|
354
|
+
cliToolId === 'codex' ||
|
|
355
|
+
cliToolId === 'copilot' ||
|
|
356
|
+
cliToolId === 'command-code') {
|
|
334
357
|
const fullOutput = lines.join('\n');
|
|
335
358
|
const promptDetection = detectPromptWithOptions(fullOutput, cliToolId);
|
|
336
359
|
if (promptDetection.isPrompt) {
|
|
@@ -374,8 +397,15 @@ function extractResponse(output, lastCapturedLine, cliToolId, captureWindowLines
|
|
|
374
397
|
? copilotStatusBar === 'idle'
|
|
375
398
|
: (cliToolId === 'codex' || cliToolId === 'gemini' || cliToolId === 'vibe-local' || cliToolId === 'antigravity') && hasPrompt && !isThinking;
|
|
376
399
|
const isClaudeComplete = cliToolId === 'claude' && hasPrompt && hasSeparator && !isThinking;
|
|
400
|
+
// Issue #2250: claude's shape, because Command Code's layout is claude's — the
|
|
401
|
+
// composer sits between two full-pane rules and is drawn only when the agent
|
|
402
|
+
// will accept input. Deliberately NOT keyed on `✻ Worked for`: that row is the
|
|
403
|
+
// live turn's, not the transcript's (it is present in `turn-version.txt` and
|
|
404
|
+
// gone from `dialog-create-file.txt`, the same pane one prompt later) and
|
|
405
|
+
// `WorkedDurationNote` omits it entirely for a turn under 1000 ms.
|
|
406
|
+
const isCommandCodeComplete = cliToolId === 'command-code' && hasPrompt && hasSeparator && !isThinking;
|
|
377
407
|
const isOpenCodeDone = cliToolId === 'opencode' && (0, response_extractor_1.isOpenCodeComplete)(cleanOutputToCheck);
|
|
378
|
-
if (isPromptBasedComplete || isClaudeComplete || isOpenCodeDone) {
|
|
408
|
+
if (isPromptBasedComplete || isClaudeComplete || isCommandCodeComplete || isOpenCodeDone) {
|
|
379
409
|
const responseLines = [];
|
|
380
410
|
const startIndex = (0, response_extractor_1.resolveExtractionStartIndex)(lastCapturedLine, totalLines, bufferReset, cliToolId, findRecentUserPromptIndex, captureWindowSaturated);
|
|
381
411
|
let endIndex = totalLines;
|
|
@@ -515,6 +545,30 @@ function extractResponse(output, lastCapturedLine, cliToolId, captureWindowLines
|
|
|
515
545
|
return incompleteResult(totalLines);
|
|
516
546
|
}
|
|
517
547
|
}
|
|
548
|
+
// Issue #2250: Command Code's launch screen is a complete, idle frame --
|
|
549
|
+
// block-art logo, three `#` banner rows, composer drawn between its two
|
|
550
|
+
// rules -- so every check above accepts it, and History would open with
|
|
551
|
+
// `# Command Code v1.40.1 / # models: … / # <cwd>` saved as the agent's
|
|
552
|
+
// first reply before the operator has said anything.
|
|
553
|
+
//
|
|
554
|
+
// The rule is ONE condition and it is a positive one: Command Code echoes
|
|
555
|
+
// every prompt into the transcript as `❯ <text>`, and the launch screen has
|
|
556
|
+
// none. That is the shape #1897 and #2247 both converged on; the anchor
|
|
557
|
+
// heuristics claude carries above (`hasBannerArt` / `hasVersionInfo` /
|
|
558
|
+
// `hasStartupTips`) are deliberately NOT reproduced here, because they are
|
|
559
|
+
// what #2247 had to take back -- a bare version string in a reply is a
|
|
560
|
+
// normal reply, and Command Code prints its own version on every launch.
|
|
561
|
+
//
|
|
562
|
+
// `findRecentUserPromptIndex` is the same `/^[>❯]\s+\S/` scan the extraction
|
|
563
|
+
// anchors on, and it stops at `contentEnd`, so the composer's own dim
|
|
564
|
+
// `❯ Ask your question...` placeholder cannot be mistaken for an echo
|
|
565
|
+
// (#1879's trap).
|
|
566
|
+
if (cliToolId === 'command-code' && findRecentUserPromptIndex(totalLines) < 0) {
|
|
567
|
+
logger.info('Command Code launch screen suppressed, response not saved', {
|
|
568
|
+
responseLength: response.length,
|
|
569
|
+
});
|
|
570
|
+
return incompleteResult(totalLines);
|
|
571
|
+
}
|
|
518
572
|
// Gemini-specific check
|
|
519
573
|
if (cliToolId === 'gemini') {
|
|
520
574
|
const bannerCharCount = (response.match(/[░███]/g) || []).length;
|
|
@@ -631,6 +685,36 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
631
685
|
(0, response_poller_core_1.stopPolling)(worktreeId, cliToolId, instanceId);
|
|
632
686
|
return false;
|
|
633
687
|
}
|
|
688
|
+
// Issue #2317 Phase D: is a human reading this pane at their own terminal
|
|
689
|
+
// size right now, and did they just stop?
|
|
690
|
+
//
|
|
691
|
+
// Asked only for the tools `attach --live` accepts — no other session can be
|
|
692
|
+
// delegated, so asking about one would be a tmux round-trip per poll with a
|
|
693
|
+
// single possible answer. The read itself is memoised for a second
|
|
694
|
+
// (`DELEGATION_TTL_MS`), which is under one poll interval.
|
|
695
|
+
const sessionName = (0, session_name_1.resolveSessionName)(cliToolId, worktreeId, instanceId);
|
|
696
|
+
const delegation = (0, tmux_session_surface_1.isLiveAttachEligibleSession)(sessionName)
|
|
697
|
+
? await (0, geometry_delegation_1.probeGeometryDelegation)(sessionName)
|
|
698
|
+
: { delegated: false, released: false };
|
|
699
|
+
if (delegation.released) {
|
|
700
|
+
// The canvas is 1000 rows again, so a cursor recorded against a 44-row
|
|
701
|
+
// frame indexes into a pane that no longer exists. Zero is the only value
|
|
702
|
+
// that cannot be wrong in either direction: too low re-saves a turn, too
|
|
703
|
+
// high suppresses every future one. Done BEFORE the state is read below so
|
|
704
|
+
// this poll already sees the reset.
|
|
705
|
+
//
|
|
706
|
+
// A no-op for claude in practice — it renders in the alternate screen, so
|
|
707
|
+
// `lineCountIsCursor` is false and the cursor is not consulted — and that
|
|
708
|
+
// is exactly why it is written here rather than left implicit: the guard
|
|
709
|
+
// has to already be right on the day a scrollback tool is added to
|
|
710
|
+
// `LIVE_ATTACH_TOOLS`.
|
|
711
|
+
(0, db_1.updateSessionState)(db, worktreeId, cliToolId, 0, resolvedInstanceId);
|
|
712
|
+
logger.info('geometry-delegation-released', {
|
|
713
|
+
worktreeId,
|
|
714
|
+
cliToolId,
|
|
715
|
+
instanceId: resolvedInstanceId,
|
|
716
|
+
});
|
|
717
|
+
}
|
|
634
718
|
// Get session state (last captured line count)
|
|
635
719
|
const sessionState = (0, db_1.getSessionState)(db, worktreeId, resolvedInstanceId);
|
|
636
720
|
const lastCapturedLine = sessionState?.lastCapturedLine || 0;
|
|
@@ -891,8 +975,25 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
891
975
|
worktreePath: worktree.path,
|
|
892
976
|
transcriptPathHint: claudeMetadata?.logFilePath ?? null,
|
|
893
977
|
}));
|
|
978
|
+
// Issue #2317 Phase D: the scrape is dropped while the geometry is
|
|
979
|
+
// delegated, and the transcript capture above is what makes that safe.
|
|
980
|
+
//
|
|
981
|
+
// ORDER IS LOAD-BEARING. The delegation test is folded in AFTER the two
|
|
982
|
+
// calls above rather than short-circuiting them: `captureStructuredHistoryTurn`
|
|
983
|
+
// is a WRITE, not a query — it is the moment claude's own transcript becomes
|
|
984
|
+
// a History row — so an `||` that put the delegation first would suppress
|
|
985
|
+
// the scrape and the real reply together, and the turn would vanish. Read as
|
|
986
|
+
// it stands: record the turn from the agent's own file, then drop the pane's
|
|
987
|
+
// copy of it, which at 44 rows is a fraction of the answer hard-wrapped at
|
|
988
|
+
// the reader's terminal width.
|
|
989
|
+
//
|
|
990
|
+
// When the transcript capture answers false (an unreadable or absent file)
|
|
991
|
+
// the turn goes UNRECORDED for as long as the delegation lasts. That is the
|
|
992
|
+
// deliberate trade: a missing row is recoverable, a truncated reply saved as
|
|
993
|
+
// the agent's answer is not.
|
|
994
|
+
const suppressScrapedHistory = structuredHistoryLive || delegation.delegated;
|
|
894
995
|
// Create Markdown log file for the conversation pair
|
|
895
|
-
if (cleanedResponse && !
|
|
996
|
+
if (cleanedResponse && !suppressScrapedHistory) {
|
|
896
997
|
await (0, conversation_logger_1.recordClaudeConversation)(db, worktreeId, cleanedResponse, cliToolId);
|
|
897
998
|
}
|
|
898
999
|
// Mark any pending prompts as answered
|
|
@@ -913,7 +1014,7 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
913
1014
|
// are not byte-comparable — the pane's copy is hard-wrapped at the pane
|
|
914
1015
|
// width and gutter-prefixed, so no content check could ever recognise them
|
|
915
1016
|
// as the same reply.
|
|
916
|
-
if (!
|
|
1017
|
+
if (!suppressScrapedHistory) {
|
|
917
1018
|
// Create new CLI tool message in database
|
|
918
1019
|
const message = (0, db_1.createMessage)(db, {
|
|
919
1020
|
worktreeId,
|
|
@@ -936,6 +1037,10 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
936
1037
|
cliToolId,
|
|
937
1038
|
instanceId: resolvedInstanceId,
|
|
938
1039
|
scrapedLength: cleanedResponse.length,
|
|
1040
|
+
// Which of the two reasons suppressed it. Without this the Phase D case
|
|
1041
|
+
// and the ordinary #2041/#2121 handover are one indistinguishable log
|
|
1042
|
+
// line, and "History is missing a turn" has two very different causes.
|
|
1043
|
+
reason: structuredHistoryLive ? 'structured-history' : 'geometry-delegated',
|
|
939
1044
|
});
|
|
940
1045
|
}
|
|
941
1046
|
// Issue #1790: the agent has just produced a reply, so whatever it was
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Whether somebody better-informed is already recording this turn (Issue #2041,
|
|
4
|
-
* extended for Claude Code in #2121, codex in #2197
|
|
4
|
+
* extended for Claude Code in #2121, codex in #2197, antigravity in #2198 and
|
|
5
|
+
* Command Code in #2252).
|
|
5
6
|
*
|
|
6
7
|
* The poller's job has always been to be the only writer of conversation
|
|
7
|
-
* history, because for most of the
|
|
8
|
-
* reply exists.
|
|
9
|
-
* replies over the SSE stream CommandMate subscribes to (#1763/#2041), and
|
|
10
|
-
* claude, codex and
|
|
11
|
-
* Two writers for one turn would put the same answer in History
|
|
12
|
-
* the agent wrote it and once as its TUI drew it — so one of
|
|
13
|
-
* down, and it is the one reading the screen.
|
|
8
|
+
* history, because for most of the seven tools the terminal is the only place
|
|
9
|
+
* the reply exists. Five of them now have a second writer: opencode publishes
|
|
10
|
+
* its replies over the SSE stream CommandMate subscribes to (#1763/#2041), and
|
|
11
|
+
* claude, codex, antigravity and command-code each keep their own transcript
|
|
12
|
+
* file on disk. Two writers for one turn would put the same answer in History
|
|
13
|
+
* twice — once as the agent wrote it and once as its TUI drew it — so one of
|
|
14
|
+
* them has to stand down, and it is the one reading the screen.
|
|
14
15
|
*
|
|
15
16
|
* ## Why this is a module and not an `if`
|
|
16
17
|
*
|
|
@@ -74,9 +75,11 @@ const subscription_1 = require("../../lib/hooks/sources/opencode/subscription");
|
|
|
74
75
|
const history_1 = require("../../lib/hooks/sources/claude/history");
|
|
75
76
|
const history_2 = require("../../lib/hooks/sources/codex/history");
|
|
76
77
|
const history_3 = require("../../lib/hooks/sources/antigravity/history");
|
|
78
|
+
const history_4 = require("../../lib/hooks/sources/command-code/history");
|
|
77
79
|
const tool_id_1 = require("../../lib/hooks/sources/claude/tool-id");
|
|
78
80
|
const tool_id_2 = require("../../lib/hooks/sources/codex/tool-id");
|
|
79
81
|
const tool_id_3 = require("../../lib/hooks/sources/antigravity/tool-id");
|
|
82
|
+
const tool_id_4 = require("../../lib/hooks/sources/command-code/tool-id");
|
|
80
83
|
const registry_1 = require("../../lib/hooks/sources/registry");
|
|
81
84
|
const logger = (0, logger_1.createLogger)('lib/polling/structured-history-gate');
|
|
82
85
|
/**
|
|
@@ -168,6 +171,10 @@ const PULL_TRANSCRIPT_READERS = {
|
|
|
168
171
|
capture: (target, capture) => (0, history_3.captureAntigravityTranscriptTurn)(target, capture),
|
|
169
172
|
locate: (target, capture) => (0, history_3.resolveAntigravityTranscriptPath)(target, capture),
|
|
170
173
|
},
|
|
174
|
+
[tool_id_4.COMMAND_CODE_CLI_TOOL_ID]: {
|
|
175
|
+
capture: (target, capture) => (0, history_4.captureCommandCodeTranscriptTurn)(target, capture),
|
|
176
|
+
locate: (target, capture) => (0, history_4.resolveCommandCodeTranscriptPath)(target, capture),
|
|
177
|
+
},
|
|
171
178
|
};
|
|
172
179
|
/**
|
|
173
180
|
* What this tool's source says about who records its replies.
|
|
@@ -20,17 +20,27 @@ exports.parseRealtimeEvent = parseRealtimeEvent;
|
|
|
20
20
|
*/
|
|
21
21
|
exports.CLIENT_VERSION_MESSAGE_TYPE = 'client_version';
|
|
22
22
|
/**
|
|
23
|
-
* Server → client notice that the
|
|
24
|
-
* tab's bundle
|
|
23
|
+
* Server → client notice that the bundle the server now serves was built from a
|
|
24
|
+
* different version than this tab's bundle (#1338/#1356/#2271). Drives the
|
|
25
|
+
* reload banner.
|
|
25
26
|
*/
|
|
26
27
|
exports.VERSION_MISMATCH_EVENT_TYPE = 'version_mismatch';
|
|
27
28
|
/**
|
|
28
|
-
* Whether
|
|
29
|
-
*
|
|
29
|
+
* Whether two **build identities** have drifted apart and the user should be
|
|
30
|
+
* nudged to reload (#1338/#1356).
|
|
31
|
+
*
|
|
32
|
+
* Both arguments are the version a bundle was *built from*, never the version
|
|
33
|
+
* installed on disk. Issue #2271: feeding this the runtime `package.json`
|
|
34
|
+
* version on the server side made it fire permanently for everyone, because the
|
|
35
|
+
* release procedure bumps that file and deliberately does not rebuild the
|
|
36
|
+
* running server's `.next` — so "installed > served" is the steady state after
|
|
37
|
+
* every release rather than evidence of anything. `resolveBundleDrift()` in
|
|
38
|
+
* `@/lib/version-checker` is the one caller that resolves the server side, and
|
|
39
|
+
* it resolves it from the build manifest.
|
|
30
40
|
*
|
|
31
41
|
* Conservative on purpose (受入条件: 版が一致している間は誤検知しない): an empty or
|
|
32
42
|
* `'0.0.0'` fallback on either side means "version unknown" and is never treated
|
|
33
|
-
* as a mismatch, so a server that cannot resolve its own
|
|
43
|
+
* as a mismatch, so a server that cannot resolve its own build stays silent.
|
|
34
44
|
*/
|
|
35
45
|
function isVersionMismatch(serverVersion, clientVersion) {
|
|
36
46
|
if (!serverVersion || !clientVersion)
|
|
@@ -160,8 +160,15 @@ function cleanGeminiResponse(response) {
|
|
|
160
160
|
* their own by {@link COPILOT_FOLD_MARKER_PATTERN} and
|
|
161
161
|
* {@link COPILOT_COMMAND_OUTPUT_PATTERN}, so nothing needs a block that can run
|
|
162
162
|
* away over a whole message.
|
|
163
|
+
*
|
|
164
|
+
* Issue #2269: the verb list moved to {@link COPILOT_TOOL_VERBS}, which
|
|
165
|
+
* `COPILOT_TOOL_ROW_PATTERN` reads as well. 1.0.82 marks most tool rows with a
|
|
166
|
+
* file-type badge rather than `●` and that pattern owns those; `●` is still the
|
|
167
|
+
* marker for a tool row whose file type has no badge (`● Read d.txt 1 line
|
|
168
|
+
* read`, measured) and for the ask-user row (`● Asked user …`), so both markers
|
|
169
|
+
* have to answer to one vocabulary.
|
|
163
170
|
*/
|
|
164
|
-
const COPILOT_TOOL_ACTION_PATTERN =
|
|
171
|
+
const COPILOT_TOOL_ACTION_PATTERN = new RegExp(`^●\\s+(?:${cli_patterns_1.COPILOT_TOOL_VERBS})[\\s:]`);
|
|
165
172
|
/**
|
|
166
173
|
* copilot 1.0.80's tool invocation row (Issue #1897).
|
|
167
174
|
*
|
|
@@ -263,6 +270,22 @@ function cleanCopilotResponse(response) {
|
|
|
263
270
|
let inThinkingBlock = false;
|
|
264
271
|
let inToolOutputBlock = false;
|
|
265
272
|
for (const line of responseLines) {
|
|
273
|
+
// Issue #2269: tested BEFORE normalisation, for the reason #1897 records at
|
|
274
|
+
// COPILOT_BOX_ROW_PATTERN and then only acted on in the accumulator:
|
|
275
|
+
// `normalizeCopilotLine` deletes every U+2500..U+257F glyph, so by the time
|
|
276
|
+
// COPILOT_SKIP_PATTERNS runs below, every glyph-anchored rule in it is dead
|
|
277
|
+
// in THIS function. That is what let two rows of copilot's launch screen
|
|
278
|
+
// through -- ` ╰─╯╰─╯ Copilot v1.0.82 uses AI.` cleans to a bare version
|
|
279
|
+
// string (1.0.82 split the one-line disclaimer the exact-match rule was
|
|
280
|
+
// written for), and ` └ Enable all permissions …` cleans to prose -- on
|
|
281
|
+
// every call that receives a raw frame rather than accumulated content.
|
|
282
|
+
//
|
|
283
|
+
// Deliberately not resetting the block flags: the reasoning block's own rows
|
|
284
|
+
// are `│ <chain of thought>`, so a box row is the middle of a block far more
|
|
285
|
+
// often than the end of one. That is the behaviour the dead `/^[│└]/` rule
|
|
286
|
+
// below was written with, and this is the live version of it.
|
|
287
|
+
if (cli_patterns_1.COPILOT_BOX_ROW_PATTERN.test(line))
|
|
288
|
+
continue;
|
|
266
289
|
// Normalize using the same function as TUI accumulator (DRY)
|
|
267
290
|
const normalized = (0, tui_accumulator_1.normalizeCopilotLine)(line);
|
|
268
291
|
if (!normalized) {
|
|
@@ -203,6 +203,17 @@ function resolveExtractionStartIndex(lastCapturedLine, totalLines, bufferReset,
|
|
|
203
203
|
const foundUserPrompt = findRecentUserPromptIndex(totalLines);
|
|
204
204
|
return foundUserPrompt >= 0 ? foundUserPrompt + 1 : Math.max(0, lastCapturedLine);
|
|
205
205
|
}
|
|
206
|
+
// Branch 2a''' (Command Code, Issue #2250): same reasoning as agy's above.
|
|
207
|
+
// Command Code is inline-rendered (`#{alternate_on}` = 0, scrollback kept), so
|
|
208
|
+
// `lastCapturedLine` is a real cursor and stays the fallback; but the echo
|
|
209
|
+
// `❯ <message>` is present in every captured turn and is the cleaner boundary,
|
|
210
|
+
// and the caller has already excluded the composer from the search window by
|
|
211
|
+
// trimming the chrome, so the echo this finds is a transcript row rather than
|
|
212
|
+
// the placeholder in the input box.
|
|
213
|
+
if (cliToolId === 'command-code') {
|
|
214
|
+
const foundUserPrompt = findRecentUserPromptIndex(totalLines);
|
|
215
|
+
return foundUserPrompt >= 0 ? foundUserPrompt + 1 : Math.max(0, lastCapturedLine);
|
|
216
|
+
}
|
|
206
217
|
// Compute bufferWasReset internally (MF-001: responsibility boundary)
|
|
207
218
|
const bufferWasReset = lastCapturedLine >= totalLines || bufferReset;
|
|
208
219
|
// Branch 1: Buffer was reset - find the most recent user prompt as anchor
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Issue #294: Executes CLI tool commands for scheduled executions
|
|
5
5
|
* Issue #379: Added OpenCode support (opencode run)
|
|
6
6
|
*
|
|
7
|
-
* Supported tools: claude, codex, gemini, vibe-local, opencode, copilot, antigravity
|
|
7
|
+
* Supported tools: claude, codex, gemini, vibe-local, opencode, copilot, antigravity, command-code
|
|
8
8
|
*
|
|
9
9
|
* Security:
|
|
10
10
|
* - Uses execFile (not exec) to prevent shell injection
|
|
@@ -14,11 +14,13 @@
|
|
|
14
14
|
* - Validates cliToolId against ALLOWED_CLI_TOOLS whitelist [SEC-001]
|
|
15
15
|
*/
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.ALLOWED_CLI_TOOLS = exports.MAX_MESSAGE_LENGTH = exports.EXECUTION_TIMEOUT_MS = exports.MAX_STORED_OUTPUT_SIZE = exports.MAX_OUTPUT_SIZE = void 0;
|
|
17
|
+
exports.COMMAND_CODE_EXIT_REASONS = exports.ALLOWED_CLI_TOOLS = exports.MAX_MESSAGE_LENGTH = exports.EXECUTION_TIMEOUT_MS = exports.MAX_STORED_OUTPUT_SIZE = exports.MAX_OUTPUT_SIZE = void 0;
|
|
18
18
|
exports.getCommandForTool = getCommandForTool;
|
|
19
19
|
exports.truncateOutput = truncateOutput;
|
|
20
20
|
exports.buildCliArgs = buildCliArgs;
|
|
21
21
|
exports.extractOpencodeFinalText = extractOpencodeFinalText;
|
|
22
|
+
exports.extractCommandCodeResult = extractCommandCodeResult;
|
|
23
|
+
exports.describeCommandCodeFailure = describeCommandCodeFailure;
|
|
22
24
|
exports.executeClaudeCommand = executeClaudeCommand;
|
|
23
25
|
exports.getActiveProcesses = getActiveProcesses;
|
|
24
26
|
const child_process_1 = require("child_process");
|
|
@@ -62,6 +64,16 @@ function getCommandForTool(cliToolId) {
|
|
|
62
64
|
// Issue #990 (Phase C): Antigravity's executable is `agy`, not the tool id.
|
|
63
65
|
case 'antigravity':
|
|
64
66
|
return 'agy';
|
|
67
|
+
// Issue #2253: Command Code ships four bins (`cmd` / `cmdc` / `command-code`
|
|
68
|
+
// / `commandcode`) and Epic #2249 決定 1 picked the unambiguous spelling, so
|
|
69
|
+
// the tool id is not the executable here either. Written as a literal to
|
|
70
|
+
// match the two cases above rather than importing
|
|
71
|
+
// `COMMAND_CODE_COMMAND` from `@/lib/cli-tools/command-code`, which would
|
|
72
|
+
// pull the tmux transport into the scheduler's dependency graph; the unit
|
|
73
|
+
// test imports both and asserts they are the same string, so the copy
|
|
74
|
+
// cannot drift.
|
|
75
|
+
case 'command-code':
|
|
76
|
+
return 'commandcode';
|
|
65
77
|
default:
|
|
66
78
|
return cliToolId;
|
|
67
79
|
}
|
|
@@ -94,6 +106,7 @@ function truncateOutput(output) {
|
|
|
94
106
|
* - vibe-local: [-p <message> -y] or [--model <model> -p <message> -y]
|
|
95
107
|
* - opencode: run --format json [-m <model>] [--agent <a>] [--variant <v>] [-c] [--title <t>] <message>
|
|
96
108
|
* - antigravity: -p <message> --dangerously-skip-permissions
|
|
109
|
+
* - command-code: -p <message> --output-format json [--yolo | --permission-mode <permission>]
|
|
97
110
|
* - others: -p <message> (fallback)
|
|
98
111
|
*
|
|
99
112
|
* @param message - Prompt message
|
|
@@ -159,6 +172,44 @@ function buildCliArgs(message, cliToolId, permission, options) {
|
|
|
159
172
|
args.push(message);
|
|
160
173
|
return args;
|
|
161
174
|
}
|
|
175
|
+
case 'command-code': {
|
|
176
|
+
// Issue #2253 (Epic #2249 Phase D): `commandcode -p <message>` runs one
|
|
177
|
+
// prompt non-interactively. `--output-format json` is unconditional for
|
|
178
|
+
// the same reason opencode's `--format json` is: the text format writes a
|
|
179
|
+
// rendered answer with no frame around it, while the json format ends in a
|
|
180
|
+
// single `{"type":"result",…}` line carrying `finalText` and `subtype`,
|
|
181
|
+
// which is what {@link extractCommandCodeResult} reads.
|
|
182
|
+
//
|
|
183
|
+
// ## `--yolo` and `--permission-mode` are different axes, and exclusive here
|
|
184
|
+
//
|
|
185
|
+
// `commandcode --help` lists them separately, and the shipped option
|
|
186
|
+
// declaration in `command-code@1.40.1/dist/cli.mjs` is
|
|
187
|
+
// `.addOption(new Be('--permission-mode <mode>', …).choices(['default',
|
|
188
|
+
// 'standard','plan','auto-accept','dont-ask']))` with `--yolo` as a plain
|
|
189
|
+
// boolean alias of `--dangerously-skip-permissions`. So `--yolo` is not a
|
|
190
|
+
// *value* of the mode flag, and sending both would ask the CLI to run
|
|
191
|
+
// under a mode and to bypass modes at once. A scheduled run has nobody to
|
|
192
|
+
// answer a permission dialog, so the default is `--yolo` and an explicit
|
|
193
|
+
// permission replaces it rather than joining it.
|
|
194
|
+
//
|
|
195
|
+
// The whitelist check follows copilot's shape (SEC4-001) rather than
|
|
196
|
+
// codex's `??`: a permission the dropdown could not have produced falls
|
|
197
|
+
// back to the unattended default instead of reaching the CLI, where an
|
|
198
|
+
// unknown `--permission-mode` value is a `.choices()` rejection and the
|
|
199
|
+
// run would fail before the prompt was ever sent.
|
|
200
|
+
//
|
|
201
|
+
// `--yolo` does not override `.commandcode/settings.json`
|
|
202
|
+
// `permissions.deny`; a denied tool call still ends the run with exit 4,
|
|
203
|
+
// which {@link describeCommandCodeExit} names in the failure reason.
|
|
204
|
+
const args = ['-p', message, '--output-format', 'json'];
|
|
205
|
+
if (schedule_config_1.COMMAND_CODE_PERMISSIONS.includes(permission)) {
|
|
206
|
+
args.push('--permission-mode', permission);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
args.push('--yolo');
|
|
210
|
+
}
|
|
211
|
+
return args;
|
|
212
|
+
}
|
|
162
213
|
case 'antigravity':
|
|
163
214
|
// Issue #990 (Phase C): `agy -p <message>` runs a single prompt non-interactively.
|
|
164
215
|
// --dangerously-skip-permissions auto-approves tool use so the process does not
|
|
@@ -292,6 +343,134 @@ function renderOpencodeErrorFrame(record) {
|
|
|
292
343
|
const message = typeof data.message === 'string' ? data.message : '';
|
|
293
344
|
return message ? `opencode error: ${name}: ${message}` : `opencode error: ${name}`;
|
|
294
345
|
}
|
|
346
|
+
// =============================================================================
|
|
347
|
+
// command-code `--output-format json` extraction (Issue #2253)
|
|
348
|
+
// =============================================================================
|
|
349
|
+
/**
|
|
350
|
+
* `PRINT_EXIT_CODE`, read off `command-code@1.40.1/dist/cli.mjs`.
|
|
351
|
+
*
|
|
352
|
+
* The bundle declares it as one object —
|
|
353
|
+
* `{SUCCESS:0, ERROR:1, AUTH_ERROR:3, PERMISSION_DENIED:4, RATE_LIMITED:5,
|
|
354
|
+
* CONNECTION_ERROR:6, SERVER_ERROR:7, MAX_TURNS_REACHED:8, NO_RESPONSE:9,
|
|
355
|
+
* INSUFFICIENT_CREDITS:10, INTERRUPTED:130}` — and `classifyPrintModeError`
|
|
356
|
+
* next to it is what picks between them. Issue #2253 lists six of the eleven;
|
|
357
|
+
* all eleven are recorded here because the point of the map is to turn a bare
|
|
358
|
+
* number in an execution log into a sentence, and a code that falls through
|
|
359
|
+
* produces exactly the log line the map exists to replace.
|
|
360
|
+
*
|
|
361
|
+
* 0 is deliberately absent: success is not a failure reason, and a lookup that
|
|
362
|
+
* answers for it would let a caller render "Reason: success" on a run that
|
|
363
|
+
* worked.
|
|
364
|
+
*/
|
|
365
|
+
exports.COMMAND_CODE_EXIT_REASONS = {
|
|
366
|
+
1: 'error',
|
|
367
|
+
3: 'authentication failed',
|
|
368
|
+
4: 'permission denied',
|
|
369
|
+
5: 'rate limited',
|
|
370
|
+
6: 'connection error',
|
|
371
|
+
7: 'server error',
|
|
372
|
+
8: 'max turns reached',
|
|
373
|
+
9: 'no response',
|
|
374
|
+
10: 'insufficient credits',
|
|
375
|
+
130: 'interrupted',
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* The result line of `commandcode -p … --output-format json`, or null.
|
|
379
|
+
*
|
|
380
|
+
* ## The measured stream
|
|
381
|
+
*
|
|
382
|
+
* One JSON object per line. Every line but the last is `{"type":"event",…}`;
|
|
383
|
+
* the last is the result. Measured on command-code 1.40.1 (fixtures under
|
|
384
|
+
* `tests/fixtures/command-code/headless/`):
|
|
385
|
+
*
|
|
386
|
+
* ```text
|
|
387
|
+
* {"type":"event","event":{"type":"run_start","sessionId":"…"}}
|
|
388
|
+
* {"type":"event","event":{"type":"text_delta","delta":"OK"}}
|
|
389
|
+
* {"type":"event","event":{"type":"run_end","result":{"finalText":"OK",…}}}
|
|
390
|
+
* {"type":"result","subtype":"success","sessionId":"…","stopReason":"end_turn",
|
|
391
|
+
* "usage":{…},"durationMs":1957,"finalText":"OK"}
|
|
392
|
+
* ```
|
|
393
|
+
*
|
|
394
|
+
* ## Why the last result line rather than `run_end`
|
|
395
|
+
*
|
|
396
|
+
* `run_end` carries a `result.finalText` too, and on a successful run they
|
|
397
|
+
* agree. But `buildPrintResultLine` in the bundle emits the result line on the
|
|
398
|
+
* failure path as well, where no `run_end` was ever produced: an empty query
|
|
399
|
+
* answers with exactly one line,
|
|
400
|
+
* `{"type":"result","subtype":"error",…,"finalText":"","error":"Error: No query
|
|
401
|
+
* provided. …"}`, and nothing else. Reading `run_end` would see nothing there.
|
|
402
|
+
*
|
|
403
|
+
* ## Why it never throws and never invents a result
|
|
404
|
+
*
|
|
405
|
+
* Null means "this stdout carried no result line", which the caller renders as
|
|
406
|
+
* raw output rather than as an empty answer — the state a run that dies before
|
|
407
|
+
* `runPrintMode` is actually in (`--model <unknown>` exits 1 with **empty
|
|
408
|
+
* stdout** and the message only on stderr). Unparseable lines are skipped for
|
|
409
|
+
* the reason the opencode reader skips them: a stray `console.log` from a mod
|
|
410
|
+
* lands on the same stdout as the stream.
|
|
411
|
+
*
|
|
412
|
+
* @param stdout - Raw stdout from `commandcode -p … --output-format json`
|
|
413
|
+
* @returns The decoded result line, or null when stdout carried none
|
|
414
|
+
*/
|
|
415
|
+
function extractCommandCodeResult(stdout) {
|
|
416
|
+
let found = null;
|
|
417
|
+
for (const line of stdout.split('\n')) {
|
|
418
|
+
const trimmed = line.trim();
|
|
419
|
+
if (!trimmed.startsWith('{'))
|
|
420
|
+
continue;
|
|
421
|
+
let frame;
|
|
422
|
+
try {
|
|
423
|
+
frame = JSON.parse(trimmed);
|
|
424
|
+
}
|
|
425
|
+
catch {
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
if (typeof frame !== 'object' || frame === null)
|
|
429
|
+
continue;
|
|
430
|
+
const record = frame;
|
|
431
|
+
if (record.type !== 'result')
|
|
432
|
+
continue;
|
|
433
|
+
if (typeof record.subtype !== 'string')
|
|
434
|
+
continue;
|
|
435
|
+
found = {
|
|
436
|
+
subtype: record.subtype,
|
|
437
|
+
finalText: typeof record.finalText === 'string' ? record.finalText : '',
|
|
438
|
+
...(typeof record.error === 'string' ? { error: record.error } : {}),
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
return found;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* One line naming why a Command Code run failed, or null when it did not.
|
|
445
|
+
*
|
|
446
|
+
* Both halves are load-bearing, because the CLI can disagree with itself. A run
|
|
447
|
+
* whose answer is blank exits `NO_RESPONSE` (9) while `buildPrintResultLine`
|
|
448
|
+
* still stamps `subtype: "success"` — the subtype is derived from `stopReason`
|
|
449
|
+
* and the exit code from `classifyPrintOutcome`, and only the pair says what
|
|
450
|
+
* happened. So a non-zero exit is a failure whatever the subtype says, and a
|
|
451
|
+
* subtype other than `success` is a failure whatever the exit code says.
|
|
452
|
+
*
|
|
453
|
+
* @param exitCode - Process exit code (null when killed by a signal)
|
|
454
|
+
* @param result - Decoded result line, when stdout carried one
|
|
455
|
+
* @returns A `Reason: …` sentence, or null when the run succeeded
|
|
456
|
+
*/
|
|
457
|
+
function describeCommandCodeFailure(exitCode, result) {
|
|
458
|
+
const failedByCode = exitCode !== null && exitCode !== 0;
|
|
459
|
+
const failedBySubtype = result !== null && result.subtype !== 'success';
|
|
460
|
+
if (!failedByCode && !failedBySubtype)
|
|
461
|
+
return null;
|
|
462
|
+
const parts = [];
|
|
463
|
+
if (exitCode !== null && exitCode !== 0) {
|
|
464
|
+
const reason = exports.COMMAND_CODE_EXIT_REASONS[exitCode];
|
|
465
|
+
parts.push(reason ? `exit ${exitCode} (${reason})` : `exit ${exitCode}`);
|
|
466
|
+
}
|
|
467
|
+
if (result) {
|
|
468
|
+
parts.push(`subtype=${result.subtype}`);
|
|
469
|
+
if (result.error)
|
|
470
|
+
parts.push(result.error);
|
|
471
|
+
}
|
|
472
|
+
return `Reason: command-code ${parts.join(' / ')}`;
|
|
473
|
+
}
|
|
295
474
|
/**
|
|
296
475
|
* Execute a CLI command in a worktree directory.
|
|
297
476
|
*
|
|
@@ -332,23 +511,43 @@ async function executeClaudeCommand(message, cwd, cliToolId = 'claude', permissi
|
|
|
332
511
|
const isMaxBuffer = errCode === 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER';
|
|
333
512
|
// maxBuffer 超過は時間切れではなく「出力過多」なので timeout 扱いにしない。
|
|
334
513
|
const isTimeout = error.killed || errCode === 'ETIMEDOUT';
|
|
514
|
+
// Issue #2253: command-code writes its whole NDJSON stream *and* a
|
|
515
|
+
// final result line before exiting non-zero — a max-turns run ends at
|
|
516
|
+
// exit 8 with a complete `{"type":"result","subtype":"max_turns",…}`
|
|
517
|
+
// line — so the answer and the CLI's own reason are on stdout even
|
|
518
|
+
// here. Decoding them turns a log that said "Error: Command failed"
|
|
519
|
+
// over a 4KB event dump into the reason plus the text.
|
|
520
|
+
const commandCodeResult = cliToolId === 'command-code'
|
|
521
|
+
? extractCommandCodeResult(stdout || '')
|
|
522
|
+
: null;
|
|
523
|
+
const exitCodeNumber = typeof errCode === 'number' ? errCode : null;
|
|
335
524
|
const errorSummary = [
|
|
336
525
|
`Error: ${error.message}`,
|
|
337
526
|
`Code: ${errCode ?? 'unknown'}`,
|
|
338
527
|
`Signal: ${error.signal ?? 'none'}`,
|
|
339
528
|
isMaxBuffer ? 'Reason: stdout exceeded execFile maxBuffer (output_limit)' : null,
|
|
529
|
+
cliToolId === 'command-code'
|
|
530
|
+
? describeCommandCodeFailure(exitCodeNumber, commandCodeResult)
|
|
531
|
+
: null,
|
|
340
532
|
]
|
|
341
533
|
.filter((line) => line !== null)
|
|
342
534
|
.join('\n');
|
|
535
|
+
// `?? stdout` on purpose, matching the success path: a run that died
|
|
536
|
+
// before it could write a result line (an unknown `--model` exits 1
|
|
537
|
+
// with empty stdout and the message on stderr) reports what it did
|
|
538
|
+
// write rather than an empty body.
|
|
539
|
+
const decodedStdout = commandCodeResult
|
|
540
|
+
? commandCodeResult.finalText
|
|
541
|
+
: (stdout || '');
|
|
343
542
|
const rawOutput = (0, cli_patterns_1.stripAnsi)([
|
|
344
543
|
errorSummary,
|
|
345
|
-
|
|
544
|
+
decodedStdout ? `\n--- stdout ---\n${decodedStdout}` : '',
|
|
346
545
|
stderr ? `\n--- stderr ---\n${stderr}` : '',
|
|
347
546
|
].join('\n'));
|
|
348
547
|
const output = truncateOutput(rawOutput);
|
|
349
548
|
resolve({
|
|
350
549
|
output,
|
|
351
|
-
exitCode:
|
|
550
|
+
exitCode: exitCodeNumber,
|
|
352
551
|
status: isTimeout ? 'timeout' : 'failed',
|
|
353
552
|
error: error.message,
|
|
354
553
|
});
|
|
@@ -358,6 +557,26 @@ async function executeClaudeCommand(message, cwd, cliToolId = 'claude', permissi
|
|
|
358
557
|
// stored output is the assistant's answer rather than the event log.
|
|
359
558
|
// `?? stdout` on purpose: an unrecognised stream is reported verbatim,
|
|
360
559
|
// never swallowed.
|
|
560
|
+
//
|
|
561
|
+
// Issue #2253: command-code is the same deal one flag over
|
|
562
|
+
// (`--output-format json`), except that its stream also carries the
|
|
563
|
+
// CLI's own verdict. `classifyPrintOutcome` in the bundle can exit 0
|
|
564
|
+
// only on `subtype: "success"`, so this branch is the success case in
|
|
565
|
+
// practice — but the subtype is read rather than assumed, because
|
|
566
|
+
// "the process exited 0" and "the agent answered" are two facts and
|
|
567
|
+
// this layer is the only one that can still see the second.
|
|
568
|
+
if (cliToolId === 'command-code') {
|
|
569
|
+
const result = extractCommandCodeResult(stdout || '');
|
|
570
|
+
const failure = describeCommandCodeFailure(0, result);
|
|
571
|
+
const body = result ? result.finalText : (stdout || '');
|
|
572
|
+
resolve({
|
|
573
|
+
output: truncateOutput((0, cli_patterns_1.stripAnsi)(failure ? `${failure}\n${body}` : body)),
|
|
574
|
+
exitCode: 0,
|
|
575
|
+
status: failure ? 'failed' : 'completed',
|
|
576
|
+
...(failure ? { error: failure } : {}),
|
|
577
|
+
});
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
361
580
|
const decoded = cliToolId === 'opencode'
|
|
362
581
|
? extractOpencodeFinalText(stdout || '') ?? stdout ?? ''
|
|
363
582
|
: stdout || '';
|