commandmate 0.41.1 → 0.42.1
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 +134 -134
- package/.next/app-path-routes-manifest.json +24 -24
- 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.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.js +1 -1
- package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/release-notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route_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/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 +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_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/relays/[relayId]/cancel/route.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/route.js +1 -1
- package/.next/server/app/api/relays/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route.js.nft.json +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_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/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]/direct-input/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.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_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/notes/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 +103 -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_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_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 +103 -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 +1 -103
- 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.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route.js +2 -2
- 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 -103
- 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.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.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.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/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +9 -9
- 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 +24 -24
- package/.next/server/chunks/1068.js +1 -0
- package/.next/server/chunks/1210.js +1 -1
- package/.next/server/chunks/1501.js +5 -5
- package/.next/server/chunks/1990.js +103 -0
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3707.js +1 -1
- package/.next/server/chunks/3718.js +1 -0
- package/.next/server/chunks/434.js +1 -1
- package/.next/server/chunks/4443.js +1 -1
- package/.next/server/chunks/5164.js +1 -1
- package/.next/server/chunks/5775.js +1 -0
- package/.next/server/chunks/611.js +1 -0
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/650.js +1 -1
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8581.js +1 -1
- package/.next/server/chunks/8583.js +1 -1
- package/.next/server/chunks/8673.js +2 -2
- package/.next/server/chunks/8728.js +3 -3
- package/.next/server/chunks/8791.js +1 -0
- package/.next/server/chunks/8800.js +1 -1
- package/.next/server/chunks/8918.js +1 -103
- package/.next/server/chunks/9130.js +2 -2
- package/.next/server/chunks/964.js +1 -1
- package/.next/server/chunks/9731.js +3 -3
- package/.next/server/chunks/9882.js +3 -3
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{2407-7bd75de2f6be3692.js → 2407-21fbf12d753b8d4d.js} +1 -1
- package/.next/static/chunks/7705-2a2936551b0cf9a3.js +1 -0
- package/.next/static/chunks/8165-934ee7ff3b4ddfd4.js +1 -0
- package/.next/static/chunks/app/{layout-51fa91ea833c97fc.js → layout-8ff4c7c08ef1f621.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/page-3c946bd2875391fd.js +1 -0
- package/.next/static/css/{974314e796232f53.css → b3f433d52b8ed5c8.css} +1 -1
- package/.next/trace +13 -13
- package/dist/cli/commands/attach.d.ts +6 -4
- package/dist/cli/commands/attach.d.ts.map +1 -1
- package/dist/cli/commands/attach.js +36 -5
- package/dist/cli/commands/instances.d.ts.map +1 -1
- package/dist/cli/commands/instances.js +5 -0
- package/dist/cli/commands/ls.d.ts.map +1 -1
- package/dist/cli/commands/ls.js +19 -9
- package/dist/cli/commands/whoami.d.ts +9 -25
- package/dist/cli/commands/whoami.d.ts.map +1 -1
- package/dist/cli/commands/whoami.js +18 -42
- package/dist/cli/types/api-responses.d.ts +37 -0
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/lib/cli-tools/session-name.d.ts +72 -4
- package/dist/lib/cli-tools/session-name.d.ts.map +1 -1
- package/dist/lib/cli-tools/session-name.js +115 -12
- package/dist/lib/detection/tools/verified-against.d.ts +11 -2
- package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
- package/dist/lib/detection/tools/verified-against.js +11 -2
- package/dist/lib/session/tmux-session-surface.d.ts +9 -7
- package/dist/lib/session/tmux-session-surface.d.ts.map +1 -1
- package/dist/lib/session/tmux-session-surface.js +15 -8
- package/dist/lib/tmux/legacy-session-alias.d.ts +43 -0
- package/dist/lib/tmux/legacy-session-alias.d.ts.map +1 -0
- package/dist/lib/tmux/legacy-session-alias.js +64 -0
- package/dist/lib/verification/verify-config.d.ts +21 -0
- package/dist/lib/verification/verify-config.d.ts.map +1 -1
- package/dist/lib/verification/verify-config.js +54 -1
- package/dist/server/locales/en/worktree.json +60 -17
- package/dist/server/locales/ja/worktree.json +63 -20
- package/dist/server/server.js +29 -0
- package/dist/server/src/lib/auto-yes-poller.js +15 -0
- package/dist/server/src/lib/cli-tools/antigravity.js +1 -1
- package/dist/server/src/lib/cli-tools/base.js +10 -1
- package/dist/server/src/lib/cli-tools/codex.js +1 -1
- package/dist/server/src/lib/cli-tools/command-code.js +1 -1
- package/dist/server/src/lib/cli-tools/copilot.js +1 -1
- package/dist/server/src/lib/cli-tools/gemini.js +1 -1
- package/dist/server/src/lib/cli-tools/legacy-session-adoption.js +19 -0
- package/dist/server/src/lib/cli-tools/opencode.js +1 -1
- package/dist/server/src/lib/cli-tools/session-name.js +115 -12
- package/dist/server/src/lib/cli-tools/session-namespace.js +55 -0
- package/dist/server/src/lib/cli-tools/session-ownership.js +21 -0
- package/dist/server/src/lib/cli-tools/vibe-local.js +1 -1
- package/dist/server/src/lib/cli-tools/worktree-session-ownership.js +28 -0
- package/dist/server/src/lib/db/app-settings-db.js +29 -0
- package/dist/server/src/lib/detection/cli-patterns.js +51 -10
- package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +8 -2
- package/dist/server/src/lib/detection/tools/codex/detect.js +8 -1
- package/dist/server/src/lib/detection/tools/codex/prompt.js +6 -2
- package/dist/server/src/lib/detection/tools/verified-against.js +11 -2
- package/dist/server/src/lib/hooks/sources/codex/hooks-config.js +77 -2
- package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +77 -1
- package/dist/server/src/lib/realtime/terminal-broadcast.js +11 -0
- package/dist/server/src/lib/session/adopt-legacy-sessions.js +89 -0
- package/dist/server/src/lib/session/claude-session.js +13 -10
- package/dist/server/src/lib/session/current-output-builder.js +18 -0
- package/dist/server/src/lib/session/send-user-message.js +26 -0
- package/dist/server/src/lib/session/session-instance-targets.js +53 -0
- package/dist/server/src/lib/session/tmux-session-surface.js +15 -8
- package/dist/server/src/lib/session/worktree-session-reconcile.js +101 -56
- package/dist/server/src/lib/session-cleanup.js +33 -3
- package/dist/server/src/lib/tmux/legacy-session-alias.js +64 -0
- package/dist/server/src/lib/tmux/session-hook-scripts.js +12 -4
- package/dist/server/src/lib/tmux/session-ownership.js +174 -0
- package/dist/server/src/lib/tmux/tmux.js +13 -3
- package/dist/server/src/lib/verification/env-clean-gate.js +46 -14
- package/dist/server/src/lib/verification/gate-runner.js +1 -0
- package/dist/server/src/lib/verification/verify-config.js +54 -1
- package/dist/server/src/lib/ws-server.js +11 -0
- package/package.json +1 -1
- package/release-notes/0.42.0.json +62 -0
- package/release-notes/0.42.1.json +16 -0
- package/.next/server/chunks/3323.js +0 -1
- package/.next/server/chunks/7075.js +0 -1
- package/.next/server/chunks/9080.js +0 -1
- package/.next/static/chunks/7705-25076b57224da370.js +0 -1
- package/.next/static/chunks/8165-d3b7c8a7aa776bc7.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-1e6300dd50cd9a4d.js +0 -1
- /package/.next/static/{_fBjTkjoWfOqdjl2SeMIN → 3M_S0B7dhEDdVE2XSJz1Y}/_buildManifest.js +0 -0
- /package/.next/static/{_fBjTkjoWfOqdjl2SeMIN → 3M_S0B7dhEDdVE2XSJz1Y}/_ssgManifest.js +0 -0
|
@@ -65,10 +65,26 @@
|
|
|
65
65
|
* resolving the worktree from `cwd`, which is exactly the hand-configured
|
|
66
66
|
* behaviour of Issue #1549. `CM_AGENT_HOOKS_INJECT=0` turns the whole thing off.
|
|
67
67
|
*
|
|
68
|
+
* ## The shared app-server daemon (Issue #2874)
|
|
69
|
+
*
|
|
70
|
+
* From codex **0.157** the TUI attaches by default (`features.daemon_auto_start`)
|
|
71
|
+
* to one machine-wide `codex app-server --managed-daemon`, and hooks run inside
|
|
72
|
+
* *that* process, so they see the daemon's environment — the first instance that
|
|
73
|
+
* started it — not the launching session's. Every later instance was reported as
|
|
74
|
+
* that first one.
|
|
75
|
+
*
|
|
76
|
+
* `-c features.daemon_auto_start=false` ({@link CODEX_EMBEDDED_MODE_ARGS}) only stops
|
|
77
|
+
* codex *starting* a daemon; one already running is still attached to (Issue #2891 —
|
|
78
|
+
* #2874 was observed with none up). `--no-daemon` ({@link CODEX_NO_DAEMON_FLAG}) stays
|
|
79
|
+
* off it even then, when {@link codexSupportsNoDaemon}; both are kept.
|
|
80
|
+
* Measured 2026-09-27 on codex-cli 0.157.1.
|
|
81
|
+
*
|
|
68
82
|
* @module lib/hooks/sources/codex/hooks-config
|
|
69
83
|
*/
|
|
70
84
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
71
|
-
exports.CODEX_HOOK_TRUST_POLICY_DEFAULT = exports.CODEX_SUPPORTED_EVENTS = exports.CODEX_PERMISSION_REQUEST_EVENT = exports.CODEX_REGISTERED_EVENTS = exports.CODEX_SESSION_END_TIMEOUT_SECONDS = exports.CODEX_HOOK_TRUST_BYPASS_FLAG = exports.CODEX_HOOK_TRUST_ENV_VAR = exports.CODEX_PERMISSION_URL_ENV_VAR = exports.CODEX_EVENT_URL_ENV_VAR = exports.CODEX_INSTANCE_ID_ENV_VAR = exports.CODEX_WORKTREE_ID_ENV_VAR = exports.CODEX_TOOL_ENV_VAR = exports.CODEX_HOME_ENV_VAR = exports.CODEX_HOOK_MARKER = void 0;
|
|
85
|
+
exports.CODEX_HOOK_TRUST_POLICY_DEFAULT = exports.CODEX_SUPPORTED_EVENTS = exports.CODEX_PERMISSION_REQUEST_EVENT = exports.CODEX_REGISTERED_EVENTS = exports.CODEX_SESSION_END_TIMEOUT_SECONDS = exports.CODEX_NO_DAEMON_FLAG = exports.CODEX_EMBEDDED_MODE_ARGS = exports.CODEX_HOOK_TRUST_BYPASS_FLAG = exports.CODEX_HOOK_TRUST_ENV_VAR = exports.CODEX_PERMISSION_URL_ENV_VAR = exports.CODEX_EVENT_URL_ENV_VAR = exports.CODEX_INSTANCE_ID_ENV_VAR = exports.CODEX_WORKTREE_ID_ENV_VAR = exports.CODEX_TOOL_ENV_VAR = exports.CODEX_HOME_ENV_VAR = exports.CODEX_HOOK_MARKER = void 0;
|
|
86
|
+
exports.codexSupportsNoDaemon = codexSupportsNoDaemon;
|
|
87
|
+
exports.resetCodexNoDaemonSupportCacheForTests = resetCodexNoDaemonSupportCacheForTests;
|
|
72
88
|
exports.resolveCodexHookTrustPolicy = resolveCodexHookTrustPolicy;
|
|
73
89
|
exports.isCodexHookTrustBypassEnabled = isCodexHookTrustBypassEnabled;
|
|
74
90
|
exports.shouldTrustCodexHooks = shouldTrustCodexHooks;
|
|
@@ -81,6 +97,7 @@ exports.buildCodexHookSettings = buildCodexHookSettings;
|
|
|
81
97
|
exports.mergeCodexHookSettings = mergeCodexHookSettings;
|
|
82
98
|
exports.writeCodexHookSettings = writeCodexHookSettings;
|
|
83
99
|
exports.buildCodexLaunchPlan = buildCodexLaunchPlan;
|
|
100
|
+
const child_process_1 = require("child_process");
|
|
84
101
|
const fs_1 = require("fs");
|
|
85
102
|
const os_1 = require("os");
|
|
86
103
|
const path_1 = require("path");
|
|
@@ -89,6 +106,7 @@ const types_1 = require("../../../../lib/cli-tools/types");
|
|
|
89
106
|
const env_1 = require("../../../../lib/env");
|
|
90
107
|
const hook_settings_generator_1 = require("../../../../lib/hooks/hook-settings-generator");
|
|
91
108
|
const logger_1 = require("../../../../lib/logger");
|
|
109
|
+
const env_sanitizer_1 = require("../../../../lib/security/env-sanitizer");
|
|
92
110
|
const path_validator_1 = require("../../../../lib/security/path-validator");
|
|
93
111
|
const event_mapper_1 = require("../event-mapper");
|
|
94
112
|
const relay_install_1 = require("./relay-install");
|
|
@@ -134,6 +152,56 @@ exports.CODEX_PERMISSION_URL_ENV_VAR = 'CM_PERMISSION_HOOK_URL';
|
|
|
134
152
|
exports.CODEX_HOOK_TRUST_ENV_VAR = 'CM_CODEX_HOOK_TRUST';
|
|
135
153
|
/** codex's own flag for running unreviewed hooks, for one invocation. */
|
|
136
154
|
exports.CODEX_HOOK_TRUST_BYPASS_FLAG = '--dangerously-bypass-hook-trust';
|
|
155
|
+
/** codex 0.157+: keep the TUI off the shared app-server daemon so hooks run with this session's env. */
|
|
156
|
+
exports.CODEX_EMBEDDED_MODE_ARGS = '-c features.daemon_auto_start=false';
|
|
157
|
+
/** codex 0.157+: stay off the shared app-server daemon even when one is already running. */
|
|
158
|
+
exports.CODEX_NO_DAEMON_FLAG = '--no-daemon';
|
|
159
|
+
/** How long `codex --help` may take before {@link codexSupportsNoDaemon} gives up. */
|
|
160
|
+
const CODEX_HELP_PROBE_TIMEOUT_MS = 5000;
|
|
161
|
+
/** `--no-daemon` as a whole option name, not the prefix of a longer one. */
|
|
162
|
+
const CODEX_NO_DAEMON_HELP_PATTERN = new RegExp(`${exports.CODEX_NO_DAEMON_FLAG}(?![\\w-])`);
|
|
163
|
+
const noDaemonSupportCache = new Map();
|
|
164
|
+
/**
|
|
165
|
+
* Whether `executablePath --help` lists `--no-daemon`. Cached per executable path for the
|
|
166
|
+
* life of the process. Any failure (spawn error, non-zero exit, timeout) → false.
|
|
167
|
+
*
|
|
168
|
+
* Decided from the help text, not from a version number: a version that was
|
|
169
|
+
* read wrongly, or a build that backported or dropped the option, still gets
|
|
170
|
+
* the answer the binary itself gives. The failure direction is the safe one — an
|
|
171
|
+
* unrecognised option would stop codex starting at all, whereas a missing flag
|
|
172
|
+
* only leaves the #2874 behaviour in place. Failures are cached too, so a codex
|
|
173
|
+
* that hangs on `--help` costs one timeout, not one per launch.
|
|
174
|
+
*
|
|
175
|
+
* Synchronous because `prepareLaunch` is. The child gets the sanitised
|
|
176
|
+
* environment: `executablePath` may be a bare name resolved off the server's
|
|
177
|
+
* `PATH`, and a `--help` probe has no use for CommandMate's credentials.
|
|
178
|
+
*/
|
|
179
|
+
function codexSupportsNoDaemon(executablePath) {
|
|
180
|
+
const cached = noDaemonSupportCache.get(executablePath);
|
|
181
|
+
if (cached !== undefined)
|
|
182
|
+
return cached;
|
|
183
|
+
let supported = false;
|
|
184
|
+
try {
|
|
185
|
+
const result = (0, child_process_1.spawnSync)(executablePath, ['--help'], {
|
|
186
|
+
encoding: 'utf8',
|
|
187
|
+
timeout: CODEX_HELP_PROBE_TIMEOUT_MS,
|
|
188
|
+
env: (0, env_sanitizer_1.sanitizeEnvForChildProcess)(),
|
|
189
|
+
});
|
|
190
|
+
supported =
|
|
191
|
+
!result.error &&
|
|
192
|
+
result.status === 0 &&
|
|
193
|
+
CODEX_NO_DAEMON_HELP_PATTERN.test(String(result.stdout ?? ''));
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
supported = false;
|
|
197
|
+
}
|
|
198
|
+
noDaemonSupportCache.set(executablePath, supported);
|
|
199
|
+
return supported;
|
|
200
|
+
}
|
|
201
|
+
/** Forget what {@link codexSupportsNoDaemon} has learned. Tests only. */
|
|
202
|
+
function resetCodexNoDaemonSupportCacheForTests() {
|
|
203
|
+
noDaemonSupportCache.clear();
|
|
204
|
+
}
|
|
137
205
|
/**
|
|
138
206
|
* `SessionEnd`'s budget, in seconds.
|
|
139
207
|
*
|
|
@@ -573,8 +641,15 @@ function buildCodexLaunchPlan(executablePath, target, options = {}) {
|
|
|
573
641
|
[exports.CODEX_EVENT_URL_ENV_VAR]: `http://${CODEX_HOOK_HOST}:${port}${hook_settings_generator_1.AGENT_EVENT_PATH}`,
|
|
574
642
|
[exports.CODEX_PERMISSION_URL_ENV_VAR]: `http://${CODEX_HOOK_HOST}:${port}${hook_settings_generator_1.PERMISSION_REQUEST_PATH}?${query.toString()}`,
|
|
575
643
|
};
|
|
644
|
+
const noDaemon = (options.supportsNoDaemon ?? codexSupportsNoDaemon(executablePath))
|
|
645
|
+
? ` ${exports.CODEX_NO_DAEMON_FLAG}`
|
|
646
|
+
: '';
|
|
576
647
|
const trust = isCodexHookTrustBypassEnabled() ? ` ${exports.CODEX_HOOK_TRUST_BYPASS_FLAG}` : '';
|
|
577
|
-
return {
|
|
648
|
+
return {
|
|
649
|
+
command: `${(0, hook_settings_generator_1.shellQuote)(executablePath)} ${exports.CODEX_EMBEDDED_MODE_ARGS}${noDaemon}${trust}`,
|
|
650
|
+
settingsPath,
|
|
651
|
+
env,
|
|
652
|
+
};
|
|
578
653
|
}
|
|
579
654
|
catch (error) {
|
|
580
655
|
logger.warn('codex-hooks-config-write-failed', {
|
|
@@ -54,13 +54,18 @@
|
|
|
54
54
|
* @module lib/polling/auto-yes-dialog-gate
|
|
55
55
|
*/
|
|
56
56
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
-
exports.UNSUPPORTED_DIALOG_LAYOUT_REASON = exports.PROMPT_NO_LONGER_ACTIVE_REASON = exports.AUTO_YES_DIALOG_GATE_ENV_VAR = exports.AUTO_YES_DIALOG_GATE_DEFAULT_MODE = exports.AUTO_YES_DIALOG_GATE_MODES = void 0;
|
|
57
|
+
exports.COMMAND_CODE_UNSUPPORTED_QUESTION_MESSAGE = exports.UNSUPPORTED_DIALOG_LAYOUT_REASON = exports.PROMPT_NO_LONGER_ACTIVE_REASON = exports.AUTO_YES_DIALOG_GATE_ENV_VAR = exports.AUTO_YES_DIALOG_GATE_DEFAULT_MODE = exports.AUTO_YES_DIALOG_GATE_MODES = void 0;
|
|
58
58
|
exports.resolveAutoYesDialogGateMode = resolveAutoYesDialogGateMode;
|
|
59
59
|
exports.evaluateAutoYesDialogGate = evaluateAutoYesDialogGate;
|
|
60
60
|
exports.evaluateDialogPresence = evaluateDialogPresence;
|
|
61
61
|
exports.judgePromptResponse = judgePromptResponse;
|
|
62
|
+
exports.assessPromptAnswerability = assessPromptAnswerability;
|
|
62
63
|
const frame_1 = require("../../lib/detection/tools/frame");
|
|
63
64
|
const registry_1 = require("../../lib/detection/tools/registry");
|
|
65
|
+
const prompt_detector_1 = require("../../lib/detection/prompt-detector");
|
|
66
|
+
const cli_patterns_1 = require("../../lib/detection/cli-patterns");
|
|
67
|
+
const dialog_1 = require("../../lib/detection/tools/antigravity/dialog");
|
|
68
|
+
const dialog_2 = require("../../lib/detection/tools/command-code/dialog");
|
|
64
69
|
/** Every accepted value of {@link AutoYesDialogGateMode}, for parsing and tests. */
|
|
65
70
|
exports.AUTO_YES_DIALOG_GATE_MODES = ['enforce', 'legacy'];
|
|
66
71
|
/**
|
|
@@ -309,3 +314,74 @@ function judgePromptResponse(promptCheck, presence) {
|
|
|
309
314
|
}
|
|
310
315
|
return { reason: exports.PROMPT_NO_LONGER_ACTIVE_REASON };
|
|
311
316
|
}
|
|
317
|
+
/**
|
|
318
|
+
* The refusal text for a Command Code question screen that is plainly up and
|
|
319
|
+
* could not be read (Issue #2522 確定仕様 B).
|
|
320
|
+
*
|
|
321
|
+
* Shares {@link UNSUPPORTED_DIALOG_LAYOUT_REASON} with Issue #2486's refusal —
|
|
322
|
+
* the reason code is what `respond --json` and the CLI branch on, and both cases
|
|
323
|
+
* are the same thing: a picker is on screen whose layout no rule could verify.
|
|
324
|
+
* The SENTENCE is its own because the next step differs in one respect worth
|
|
325
|
+
* saying out loud: this screen's LIST is what could not be read, so retrying
|
|
326
|
+
* once the pane has repainted is genuinely worth a try before walking over to it.
|
|
327
|
+
*
|
|
328
|
+
* Fixed text that never quotes the answer or the frame (SEC-003), so it is safe
|
|
329
|
+
* to return to a client verbatim.
|
|
330
|
+
*/
|
|
331
|
+
exports.COMMAND_CODE_UNSUPPORTED_QUESTION_MESSAGE = 'A Command Code question is on screen, but its option list could not be read, so no key was ' +
|
|
332
|
+
'sent. Answer it in the terminal, or retry once the screen has settled.';
|
|
333
|
+
/**
|
|
334
|
+
* May this frame be answered from CommandMate? (Issue #2870)
|
|
335
|
+
*
|
|
336
|
+
* The ONE reading both `/prompt-response` (before it sends a key) and the status
|
|
337
|
+
* API (`promptAnswerable`, before the UI offers Send) use, so the two can no
|
|
338
|
+
* longer disagree: in #2868 the status API published a prompt off the generic
|
|
339
|
+
* parser alone while `/prompt-response` refused it, and Send did nothing.
|
|
340
|
+
*
|
|
341
|
+
* The order is the route's (#161, #2364, #2457, #2486, #2522): the tool's own
|
|
342
|
+
* reader (agy's `↑/↓ Navigate` dialog, Command Code's question) → the generic
|
|
343
|
+
* parser → {@link evaluateDialogPresence} → {@link judgePromptResponse}.
|
|
344
|
+
*
|
|
345
|
+
* @param cliToolId - CLI tool the frame came from
|
|
346
|
+
* @param frame - The capture itself (ANSI and box drawing intact). It is cleaned
|
|
347
|
+
* here for the parsers; Command Code's reader and the presence gate read it as
|
|
348
|
+
* captured (see {@link evaluateDialogPresence}).
|
|
349
|
+
*/
|
|
350
|
+
function assessPromptAnswerability(cliToolId, frame) {
|
|
351
|
+
const cleanOutput = (0, cli_patterns_1.stripBoxDrawing)((0, cli_patterns_1.stripAnsi)(frame));
|
|
352
|
+
const toolDialog = cliToolId === 'antigravity'
|
|
353
|
+
? (0, dialog_1.detectAntigravityNumberedDialogPrompt)(cleanOutput)
|
|
354
|
+
: null;
|
|
355
|
+
const commandCodeQuestion = cliToolId === 'command-code'
|
|
356
|
+
? (0, dialog_2.readCommandCodeQuestionDialog)(frame)
|
|
357
|
+
: { kind: 'none' };
|
|
358
|
+
// Plainly up and unreadable: refuse before the generic parser, whose partial
|
|
359
|
+
// list is exactly what must not reach a keystroke.
|
|
360
|
+
if (commandCodeQuestion.kind === 'unsupported') {
|
|
361
|
+
return {
|
|
362
|
+
promptCheck: { isPrompt: false, cleanContent: cleanOutput },
|
|
363
|
+
isCommandCodeQuestion: false,
|
|
364
|
+
refusal: {
|
|
365
|
+
reason: exports.UNSUPPORTED_DIALOG_LAYOUT_REASON,
|
|
366
|
+
message: exports.COMMAND_CODE_UNSUPPORTED_QUESTION_MESSAGE,
|
|
367
|
+
},
|
|
368
|
+
presence: {
|
|
369
|
+
present: false,
|
|
370
|
+
dialog: null,
|
|
371
|
+
mode: exports.AUTO_YES_DIALOG_GATE_DEFAULT_MODE[cliToolId] ?? 'legacy',
|
|
372
|
+
gated: false,
|
|
373
|
+
},
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
const isCommandCodeQuestion = commandCodeQuestion.kind === 'prompt';
|
|
377
|
+
const promptCheck = (commandCodeQuestion.kind === 'prompt' ? commandCodeQuestion.prompt : null)
|
|
378
|
+
?? toolDialog
|
|
379
|
+
?? (0, prompt_detector_1.detectPrompt)(cleanOutput, (0, cli_patterns_1.buildDetectPromptOptions)(cliToolId));
|
|
380
|
+
const presence = evaluateDialogPresence(cliToolId, promptCheck.promptData?.type, frame);
|
|
381
|
+
return {
|
|
382
|
+
promptCheck,
|
|
383
|
+
isCommandCodeQuestion,
|
|
384
|
+
refusal: judgePromptResponse(promptCheck, presence),
|
|
385
|
+
presence,
|
|
386
|
+
};
|
|
387
|
+
}
|
|
@@ -63,6 +63,11 @@ function snapshotFingerprint(payload) {
|
|
|
63
63
|
payload.sessionStatus,
|
|
64
64
|
payload.thinking ?? false,
|
|
65
65
|
payload.isPromptWaiting ?? false,
|
|
66
|
+
// Issue #2887: so a redraw whose only change is this verdict (a dialog's
|
|
67
|
+
// answerability flipping between `#2870`'s judgement calls) still reaches
|
|
68
|
+
// the push, the same reason `sessionStatus` and the two dismiss-panel
|
|
69
|
+
// fields above are here.
|
|
70
|
+
payload.promptAnswerable ?? null,
|
|
66
71
|
payload.isSelectionListActive ?? false,
|
|
67
72
|
payload.isPagerActive ?? false,
|
|
68
73
|
// Issue #2369: in the fingerprint for the same reason `sessionStatus` is —
|
|
@@ -96,6 +101,12 @@ function emitTerminalSnapshot(worktreeId, cliToolId, payload, instanceId) {
|
|
|
96
101
|
thinking: payload.thinking ?? false,
|
|
97
102
|
isPromptWaiting: payload.isPromptWaiting ?? false,
|
|
98
103
|
promptData: payload.promptData ?? null,
|
|
104
|
+
// Issue #2887: straight through, unlike its neighbours above — not
|
|
105
|
+
// `?? false`. `buildCurrentOutput` publishes this only when it judged the
|
|
106
|
+
// prompt (#2870), and `undefined` here means "no verdict", which
|
|
107
|
+
// `JSON.stringify` (in `broadcast`) already drops from the wire on its own.
|
|
108
|
+
// Defaulting it would turn "not judged" into a judgement.
|
|
109
|
+
promptAnswerable: payload.promptAnswerable,
|
|
99
110
|
isSelectionListActive: payload.isSelectionListActive ?? false,
|
|
100
111
|
isPagerActive: payload.isPagerActive ?? false,
|
|
101
112
|
isDismissablePanelActive: payload.isDismissablePanelActive ?? false,
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Keep using this server's pre-namespace tmux sessions (Issue #2866).
|
|
4
|
+
*
|
|
5
|
+
* Once a namespace is set, `resolveSessionName` names a session
|
|
6
|
+
* `mcbd-{ns}-{cli}-{worktreeId}[-{suffix}]`. A session the same server started
|
|
7
|
+
* before that is still running under `mcbd-{cli}-{worktreeId}[-{suffix}]`, and
|
|
8
|
+
* would vanish from the UI while its agent keeps running. It is NOT renamed —
|
|
9
|
+
* an older CommandMate running beside this one, or this one after a downgrade,
|
|
10
|
+
* must still find it — but adopted: the new-format name is aliased to the
|
|
11
|
+
* legacy one (`legacy-session-alias.ts`), and the alias is dropped once the
|
|
12
|
+
* legacy session is killed or found gone.
|
|
13
|
+
*
|
|
14
|
+
* Only a session whose `#{session_path}` is the worktree's own directory is
|
|
15
|
+
* adopted (Issue #2865): the same legacy name may be another server's session.
|
|
16
|
+
*
|
|
17
|
+
* Runs once at startup, after `initSessionNamespace` and the worktree-ID
|
|
18
|
+
* session reconcile.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.adoptLegacySessions = adoptLegacySessions;
|
|
22
|
+
const session_name_1 = require("../../lib/cli-tools/session-name");
|
|
23
|
+
const session_namespace_1 = require("../../lib/cli-tools/session-namespace");
|
|
24
|
+
const session_ownership_1 = require("../../lib/cli-tools/session-ownership");
|
|
25
|
+
const legacy_session_adoption_1 = require("../../lib/cli-tools/legacy-session-adoption");
|
|
26
|
+
const logger_1 = require("../../lib/logger");
|
|
27
|
+
const session_instance_targets_1 = require("./session-instance-targets");
|
|
28
|
+
const logger = (0, logger_1.createLogger)('adopt-legacy-sessions');
|
|
29
|
+
/**
|
|
30
|
+
* Every worktree row. Queried directly rather than through `worktree-db`, for
|
|
31
|
+
* the same reason `worktree-session-reconcile.ts` does: suites mock that module.
|
|
32
|
+
*/
|
|
33
|
+
function readWorktrees(db) {
|
|
34
|
+
return db.prepare('SELECT id, path FROM worktrees').all();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Alias each worktree instance's new-format session name to its live legacy
|
|
38
|
+
* session, when the legacy session is this worktree's own and no new-format
|
|
39
|
+
* session exists yet.
|
|
40
|
+
*
|
|
41
|
+
* Never throws — a startup pass must not be able to stop the server.
|
|
42
|
+
*
|
|
43
|
+
* @param db - Database instance (worktrees and the agent roster)
|
|
44
|
+
*/
|
|
45
|
+
async function adoptLegacySessions(db, options) {
|
|
46
|
+
const result = { adopted: [], errors: [] };
|
|
47
|
+
const namespace = options?.namespace !== undefined ? options.namespace : (0, session_namespace_1.getSessionNamespace)();
|
|
48
|
+
// No namespace: the current name IS the legacy name, nothing to adopt.
|
|
49
|
+
if (namespace === null)
|
|
50
|
+
return result;
|
|
51
|
+
const list = options?.tmux?.listSessions ?? legacy_session_adoption_1.listSessions;
|
|
52
|
+
const isOwnedBy = options?.tmux?.isSessionOwnedBy ?? session_ownership_1.isSessionPathOwnedBy;
|
|
53
|
+
let livePaths;
|
|
54
|
+
let worktrees;
|
|
55
|
+
try {
|
|
56
|
+
const sessions = await list();
|
|
57
|
+
livePaths = new Map(sessions.map((session) => [session.name, session.path]));
|
|
58
|
+
worktrees = livePaths.size === 0 ? [] : readWorktrees(db);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
result.errors.push(error instanceof Error ? error.message : String(error));
|
|
62
|
+
logger.warn('adopt-legacy:failed', { error: result.errors[0] });
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
for (const worktree of worktrees) {
|
|
66
|
+
for (const { cliToolId, instanceId } of (0, session_instance_targets_1.collectInstanceTargets)(db, [worktree.id])) {
|
|
67
|
+
try {
|
|
68
|
+
const legacyName = (0, session_name_1.resolveLegacySessionName)(cliToolId, worktree.id, instanceId);
|
|
69
|
+
if (!livePaths.has(legacyName))
|
|
70
|
+
continue;
|
|
71
|
+
const newName = (0, session_name_1.resolveNamespacedSessionName)(namespace, cliToolId, worktree.id, instanceId);
|
|
72
|
+
if (livePaths.has(newName))
|
|
73
|
+
continue;
|
|
74
|
+
if (!isOwnedBy(livePaths.get(legacyName) ?? null, worktree.path))
|
|
75
|
+
continue;
|
|
76
|
+
(0, legacy_session_adoption_1.registerLegacyAlias)(newName, legacyName);
|
|
77
|
+
result.adopted.push({ worktreeId: worktree.id, newName, legacyName });
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
result.errors.push(`${worktree.id}/${instanceId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
logger.info('adopt-legacy:complete', {
|
|
85
|
+
adopted: result.adopted.length,
|
|
86
|
+
errors: result.errors.length,
|
|
87
|
+
});
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
@@ -27,8 +27,9 @@ const child_process_1 = require("child_process");
|
|
|
27
27
|
const util_1 = require("util");
|
|
28
28
|
const promises_1 = require("fs/promises");
|
|
29
29
|
const logger_1 = require("../../lib/logger");
|
|
30
|
+
const session_ownership_1 = require("../../lib/cli-tools/session-ownership");
|
|
30
31
|
const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
|
|
31
|
-
const
|
|
32
|
+
const session_name_1 = require("../../lib/cli-tools/session-name");
|
|
32
33
|
const sources_1 = require("../../lib/hooks/sources");
|
|
33
34
|
const hook_settings_generator_1 = require("../../lib/hooks/hook-settings-generator");
|
|
34
35
|
const cmate_cli_tool_parser_1 = require("../../lib/cmate-cli-tool-parser");
|
|
@@ -340,9 +341,9 @@ async function ensureHealthySession(sessionName) {
|
|
|
340
341
|
* Get tmux session name for a worktree
|
|
341
342
|
*
|
|
342
343
|
* Issue #868: Supports additional agent instances. The primary instance
|
|
343
|
-
* (instanceId omitted or equal to 'claude')
|
|
344
|
-
*
|
|
345
|
-
*
|
|
344
|
+
* (instanceId omitted or equal to 'claude') carries no suffix; additional
|
|
345
|
+
* instances append a suffix derived from the instance ID. Issue #2866: the
|
|
346
|
+
* rule is `resolveSessionName`'s (server namespace included).
|
|
346
347
|
*
|
|
347
348
|
* @param worktreeId - Worktree ID
|
|
348
349
|
* @param instanceId - Optional agent instance ID (defaults to primary)
|
|
@@ -355,12 +356,11 @@ async function ensureHealthySession(sessionName) {
|
|
|
355
356
|
* ```
|
|
356
357
|
*/
|
|
357
358
|
function getSessionName(worktreeId, instanceId) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
return suffix ? `${base}-${suffix}` : base;
|
|
359
|
+
// Issue #2866: delegated so the server namespace and adopted legacy sessions
|
|
360
|
+
// apply to Claude exactly as to every other tool. A local copy of the rule
|
|
361
|
+
// would start, send to and stop `mcbd-claude-*` while capture and the UI
|
|
362
|
+
// address `mcbd-{ns}-claude-*`.
|
|
363
|
+
return (0, session_name_1.resolveSessionName)('claude', worktreeId, instanceId);
|
|
364
364
|
}
|
|
365
365
|
/**
|
|
366
366
|
* Check if Claude is installed and available
|
|
@@ -486,6 +486,9 @@ async function startClaudeSession(options) {
|
|
|
486
486
|
// Check if session already exists
|
|
487
487
|
const exists = await (0, tmux_1.hasSession)(sessionName);
|
|
488
488
|
if (exists) {
|
|
489
|
+
// Issue #2865: a same-named session another CommandMate server created is
|
|
490
|
+
// refused before the health check can kill or reuse it.
|
|
491
|
+
await (0, session_ownership_1.assertSessionNotForeign)(sessionName, worktreePath);
|
|
489
492
|
// SF-S2-004: Health check on existing session
|
|
490
493
|
const healthy = await ensureHealthySession(sessionName);
|
|
491
494
|
if (healthy) {
|
|
@@ -85,6 +85,7 @@ const prompt_waiting_composition_1 = require("../../lib/session/prompt-waiting-c
|
|
|
85
85
|
const provisional_turn_1 = require("../../lib/session/provisional-turn");
|
|
86
86
|
const status_evidence_1 = require("../../lib/session/status-evidence");
|
|
87
87
|
const ask_user_question_prompt_1 = require("../../lib/session/ask-user-question-prompt");
|
|
88
|
+
const auto_yes_dialog_gate_1 = require("../../lib/polling/auto-yes-dialog-gate");
|
|
88
89
|
const layer_disagreement_1 = require("../../lib/session/layer-disagreement");
|
|
89
90
|
const structured_prompt_1 = require("../../lib/session/structured-prompt");
|
|
90
91
|
const logger = (0, logger_1.createLogger)('current-output-builder');
|
|
@@ -632,6 +633,9 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
632
633
|
const resolvedInstanceId = instanceId ?? cliToolId;
|
|
633
634
|
const manager = manager_1.CLIToolManager.getInstance();
|
|
634
635
|
const cliTool = manager.getTool(cliToolId);
|
|
636
|
+
// Issue #2886: read once, independent of `isRunning`, so both return paths
|
|
637
|
+
// below publish the same value the pane is (or would be) reached at.
|
|
638
|
+
const sessionName = cliTool.getSessionName(worktreeId, instanceId);
|
|
635
639
|
const stopEventAt = (0, agent_event_state_1.getLastStopEventAt)(worktreeId, cliToolId, instanceId);
|
|
636
640
|
const lastEvent = (0, agent_event_state_1.getLastAgentEvent)(worktreeId, cliToolId, instanceId);
|
|
637
641
|
// Issue #1924: the registry answers for every tool — a real implementation
|
|
@@ -743,6 +747,7 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
743
747
|
(0, status_evidence_1.forgetLastKnownStatus)((0, auto_yes_manager_1.buildCompositeKey)(worktreeId, cliToolId, instanceId));
|
|
744
748
|
return {
|
|
745
749
|
isRunning: false,
|
|
750
|
+
sessionName,
|
|
746
751
|
content: '',
|
|
747
752
|
lineCount: 0,
|
|
748
753
|
cliToolId,
|
|
@@ -1029,6 +1034,17 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
1029
1034
|
: structuredFacts
|
|
1030
1035
|
? (0, structured_prompt_1.buildStructuredPromptData)(worktreeId, structuredFacts)
|
|
1031
1036
|
: null;
|
|
1037
|
+
// Issue #2870: whether `/prompt-response` would answer the prompt published
|
|
1038
|
+
// above, read by the SAME function it re-verifies with. In #2868 `promptData`
|
|
1039
|
+
// came off the generic parser alone, the route refused it, and the UI's Send
|
|
1040
|
+
// did nothing. Only for a parser-read prompt: the structured form (hook
|
|
1041
|
+
// `decisionId`, degraded) is answered by id or not by number at all, so the
|
|
1042
|
+
// key is left out there, as it is when no prompt is up. `isPromptWaiting` /
|
|
1043
|
+
// `promptData` / `sessionStatus` are untouched — `wait`'s exit 10, Auto-Yes
|
|
1044
|
+
// and push notifications keep reading exactly what they read before.
|
|
1045
|
+
const promptAnswerable = scraperPromptWaiting && (correctedPromptData ?? scraperPromptData)
|
|
1046
|
+
? (0, auto_yes_dialog_gate_1.assessPromptAnswerability)(cliToolId, output).refusal === null
|
|
1047
|
+
: undefined;
|
|
1032
1048
|
// Issue #1723 §3: the field data this Epic is being built on. Every line is
|
|
1033
1049
|
// one poll where the screen and the agent disagreed about what the agent was
|
|
1034
1050
|
// doing, which is the only way to answer "how wrong was the scraper?" with a
|
|
@@ -1165,6 +1181,7 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
1165
1181
|
const lastKnown = (0, status_evidence_1.getLastKnownStatus)(compositeKey);
|
|
1166
1182
|
return {
|
|
1167
1183
|
isRunning: true,
|
|
1184
|
+
sessionName,
|
|
1168
1185
|
cliToolId,
|
|
1169
1186
|
sessionStatus: merged.status,
|
|
1170
1187
|
sessionStatusReason: merged.reason,
|
|
@@ -1181,6 +1198,7 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
1181
1198
|
thinkingMessage: merged.thinking ? `${(0, types_2.getCliToolDisplayName)(cliToolId)} is thinking...` : null,
|
|
1182
1199
|
isPromptWaiting,
|
|
1183
1200
|
promptData,
|
|
1201
|
+
...(promptAnswerable !== undefined ? { promptAnswerable } : {}),
|
|
1184
1202
|
autoYes: {
|
|
1185
1203
|
enabled: autoYesState?.enabled ?? false,
|
|
1186
1204
|
expiresAt: autoYesState?.enabled ? autoYesState.expiresAt : null,
|
|
@@ -44,6 +44,8 @@ const assistant_response_saver_1 = require("../../lib/assistant-response-saver")
|
|
|
44
44
|
const ws_server_1 = require("../../lib/ws-server");
|
|
45
45
|
const types_2 = require("../../lib/realtime/types");
|
|
46
46
|
const logger_1 = require("../../lib/logger");
|
|
47
|
+
const worktree_session_ownership_1 = require("../../lib/cli-tools/worktree-session-ownership");
|
|
48
|
+
const session_name_1 = require("../../lib/cli-tools/session-name");
|
|
47
49
|
const prompt_waiting_guard_1 = require("../../lib/session/prompt-waiting-guard");
|
|
48
50
|
const opencode_1 = require("../../lib/cli-tools/opencode");
|
|
49
51
|
const logger = (0, logger_1.createLogger)('session/send-user-message');
|
|
@@ -108,6 +110,30 @@ async function sendUserMessage(db, params) {
|
|
|
108
110
|
*/
|
|
109
111
|
const resolvedInstanceId = instanceId ?? cliToolId;
|
|
110
112
|
const cliTool = manager_1.CLIToolManager.getInstance().getTool(cliToolId);
|
|
113
|
+
// Issue #2865: the send route checks ownership itself, but the timer manager
|
|
114
|
+
// and relay delivery reach tmux only through here. A session under this
|
|
115
|
+
// worktree's name that was created in another directory belongs to another
|
|
116
|
+
// CommandMate server; nothing is typed into it and no poller watches it.
|
|
117
|
+
// Checked before the prompt guard, which would otherwise read that pane.
|
|
118
|
+
const sessionName = (0, session_name_1.resolveSessionName)(cliToolId, worktreeId, instanceId);
|
|
119
|
+
const ownership = await (0, worktree_session_ownership_1.checkWorktreeSessionOwnership)(worktreeId, sessionName, db);
|
|
120
|
+
if (ownership === null || ownership.verdict === 'foreign') {
|
|
121
|
+
logger.warn('send-refused-foreign-session', {
|
|
122
|
+
worktreeId,
|
|
123
|
+
cliToolId,
|
|
124
|
+
instanceId: resolvedInstanceId,
|
|
125
|
+
sessionName,
|
|
126
|
+
sessionPath: ownership?.sessionPath ?? null,
|
|
127
|
+
reason: ownership ? 'foreign' : 'worktree_not_found',
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
ok: false,
|
|
131
|
+
stage: 'foreign_session',
|
|
132
|
+
error: ownership
|
|
133
|
+
? `tmux session "${sessionName}" belongs to another CommandMate server`
|
|
134
|
+
: `Worktree '${worktreeId}' not found; cannot confirm tmux session "${sessionName}" is this server's`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
111
137
|
// Issue #1708: refuse before the first side effect. A prompt dialog does not
|
|
112
138
|
// forward keystrokes to the agent — they accumulate in its own input line — so
|
|
113
139
|
// the message is lost AND the next `respond` has to answer a prompt whose
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Every (CLI tool, instance) pair whose tmux session could belong to a worktree
|
|
4
|
+
* (Issue #1621, extracted for #2866).
|
|
5
|
+
*
|
|
6
|
+
* Shared by the startup passes that predict session names from the database —
|
|
7
|
+
* `worktree-session-reconcile.ts` (ID moves) and `adopt-legacy-sessions.ts`
|
|
8
|
+
* (legacy-name adoption) — so both enumerate the same set.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.collectInstanceTargets = collectInstanceTargets;
|
|
12
|
+
const types_1 = require("../../lib/cli-tools/types");
|
|
13
|
+
const agent_instances_db_1 = require("../../lib/db/agent-instances-db");
|
|
14
|
+
/**
|
|
15
|
+
* The primary instance of every CLI tool, plus every roster row under any of
|
|
16
|
+
* `worktreeIds`.
|
|
17
|
+
*
|
|
18
|
+
* The primary instance of every CLI tool is always included — a worktree that
|
|
19
|
+
* predates the roster (#1000) has no `agent_instances` rows at all yet can
|
|
20
|
+
* absolutely have a running `mcbd-claude-<id>` session.
|
|
21
|
+
*
|
|
22
|
+
* @param db - Database instance (read for the agent roster)
|
|
23
|
+
* @param worktreeIds - The worktree IDs whose roster rows to include
|
|
24
|
+
*/
|
|
25
|
+
function collectInstanceTargets(db, worktreeIds) {
|
|
26
|
+
const seen = new Set();
|
|
27
|
+
const targets = [];
|
|
28
|
+
const add = (cliToolId, instanceId) => {
|
|
29
|
+
const key = `${cliToolId}|${instanceId}`;
|
|
30
|
+
if (seen.has(key))
|
|
31
|
+
return;
|
|
32
|
+
seen.add(key);
|
|
33
|
+
targets.push({ cliToolId, instanceId });
|
|
34
|
+
};
|
|
35
|
+
for (const cliToolId of types_1.CLI_TOOL_IDS)
|
|
36
|
+
add(cliToolId, cliToolId);
|
|
37
|
+
for (const worktreeId of worktreeIds) {
|
|
38
|
+
let instances;
|
|
39
|
+
try {
|
|
40
|
+
instances = (0, agent_instances_db_1.getAgentInstances)(db, worktreeId);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// No agent_instances table (older database) — the primary instances above
|
|
44
|
+
// already cover the pre-roster shape.
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
for (const instance of instances) {
|
|
48
|
+
if ((0, types_1.isCliToolType)(instance.cliTool))
|
|
49
|
+
add(instance.cliTool, instance.id);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return targets;
|
|
53
|
+
}
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* The tmux "surface" CommandMate publishes on its own sessions (Issue #2317).
|
|
4
4
|
*
|
|
5
5
|
* Everything here is a pure argument builder or a pure predicate — no
|
|
6
|
-
* `child_process`, no `@/` path alias,
|
|
7
|
-
* constraints put it here rather than under
|
|
8
|
-
* load-bearing:
|
|
6
|
+
* `child_process`, no `@/` path alias, one constants import and the pure
|
|
7
|
+
* session-name parser. Three constraints put it here rather than under
|
|
8
|
+
* `lib/tmux/`, and all three are load-bearing:
|
|
9
9
|
*
|
|
10
10
|
* 1. **`tsconfig.cli.json` sets `"paths": {}`.** The CLI bundle resolves nothing
|
|
11
11
|
* through `@/…`, so a module the `attach` command needs may only reach the
|
|
@@ -67,6 +67,10 @@ exports.buildRemoveAutoPopupHookArgs = buildRemoveAutoPopupHookArgs;
|
|
|
67
67
|
exports.buildDelegateGeometryCommands = buildDelegateGeometryCommands;
|
|
68
68
|
exports.buildRestoreGeometryCommands = buildRestoreGeometryCommands;
|
|
69
69
|
const tmux_pane_config_1 = require("../../config/tmux-pane-config");
|
|
70
|
+
// Relative on purpose (constraint 1 above). `session-name.ts` is already part of
|
|
71
|
+
// the CLI bundle (`commands/attach.ts` imports it) and reaches nothing through
|
|
72
|
+
// `@/…`, so it costs the bundle nothing new (Issue #2866).
|
|
73
|
+
const session_name_1 = require("../cli-tools/session-name");
|
|
70
74
|
/**
|
|
71
75
|
* Session-name prefix every CommandMate tmux session carries.
|
|
72
76
|
*
|
|
@@ -308,8 +312,9 @@ function isLiveAttachSupported(cliToolId) {
|
|
|
308
312
|
/**
|
|
309
313
|
* Whether a tmux session's NAME says it runs a tool `--live` supports.
|
|
310
314
|
*
|
|
311
|
-
* The session name is `mcbd
|
|
312
|
-
*
|
|
315
|
+
* The session name is `mcbd-[<ns>-]<tool>-<worktree>` and `parseSessionName`
|
|
316
|
+
* reads the tool out of either form (Issue #2866), so this is exact rather
|
|
317
|
+
* than a guess. It exists because
|
|
313
318
|
* the two callers that need the answer — the attach hook script's installer and
|
|
314
319
|
* the response poller — hold a session name and nothing else: a hook fires with
|
|
315
320
|
* tmux formats, and the poller must not pay a tmux round-trip to ask about a
|
|
@@ -320,7 +325,8 @@ function isLiveAttachSupported(cliToolId) {
|
|
|
320
325
|
function isLiveAttachEligibleSession(sessionName) {
|
|
321
326
|
if (!isCommandMateSession(sessionName))
|
|
322
327
|
return false;
|
|
323
|
-
|
|
328
|
+
const cliToolId = (0, session_name_1.parseSessionName)(sessionName)?.cliToolId;
|
|
329
|
+
return cliToolId !== undefined && exports.LIVE_ATTACH_TOOLS.includes(cliToolId);
|
|
324
330
|
}
|
|
325
331
|
/**
|
|
326
332
|
* CLI tools that paint their transcript in the terminal's alternate screen.
|
|
@@ -331,8 +337,9 @@ function isLiveAttachEligibleSession(sessionName) {
|
|
|
331
337
|
* else. `attach` prints its hint for exactly these.
|
|
332
338
|
*
|
|
333
339
|
* Deliberately a local list rather than an import of `usesAlternateScreen()`:
|
|
334
|
-
* this module must stay free of `lib/cli-tools
|
|
335
|
-
*
|
|
340
|
+
* this module must stay free of `lib/cli-tools` beyond the pure
|
|
341
|
+
* `session-name.ts`, whose tool graph the CLI bundle cannot afford (see the
|
|
342
|
+
* module docblock). The two are pinned to each other by
|
|
336
343
|
* `tests/unit/tmux/session-surface-2317.test.ts`, so a tool moving in or out of
|
|
337
344
|
* the alternate screen breaks a test rather than silently dropping the hint.
|
|
338
345
|
*/
|