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
package/README.md
CHANGED
|
@@ -50,14 +50,24 @@ If this is the kind of AI development workflow you want, [give the repo a star](
|
|
|
50
50
|
| **Skills Catalog** | Install and update official Skills per worktree, from the web UI or `commandmate skill` | The method is installed for the agent to read, not kept in someone's head |
|
|
51
51
|
| **Never miss a waiting agent** | A waiting agent shows up as a badge, a toast, the tab title, the PWA app badge and a push notification | You find out the moment an agent needs you, even away from the desk |
|
|
52
52
|
| **Git Worktree Sessions** | One session per worktree, parallel execution | Multiple issues progress simultaneously without interference |
|
|
53
|
-
| **Multi-Agent Support** | Choose Claude Code, Codex, Gemini CLI, Copilot, OpenCode, Antigravity or local models per worktree | Pick the right agent for each task |
|
|
53
|
+
| **Multi-Agent Support** | Choose Claude Code, Codex, Gemini CLI, Copilot, OpenCode, Antigravity, Command Code or local models per worktree | Pick the right agent for each task |
|
|
54
54
|
| **Auto Yes Mode** | Agent runs without stopping for confirmations | Optional unattended mode for trusted workflows — review the Security section before enabling |
|
|
55
55
|
| **Web UI (Desktop & Mobile)** | Full session control from any browser | Monitor and steer from your desk or your phone |
|
|
56
|
+
| **Conversation view** | Switch a session's output between the raw terminal and a chat transcript — replies render in full, tool runs and approvals fold into chips, and a TUI dialog is answerable from the chat surface | Follow the run and answer it — from your desk or your phone — without reading the TUI |
|
|
56
57
|
| **File Viewer & Markdown Editor** | Browse and edit worktree files in the browser | Review changes and update AI instructions without opening an IDE |
|
|
57
58
|
| **Screenshot Instructions** | Attach images to your prompts | Snap a bug → "Fix this" — the agent sees the screenshot |
|
|
58
59
|
| **Scheduled Execution** | Cron-based auto-run via CMATE.md | Daily reviews, nightly tests — agents work on a schedule |
|
|
59
60
|
| **Token Authentication** | SHA-256 hashed token + HTTPS + rate limiting | Secure remote access — no credentials leaked, brute-force protected |
|
|
60
61
|
|
|
62
|
+
### Supported agents
|
|
63
|
+
|
|
64
|
+
All eight are first-class. Each one gets the same treatment inside CommandMate — its own launch path, its own hook source and its own status detection — so the worktree session, the task contract, the verification gates and the evidence trail behave the same way whichever agent you pick.
|
|
65
|
+
|
|
66
|
+
- **Claude Code**, **Codex**, **Gemini CLI**, **Copilot**, **Antigravity** — choose per worktree, per task.
|
|
67
|
+
- **OpenCode** — the open-source terminal agent, driven through the same contract-and-gate path as the rest.
|
|
68
|
+
- **Command Code** — driven the same way, its hooks and its transcript included.
|
|
69
|
+
- **Local models** (`vibe-local`) — run the same loop against a model you host yourself.
|
|
70
|
+
|
|
61
71
|
---
|
|
62
72
|
|
|
63
73
|
## Use Cases
|
|
@@ -341,20 +351,36 @@ commandmate start -p 3001
|
|
|
341
351
|
|
|
342
352
|
### Session stuck or not responding?
|
|
343
353
|
|
|
344
|
-
|
|
354
|
+
Look at the session with CommandMate's own commands — they resolve the tmux session name for you:
|
|
345
355
|
|
|
346
356
|
```bash
|
|
347
|
-
#
|
|
348
|
-
|
|
357
|
+
# What every worktree's agent is doing, and the tmux session it runs in
|
|
358
|
+
commandmate ls
|
|
359
|
+
commandmate ls --json | jq -r '.[] | "\(.id)\t\(.tmuxSession)"'
|
|
360
|
+
|
|
361
|
+
# Read the transcript WITHOUT attaching
|
|
362
|
+
commandmate capture <worktree-id> --pane --tail 60
|
|
363
|
+
commandmate capture <worktree-id> --pane --follow # follow a reply as it is generated
|
|
349
364
|
|
|
350
|
-
#
|
|
351
|
-
|
|
365
|
+
# Attach this terminal (detach with Ctrl+b then d)
|
|
366
|
+
commandmate attach <worktree-id>
|
|
367
|
+
commandmate attach <worktree-id> --live # re-lay out to your terminal (claude only)
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
**Why a bare `tmux attach` looks empty.** A CommandMate session is pinned to a 200x1000 canvas so
|
|
371
|
+
`capture-pane` keeps enough history for status detection. Alternate-screen agents (claude / opencode /
|
|
372
|
+
copilot) draw their transcript at the top of that canvas and their composer at the bottom, and tmux
|
|
373
|
+
follows the cursor — so a normal-sized terminal sees the composer, blank rows, and not one line of the
|
|
374
|
+
conversation. Nothing is broken. Read it with `capture --pane` above, with `prefix + g` while
|
|
375
|
+
attached, or hand the window to your terminal with `attach --live`.
|
|
352
376
|
|
|
353
|
-
|
|
354
|
-
|
|
377
|
+
From tmux itself, without attaching at all:
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
tmux ls -F '#{session_name} #{@cm_status} #{@cm_tool}/#{@cm_instance}'
|
|
355
381
|
|
|
356
|
-
# Kill a broken session
|
|
357
|
-
tmux kill-session -t
|
|
382
|
+
# Kill a broken session (`=name:` is an exact match; quote it — zsh eats a bare `=`)
|
|
383
|
+
tmux kill-session -t '=mcbd-claude-feature-123:'
|
|
358
384
|
```
|
|
359
385
|
|
|
360
386
|
> **Note:** When attached, avoid typing directly into the session — this can interfere with CommandMate's session management. Use `Ctrl+b` then `d` to detach and operate through the CommandMate UI instead.
|
|
@@ -446,7 +472,7 @@ The comparison that matters is not against other products; it is against the way
|
|
|
446
472
|
| Evidence | A chat transcript | Commits, gate logs, `verify history`, `report metrics` |
|
|
447
473
|
| Parallel work | Terminal tabs | One worktree and one contract per task |
|
|
448
474
|
| When it stops | You notice, eventually | Waiting is surfaced: badge, toast, tab title, push |
|
|
449
|
-
| Which agent | Locked to one | Claude Code, Codex, Gemini CLI, Copilot, OpenCode, Antigravity, local models |
|
|
475
|
+
| Which agent | Locked to one | Claude Code, Codex, Gemini CLI, Copilot, OpenCode, Antigravity, Command Code, local models |
|
|
450
476
|
|
|
451
477
|
</details>
|
|
452
478
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attach Command - open a worktree's tmux session in this terminal (Issue #2317, Phase A/D)
|
|
3
|
+
*
|
|
4
|
+
* commandmate attach <worktree-id> [--instance <id>] [--read-only] [--live]
|
|
5
|
+
*
|
|
6
|
+
* ## Why this exists when `tmux attach` already does
|
|
7
|
+
*
|
|
8
|
+
* Three reasons, and each one is a thing an operator got wrong before it:
|
|
9
|
+
*
|
|
10
|
+
* 1. **The session name.** It is `mcbd-<tool>-<worktree>[-<suffix>]`, and the
|
|
11
|
+
* suffix depends on the agent-instance roster. `commandmate ls` did not print
|
|
12
|
+
* it, so the name had to be assembled by hand from three facts spread across
|
|
13
|
+
* two commands.
|
|
14
|
+
* 2. **The `=` trap.** The exact-match target form is `'=<name>:'` (Issue #1156),
|
|
15
|
+
* and in zsh an unquoted `=name` is an equals expansion — `tmux attach -t
|
|
16
|
+
* =mcbd-…:` fails with `not found` before tmux ever runs. Measured; it is in
|
|
17
|
+
* the Issue. This command quotes it so nobody has to know.
|
|
18
|
+
* 3. **What you will see.** For an alternate-screen agent a bare attach shows
|
|
19
|
+
* the composer and nothing else — the transcript is at the top of a 1000-row
|
|
20
|
+
* canvas and tmux follows the cursor at row 997. That is not a fault to
|
|
21
|
+
* debug, it is the geometry, and the hint printed before attaching says so
|
|
22
|
+
* and names the three ways to read anyway.
|
|
23
|
+
*
|
|
24
|
+
* ## `--live` is claude-only, and that is a measurement
|
|
25
|
+
*
|
|
26
|
+
* See `LIVE_ATTACH_TOOLS` in `lib/tmux/session-surface.ts`. Every other tool
|
|
27
|
+
* either reads its reply off the pane, or has detection rules measured only at
|
|
28
|
+
* 200x1000, or cannot survive a width change at all.
|
|
29
|
+
*/
|
|
30
|
+
import { Command } from 'commander';
|
|
31
|
+
/**
|
|
32
|
+
* The lines printed to stderr before the terminal is handed to tmux.
|
|
33
|
+
*
|
|
34
|
+
* stderr, not stdout: the session takes the screen over immediately afterwards,
|
|
35
|
+
* and a caller piping this command's stdout is not asking for advice.
|
|
36
|
+
*
|
|
37
|
+
* Exported so the test asserts the text a user actually sees rather than a
|
|
38
|
+
* paraphrase of it.
|
|
39
|
+
*
|
|
40
|
+
* @param cliToolId - Resolved CLI tool
|
|
41
|
+
* @param worktreeId - Worktree id, so the hint's commands are copy-pasteable
|
|
42
|
+
* @param sessionName - Resolved tmux session name
|
|
43
|
+
* @param options - The flags as given
|
|
44
|
+
*/
|
|
45
|
+
export declare function buildAttachHints(cliToolId: string, worktreeId: string, sessionName: string, options: {
|
|
46
|
+
readOnly?: boolean;
|
|
47
|
+
live?: boolean;
|
|
48
|
+
}): string[];
|
|
49
|
+
export declare function createAttachCommand(): Command;
|
|
50
|
+
//# sourceMappingURL=attach.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/attach.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuDpC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9C,MAAM,EAAE,CAmCV;AAiDD,wBAAgB,mBAAmB,IAAI,OAAO,CAmE7C"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* attach Command - open a worktree's tmux session in this terminal (Issue #2317, Phase A/D)
|
|
4
|
+
*
|
|
5
|
+
* commandmate attach <worktree-id> [--instance <id>] [--read-only] [--live]
|
|
6
|
+
*
|
|
7
|
+
* ## Why this exists when `tmux attach` already does
|
|
8
|
+
*
|
|
9
|
+
* Three reasons, and each one is a thing an operator got wrong before it:
|
|
10
|
+
*
|
|
11
|
+
* 1. **The session name.** It is `mcbd-<tool>-<worktree>[-<suffix>]`, and the
|
|
12
|
+
* suffix depends on the agent-instance roster. `commandmate ls` did not print
|
|
13
|
+
* it, so the name had to be assembled by hand from three facts spread across
|
|
14
|
+
* two commands.
|
|
15
|
+
* 2. **The `=` trap.** The exact-match target form is `'=<name>:'` (Issue #1156),
|
|
16
|
+
* and in zsh an unquoted `=name` is an equals expansion — `tmux attach -t
|
|
17
|
+
* =mcbd-…:` fails with `not found` before tmux ever runs. Measured; it is in
|
|
18
|
+
* the Issue. This command quotes it so nobody has to know.
|
|
19
|
+
* 3. **What you will see.** For an alternate-screen agent a bare attach shows
|
|
20
|
+
* the composer and nothing else — the transcript is at the top of a 1000-row
|
|
21
|
+
* canvas and tmux follows the cursor at row 997. That is not a fault to
|
|
22
|
+
* debug, it is the geometry, and the hint printed before attaching says so
|
|
23
|
+
* and names the three ways to read anyway.
|
|
24
|
+
*
|
|
25
|
+
* ## `--live` is claude-only, and that is a measurement
|
|
26
|
+
*
|
|
27
|
+
* See `LIVE_ATTACH_TOOLS` in `lib/tmux/session-surface.ts`. Every other tool
|
|
28
|
+
* either reads its reply off the pane, or has detection rules measured only at
|
|
29
|
+
* 200x1000, or cannot survive a width change at all.
|
|
30
|
+
*/
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.buildAttachHints = buildAttachHints;
|
|
33
|
+
exports.createAttachCommand = createAttachCommand;
|
|
34
|
+
const child_process_1 = require("child_process");
|
|
35
|
+
const commander_1 = require("commander");
|
|
36
|
+
const types_1 = require("../types");
|
|
37
|
+
const api_client_1 = require("../utils/api-client");
|
|
38
|
+
const command_helpers_1 = require("../utils/command-helpers");
|
|
39
|
+
const cli_tool_ids_1 = require("../config/cli-tool-ids");
|
|
40
|
+
const agent_target_options_1 = require("../config/agent-target-options");
|
|
41
|
+
const session_target_1 = require("../utils/session-target");
|
|
42
|
+
const session_name_1 = require("../../lib/cli-tools/session-name");
|
|
43
|
+
const tmux_session_surface_1 = require("../../lib/session/tmux-session-surface");
|
|
44
|
+
/** Run one tmux command, inheriting nothing. Returns true on exit 0. */
|
|
45
|
+
function runTmux(args) {
|
|
46
|
+
const result = (0, child_process_1.spawnSync)('tmux', args, { stdio: ['ignore', 'ignore', 'ignore'] });
|
|
47
|
+
return result.status === 0;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolve which (tool, instance) pair the worktree id addresses.
|
|
51
|
+
*
|
|
52
|
+
* Through the server's resolver, exactly as `send` / `capture` / `wait` do
|
|
53
|
+
* (Issue #1925): the tool id is half the tmux session name, so a locally-guessed
|
|
54
|
+
* one is a different session. A `--agent` the roster contradicts is a hard error
|
|
55
|
+
* here rather than a warning — attaching is a thing you do WITH a session, and
|
|
56
|
+
* doing it to the wrong one wastes the reader's time in a way a wrong `capture`
|
|
57
|
+
* does not.
|
|
58
|
+
*/
|
|
59
|
+
async function resolveTarget(client, worktreeId, options) {
|
|
60
|
+
const target = await (0, session_target_1.resolveSessionTarget)(client, worktreeId, {
|
|
61
|
+
instanceId: options.instance,
|
|
62
|
+
requestedCliTool: options.agent,
|
|
63
|
+
});
|
|
64
|
+
if (target.conflict) {
|
|
65
|
+
console.error(`Error: ${(0, session_target_1.describeSessionTargetConflict)(target.conflict)}`);
|
|
66
|
+
process.exit(types_1.ExitCode.CONFIG_ERROR);
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
cliToolId: target.cliToolId ?? options.agent ?? cli_tool_ids_1.DEFAULT_CLI_TOOL_ID,
|
|
70
|
+
instanceId: target.instanceId ?? options.instance,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The lines printed to stderr before the terminal is handed to tmux.
|
|
75
|
+
*
|
|
76
|
+
* stderr, not stdout: the session takes the screen over immediately afterwards,
|
|
77
|
+
* and a caller piping this command's stdout is not asking for advice.
|
|
78
|
+
*
|
|
79
|
+
* Exported so the test asserts the text a user actually sees rather than a
|
|
80
|
+
* paraphrase of it.
|
|
81
|
+
*
|
|
82
|
+
* @param cliToolId - Resolved CLI tool
|
|
83
|
+
* @param worktreeId - Worktree id, so the hint's commands are copy-pasteable
|
|
84
|
+
* @param sessionName - Resolved tmux session name
|
|
85
|
+
* @param options - The flags as given
|
|
86
|
+
*/
|
|
87
|
+
function buildAttachHints(cliToolId, worktreeId, sessionName, options) {
|
|
88
|
+
const hints = [`Attaching to ${sessionName} (${cliToolId}). Detach with Ctrl+b then d.`];
|
|
89
|
+
if ((0, tmux_session_surface_1.usesAltScreen)(cliToolId) && !options.live) {
|
|
90
|
+
hints.push(`${cliToolId} draws its transcript at the top of a 200x1000 canvas and its composer at the`, 'bottom, and tmux follows the cursor — so this attach shows the composer and blank rows,', 'not the conversation. To read it:', ` prefix + g popup, in this terminal`, ` commandmate capture ${worktreeId} --pane --tail 60 without attaching`, ` commandmate capture ${worktreeId} --pane --follow live, without attaching`);
|
|
91
|
+
if ((0, tmux_session_surface_1.isLiveAttachSupported)(cliToolId)) {
|
|
92
|
+
hints.push(` commandmate attach ${worktreeId} --live re-lay-out to this terminal`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (options.readOnly) {
|
|
96
|
+
hints.push('Read-only attach: tmux delivers no keys but the detach one, so prefix + g does NOT open', 'the popup here. Read with `commandmate capture <id> --pane --follow` in another terminal.');
|
|
97
|
+
}
|
|
98
|
+
if (options.live) {
|
|
99
|
+
hints.push('Live attach: this session follows THIS terminal until you detach, then goes back to', '200x1000. The web terminal shows the smaller frame while you are attached.');
|
|
100
|
+
}
|
|
101
|
+
hints.push(`Status without attaching: tmux ls -F '#{session_name} #{@cm_status}'`);
|
|
102
|
+
return hints;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Hand the geometry over, attach, and hand it back (Phase D).
|
|
106
|
+
*
|
|
107
|
+
* The restore runs in a `finally`, so a tmux that exits non-zero — or a
|
|
108
|
+
* `attach-session` interrupted by a signal — still gives the canvas back. The
|
|
109
|
+
* server's poll (`reconcileDelegatedGeometry`) is the second net for the case
|
|
110
|
+
* this process does not survive to run it.
|
|
111
|
+
*/
|
|
112
|
+
function attachLive(sessionName, readOnly) {
|
|
113
|
+
for (const args of (0, tmux_session_surface_1.buildDelegateGeometryCommands)(sessionName)) {
|
|
114
|
+
runTmux(args);
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const result = (0, child_process_1.spawnSync)('tmux', (0, tmux_session_surface_1.buildAttachArgs)(sessionName, readOnly), {
|
|
118
|
+
stdio: 'inherit',
|
|
119
|
+
});
|
|
120
|
+
return result.status ?? types_1.ExitCode.UNEXPECTED_ERROR;
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
for (const args of (0, tmux_session_surface_1.buildRestoreGeometryCommands)(sessionName)) {
|
|
124
|
+
runTmux(args);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Attach, or switch this tmux client, to `sessionName`.
|
|
130
|
+
*
|
|
131
|
+
* `switch-client` rather than an error when `$TMUX` is set: attaching a session
|
|
132
|
+
* inside another session is what tmux refuses, and switching is what the user
|
|
133
|
+
* meant. When the switch fails — the ambient `$TMUX` is a DIFFERENT tmux server,
|
|
134
|
+
* which is the case CommandMate's own agents run under — the manual command is
|
|
135
|
+
* printed, quoted, rather than a bare "nested sessions" complaint.
|
|
136
|
+
*/
|
|
137
|
+
function attachOrSwitch(sessionName, readOnly) {
|
|
138
|
+
if (process.env.TMUX) {
|
|
139
|
+
if (runTmux((0, tmux_session_surface_1.buildSwitchClientArgs)(sessionName)))
|
|
140
|
+
return types_1.ExitCode.SUCCESS;
|
|
141
|
+
console.error('Error: already inside tmux, and this client could not switch to that session '
|
|
142
|
+
+ '(a different tmux server?). From a terminal outside tmux, run:\n'
|
|
143
|
+
+ ` tmux attach -t '${(0, tmux_session_surface_1.exactSessionTarget)(sessionName)}'`);
|
|
144
|
+
return types_1.ExitCode.UNEXPECTED_ERROR;
|
|
145
|
+
}
|
|
146
|
+
const result = (0, child_process_1.spawnSync)('tmux', (0, tmux_session_surface_1.buildAttachArgs)(sessionName, readOnly), { stdio: 'inherit' });
|
|
147
|
+
return result.status ?? types_1.ExitCode.UNEXPECTED_ERROR;
|
|
148
|
+
}
|
|
149
|
+
function createAttachCommand() {
|
|
150
|
+
const cmd = new commander_1.Command('attach');
|
|
151
|
+
cmd
|
|
152
|
+
.description("Attach this terminal to a worktree's agent tmux session")
|
|
153
|
+
.argument('<worktree-id>', 'Worktree ID')
|
|
154
|
+
.option('--instance <id>', agent_target_options_1.INSTANCE_OPTION_DESCRIPTION)
|
|
155
|
+
.option('--agent <agent>', agent_target_options_1.AGENT_OPTION_DESCRIPTION)
|
|
156
|
+
.option('-r, --read-only', 'Attach without sending any input to the session')
|
|
157
|
+
.option('--live', 'Re-lay the session out to this terminal while attached, restoring 200x1000 on detach (claude only)')
|
|
158
|
+
.option('--token <token>', command_helpers_1.TOKEN_WARNING)
|
|
159
|
+
.action(async (worktreeId, options) => {
|
|
160
|
+
try {
|
|
161
|
+
if (!(0, api_client_1.isValidWorktreeId)(worktreeId)) {
|
|
162
|
+
console.error('Error: Invalid worktree ID format.');
|
|
163
|
+
process.exit(types_1.ExitCode.CONFIG_ERROR);
|
|
164
|
+
}
|
|
165
|
+
if (options.agent && !(0, cli_tool_ids_1.isCliToolId)(options.agent)) {
|
|
166
|
+
console.error('Error: Invalid agent.');
|
|
167
|
+
process.exit(types_1.ExitCode.CONFIG_ERROR);
|
|
168
|
+
}
|
|
169
|
+
if (options.instance && !(0, api_client_1.isValidInstanceId)(options.instance)) {
|
|
170
|
+
console.error('Error: Invalid --instance. Must be an alphanumeric/underscore/hyphen identifier (max 64 chars).');
|
|
171
|
+
process.exit(types_1.ExitCode.CONFIG_ERROR);
|
|
172
|
+
}
|
|
173
|
+
const client = new api_client_1.ApiClient({ token: options.token });
|
|
174
|
+
const { cliToolId, instanceId } = await resolveTarget(client, worktreeId, options);
|
|
175
|
+
if (options.live && !(0, tmux_session_surface_1.isLiveAttachSupported)(cliToolId)) {
|
|
176
|
+
console.error(`Error: --live is not supported for ${cliToolId}. It is claude-only until each other `
|
|
177
|
+
+ "agent's detection rules are re-measured at a terminal-sized pane (Issue #2317). "
|
|
178
|
+
+ `Attach without it, or read with: commandmate capture ${worktreeId} --pane --follow`);
|
|
179
|
+
process.exit(types_1.ExitCode.CONFIG_ERROR);
|
|
180
|
+
}
|
|
181
|
+
const sessionName = (0, session_name_1.resolveSessionName)(cliToolId, worktreeId, instanceId);
|
|
182
|
+
if (!runTmux(['has-session', '-t', (0, tmux_session_surface_1.exactSessionTarget)(sessionName)])) {
|
|
183
|
+
console.error(`Error: no tmux session named ${sessionName}.\n`
|
|
184
|
+
+ ` commandmate ls which worktrees have a running session\n`
|
|
185
|
+
+ ` commandmate instances ${worktreeId} which agents this worktree runs`);
|
|
186
|
+
process.exit(types_1.ExitCode.UNEXPECTED_ERROR);
|
|
187
|
+
}
|
|
188
|
+
for (const line of buildAttachHints(cliToolId, worktreeId, sessionName, {
|
|
189
|
+
readOnly: options.readOnly,
|
|
190
|
+
live: options.live,
|
|
191
|
+
})) {
|
|
192
|
+
console.error(line);
|
|
193
|
+
}
|
|
194
|
+
const status = options.live
|
|
195
|
+
? attachLive(sessionName, Boolean(options.readOnly))
|
|
196
|
+
: attachOrSwitch(sessionName, Boolean(options.readOnly));
|
|
197
|
+
process.exit(status);
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
(0, command_helpers_1.handleCommandError)(error);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
return cmd;
|
|
204
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/capture.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/capture.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwYpC,wBAAgB,oBAAoB,IAAI,OAAO,CA4H9C"}
|
|
@@ -28,6 +28,17 @@ const transcript_squeeze_1 = require("../../lib/tmux/transcript-squeeze");
|
|
|
28
28
|
* RESULT instead (see {@link CaptureOptions.tail}).
|
|
29
29
|
*/
|
|
30
30
|
const PANE_CAPTURE_LINES = 1000;
|
|
31
|
+
/**
|
|
32
|
+
* Default redraw interval of `--pane --follow`, in milliseconds (Issue #2317).
|
|
33
|
+
*
|
|
34
|
+
* Two seconds, matching the response poller's own cadence: a faster redraw
|
|
35
|
+
* cannot show anything the server has not captured yet, and would only add tmux
|
|
36
|
+
* round-trips to a session someone is already watching.
|
|
37
|
+
*/
|
|
38
|
+
const DEFAULT_FOLLOW_INTERVAL_MS = 2000;
|
|
39
|
+
/** Floor and ceiling for `--interval`. */
|
|
40
|
+
const MIN_FOLLOW_INTERVAL_MS = 250;
|
|
41
|
+
const MAX_FOLLOW_INTERVAL_MS = 60_000;
|
|
31
42
|
/**
|
|
32
43
|
* `promptData.type` the server writes for a frame the detection layer could not
|
|
33
44
|
* classify (Issue #1708). Mirrors UNCLASSIFIED_PROMPT_TYPE in
|
|
@@ -247,6 +258,85 @@ async function capturePane(worktreeId, options) {
|
|
|
247
258
|
}
|
|
248
259
|
(0, pager_1.printMaybePaged)(text);
|
|
249
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Parse and validate `--interval <ms>`.
|
|
263
|
+
*
|
|
264
|
+
* @param raw - Raw option value, if the user passed one
|
|
265
|
+
* @returns The interval in milliseconds
|
|
266
|
+
*/
|
|
267
|
+
function parseFollowInterval(raw) {
|
|
268
|
+
if (raw === undefined)
|
|
269
|
+
return DEFAULT_FOLLOW_INTERVAL_MS;
|
|
270
|
+
const value = Number(raw);
|
|
271
|
+
if (!Number.isInteger(value) ||
|
|
272
|
+
value < MIN_FOLLOW_INTERVAL_MS ||
|
|
273
|
+
value > MAX_FOLLOW_INTERVAL_MS) {
|
|
274
|
+
console.error(`Error: --interval must be an integer between ${MIN_FOLLOW_INTERVAL_MS} and ${MAX_FOLLOW_INTERVAL_MS} (milliseconds).`);
|
|
275
|
+
process.exit(types_1.ExitCode.CONFIG_ERROR);
|
|
276
|
+
}
|
|
277
|
+
return value;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* `--pane --follow`: redraw the squeezed transcript on an interval (Issue #2317).
|
|
281
|
+
*
|
|
282
|
+
* ## Why this exists next to `prefix + g`
|
|
283
|
+
*
|
|
284
|
+
* The popup #1623 added is a SNAPSHOT and needs a key press to refresh, and it
|
|
285
|
+
* does not work at all under `tmux attach -r` (a read-only client is delivered
|
|
286
|
+
* no keys but the detach one). This is the reading path that needs neither a
|
|
287
|
+
* tmux client nor a key table: it works from any terminal, over ssh, and while
|
|
288
|
+
* somebody else is attached.
|
|
289
|
+
*
|
|
290
|
+
* ## What it does NOT do
|
|
291
|
+
*
|
|
292
|
+
* It never writes. Every iteration makes exactly the request `--pane` already
|
|
293
|
+
* makes — same route, same {@link PANE_CAPTURE_LINES} — so the detection
|
|
294
|
+
* pipeline sees no different payload because a human is watching, and the
|
|
295
|
+
* session's geometry is untouched (Issue #2317 受入条件 Phase C 2).
|
|
296
|
+
*
|
|
297
|
+
* Ctrl-C is the exit, and it needs no handler: SIGINT's default action ends the
|
|
298
|
+
* process, and the alternate screen is left with the cursor restored by the
|
|
299
|
+
* `finally` below.
|
|
300
|
+
*/
|
|
301
|
+
async function capturePaneFollow(worktreeId, options) {
|
|
302
|
+
if (!process.stdout.isTTY) {
|
|
303
|
+
console.error('Error: --follow needs a terminal (it redraws the screen). '
|
|
304
|
+
+ 'Without one, loop over `commandmate capture <id> --pane --tail N` instead.');
|
|
305
|
+
process.exit(types_1.ExitCode.CONFIG_ERROR);
|
|
306
|
+
}
|
|
307
|
+
const client = new api_client_1.ApiClient({ token: options.token });
|
|
308
|
+
const tail = parseTail(options.tail);
|
|
309
|
+
const intervalMs = parseFollowInterval(options.interval);
|
|
310
|
+
const cliToolId = await resolvePaneCliTool(client, worktreeId, options.agent, options.instance);
|
|
311
|
+
// Hide the cursor while redrawing, and put it back whatever ends the loop.
|
|
312
|
+
process.stdout.write('\u001b[?25l');
|
|
313
|
+
const restoreCursor = () => {
|
|
314
|
+
process.stdout.write('\u001b[?25h');
|
|
315
|
+
};
|
|
316
|
+
process.on('exit', restoreCursor);
|
|
317
|
+
try {
|
|
318
|
+
for (;;) {
|
|
319
|
+
const data = await client.post(`/api/worktrees/${worktreeId}/capture`, {
|
|
320
|
+
cliToolId,
|
|
321
|
+
lines: PANE_CAPTURE_LINES,
|
|
322
|
+
...(options.instance ? { instanceId: options.instance } : {}),
|
|
323
|
+
});
|
|
324
|
+
const squeezed = (0, transcript_squeeze_1.squeezeTranscript)(data.output ?? '', { tail });
|
|
325
|
+
// The visible rows, minus one for the footer. Slicing HERE rather than
|
|
326
|
+
// asking the server for fewer lines is the same choice `--tail` makes: the
|
|
327
|
+
// squeeze has to run over the whole frame or the blank padding is what
|
|
328
|
+
// gets kept.
|
|
329
|
+
const rows = Math.max(1, (process.stdout.rows || 40) - 1);
|
|
330
|
+
const body = squeezed.text.split('\n').slice(-rows).join('\n');
|
|
331
|
+
process.stdout.write(`\u001b[H\u001b[2J${body}\n`);
|
|
332
|
+
process.stdout.write(`\u001b[7m[CommandMate] ${worktreeId} / ${cliToolId} — Ctrl-C to stop\u001b[0m`);
|
|
333
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
finally {
|
|
337
|
+
restoreCursor();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
250
340
|
function createCaptureCommand() {
|
|
251
341
|
const cmd = new commander_1.Command('capture');
|
|
252
342
|
cmd
|
|
@@ -258,6 +348,9 @@ function createCaptureCommand() {
|
|
|
258
348
|
.option('--pane', 'Read the raw tmux pane as a transcript, with blank layout rows squeezed')
|
|
259
349
|
.option('--tail <n>', 'With --pane: keep only the last N lines OF THE SQUEEZED transcript')
|
|
260
350
|
.option('--raw', 'With --pane: skip the squeeze and print the pane verbatim')
|
|
351
|
+
// Issue #2317: the reading path that needs no tmux client and no key table.
|
|
352
|
+
.option('--follow', 'With --pane: redraw on an interval instead of printing once (Ctrl-C to stop)')
|
|
353
|
+
.option('--interval <ms>', `With --pane --follow: redraw interval in milliseconds (default ${DEFAULT_FOLLOW_INTERVAL_MS})`)
|
|
261
354
|
// Issue #1685: audit trail of resolved prompts (question/options/answer/answeredBy)
|
|
262
355
|
.option('--prompts', 'List recent prompts from chat history (including ones Auto-Yes already resolved)')
|
|
263
356
|
.option('--limit <n>', `With --prompts: number of most recent prompts to list (default ${DEFAULT_PROMPTS_LIMIT})`)
|
|
@@ -286,6 +379,23 @@ function createCaptureCommand() {
|
|
|
286
379
|
console.error('Error: --tail and --raw require --pane.');
|
|
287
380
|
process.exit(types_1.ExitCode.CONFIG_ERROR);
|
|
288
381
|
}
|
|
382
|
+
// Issue #2317: same rule as --tail/--raw. A --follow that silently did
|
|
383
|
+
// nothing outside --pane would look like the flag was accepted.
|
|
384
|
+
if (!options.pane && (options.follow || options.interval !== undefined)) {
|
|
385
|
+
console.error('Error: --follow and --interval require --pane.');
|
|
386
|
+
process.exit(types_1.ExitCode.CONFIG_ERROR);
|
|
387
|
+
}
|
|
388
|
+
if (options.interval !== undefined && !options.follow) {
|
|
389
|
+
console.error('Error: --interval requires --follow.');
|
|
390
|
+
process.exit(types_1.ExitCode.CONFIG_ERROR);
|
|
391
|
+
}
|
|
392
|
+
// The follow loop redraws the screen; --json and --raw are both "give me
|
|
393
|
+
// the bytes", and neither has a meaning that survives being overwritten
|
|
394
|
+
// every two seconds.
|
|
395
|
+
if (options.follow && (options.json || options.raw)) {
|
|
396
|
+
console.error('Error: --follow cannot be combined with --json or --raw.');
|
|
397
|
+
process.exit(types_1.ExitCode.CONFIG_ERROR);
|
|
398
|
+
}
|
|
289
399
|
// Issue #1685: --prompts reads history, --pane reads the live pane —
|
|
290
400
|
// asking for both at once has no meaningful answer.
|
|
291
401
|
if (options.prompts && options.pane) {
|
|
@@ -301,6 +411,10 @@ function createCaptureCommand() {
|
|
|
301
411
|
return;
|
|
302
412
|
}
|
|
303
413
|
if (options.pane) {
|
|
414
|
+
if (options.follow) {
|
|
415
|
+
await capturePaneFollow(worktreeId, options);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
304
418
|
await capturePane(worktreeId, options);
|
|
305
419
|
return;
|
|
306
420
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/instances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAE,SAAS,EAAwC,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/instances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAE,SAAS,EAAwC,MAAM,qBAAqB,CAAC;AA8HtF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,IAAI,GAAE,oBAA+B,GACpC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAiB7B;AA2ND,wBAAgB,sBAAsB,IAAI,OAAO,CAqEhD"}
|
|
@@ -19,6 +19,23 @@ const command_helpers_1 = require("../utils/command-helpers");
|
|
|
19
19
|
const cli_tool_ids_1 = require("../config/cli-tool-ids");
|
|
20
20
|
const agent_instances_1 = require("../utils/agent-instances");
|
|
21
21
|
const session_target_1 = require("../utils/session-target");
|
|
22
|
+
// Issue #2317: the tmux session name each instance runs in, so `commandmate
|
|
23
|
+
// attach` / `tmux attach` need no hand-assembly of `mcbd-<tool>-<wt>[-<suffix>]`.
|
|
24
|
+
const session_name_1 = require("../../lib/cli-tools/session-name");
|
|
25
|
+
/**
|
|
26
|
+
* The tmux session name for one roster row, or null.
|
|
27
|
+
*
|
|
28
|
+
* @param worktreeId - Worktree ID
|
|
29
|
+
* @param inst - Roster entry
|
|
30
|
+
*/
|
|
31
|
+
function deriveInstanceSession(worktreeId, inst) {
|
|
32
|
+
try {
|
|
33
|
+
return (0, session_name_1.resolveSessionName)(inst.cliTool, worktreeId, inst.id);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
22
39
|
/**
|
|
23
40
|
* Longest session title printed in the table (Issue #2038).
|
|
24
41
|
*
|
|
@@ -39,8 +56,8 @@ function formatInstancesTable(rows) {
|
|
|
39
56
|
const headers = [
|
|
40
57
|
'INSTANCE_ID', 'ALIAS', 'CLI_TOOL', 'RUNNING', 'AUTO_YES', 'MODEL', 'EFFORT',
|
|
41
58
|
// Issue #2038 appends, exactly as #1785 did, so anything reading this table
|
|
42
|
-
// by column position keeps working.
|
|
43
|
-
'SESSION_ID', 'SESSION_TITLE',
|
|
59
|
+
// by column position keeps working. Issue #2317 appends for the same reason.
|
|
60
|
+
'SESSION_ID', 'SESSION_TITLE', 'TMUX_SESSION',
|
|
44
61
|
];
|
|
45
62
|
const dataRows = rows.map(r => [
|
|
46
63
|
r.instanceId,
|
|
@@ -55,6 +72,7 @@ function formatInstancesTable(rows) {
|
|
|
55
72
|
r.reasoningEffort ?? '',
|
|
56
73
|
r.sessionId ?? '',
|
|
57
74
|
(r.sessionTitle ?? '').slice(0, MAX_SESSION_TITLE_COLUMN),
|
|
75
|
+
r.tmuxSession ?? '',
|
|
58
76
|
]);
|
|
59
77
|
const colWidths = headers.map((h, i) => Math.max(h.length, ...dataRows.map(r => r[i].length)));
|
|
60
78
|
const headerLine = headers.map((h, i) => h.padEnd(colWidths[i])).join(' ');
|
|
@@ -158,6 +176,9 @@ async function listInstances(worktreeId, options) {
|
|
|
158
176
|
// Issue #2038: additive, and absent for every tool that is not opencode.
|
|
159
177
|
sessionId: opencodeSessions.get(inst.id)?.sessionId ?? null,
|
|
160
178
|
sessionTitle: opencodeSessions.get(inst.id)?.title ?? null,
|
|
179
|
+
// Issue #2317: additive, and in both the table and `--json` — the table
|
|
180
|
+
// is where somebody who does not know the naming rule will see it.
|
|
181
|
+
tmuxSession: deriveInstanceSession(worktreeId, inst),
|
|
161
182
|
};
|
|
162
183
|
}));
|
|
163
184
|
if (options.json) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/ls.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/ls.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6LpC;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CA8CzC"}
|
package/dist/cli/commands/ls.js
CHANGED
|
@@ -11,6 +11,10 @@ const api_client_1 = require("../utils/api-client");
|
|
|
11
11
|
// and the server must not be able to disagree about what `exited` is spelled.
|
|
12
12
|
const status_reason_1 = require("../../lib/detection/status-reason");
|
|
13
13
|
const command_helpers_1 = require("../utils/command-helpers");
|
|
14
|
+
// Issue #2317: the tmux session name, so nobody has to assemble
|
|
15
|
+
// `mcbd-<tool>-<worktree>[-<suffix>]` by hand from two commands' output.
|
|
16
|
+
const cli_tool_ids_1 = require("../config/cli-tool-ids");
|
|
17
|
+
const session_name_1 = require("../../lib/cli-tools/session-name");
|
|
14
18
|
/**
|
|
15
19
|
* Derive display status from worktree flags.
|
|
16
20
|
*
|
|
@@ -117,6 +121,35 @@ function formatTable(worktrees) {
|
|
|
117
121
|
const dataLines = rows.map(r => r.map((cell, i) => cell.padEnd(colWidths[i])).join(' '));
|
|
118
122
|
return [headerLine, separator, ...dataLines].join('\n');
|
|
119
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* The tmux session name of this worktree's DEFAULT agent, or null (Issue #2317).
|
|
126
|
+
*
|
|
127
|
+
* The default agent's PRIMARY instance, which is the session `commandmate
|
|
128
|
+
* attach <id>` opens with no flags — so the two answers cannot disagree. A
|
|
129
|
+
* worktree running several agents has several sessions, and this field names one
|
|
130
|
+
* of them on purpose: the complete per-instance list is what
|
|
131
|
+
* `commandmate instances <id>` is for, and duplicating it here would put the
|
|
132
|
+
* roster in two places.
|
|
133
|
+
*
|
|
134
|
+
* Null when the row names no default agent, or names one this CLI does not know
|
|
135
|
+
* (a server newer than the CLI), or when the id would not survive
|
|
136
|
+
* `validateSessionName` — the same three cases in which there is no name to
|
|
137
|
+
* give rather than a wrong one.
|
|
138
|
+
*
|
|
139
|
+
* Computed CLIENT-side. The server does not publish it, and asking it to would
|
|
140
|
+
* mean `/api/worktrees` — the sidebar's poll, for every worktree, every couple
|
|
141
|
+
* of seconds — carrying a string derivable from two fields already in the row.
|
|
142
|
+
*/
|
|
143
|
+
function deriveTmuxSession(wt) {
|
|
144
|
+
if (!wt.cliToolId || !(0, cli_tool_ids_1.isCliToolId)(wt.cliToolId))
|
|
145
|
+
return null;
|
|
146
|
+
try {
|
|
147
|
+
return (0, session_name_1.resolveSessionName)(wt.cliToolId, wt.id);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
120
153
|
/**
|
|
121
154
|
* Format output based on options [DR1-02]
|
|
122
155
|
*
|
|
@@ -135,7 +168,14 @@ function formatTable(worktrees) {
|
|
|
135
168
|
*/
|
|
136
169
|
function formatOutput(worktrees, options) {
|
|
137
170
|
if (options.json) {
|
|
138
|
-
|
|
171
|
+
// Issue #2317 appends one key and changes nothing else: every field the
|
|
172
|
+
// server sent still passes through verbatim, so a consumer reading
|
|
173
|
+
// `sessionStatusByCli.<tool>.statusEvidence` is unaffected.
|
|
174
|
+
const rows = worktrees.map((wt) => ({
|
|
175
|
+
...wt,
|
|
176
|
+
tmuxSession: deriveTmuxSession(wt),
|
|
177
|
+
}));
|
|
178
|
+
return JSON.stringify(rows, null, 2);
|
|
139
179
|
}
|
|
140
180
|
if (options.quiet) {
|
|
141
181
|
return worktrees.map(wt => wt.id).join('\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-dependencies.d.ts","sourceRoot":"","sources":["../../../src/cli/config/cli-dependencies.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"cli-dependencies.d.ts","sourceRoot":"","sources":["../../../src/cli/config/cli-dependencies.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,eAAe,EAmGzC,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,IAAI,eAAe,EAAE,CAEnD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,eAAe,EAAE,CAE3D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,eAAe,EAAE,CAE3D"}
|