commandmate 0.39.1 → 0.40.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 +249 -242
- package/.next/app-path-routes-manifest.json +25 -24
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +12 -12
- package/.next/required-server-files.json +1 -1
- package/.next/routes-manifest.json +8 -0
- 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/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.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.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.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.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_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.js +2 -2
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -0
- 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 +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_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 +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_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_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/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.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +1 -1
- package/.next/server/app/sessions/page.js.nft.json +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page_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 +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 +25 -24
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/252.js +1 -0
- package/.next/server/chunks/2816.js +1 -1
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3323.js +1 -1
- package/.next/server/chunks/4443.js +1 -1
- package/.next/server/chunks/5164.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/650.js +1 -1
- package/.next/server/chunks/6661.js +1 -1
- package/.next/server/chunks/6793.js +1 -1
- package/.next/server/chunks/7685.js +1 -1
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8581.js +29 -29
- package/.next/server/chunks/8673.js +14 -0
- package/.next/server/chunks/8728.js +4 -3
- package/.next/server/chunks/8800.js +1 -1
- package/.next/server/chunks/9080.js +1 -1
- package/.next/server/chunks/9731.js +2 -2
- 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-9ac8b6188ddbb119.js → 2407-d750620d0511e94f.js} +1 -1
- package/.next/static/chunks/4768-979c8a03bed218e7.js +1 -0
- package/.next/static/chunks/7705-25076b57224da370.js +1 -0
- package/.next/static/chunks/8606-9a381b996f9b6834.js +1 -0
- package/.next/static/chunks/9619-22adf5367c4b7080.js +1 -0
- package/.next/static/chunks/app/api/agents/update/{route-70779af8b4c8259a.js → route-0468c3c4baa46028.js} +1 -1
- package/.next/static/chunks/app/api/agents/versions/{route-70779af8b4c8259a.js → route-0468c3c4baa46028.js} +1 -1
- package/.next/static/chunks/app/api/app/release-notes/{route-70779af8b4c8259a.js → route-0468c3c4baa46028.js} +1 -1
- package/.next/static/chunks/app/api/app/update/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/app/update-check/{route-70779af8b4c8259a.js → route-0468c3c4baa46028.js} +1 -1
- package/.next/static/chunks/app/api/auth/login/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/auth/status/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/capabilities/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/status/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/external-apps/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/fs/browse/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/fs/recent-paths/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/hooks/agent-event/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/hooks/claude-done/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/hooks/permission-request/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/metrics/vibe/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/ollama/models/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/push/escalation/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/push/subscriptions/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/push/vapid/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/relays/[relayId]/cancel/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/relays/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/remote/pair/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/repositories/excluded/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/repositories/restore/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/repositories/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/repositories/scan/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/repositories/sync/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/repositories/validate-path/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/settings/default-agents/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/settings/default-surface-mode/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/sidebar/group-order/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/skills/[id]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/skills/installations/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/skills/operations/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/skills/reindex/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/skills/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/slash-commands/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/templates/[id]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/templates/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/direct-input/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/instances/notes/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/layout-3d3fcc8aac7b3bb5.js +1 -0
- package/.next/static/chunks/app/manifest.webmanifest/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/proxy/[...path]/route-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/review/page-30616daa1dc595c2.js +1 -0
- package/.next/static/chunks/app/sessions/page-1a8ba152bbcb9efb.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/layout-0468c3c4baa46028.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-a91e812ad9d94697.js +1 -0
- package/.next/static/css/974314e796232f53.css +1 -0
- package/.next/trace +13 -13
- package/.next/types/app/api/worktrees/[id]/direct-input/route.ts +347 -0
- package/.next/types/routes.d.ts +2 -1
- package/.next/types/validator.ts +9 -0
- package/dist/cli/commands/ls.d.ts.map +1 -1
- package/dist/cli/commands/ls.js +9 -0
- package/dist/cli/commands/peers.d.ts.map +1 -1
- package/dist/cli/commands/peers.js +4 -0
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +20 -6
- package/dist/cli/config/model-validation.d.ts +22 -0
- package/dist/cli/config/model-validation.d.ts.map +1 -1
- package/dist/cli/config/model-validation.js +35 -1
- package/dist/cli/types/api-responses.d.ts +11 -0
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/lib/detection/status-reason.d.ts +13 -0
- package/dist/lib/detection/status-reason.d.ts.map +1 -1
- package/dist/lib/detection/status-reason.js +13 -0
- package/dist/lib/detection/tools/verified-against.d.ts +74 -5
- package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
- package/dist/lib/detection/tools/verified-against.js +74 -5
- package/dist/server/locales/en/worktree.json +58 -0
- package/dist/server/locales/ja/worktree.json +58 -0
- package/dist/server/src/config/claude-constants.js +27 -0
- package/dist/server/src/lib/cli-tools/base.js +2 -1
- package/dist/server/src/lib/cli-tools/claude.js +5 -1
- package/dist/server/src/lib/cli-tools/command-code.js +5 -1
- package/dist/server/src/lib/cli-tools/direct-input.js +22 -0
- package/dist/server/src/lib/cmate-cli-tool-parser.js +31 -0
- package/dist/server/src/lib/detection/cli-patterns.js +44 -5
- package/dist/server/src/lib/detection/model-info-extractor.js +49 -10
- package/dist/server/src/lib/detection/selection-shape.js +274 -19
- package/dist/server/src/lib/detection/status-detector.js +2 -0
- package/dist/server/src/lib/detection/status-reason.js +13 -0
- package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +67 -27
- package/dist/server/src/lib/detection/tools/codex/detect.js +18 -3
- package/dist/server/src/lib/detection/tools/command-code/detect.js +46 -0
- package/dist/server/src/lib/detection/tools/command-code/dialog.js +116 -25
- package/dist/server/src/lib/detection/tools/verified-against.js +74 -5
- package/dist/server/src/lib/detection/tui-detection-frame.js +18 -3
- package/dist/server/src/lib/polling/auto-yes-resolver.js +8 -0
- package/dist/server/src/lib/prompt-answer-sender.js +255 -1
- package/dist/server/src/lib/realtime-snippet.js +53 -0
- package/dist/server/src/lib/session/agent-event-state.js +8 -1
- package/dist/server/src/lib/session/claude-session.js +19 -2
- package/dist/server/src/lib/session/current-output-builder.js +4 -1
- package/dist/server/src/lib/session/status-mapping.js +58 -8
- package/dist/server/src/lib/tmux/key-sequence.js +27 -1
- package/dist/server/src/lib/tmux/tmux-control-client.js +26 -3
- package/dist/server/src/lib/tmux/tmux.js +64 -3
- package/dist/server/src/types/direct-input.js +113 -0
- package/dist/server/src/types/sidebar.js +67 -7
- package/dist/server/src/types/terminal-keys.js +33 -1
- package/dist/types/terminal-keys.d.ts +28 -1
- package/dist/types/terminal-keys.d.ts.map +1 -1
- package/dist/types/terminal-keys.js +33 -1
- package/package.json +1 -1
- package/release-notes/0.40.0.json +69 -0
- package/release-notes/0.40.1.json +20 -0
- package/.next/server/chunks/6092.js +0 -14
- package/.next/static/chunks/4768-0ad5eb716bed5de9.js +0 -1
- package/.next/static/chunks/8606-e893c1dab6fb81bc.js +0 -1
- package/.next/static/chunks/9619-7bc0e9524f0773b5.js +0 -1
- package/.next/static/chunks/982-edf98d9d54c5ce9b.js +0 -1
- package/.next/static/chunks/app/api/app/update/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/auth/login/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/auth/status/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/capabilities/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/status/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/external-apps/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/fs/browse/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/fs/recent-paths/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/hooks/agent-event/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/hooks/claude-done/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/hooks/permission-request/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/metrics/vibe/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/ollama/models/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/push/escalation/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/push/subscriptions/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/push/vapid/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/relays/[relayId]/cancel/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/relays/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/remote/pair/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/repositories/excluded/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/repositories/restore/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/repositories/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/repositories/scan/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/repositories/sync/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/repositories/validate-path/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/settings/default-agents/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/settings/default-surface-mode/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/sidebar/group-order/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/skills/[id]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/skills/installations/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/skills/operations/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/skills/reindex/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/skills/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/slash-commands/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/templates/[id]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/templates/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/instances/notes/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/layout-542d075e9d7cc541.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/proxy/[...path]/route-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/review/page-8ed49e2edcc7667b.js +0 -1
- package/.next/static/chunks/app/sessions/page-56f6a2466dd0479d.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/layout-70779af8b4c8259a.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-760408096ad697b4.js +0 -1
- package/.next/static/css/b4aaf81d10efdd00.css +0 -1
- /package/.next/static/{7Ge9-hsqlip_Z6bhEnVkd → JfzIPPhL-ikSVcJYOKgfD}/_buildManifest.js +0 -0
- /package/.next/static/{7Ge9-hsqlip_Z6bhEnVkd → JfzIPPhL-ikSVcJYOKgfD}/_ssgManifest.js +0 -0
|
@@ -7,17 +7,35 @@
|
|
|
7
7
|
* the promptType/defaultOptionNumber fallback introduced in Bug1).
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.FreeTextAtChoiceOnlyPromptError = exports.FreeTextAnswerRejectedError = exports.FREE_TEXT_AT_MENU_ROW_REASON = exports.PromptAnswerRejectedError = exports.ANSWER_MODE_KEYS_REASON = void 0;
|
|
10
|
+
exports.MultiSelectAnswerRejectedError = exports.MULTI_SELECT_NOT_COMMITTED_REASON = exports.FreeTextAtChoiceOnlyPromptError = exports.FreeTextAnswerRejectedError = exports.FREE_TEXT_AT_MENU_ROW_REASON = exports.PromptAnswerRejectedError = exports.ANSWER_MODE_KEYS_REASON = void 0;
|
|
11
11
|
exports.sendPromptAnswer = sendPromptAnswer;
|
|
12
12
|
const tmux_1 = require("./tmux/tmux");
|
|
13
13
|
const frame_1 = require("../lib/detection/tools/frame");
|
|
14
14
|
const registry_1 = require("../lib/detection/tools/registry");
|
|
15
15
|
const prompt_detect_multiple_choice_1 = require("../lib/detection/prompt-detect-multiple-choice");
|
|
16
|
+
const dialog_1 = require("../lib/detection/tools/command-code/dialog");
|
|
17
|
+
const selection_shape_1 = require("../lib/detection/selection-shape");
|
|
16
18
|
const models_1 = require("../types/models");
|
|
17
19
|
const tmux_capture_cache_1 = require("./tmux/tmux-capture-cache");
|
|
18
20
|
const cli_tool_timing_config_1 = require("../config/cli-tool-timing-config");
|
|
19
21
|
/** Regex pattern to detect checkbox-style multi-select options */
|
|
20
22
|
const CHECKBOX_OPTION_PATTERN = /^\[[ x]\] /;
|
|
23
|
+
/**
|
|
24
|
+
* A validated SELECTION SET, as opposed to free text (Issue #2755).
|
|
25
|
+
*
|
|
26
|
+
* `"1,3"` does not match `/^\d+$/`, which is the shape every guard in this
|
|
27
|
+
* module asks "is this a number?" with — so without this the answer for a
|
|
28
|
+
* checkbox question would be judged, and refused, as free text aimed at a menu
|
|
29
|
+
* row (#2573 / #2583 / #2584). The set is recognised BEFORE those guards run
|
|
30
|
+
* and takes its own arm; none of them is loosened, and every other answer still
|
|
31
|
+
* meets them exactly as it did.
|
|
32
|
+
*
|
|
33
|
+
* Deliberately strict: digits and single commas, no spaces, no empty members.
|
|
34
|
+
* `/prompt-response` normalises what it accepts into this spelling and refuses
|
|
35
|
+
* anything else with nothing sent, so a string reaching here is one the route
|
|
36
|
+
* has already range-checked against the option list on the FRESH frame.
|
|
37
|
+
*/
|
|
38
|
+
const SELECTION_SET_PATTERN = /^\d+(?:,\d+)*$/;
|
|
21
39
|
/**
|
|
22
40
|
* The reason code a caller gets back when a digit meets a `keys`-mode dialog
|
|
23
41
|
* (Issue #2033).
|
|
@@ -498,6 +516,229 @@ function assertFreeTextCursorIsOnTheField(params) {
|
|
|
498
516
|
return;
|
|
499
517
|
throw new FreeTextAnswerRejectedError(params.cliToolId, fields.map((option) => option.number), { kind: 'cursor_elsewhere', cursorOptionNumber: cursor.number });
|
|
500
518
|
}
|
|
519
|
+
/**
|
|
520
|
+
* The reason code every Command Code multi-select refusal carries
|
|
521
|
+
* (Issue #2755).
|
|
522
|
+
*
|
|
523
|
+
* Shares the shape of {@link ANSWER_MODE_KEYS_REASON} and
|
|
524
|
+
* {@link FREE_TEXT_AT_MENU_ROW_REASON} — a machine-readable code the API and
|
|
525
|
+
* `respond` branch on — and means one thing: **the question was not
|
|
526
|
+
* committed.** What varies is how far the arm got, which
|
|
527
|
+
* {@link MultiSelectAnswerRejectedError.stage} says.
|
|
528
|
+
*/
|
|
529
|
+
exports.MULTI_SELECT_NOT_COMMITTED_REASON = 'multi_select_not_committed';
|
|
530
|
+
/**
|
|
531
|
+
* A Command Code checkbox answer that did not reach the agent (Issue #2755).
|
|
532
|
+
*
|
|
533
|
+
* The sibling of {@link PromptAnswerRejectedError} for the two-stage confirm.
|
|
534
|
+
* Unlike that one it does NOT always promise an untouched pane — ticking boxes
|
|
535
|
+
* is the first half of this answer and it may already have happened — so
|
|
536
|
+
* {@link keysSent} says which of the two the caller is looking at. What it does
|
|
537
|
+
* promise in every case is that the question was **not submitted**: the arm
|
|
538
|
+
* stops before the confirm row whenever the screen it re-read is not the one it
|
|
539
|
+
* was asked to answer.
|
|
540
|
+
*
|
|
541
|
+
* Fixed text, a tool id and option numbers only (SEC-003, as in
|
|
542
|
+
* `prompt-answer-semantic`): `/prompt-response` returns this message verbatim.
|
|
543
|
+
*/
|
|
544
|
+
class MultiSelectAnswerRejectedError extends Error {
|
|
545
|
+
/** Machine-readable code, always {@link MULTI_SELECT_NOT_COMMITTED_REASON}. */
|
|
546
|
+
reason;
|
|
547
|
+
stage;
|
|
548
|
+
/** Whether any key reached the pane before the refusal. */
|
|
549
|
+
keysSent;
|
|
550
|
+
/** The set the caller asked for, ascending. */
|
|
551
|
+
wanted;
|
|
552
|
+
constructor(stage, keysSent, wanted) {
|
|
553
|
+
super(`The question was not submitted (${stage}). `
|
|
554
|
+
+ (keysSent
|
|
555
|
+
? 'Some boxes may have been ticked, but the confirm row was not pressed, so the '
|
|
556
|
+
+ 'question is still on screen exactly as the pane shows it. '
|
|
557
|
+
: 'No key was sent. ')
|
|
558
|
+
+ `Requested selection: ${wanted.join(', ')}. Check the terminal and answer it there, or `
|
|
559
|
+
+ 'retry once the screen has settled.');
|
|
560
|
+
this.name = 'MultiSelectAnswerRejectedError';
|
|
561
|
+
this.reason = exports.MULTI_SELECT_NOT_COMMITTED_REASON;
|
|
562
|
+
this.stage = stage;
|
|
563
|
+
this.keysSent = keysSent;
|
|
564
|
+
this.wanted = wanted;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
exports.MultiSelectAnswerRejectedError = MultiSelectAnswerRejectedError;
|
|
568
|
+
/**
|
|
569
|
+
* Is this request a Command Code checkbox answer? (Issue #2755)
|
|
570
|
+
*
|
|
571
|
+
* Three conditions, all of them about the FRESH reading rather than about the
|
|
572
|
+
* caller's claim: the tool, the payload's own `multiSelect` and the shape of
|
|
573
|
+
* the answer. `promptData` here is what `/prompt-response` re-verified against
|
|
574
|
+
* the pane a moment ago, which is why this arm may act on `option.checked`
|
|
575
|
+
* without taking a capture of its own first.
|
|
576
|
+
*
|
|
577
|
+
* A bare `"2"` counts. On a `multiSelect: true` payload the digit is a TOGGLE,
|
|
578
|
+
* so "the answer is 2" is not an available reading of it — which is the half of
|
|
579
|
+
* 確定仕様 5 this function owns; the other half, telling a one-item checkbox
|
|
580
|
+
* answer apart from a single-select one, is a request-shape question and lives
|
|
581
|
+
* in the route.
|
|
582
|
+
*/
|
|
583
|
+
function readMultiSelectRequest(params) {
|
|
584
|
+
if (params.cliToolId !== 'command-code')
|
|
585
|
+
return null;
|
|
586
|
+
const { promptData } = params;
|
|
587
|
+
if (promptData?.type !== 'multiple_choice')
|
|
588
|
+
return null;
|
|
589
|
+
if (promptData.multiSelect !== true)
|
|
590
|
+
return null;
|
|
591
|
+
if (!SELECTION_SET_PATTERN.test(params.answer))
|
|
592
|
+
return null;
|
|
593
|
+
const wanted = [...new Set(params.answer.split(',').map(Number))].sort((a, b) => a - b);
|
|
594
|
+
return { promptData, wanted };
|
|
595
|
+
}
|
|
596
|
+
/** `Down` this many times, as {@link sendSpecialKeys} names the key. */
|
|
597
|
+
function downKeys(count) {
|
|
598
|
+
return Array.from({ length: Math.max(0, count) }, () => 'Down');
|
|
599
|
+
}
|
|
600
|
+
/** The ticked option numbers of a reading, ascending. */
|
|
601
|
+
function tickedNumbers(promptData) {
|
|
602
|
+
return promptData.options.filter((o) => o.checked === true).map((o) => o.number);
|
|
603
|
+
}
|
|
604
|
+
function sameNumbers(a, b) {
|
|
605
|
+
return a.length === b.length && a.every((value, index) => value === b[index]);
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Re-read the pane after a keystroke, or null when it cannot be read.
|
|
609
|
+
*
|
|
610
|
+
* `capturePane` here rather than the caller's `frame`: the whole point of the
|
|
611
|
+
* read is that the screen has moved since. {@link TUI_MESSAGE_PROCESSED_WAIT_MS}
|
|
612
|
+
* is the settle the rest of this file already uses for a TUI that has just been
|
|
613
|
+
* typed at.
|
|
614
|
+
*/
|
|
615
|
+
async function recaptureAfterKeys(sessionName) {
|
|
616
|
+
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_MESSAGE_PROCESSED_WAIT_MS));
|
|
617
|
+
try {
|
|
618
|
+
return await (0, tmux_1.capturePane)(sessionName, GUARD_CAPTURE_LINES);
|
|
619
|
+
}
|
|
620
|
+
catch {
|
|
621
|
+
return null;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Answer Command Code's checkbox `AskUserQuestion` (Issue #2755 §6 / §7).
|
|
626
|
+
*
|
|
627
|
+
* ## What the keys mean, measured
|
|
628
|
+
*
|
|
629
|
+
* Every line below is from #2754's twenty-six live captures
|
|
630
|
+
* (`docs/design/command-code-1541-askuserquestion.md` §4), taken one keystroke
|
|
631
|
+
* at a time with a capture on each side:
|
|
632
|
+
*
|
|
633
|
+
* | key | on this screen |
|
|
634
|
+
* |---|---|
|
|
635
|
+
* | `1`–`9` | **toggles** that box. The cursor does not move. Dead while the `❯` is off the list |
|
|
636
|
+
* | `Enter` on an option row | toggles that row. It is NOT a confirm |
|
|
637
|
+
* | `Enter` on `Submit` / `Next` | opens the **Review page**, or advances to the next question. Still not a send |
|
|
638
|
+
* | `Enter` on the Review page's `❯ 1. Submit` | **this** is where the answer is sent |
|
|
639
|
+
* | `Space` | works, but from `Submit` it ticked a row the cursor was nowhere near. Not sent |
|
|
640
|
+
* | `Esc` / `c` / `d` / `n` | cancel, send-as-chat, finish, mode switch. One keystroke each, no confirmation. Not sent |
|
|
641
|
+
*
|
|
642
|
+
* So the sequence is: **toggle the symmetric difference → walk down to the
|
|
643
|
+
* confirm row → Enter → confirm on the Review page.** The confirm is two stages
|
|
644
|
+
* and an implementation that stopped at the first one would report an answer
|
|
645
|
+
* the agent never received.
|
|
646
|
+
*
|
|
647
|
+
* ## Why a symmetric difference and not "press the numbers"
|
|
648
|
+
*
|
|
649
|
+
* The answer is the SET the operator wants ticked, not a list of toggles. A row
|
|
650
|
+
* the human already ticked in the terminal is `[✔]` on the frame, and pressing
|
|
651
|
+
* its number would turn it OFF; a row they want off but that is already on has
|
|
652
|
+
* to be pressed even though it is not in the answer. `current` comes from
|
|
653
|
+
* `option.checked` on the payload `/prompt-response` verified against the pane
|
|
654
|
+
* moments earlier, so both halves are read rather than assumed.
|
|
655
|
+
*
|
|
656
|
+
* ## Why it re-reads before the confirm
|
|
657
|
+
*
|
|
658
|
+
* Because a toggle is only measured to work while the cursor is in the list,
|
|
659
|
+
* and nothing on the frame proves the tool accepted the keystroke. Confirming a
|
|
660
|
+
* set nobody verified is the failure this whole Issue is about, one screen
|
|
661
|
+
* later. If the re-read does not equal the request, the confirm is not pressed
|
|
662
|
+
* and the operator gets the pane back exactly as it is.
|
|
663
|
+
*
|
|
664
|
+
* @throws {MultiSelectAnswerRejectedError} whenever the question was not
|
|
665
|
+
* committed; `keysSent` says whether the pane was touched.
|
|
666
|
+
*/
|
|
667
|
+
async function sendCommandCodeMultiSelectAnswer(sessionName, promptData, wanted) {
|
|
668
|
+
const cursor = promptData.options.find((option) => option.isDefault === true);
|
|
669
|
+
if (cursor === undefined) {
|
|
670
|
+
throw new MultiSelectAnswerRejectedError('cursor-unknown', false, wanted);
|
|
671
|
+
}
|
|
672
|
+
// 1. The symmetric difference, ascending, one digit per press. An empty one
|
|
673
|
+
// sends nothing at all — the set on screen is already the set asked for,
|
|
674
|
+
// and the only thing left to do is commit it.
|
|
675
|
+
const current = tickedNumbers(promptData);
|
|
676
|
+
const toggles = [
|
|
677
|
+
...wanted.filter((n) => !current.includes(n)),
|
|
678
|
+
...current.filter((n) => !wanted.includes(n)),
|
|
679
|
+
].sort((a, b) => a - b);
|
|
680
|
+
if (toggles.length > 0) {
|
|
681
|
+
await (0, tmux_1.sendSpecialKeys)(sessionName, toggles.map(String));
|
|
682
|
+
}
|
|
683
|
+
const keysSent = toggles.length > 0;
|
|
684
|
+
// 2. Read the screen back and refuse unless it is the same question with
|
|
685
|
+
// exactly the requested boxes ticked.
|
|
686
|
+
const afterToggle = await recaptureAfterKeys(sessionName);
|
|
687
|
+
if (afterToggle === null) {
|
|
688
|
+
throw new MultiSelectAnswerRejectedError('recapture-failed', keysSent, wanted);
|
|
689
|
+
}
|
|
690
|
+
const reading = (0, dialog_1.readCommandCodeQuestionDialog)(afterToggle);
|
|
691
|
+
if (reading.kind !== 'prompt' ||
|
|
692
|
+
reading.prompt.promptData?.type !== 'multiple_choice' ||
|
|
693
|
+
reading.prompt.promptData.multiSelect !== true ||
|
|
694
|
+
reading.prompt.promptData.question !== promptData.question ||
|
|
695
|
+
reading.prompt.promptData.options.length !== promptData.options.length) {
|
|
696
|
+
throw new MultiSelectAnswerRejectedError('screen-changed', keysSent, wanted);
|
|
697
|
+
}
|
|
698
|
+
const verified = reading.prompt.promptData;
|
|
699
|
+
if (!sameNumbers(tickedNumbers(verified), [...wanted])) {
|
|
700
|
+
throw new MultiSelectAnswerRejectedError('toggle-mismatch', keysSent, wanted);
|
|
701
|
+
}
|
|
702
|
+
// 3. Walk to the confirm row and open it. `Down` is the only movement key
|
|
703
|
+
// measured to be deterministic here: it steps one row at a time through
|
|
704
|
+
// the options, then the free-text row, then stops on `Submit` / `Next`.
|
|
705
|
+
// (`Up` from option 1 goes to two different rows depending on whether the
|
|
706
|
+
// list has ever reported a highlight — invisible on the frame.) The cursor
|
|
707
|
+
// is re-read rather than reused, because the request is allowed to have
|
|
708
|
+
// been built from a slightly older frame.
|
|
709
|
+
const cursorNow = verified.options.find((option) => option.isDefault === true);
|
|
710
|
+
if (cursorNow === undefined) {
|
|
711
|
+
throw new MultiSelectAnswerRejectedError('cursor-unknown', keysSent, wanted);
|
|
712
|
+
}
|
|
713
|
+
await (0, tmux_1.sendSpecialKeys)(sessionName, [
|
|
714
|
+
...downKeys(verified.options.length - cursorNow.number + 1),
|
|
715
|
+
'Enter',
|
|
716
|
+
]);
|
|
717
|
+
// 4. The second stage. `Submit` opens the Review page and the answer is sent
|
|
718
|
+
// from there; `Next` advances to the following question, which IS the
|
|
719
|
+
// commit for this one (its tab turns `✔`).
|
|
720
|
+
const afterConfirm = await recaptureAfterKeys(sessionName);
|
|
721
|
+
if (afterConfirm === null) {
|
|
722
|
+
throw new MultiSelectAnswerRejectedError('recapture-failed', true, wanted);
|
|
723
|
+
}
|
|
724
|
+
const review = (0, selection_shape_1.readCommandCodeReviewPage)(afterConfirm);
|
|
725
|
+
if (review !== null) {
|
|
726
|
+
// Reached with answers still missing — the `d` shape. Confirming it would
|
|
727
|
+
// send `No answer` for questions nobody has been shown (Issue #2755 §7).
|
|
728
|
+
if (review.hasUnansweredWarning) {
|
|
729
|
+
throw new MultiSelectAnswerRejectedError('review-unanswered', true, wanted);
|
|
730
|
+
}
|
|
731
|
+
await (0, tmux_1.sendSpecialKeys)(sessionName, ['Enter']);
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
const next = (0, dialog_1.readCommandCodeQuestionDialog)(afterConfirm);
|
|
735
|
+
const advanced = next.kind === 'prompt' &&
|
|
736
|
+
next.prompt.promptData?.type === 'multiple_choice' &&
|
|
737
|
+
next.prompt.promptData.question !== promptData.question;
|
|
738
|
+
if (!advanced) {
|
|
739
|
+
throw new MultiSelectAnswerRejectedError('not-committed', true, wanted);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
501
742
|
/**
|
|
502
743
|
* Send an answer to a tmux session, using cursor-key navigation for
|
|
503
744
|
* Claude Code / Antigravity multiple-choice prompts and text input for
|
|
@@ -509,6 +750,19 @@ function assertFreeTextCursorIsOnTheField(params) {
|
|
|
509
750
|
*/
|
|
510
751
|
async function sendPromptAnswer(params) {
|
|
511
752
|
const { sessionName, answer, cliToolId, promptData, fallbackPromptType, fallbackDefaultOptionNumber } = params;
|
|
753
|
+
// Issue #2755: Command Code's checkbox question, before every guard below.
|
|
754
|
+
// Its answer is a SET (`"1,3"`), which none of them can read — `/^\d+$/` is
|
|
755
|
+
// how all three ask "is this a number?", so a set would be judged as free
|
|
756
|
+
// text and refused as text aimed at a menu row. The arm is entered only on a
|
|
757
|
+
// reading that says `multiSelect: true`, so nothing else's path moves, and it
|
|
758
|
+
// returns rather than falling through: what this screen needs is toggles and
|
|
759
|
+
// a two-stage confirm, not a digit and an Enter.
|
|
760
|
+
const multiSelect = readMultiSelectRequest(params);
|
|
761
|
+
if (multiSelect !== null) {
|
|
762
|
+
await sendCommandCodeMultiSelectAnswer(sessionName, multiSelect.promptData, multiSelect.wanted);
|
|
763
|
+
(0, tmux_capture_cache_1.invalidateCache)(sessionName);
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
512
766
|
// Issue #2033: before ANY key is chosen, let the tool's own dialog rules
|
|
513
767
|
// refuse a digit its dialog cannot take. Placed above the branch rather than
|
|
514
768
|
// inside the text arm because the number->offset arithmetic the cursor arm
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The rows `CurrentOutputPayload.realtimeSnippet` publishes (Issue #2768).
|
|
4
|
+
*
|
|
5
|
+
* The snippet has always been "the last 100 rows of the capture". CommandMate
|
|
6
|
+
* pins agent panes to 200x1000, and an inline tool (codex, antigravity, Command
|
|
7
|
+
* Code, gemini, vibe-local) paints from the TOP of that canvas: until a session
|
|
8
|
+
* has scrolled a thousand rows, everything it has drawn sits in rows 1..N and
|
|
9
|
+
* rows N+1..1000 are blank. The last 100 rows of such a capture are 100 empty
|
|
10
|
+
* strings — measured on a live Command Code pane whose content ended at row 173.
|
|
11
|
+
*
|
|
12
|
+
* So the window is anchored to the last row that carries content, but ONLY when
|
|
13
|
+
* the plain tail window is entirely blank. Any frame whose last 100 rows hold so
|
|
14
|
+
* much as one glyph is returned exactly as before, which is every bottom-anchored
|
|
15
|
+
* (alternate-screen) tool and every inline session that has filled its canvas.
|
|
16
|
+
*
|
|
17
|
+
* Browser-safe on purpose: the server builds the payload with it and
|
|
18
|
+
* `useTerminalPanePolling` rebuilds the same field from a pushed snapshot, and
|
|
19
|
+
* the two must not be able to disagree about one frame.
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.REALTIME_SNIPPET_ROW_COUNT = void 0;
|
|
23
|
+
exports.selectRealtimeSnippetRows = selectRealtimeSnippetRows;
|
|
24
|
+
exports.buildRealtimeSnippet = buildRealtimeSnippet;
|
|
25
|
+
const ansi_1 = require("../lib/detection/ansi");
|
|
26
|
+
/** Rows in the snippet. The 100 that Issue #1839 / #2095 read their verdicts off. */
|
|
27
|
+
exports.REALTIME_SNIPPET_ROW_COUNT = 100;
|
|
28
|
+
function isBlankRow(row) {
|
|
29
|
+
return (0, ansi_1.stripAnsi)(row).trim() === '';
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Pick the snippet rows out of a capture already split on `\n`.
|
|
33
|
+
*
|
|
34
|
+
* @param lines - every row of the capture, in order
|
|
35
|
+
* @returns at most {@link REALTIME_SNIPPET_ROW_COUNT} rows
|
|
36
|
+
*/
|
|
37
|
+
function selectRealtimeSnippetRows(lines) {
|
|
38
|
+
const tail = lines.slice(-exports.REALTIME_SNIPPET_ROW_COUNT);
|
|
39
|
+
if (tail.some((row) => !isBlankRow(row)))
|
|
40
|
+
return tail;
|
|
41
|
+
let last = lines.length - 1;
|
|
42
|
+
while (last >= 0 && isBlankRow(lines[last]))
|
|
43
|
+
last -= 1;
|
|
44
|
+
// Nothing on the pane at all: the old answer (a run of blank rows) is as good
|
|
45
|
+
// as any, and keeping it means an empty pane is reported exactly as before.
|
|
46
|
+
if (last < 0)
|
|
47
|
+
return tail;
|
|
48
|
+
return lines.slice(Math.max(0, last + 1 - exports.REALTIME_SNIPPET_ROW_COUNT), last + 1);
|
|
49
|
+
}
|
|
50
|
+
/** {@link selectRealtimeSnippetRows}, joined the way the payload carries it. */
|
|
51
|
+
function buildRealtimeSnippet(output) {
|
|
52
|
+
return selectRealtimeSnippetRows(output.split('\n')).join('\n');
|
|
53
|
+
}
|
|
@@ -1363,6 +1363,13 @@ function getLastKnownAgentModel(worktreeId, cliToolId, instanceId) {
|
|
|
1363
1363
|
* which is the honest state for gemini/copilot and for any session whose chrome
|
|
1364
1364
|
* this module has no rule for.
|
|
1365
1365
|
*
|
|
1366
|
+
* **The one exception is an effort the frame shows but cannot name** (Issue
|
|
1367
|
+
* #2835, `info.effortUnreadable`). A codex bar that draws `default` or a
|
|
1368
|
+
* model-defined value where `xhigh` used to be is not "not showing" the effort
|
|
1369
|
+
* — it is showing a different one. Keeping `xhigh` would publish a value the
|
|
1370
|
+
* session is no longer running at, so the effort half is dropped to null and
|
|
1371
|
+
* the model half latches as usual.
|
|
1372
|
+
*
|
|
1366
1373
|
* @param info - {@link import('../../lib/detection/model-info-extractor').extractModelInfo}'s answer
|
|
1367
1374
|
*/
|
|
1368
1375
|
function recordCapturedModelInfo(worktreeId, cliToolId, instanceId, info, at = Date.now()) {
|
|
@@ -1373,7 +1380,7 @@ function recordCapturedModelInfo(worktreeId, cliToolId, instanceId, info, at = D
|
|
|
1373
1380
|
const model = info.model ? info.model.slice(0, agent_event_types_1.MAX_EVENT_DETAIL_LENGTH) : (previous?.model ?? null);
|
|
1374
1381
|
capturedModelInfo.set(key, {
|
|
1375
1382
|
model,
|
|
1376
|
-
effort: info.effort ?? previous?.effort ?? null,
|
|
1383
|
+
effort: info.effortUnreadable ? null : (info.effort ?? previous?.effort ?? null),
|
|
1377
1384
|
// Issue #2361: the change stamp moves only when the model half takes a
|
|
1378
1385
|
// different value. A banner re-read on every poll keeps the stamp where the
|
|
1379
1386
|
// first sighting put it, so it never out-dates a hook by mere repetition.
|
|
@@ -30,6 +30,8 @@ const logger_1 = require("../../lib/logger");
|
|
|
30
30
|
const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
|
|
31
31
|
const types_1 = require("../../lib/cli-tools/types");
|
|
32
32
|
const sources_1 = require("../../lib/hooks/sources");
|
|
33
|
+
const hook_settings_generator_1 = require("../../lib/hooks/hook-settings-generator");
|
|
34
|
+
const cmate_cli_tool_parser_1 = require("../../lib/cmate-cli-tool-parser");
|
|
33
35
|
const agent_session_lifecycle_1 = require("../../lib/session/agent-session-lifecycle");
|
|
34
36
|
const agent_event_state_1 = require("../../lib/session/agent-event-state");
|
|
35
37
|
const session_start_error_1 = require("../../lib/session/session-start-error");
|
|
@@ -465,7 +467,16 @@ async function waitForPrompt(sessionName, timeout = exports.CLAUDE_PROMPT_WAIT_T
|
|
|
465
467
|
* ```
|
|
466
468
|
*/
|
|
467
469
|
async function startClaudeSession(options) {
|
|
468
|
-
const { worktreeId, worktreePath, instanceId } = options;
|
|
470
|
+
const { worktreeId, worktreePath, instanceId, model } = options;
|
|
471
|
+
// Issue #2771: the model is about to be typed into a shell. The route and the
|
|
472
|
+
// CLI have both validated it already; this is the copy that cannot be
|
|
473
|
+
// forgotten by a future caller, and it runs before anything is created.
|
|
474
|
+
if (model !== undefined) {
|
|
475
|
+
const modelValidation = (0, cmate_cli_tool_parser_1.validateClaudeModelName)(model);
|
|
476
|
+
if (!modelValidation.valid) {
|
|
477
|
+
throw new Error(`Invalid Claude model name: ${modelValidation.reason}`);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
469
480
|
// Check if Claude is installed
|
|
470
481
|
const claudeAvailable = await isClaudeInstalled();
|
|
471
482
|
if (!claudeAvailable) {
|
|
@@ -532,11 +543,17 @@ async function startClaudeSession(options) {
|
|
|
532
543
|
// Issue #1759: which config file gets written, and whether one is written
|
|
533
544
|
// at all, belongs to the tool's `AgentEventSource` (S3/S4). Claude's
|
|
534
545
|
// delegates to `buildClaudeLaunchCommand`, unchanged.
|
|
535
|
-
const
|
|
546
|
+
const baseLaunchCommand = (0, agent_session_lifecycle_1.buildAgentLaunchCommandLine)({
|
|
536
547
|
target: { worktreeId, cliToolId: sources_1.CLAUDE_CLI_TOOL_ID, instanceId },
|
|
537
548
|
executablePath: claudePath,
|
|
538
549
|
worktreePath,
|
|
539
550
|
});
|
|
551
|
+
// Issue #2771: `--model` goes AFTER the rendered line, the shape
|
|
552
|
+
// `AntigravityTool` uses, so the env assignments stay in front of the
|
|
553
|
+
// executable. Single-quoted because `opus[1m]` is a glob to the pane's zsh.
|
|
554
|
+
// The flag outranks a `model` in the worktree's `.claude/settings.local.json`
|
|
555
|
+
// and the operator's `~/.claude/settings.json` (measured on 2.1.278).
|
|
556
|
+
const launchCommand = model === undefined ? baseLaunchCommand : `${baseLaunchCommand} --model ${(0, hook_settings_generator_1.shellQuote)(model)}`;
|
|
540
557
|
// Start Claude CLI in interactive mode using dynamically resolved path
|
|
541
558
|
await (0, tmux_1.sendKeys)(sessionName, launchCommand, true);
|
|
542
559
|
// Wait for Claude to initialize with dynamic detection (OCP-001)
|
|
@@ -79,6 +79,7 @@ const auto_yes_suppression_state_1 = require("../../lib/polling/auto-yes-suppres
|
|
|
79
79
|
const prompt_dedup_state_1 = require("../../lib/polling/prompt-dedup-state");
|
|
80
80
|
const status_capture_config_1 = require("../../config/status-capture-config");
|
|
81
81
|
const tmux_capture_cache_1 = require("../../lib/tmux/tmux-capture-cache");
|
|
82
|
+
const realtime_snippet_1 = require("../../lib/realtime-snippet");
|
|
82
83
|
const agent_event_state_1 = require("../../lib/session/agent-event-state");
|
|
83
84
|
const prompt_waiting_composition_1 = require("../../lib/session/prompt-waiting-composition");
|
|
84
85
|
const provisional_turn_1 = require("../../lib/session/provisional-turn");
|
|
@@ -1052,7 +1053,9 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
1052
1053
|
// once, here, above the first reader. The 100 rows are also what the payload
|
|
1053
1054
|
// publishes, which is the property both fields rest on: what they claim can be
|
|
1054
1055
|
// checked against the rows printed next to them in `capture --json`.
|
|
1055
|
-
|
|
1056
|
+
// Issue #2768: still "the 100 rows this payload publishes" — but anchored to
|
|
1057
|
+
// the last content row when the plain tail is entirely blank (top-anchored panes).
|
|
1058
|
+
const realtimeSnippet = (0, realtime_snippet_1.selectRealtimeSnippetRows)(lines).join('\n');
|
|
1056
1059
|
// Issue #2095: gated on the tool because the anchors are opencode's own box
|
|
1057
1060
|
// drawing. Every other CLI's detection is untouched by construction — nothing
|
|
1058
1061
|
// here even looks at its frame. Computed before the unclassified-frame writer
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
* -> deriveCliStatus() (this module)
|
|
30
30
|
* -> BranchStatus (sidebar / header / tab dots)
|
|
31
31
|
*
|
|
32
|
+
* An unclassified frame (Issue #2775) takes the same chain with no activity
|
|
33
|
+
* flag raised, and `isUnclassifiedCliStatus()` is how a surface tells its
|
|
34
|
+
* `ready` apart from a real one.
|
|
35
|
+
*
|
|
32
36
|
* `deriveSessionStatus()` is the reverse edge of that chain: the worktrees API
|
|
33
37
|
* folds the boolean triple back into a `SessionStatus` for its JSON payload.
|
|
34
38
|
*
|
|
@@ -48,6 +52,7 @@ exports.HOOK_STATUS_REASON = void 0;
|
|
|
48
52
|
exports.agentEventToSessionStatus = agentEventToSessionStatus;
|
|
49
53
|
exports.sessionStatusToActivityFlags = sessionStatusToActivityFlags;
|
|
50
54
|
exports.deriveCliStatus = deriveCliStatus;
|
|
55
|
+
exports.isUnclassifiedCliStatus = isUnclassifiedCliStatus;
|
|
51
56
|
exports.deriveSessionStatus = deriveSessionStatus;
|
|
52
57
|
exports.deriveBranchStatus = deriveBranchStatus;
|
|
53
58
|
/**
|
|
@@ -173,19 +178,40 @@ function agentEventToSessionStatus(event, detail) {
|
|
|
173
178
|
* existence (plus the Claude health check), which is independent of what the
|
|
174
179
|
* terminal output says.
|
|
175
180
|
*
|
|
176
|
-
* | SessionStatus | isWaitingForResponse | isProcessing |
|
|
177
|
-
*
|
|
178
|
-
* | `idle` | false | false |
|
|
179
|
-
* | `ready` | false | false |
|
|
180
|
-
* | `running` | false | true |
|
|
181
|
-
* | `
|
|
181
|
+
* | SessionStatus | unclassified | isWaitingForResponse | isProcessing |
|
|
182
|
+
* |---------------|--------------|----------------------|--------------|
|
|
183
|
+
* | `idle` | (ignored) | false | false |
|
|
184
|
+
* | `ready` | (ignored) | false | false |
|
|
185
|
+
* | `running` | false | false | true |
|
|
186
|
+
* | `running` | true | false | false |
|
|
187
|
+
* | `waiting` | (ignored) | true | false |
|
|
188
|
+
*
|
|
189
|
+
* ## The `running` + unclassified row (Issue #2775)
|
|
190
|
+
*
|
|
191
|
+
* The detector's floors (`default` / `unknown_frame` / `no_recent_output`)
|
|
192
|
+
* answer `running`, and `running` keeps meaning what it means there — the
|
|
193
|
+
* detector is not touched. What changes is only this projection: `isProcessing`
|
|
194
|
+
* is what the sidebar, the header, `commandmate ls` and `peers` read as "it is
|
|
195
|
+
* working", and "no rule could read the frame" is not an observation that it
|
|
196
|
+
* is. So an unclassified `running` raises no activity flag at all, and the
|
|
197
|
+
* caller publishes the fact itself (`isUnclassified`) for the surfaces that
|
|
198
|
+
* draw it.
|
|
199
|
+
*
|
|
200
|
+
* `unclassified` is the caller's `isUnclassifiedFrame(status, reason)`, passed
|
|
201
|
+
* in rather than recomputed: that function is the single producer of the fact,
|
|
202
|
+
* and this module stays free of the server-side imports it would need to call
|
|
203
|
+
* it. It is ignored for every status but `running`, which is the only status it
|
|
204
|
+
* can be true for.
|
|
205
|
+
*
|
|
206
|
+
* @param status - The detector's verdict
|
|
207
|
+
* @param unclassified - `isUnclassifiedFrame(status, reason)` for the same frame
|
|
182
208
|
*/
|
|
183
|
-
function sessionStatusToActivityFlags(status) {
|
|
209
|
+
function sessionStatusToActivityFlags(status, unclassified = false) {
|
|
184
210
|
switch (status) {
|
|
185
211
|
case 'waiting':
|
|
186
212
|
return { isWaitingForResponse: true, isProcessing: false };
|
|
187
213
|
case 'running':
|
|
188
|
-
return { isWaitingForResponse: false, isProcessing:
|
|
214
|
+
return { isWaitingForResponse: false, isProcessing: !unclassified };
|
|
189
215
|
case 'idle':
|
|
190
216
|
case 'ready':
|
|
191
217
|
return { isWaitingForResponse: false, isProcessing: false };
|
|
@@ -220,6 +246,30 @@ function deriveCliStatus(toolStatus) {
|
|
|
220
246
|
return 'ready';
|
|
221
247
|
return 'idle';
|
|
222
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Whether one session should be drawn as "cannot tell" rather than as the
|
|
251
|
+
* `BranchStatus` {@link deriveCliStatus} names for it (Issue #2775).
|
|
252
|
+
*
|
|
253
|
+
* True exactly when the server flagged the frame unclassified AND nothing more
|
|
254
|
+
* significant is known, i.e. {@link deriveCliStatus} lands on `ready`. The
|
|
255
|
+
* second half is not decoration:
|
|
256
|
+
*
|
|
257
|
+
* - an unclassified session raises no activity flag of its own (see
|
|
258
|
+
* {@link sessionStatusToActivityFlags}), so on its own it derives `ready` —
|
|
259
|
+
* the one `BranchStatus` that would otherwise claim "you can send now";
|
|
260
|
+
* - a `waiting` the agent's own events reported, or a `running` from another
|
|
261
|
+
* instance folded into the same per-tool aggregate, is a reading, and a
|
|
262
|
+
* reading outranks "cannot tell". Those keep their dot.
|
|
263
|
+
*
|
|
264
|
+
* Which also means a `running` with positive evidence can never be redrawn by
|
|
265
|
+
* this: it has no `isUnclassified`, and even if it had, it derives `running`.
|
|
266
|
+
*
|
|
267
|
+
* Reads the published flag, never `(status, reason)`: the classification itself
|
|
268
|
+
* has one producer, `isUnclassifiedFrame` in `status-evidence.ts`.
|
|
269
|
+
*/
|
|
270
|
+
function isUnclassifiedCliStatus(toolStatus) {
|
|
271
|
+
return toolStatus?.isUnclassified === true && deriveCliStatus(toolStatus) === 'ready';
|
|
272
|
+
}
|
|
223
273
|
/**
|
|
224
274
|
* Fold a worktree-level boolean triple back into a `SessionStatus` for the
|
|
225
275
|
* worktrees API payload — the reverse edge of `sessionStatusToActivityFlags`.
|
|
@@ -56,10 +56,33 @@
|
|
|
56
56
|
* @module lib/tmux/key-sequence
|
|
57
57
|
*/
|
|
58
58
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
|
+
exports.escapeTrailingSemicolon = escapeTrailingSemicolon;
|
|
59
60
|
exports.keySequenceArgs = keySequenceArgs;
|
|
60
61
|
exports.runKeySequence = runKeySequence;
|
|
61
62
|
exports.describeKeySequence = describeKeySequence;
|
|
62
63
|
const cli_tool_contracts_1 = require("../../types/cli-tool-contracts");
|
|
64
|
+
/**
|
|
65
|
+
* Make `text` survive tmux's own reading of a `send-keys` argument (Issue #2769).
|
|
66
|
+
*
|
|
67
|
+
* tmux treats a `;` at the END of an argument as its command separator — even
|
|
68
|
+
* under `-l`, even after `--`, even though `execFile` never involved a shell —
|
|
69
|
+
* and drops it; `\;` is how it is told the semicolon is text. Measured on
|
|
70
|
+
* tmux 3.5a against a raw pty:
|
|
71
|
+
*
|
|
72
|
+
* 'a;' -> a (the `;` is gone, rc 0) ';' -> nothing at all
|
|
73
|
+
* 'a\;' -> a; (one backslash consumed) 'a;;' -> a;
|
|
74
|
+
* 'a;b' -> a;b (only a TRAILING `;` counts)
|
|
75
|
+
*
|
|
76
|
+
* One rule covers every case: when the text ends in `;`, put one backslash in
|
|
77
|
+
* front of that last `;`. tmux removes exactly that backslash, so `a;` arrives
|
|
78
|
+
* as `a;` and a body that really ends in `\;` arrives as `\;` too.
|
|
79
|
+
*
|
|
80
|
+
* @param text - Text about to be placed in a `send-keys` argv entry
|
|
81
|
+
* @returns The same text, escaped only if its last character is `;`
|
|
82
|
+
*/
|
|
83
|
+
function escapeTrailingSemicolon(text) {
|
|
84
|
+
return text.endsWith(';') ? `${text.slice(0, -1)}\\;` : text;
|
|
85
|
+
}
|
|
63
86
|
/**
|
|
64
87
|
* The `tmux` arguments that send one step to a pane.
|
|
65
88
|
*
|
|
@@ -74,7 +97,10 @@ function keySequenceArgs(target, step) {
|
|
|
74
97
|
// `-l` stops the key-table lookup; `--` stops the getopt parse. Both are
|
|
75
98
|
// required: without `-l` a body of `Escape` is the ESC key, and without
|
|
76
99
|
// `--` a body of `-l` is consumed as a flag and nothing is sent at all.
|
|
77
|
-
|
|
100
|
+
//
|
|
101
|
+
// Neither protects a TRAILING `;`, which tmux takes for its command
|
|
102
|
+
// separator and drops — see {@link escapeTrailingSemicolon}.
|
|
103
|
+
return ['send-keys', '-t', target, '-l', '--', escapeTrailingSemicolon(step.text)];
|
|
78
104
|
}
|
|
79
105
|
if (!(0, cli_tool_contracts_1.isKeySequenceKeyName)(step.name)) {
|
|
80
106
|
throw new Error(`Invalid key sequence key name: ${step.name}`);
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TmuxControlClient = void 0;
|
|
3
|
+
exports.TmuxControlClient = exports.CONTROL_SEND_KEYS_CHUNK_BYTES = void 0;
|
|
4
4
|
const child_process_1 = require("child_process");
|
|
5
5
|
const logger_1 = require("../../lib/logger");
|
|
6
6
|
const tmux_control_parser_1 = require("./tmux-control-parser");
|
|
7
7
|
const tmux_1 = require("./tmux");
|
|
8
8
|
const logger = (0, logger_1.createLogger)('tmux-control-client');
|
|
9
9
|
const DEFAULT_CONTROL_CLIENT_IDLE_TIMEOUT_MS = 30_000;
|
|
10
|
+
/**
|
|
11
|
+
* Bytes of user input per `send-keys -H` command (Issue #2767).
|
|
12
|
+
*
|
|
13
|
+
* A control-mode client's stdin is a stream of tmux COMMANDS, one per line — it
|
|
14
|
+
* is not the pane's keyboard. Input is therefore delivered as `send-keys -H`
|
|
15
|
+
* followed by the bytes in hex, and a long paste is split so no single command
|
|
16
|
+
* line grows without bound (256 bytes is 767 characters of hex).
|
|
17
|
+
*/
|
|
18
|
+
exports.CONTROL_SEND_KEYS_CHUNK_BYTES = 256;
|
|
10
19
|
/**
|
|
11
20
|
* Thin wrapper around a tmux control mode child process.
|
|
12
21
|
*
|
|
@@ -70,12 +79,26 @@ class TmuxControlClient {
|
|
|
70
79
|
this.handlers.delete(handler);
|
|
71
80
|
};
|
|
72
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Deliver user input to the pane (Issue #2767).
|
|
84
|
+
*
|
|
85
|
+
* A control-mode client's stdin is where tmux COMMANDS are written, not the
|
|
86
|
+
* pane's keyboard. Before #2767 the raw input was written straight through, so
|
|
87
|
+
* a line typed in the browser terminal ran as a tmux command (`kill-server` +
|
|
88
|
+
* Enter took down every session) and never reached the pane. The input is now
|
|
89
|
+
* wrapped in `send-keys -H` with the bytes in hex: not one character of the
|
|
90
|
+
* input appears in the line that is written, so it cannot be parsed as a command.
|
|
91
|
+
*/
|
|
73
92
|
sendInput(input) {
|
|
74
|
-
if (!this.child?.stdin.writable) {
|
|
93
|
+
if (!this.child?.stdin.writable || this.sessionName === null) {
|
|
75
94
|
throw new Error('Tmux control client is not writable');
|
|
76
95
|
}
|
|
77
96
|
this.touch();
|
|
78
|
-
|
|
97
|
+
const bytes = Buffer.from(input, 'utf8');
|
|
98
|
+
for (let offset = 0; offset < bytes.length; offset += exports.CONTROL_SEND_KEYS_CHUNK_BYTES) {
|
|
99
|
+
const hex = Array.from(bytes.subarray(offset, offset + exports.CONTROL_SEND_KEYS_CHUNK_BYTES), (byte) => byte.toString(16).padStart(2, '0')).join(' ');
|
|
100
|
+
this.child.stdin.write(`send-keys -t ${(0, tmux_1.exactTarget)(this.sessionName)} -H ${hex}\n`);
|
|
101
|
+
}
|
|
79
102
|
}
|
|
80
103
|
resize(cols, rows) {
|
|
81
104
|
if (!this.child?.stdin.writable) {
|