commandmate 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +431 -403
- package/.next/app-path-routes-manifest.json +26 -22
- package/.next/build-manifest.json +5 -5
- package/.next/prerender-manifest.json +9 -9
- package/.next/react-loadable-manifest.json +6 -6
- package/.next/required-server-files.json +1 -1
- package/.next/routes-manifest.json +24 -0
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.js +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route.js +1 -1
- package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route.js +1 -1
- package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/terminal/route.js +2 -2
- package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -0
- package/.next/server/app/api/capabilities/route.js.nft.json +1 -0
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -0
- 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.js +2 -2
- package/.next/server/app/api/fs/browse/route.js.nft.json +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.js +2 -2
- package/.next/server/app/api/fs/recent-paths/route.js.nft.json +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 +19 -1
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route.js +1 -1
- package/.next/server/app/api/push/escalation/route.js.nft.json +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route.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.js +1 -1
- package/.next/server/app/api/push/vapid/route.js.nft.json +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/validate-path/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.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/todos/route.js +1 -1
- package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route.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.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 -0
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/[id]/cli-tool/route.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 +1 -1
- 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 +2 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route.js +2 -0
- package/.next/server/app/api/worktrees/[id]/env/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js.nft.json +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.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.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.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.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.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.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.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.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]/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.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.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.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.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.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]/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.js +1 -0
- package/.next/server/app/api/worktrees/[id]/resolve-target/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +1 -5
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js.nft.json +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.js +2 -6
- package/.next/server/app/api/worktrees/[id]/schedules/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +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 +3 -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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route.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.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 +3 -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.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.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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +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/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js.nft.json +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]/route.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.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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/chat/page.js +2 -2
- package/.next/server/app/chat/page.js.nft.json +1 -1
- package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page.js +2 -2
- package/.next/server/app/login/page.js.nft.json +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page.js +2 -2
- package/.next/server/app/more/page.js.nft.json +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page.js +1 -1
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page.js +2 -2
- package/.next/server/app/repositories/page.js.nft.json +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page.js +1 -1
- package/.next/server/app/review/page.js.nft.json +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +1 -1
- package/.next/server/app/sessions/page.js.nft.json +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page.js +2 -2
- package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page.js +2 -2
- package/.next/server/app/skills/installed/page.js.nft.json +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page.js +2 -2
- package/.next/server/app/skills/page.js.nft.json +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js +2 -2
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +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 -7
- 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 +26 -22
- package/.next/server/chunks/1029.js +1 -1
- package/.next/server/chunks/1068.js +3 -1
- package/.next/server/chunks/1296.js +1 -1
- package/.next/server/chunks/1538.js +7 -0
- package/.next/server/chunks/1601.js +2 -2
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2404.js +3 -2
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/2546.js +1 -1
- package/.next/server/chunks/2689.js +13 -0
- package/.next/server/chunks/2759.js +8 -0
- package/.next/server/chunks/2839.js +1 -0
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3292.js +1 -0
- package/.next/server/chunks/3417.js +1 -1
- package/.next/server/chunks/3480.js +1 -17
- package/.next/server/chunks/4393.js +1 -1
- package/.next/server/chunks/4423.js +1 -0
- package/.next/server/chunks/4444.js +22 -8
- package/.next/server/chunks/4565.js +3 -0
- package/.next/server/chunks/467.js +1 -0
- package/.next/server/chunks/4905.js +5 -0
- package/.next/server/chunks/5017.js +1 -0
- package/.next/server/chunks/5089.js +1 -0
- package/.next/server/chunks/5164.js +1 -1
- package/.next/server/chunks/5220.js +1 -0
- package/.next/server/chunks/5354.js +1 -0
- package/.next/server/chunks/552.js +19 -0
- package/.next/server/chunks/5571.js +1 -1
- package/.next/server/chunks/5998.js +3 -3
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6274.js +11 -11
- package/.next/server/chunks/6285.js +1 -1
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/7472.js +1 -0
- package/.next/server/chunks/7506.js +1 -0
- package/.next/server/chunks/848.js +1 -1
- package/.next/server/chunks/8536.js +1 -1
- package/.next/server/chunks/880.js +1 -1
- package/.next/server/chunks/8807.js +5 -5
- package/.next/server/chunks/9067.js +1 -1
- package/.next/server/chunks/9284.js +1 -0
- package/.next/server/chunks/9358.js +1 -1
- package/.next/server/chunks/9508.js +1 -0
- package/.next/server/chunks/9938.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{2053-dfac2d49227cc942.js → 2053-c0e931eb4391baa1.js} +1 -1
- package/.next/static/chunks/3361-5d6e93fba8a92bc1.js +1 -0
- package/.next/static/chunks/3922.0d2e64daf9f187da.js +1 -0
- package/.next/static/chunks/{5229-35f9acab97a553c5.js → 5229-1f5f19740a8d6c11.js} +1 -1
- package/.next/static/chunks/{6381-9303430933084b56.js → 6381-b7250e8ca7a44c6c.js} +1 -1
- package/.next/static/chunks/{8649-f551b0010dba4986.js → 8521-c43994fb58501d13.js} +1 -1
- package/.next/static/chunks/app/api/app/update/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/app/update-check/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/assistant/conversation/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/assistant/current-output/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/assistant/messages/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/assistant/session/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/assistant/start/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/assistant/terminal/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/assistant/tools/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/auth/login/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/auth/status/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/capabilities/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/status/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/external-apps/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/fs/browse/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/fs/recent-paths/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/hooks/agent-event/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/hooks/claude-done/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/hooks/permission-request/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/metrics/vibe/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/ollama/models/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/push/escalation/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/push/subscriptions/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/push/vapid/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/repositories/excluded/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/repositories/restore/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/repositories/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/repositories/scan/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/repositories/sync/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/repositories/validate-path/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/sidebar/group-order/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/skills/[id]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/skills/installations/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/skills/operations/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/skills/reindex/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/skills/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/slash-commands/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/templates/[id]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/templates/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/todos/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/chat/{page-439b35c9cb90dbe0.js → page-231df45127e876c2.js} +1 -1
- package/.next/static/chunks/app/login/{page-eefd515d8c37e5ee.js → page-adc51f0f7cbb7ac6.js} +1 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/more/{page-889b7546a8a553dc.js → page-3266dfa945972649.js} +1 -1
- package/.next/static/chunks/app/{page-a8d04ac0e3e4c9fc.js → page-0305431f43195431.js} +1 -1
- package/.next/static/chunks/app/proxy/[...path]/route-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/repositories/{page-f3c4d8839b1ca203.js → page-ae8fa55749976f79.js} +1 -1
- package/.next/static/chunks/app/review/{page-6dc88649fe88ac16.js → page-8f63aff862fee421.js} +1 -1
- package/.next/static/chunks/app/sessions/{page-2c9ed9e969097688.js → page-4d5382b257077c14.js} +1 -1
- package/.next/static/chunks/app/skills/[skillId]/{page-19beef6121c4c982.js → page-aaf0bcb1dfb558b9.js} +1 -1
- package/.next/static/chunks/app/skills/installed/{page-d5b9cef6d21fabda.js → page-dafc486410e839b7.js} +1 -1
- package/.next/static/chunks/app/skills/{page-06ef637e07dd9377.js → page-9e3c91da31514893.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/files/[...path]/{page-5fed3984fafcd910.js → page-90f96977c741bbf8.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/layout-6add0d88e2828c23.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-e4f28966b4fc0ce1.js +1 -0
- package/.next/static/chunks/{webpack-9d892a9ff07c289d.js → webpack-6a9668cf54a26eba.js} +1 -1
- package/.next/static/css/928e5a8830fbf997.css +1 -0
- package/.next/static/t0BoV4H46ZgKmTjSi7GIz/_buildManifest.js +1 -0
- package/.next/trace +13 -12
- package/.next/types/app/api/capabilities/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/clear-composer/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/env/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/resolve-target/route.ts +347 -0
- package/.next/types/routes.d.ts +5 -1
- package/.next/types/validator.ts +36 -0
- package/dist/cli/commands/auto-yes.d.ts.map +1 -1
- package/dist/cli/commands/auto-yes.js +40 -2
- package/dist/cli/commands/capture.d.ts.map +1 -1
- package/dist/cli/commands/capture.js +28 -13
- package/dist/cli/commands/instances.d.ts +30 -18
- package/dist/cli/commands/instances.d.ts.map +1 -1
- package/dist/cli/commands/instances.js +32 -36
- package/dist/cli/commands/ls.d.ts.map +1 -1
- package/dist/cli/commands/ls.js +73 -1
- package/dist/cli/commands/respond.d.ts.map +1 -1
- package/dist/cli/commands/respond.js +18 -1
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +21 -15
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +38 -0
- package/dist/cli/commands/wait.d.ts +26 -0
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +390 -43
- package/dist/cli/config/cli-dependencies.d.ts.map +1 -1
- package/dist/cli/config/cli-dependencies.js +16 -0
- package/dist/cli/config/cli-tool-ids.d.ts +11 -0
- package/dist/cli/config/cli-tool-ids.d.ts.map +1 -1
- package/dist/cli/config/cli-tool-ids.js +12 -1
- package/dist/cli/types/api-responses.d.ts +443 -2
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/utils/api-client.d.ts +18 -0
- package/dist/cli/utils/api-client.d.ts.map +1 -1
- package/dist/cli/utils/api-client.js +22 -0
- package/dist/cli/utils/server-capabilities.d.ts +56 -0
- package/dist/cli/utils/server-capabilities.d.ts.map +1 -0
- package/dist/cli/utils/server-capabilities.js +166 -0
- package/dist/cli/utils/session-target.d.ts +70 -0
- package/dist/cli/utils/session-target.d.ts.map +1 -0
- package/dist/cli/utils/session-target.js +118 -0
- package/dist/lib/cli-tools/copilot-executable.d.ts +79 -0
- package/dist/lib/cli-tools/copilot-executable.d.ts.map +1 -0
- package/dist/lib/cli-tools/copilot-executable.js +155 -0
- package/dist/lib/cli-tools/types.d.ts +61 -0
- package/dist/lib/cli-tools/types.d.ts.map +1 -1
- package/dist/lib/cli-tools/types.js +41 -0
- package/dist/lib/detection/ansi.d.ts +2 -1
- package/dist/lib/detection/ansi.d.ts.map +1 -1
- package/dist/lib/detection/ansi.js +3 -2
- package/dist/lib/detection/tools/verified-against.d.ts +84 -0
- package/dist/lib/detection/tools/verified-against.d.ts.map +1 -0
- package/dist/lib/detection/tools/verified-against.js +88 -0
- package/dist/lib/detection/version-probes.d.ts +207 -0
- package/dist/lib/detection/version-probes.d.ts.map +1 -0
- package/dist/lib/detection/version-probes.js +290 -0
- package/dist/lib/security/env-sanitizer.d.ts +198 -0
- package/dist/lib/security/env-sanitizer.d.ts.map +1 -0
- package/dist/lib/security/env-sanitizer.js +232 -0
- package/dist/server/locales/en/notifications.json +17 -6
- package/dist/server/locales/ja/notifications.json +17 -6
- package/dist/server/src/config/activity-bar-config.js +4 -0
- package/dist/server/src/config/cli-tool-timing-config.js +59 -2
- package/dist/server/src/config/copilot-constants.js +11 -1
- package/dist/server/src/config/detection-evidence-config.js +129 -0
- package/dist/server/src/config/schedule-config.js +56 -7
- package/dist/server/src/config/tmux-pane-config.js +18 -1
- package/dist/server/src/lib/auto-yes-poller.js +36 -0
- package/dist/server/src/lib/cli-tools/antigravity.js +4 -2
- package/dist/server/src/lib/cli-tools/base.js +131 -10
- package/dist/server/src/lib/cli-tools/capture-spec.js +56 -0
- package/dist/server/src/lib/cli-tools/claude.js +1 -1
- package/dist/server/src/lib/cli-tools/codex.js +6 -2
- package/dist/server/src/lib/cli-tools/composer-spec.js +96 -0
- package/dist/server/src/lib/cli-tools/copilot-executable.js +155 -0
- package/dist/server/src/lib/cli-tools/copilot.js +307 -81
- package/dist/server/src/lib/cli-tools/gemini.js +8 -6
- package/dist/server/src/lib/cli-tools/graceful-exit.js +181 -0
- package/dist/server/src/lib/cli-tools/index.js +11 -1
- package/dist/server/src/lib/cli-tools/manager.js +56 -4
- package/dist/server/src/lib/cli-tools/opencode-config.js +195 -24
- package/dist/server/src/lib/cli-tools/opencode.js +233 -30
- package/dist/server/src/lib/cli-tools/session-name.js +57 -0
- package/dist/server/src/lib/cli-tools/submit-verified-sender.js +213 -30
- package/dist/server/src/lib/cli-tools/types.js +41 -0
- package/dist/server/src/lib/cli-tools/vibe-local.js +7 -3
- package/dist/server/src/lib/cmate-cli-tool-parser.js +29 -1
- package/dist/server/src/lib/cmate-parser.js +12 -4
- package/dist/server/src/lib/db/db.js +5 -1
- package/dist/server/src/lib/db/migrations/v41-push-subscriptions.js +11 -0
- package/dist/server/src/lib/db/push-subscriptions-db.js +60 -3
- package/dist/server/src/lib/detection/ansi.js +3 -2
- package/dist/server/src/lib/detection/cli-patterns.js +901 -67
- package/dist/server/src/lib/detection/composer-text.js +455 -0
- package/dist/server/src/lib/detection/idle-evidence-observation.js +51 -0
- package/dist/server/src/lib/detection/model-info-extractor.js +195 -4
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +19 -0
- package/dist/server/src/lib/detection/status-detector.js +76 -675
- package/dist/server/src/lib/detection/status-reason.js +57 -0
- package/dist/server/src/lib/detection/tools/antigravity/detect.js +75 -0
- package/dist/server/src/lib/detection/tools/claude/detect.js +144 -0
- package/dist/server/src/lib/detection/tools/claude/patterns.js +98 -0
- package/dist/server/src/lib/detection/tools/claude/prompt.js +124 -0
- package/dist/server/src/lib/detection/tools/codex/detect.js +343 -0
- package/dist/server/src/lib/detection/tools/codex/prompt.js +104 -0
- package/dist/server/src/lib/detection/tools/copilot/detect.js +185 -0
- package/dist/server/src/lib/detection/tools/copilot/prompt.js +89 -0
- package/dist/server/src/lib/detection/tools/dialog-block.js +159 -0
- package/dist/server/src/lib/detection/tools/frame.js +47 -0
- package/dist/server/src/lib/detection/tools/opencode/detect.js +242 -0
- package/dist/server/src/lib/detection/tools/opencode/prompt.js +85 -0
- package/dist/server/src/lib/detection/tools/registry.js +58 -0
- package/dist/server/src/lib/detection/tools/run-detection.js +202 -0
- package/dist/server/src/lib/detection/tools/types.js +34 -0
- package/dist/server/src/lib/detection/tools/verified-against.js +88 -0
- package/dist/server/src/lib/hooks/agent-event-types.js +19 -1
- package/dist/server/src/lib/hooks/permission-adjudication.js +160 -0
- package/dist/server/src/lib/hooks/permission-decision-service.js +81 -14
- package/dist/server/src/lib/hooks/permission-decision-state.js +62 -0
- package/dist/server/src/lib/hooks/permission-request-payload.js +18 -1
- package/dist/server/src/lib/hooks/sources/antigravity/source.js +10 -0
- package/dist/server/src/lib/hooks/sources/claude/source.js +20 -0
- package/dist/server/src/lib/hooks/sources/codex/source.js +10 -0
- package/dist/server/src/lib/hooks/sources/copilot/hook-settings.js +403 -50
- package/dist/server/src/lib/hooks/sources/copilot/source.js +40 -4
- package/dist/server/src/lib/hooks/sources/define-source.js +23 -1
- package/dist/server/src/lib/hooks/sources/event-mapper.js +29 -1
- package/dist/server/src/lib/hooks/sources/gemini/source.js +10 -0
- package/dist/server/src/lib/hooks/sources/index.js +3 -1
- package/dist/server/src/lib/hooks/sources/launch-command.js +96 -1
- package/dist/server/src/lib/hooks/sources/legacy-relay.js +12 -0
- package/dist/server/src/lib/hooks/sources/opencode/client.js +295 -32
- package/dist/server/src/lib/hooks/sources/opencode/ingest.js +120 -42
- package/dist/server/src/lib/hooks/sources/opencode/mappers.js +95 -3
- package/dist/server/src/lib/hooks/sources/opencode/ports.js +70 -9
- package/dist/server/src/lib/hooks/sources/opencode/runtime.js +62 -4
- package/dist/server/src/lib/hooks/sources/opencode/source.js +54 -3
- package/dist/server/src/lib/hooks/sources/opencode/subscription.js +254 -26
- package/dist/server/src/lib/hooks/sources/opencode/turn-gate.js +119 -4
- package/dist/server/src/lib/hooks/sources/pending-decisions.js +40 -2
- package/dist/server/src/lib/hooks/tool-input-normalization-state.js +67 -0
- package/dist/server/src/lib/hooks/tool-input-normalization.js +157 -0
- package/dist/server/src/lib/job-executor.js +16 -4
- package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +184 -0
- package/dist/server/src/lib/polling/response-checker.js +243 -26
- package/dist/server/src/lib/push/failure-episode-state.js +127 -0
- package/dist/server/src/lib/push/failure-push-notifier.js +344 -0
- package/dist/server/src/lib/push/index.js +35 -1
- package/dist/server/src/lib/push/prompt-card-state.js +93 -0
- package/dist/server/src/lib/push/prompt-push-gate.js +130 -0
- package/dist/server/src/lib/push/push-sender.js +82 -7
- package/dist/server/src/lib/push/resolution-push-notifier.js +193 -0
- package/dist/server/src/lib/push/waiting-push-notifier.js +42 -0
- package/dist/server/src/lib/response-cleaner.js +93 -20
- package/dist/server/src/lib/response-extractor.js +98 -5
- package/dist/server/src/lib/security/env-sanitizer.js +179 -5
- package/dist/server/src/lib/session/agent-event-state.js +1038 -189
- package/dist/server/src/lib/session/agent-session-lifecycle.js +8 -0
- package/dist/server/src/lib/session/claude-executor.js +23 -3
- package/dist/server/src/lib/session/claude-session.js +11 -1
- package/dist/server/src/lib/session/composer-clear.js +95 -0
- package/dist/server/src/lib/session/current-output-builder.js +267 -25
- package/dist/server/src/lib/session/provisional-turn.js +310 -0
- package/dist/server/src/lib/session/resolve-session-target.js +156 -0
- package/dist/server/src/lib/session/send-user-message.js +14 -18
- package/dist/server/src/lib/session/session-start-error.js +53 -1
- package/dist/server/src/lib/session/status-evidence.js +217 -0
- package/dist/server/src/lib/session/structured-prompt.js +46 -4
- package/dist/server/src/lib/session/waiting-episode-state.js +24 -0
- package/dist/server/src/lib/tmux/key-sequence.js +120 -0
- package/dist/server/src/lib/tmux/tmux.js +91 -19
- package/dist/server/src/lib/tui-accumulator.js +68 -1
- package/dist/server/src/lib/verification/gate-runner.js +84 -1
- package/dist/server/src/lib/ws-server.js +8 -5
- package/dist/server/src/types/cli-tool-contracts.js +75 -0
- package/dist/server/src/types/terminal-keys.js +37 -0
- package/dist/types/cli-tool-contracts.d.ts +235 -0
- package/dist/types/cli-tool-contracts.d.ts.map +1 -0
- package/dist/types/cli-tool-contracts.js +75 -0
- package/package.json +3 -2
- package/public/sw.js +65 -2
- package/.next/server/chunks/1841.js +0 -1
- package/.next/server/chunks/233.js +0 -1
- package/.next/server/chunks/3022.js +0 -1
- package/.next/server/chunks/3270.js +0 -1
- package/.next/server/chunks/4455.js +0 -1
- package/.next/server/chunks/5959.js +0 -27
- package/.next/server/chunks/7458.js +0 -6
- package/.next/server/chunks/8730.js +0 -1
- package/.next/server/chunks/9058.js +0 -1
- package/.next/server/chunks/9687.js +0 -3
- package/.next/static/chunks/3898-ef488bfa804507d9.js +0 -1
- package/.next/static/chunks/9263.f2034ec525abcf72.js +0 -1
- package/.next/static/chunks/app/api/app/update/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/app/update-check/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/assistant/conversation/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/assistant/current-output/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/assistant/messages/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/assistant/session/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/assistant/start/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/assistant/terminal/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/assistant/tools/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/auth/login/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/auth/status/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/status/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/external-apps/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/fs/browse/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/fs/recent-paths/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/hooks/agent-event/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/hooks/claude-done/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/hooks/permission-request/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/metrics/vibe/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/ollama/models/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/push/escalation/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/push/subscriptions/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/push/vapid/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/repositories/excluded/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/repositories/restore/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/repositories/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/repositories/scan/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/repositories/sync/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/repositories/validate-path/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/sidebar/group-order/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/skills/[id]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/skills/installations/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/skills/operations/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/skills/reindex/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/skills/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/slash-commands/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/templates/[id]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/templates/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/todos/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/proxy/[...path]/route-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/layout-fae89f8d4cc3ff97.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-fbdf4621a2911ac1.js +0 -1
- package/.next/static/css/e865c4979a41aa03.css +0 -1
- package/.next/static/hNdNiFes2xLls68SWhAU9/_buildManifest.js +0 -1
- /package/.next/static/{hNdNiFes2xLls68SWhAU9 → t0BoV4H46ZgKmTjSi7GIz}/_ssgManifest.js +0 -0
|
@@ -4,18 +4,28 @@
|
|
|
4
4
|
* Shared between response-poller.ts and API routes
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
7
|
+
exports.COPILOT_SELECTION_FOOTER_PATTERN = exports.COPILOT_BOOT_BANNER_ANCHORS = exports.COPILOT_TRANSCRIPT_CONTINUATION_PATTERN = exports.COPILOT_USER_ECHO_PATTERN = exports.COPILOT_REASONING_HEADER_PATTERN = exports.COPILOT_BOX_ROW_PATTERN = exports.COPILOT_SEPARATOR_PATTERN = exports.COPILOT_IDLE_STATUS_PATTERN = exports.COPILOT_WORKING_STATUS_PATTERN = exports.COPILOT_THINKING_PATTERN = exports.COPILOT_PROMPT_PATTERN = exports.OPENCODE_SKIP_PATTERNS = exports.OPENCODE_SEPARATOR_PATTERN = exports.CLAUDE_SELECTION_LIST_FOOTER = exports.CLAUDE_MODEL_OVERLAY_FOOTER_PATTERN = exports.OPENCODE_SELECTION_LIST_PATTERN = exports.OPENCODE_FOOTER_STATUS_PATTERN = exports.OPENCODE_USER_ECHO_PATTERN = exports.OPENCODE_GUTTER_ROW_PATTERN = exports.OPENCODE_COMPOSER_BOTTOM_BORDER = exports.OPENCODE_PROCESSING_INDICATOR = exports.OPENCODE_PERMISSION_PATTERN = exports.OPENCODE_TURN_COMPLETE_PATTERN = exports.OPENCODE_RESPONSE_COMPLETE = exports.OPENCODE_LOADING_PATTERN = exports.OPENCODE_THINKING_PATTERN = exports.OPENCODE_PROMPT_AFTER_RESPONSE = exports.OPENCODE_IDLE_COMPOSER_PATTERN = exports.OPENCODE_PROMPT_PATTERN = exports.GEMINI_THINKING_PATTERN = exports.GEMINI_PROMPT_PATTERN = exports.MAX_PASTED_TEXT_RETRIES = exports.PASTED_TEXT_DETECT_DELAY = exports.PASTED_TEXT_PATTERN = exports.CODEX_STATUS_BAR_PATTERN = exports.CODEX_PAGER_FOOTER_PATTERN = exports.CODEX_APPROVAL_FOOTER_PATTERN = exports.CODEX_SELECTION_LIST_PATTERN = exports.CODEX_SEPARATOR_PATTERN = exports.CODEX_HOOKS_REVIEW_ANCHORS = exports.CODEX_DIALOG_PATTERN = exports.CODEX_PROMPT_PATTERN = exports.CLAUDE_TRUST_DIALOG_PATTERN = exports.CLAUDE_SEPARATOR_PATTERN = exports.CLAUDE_PROMPT_PATTERN = exports.CODEX_INTERRUPT_HINT_PATTERN = exports.CODEX_THINKING_PATTERN = exports.CLAUDE_INTERRUPT_HINT_PATTERN = exports.CLAUDE_THINKING_PATTERN = exports.CLAUDE_SPINNER_CHARS = void 0;
|
|
8
|
+
exports.CLAUDE_SESSION_ERROR_REGEX_PATTERNS = exports.CLAUDE_SESSION_ERROR_PATTERNS = exports.extractAnsiSequences = exports.stripAnsi = exports.ANTIGRAVITY_SKIP_PATTERNS = exports.ANTIGRAVITY_SELECTION_LIST_PATTERN = exports.ANTIGRAVITY_SEPARATOR_PATTERN = exports.ANTIGRAVITY_THINKING_PATTERN = exports.ANTIGRAVITY_PROMPT_PATTERN = exports.VIBE_LOCAL_THINKING_PATTERN = exports.VIBE_LOCAL_PROMPT_PATTERN = exports.COPILOT_SKIP_PATTERNS = exports.COPILOT_FOLDER_TRUST_ANSWER_KEY = exports.COPILOT_FOLDER_TRUST_SESSION_OPTION_PATTERN = exports.COPILOT_FOLDER_TRUST_ANCHORS = void 0;
|
|
8
9
|
exports.isCodexTurnActive = isCodexTurnActive;
|
|
9
10
|
exports.findClaudeChromeStart = findClaudeChromeStart;
|
|
10
11
|
exports.isCodexPromptReady = isCodexPromptReady;
|
|
11
12
|
exports.getCodexActiveDialog = getCodexActiveDialog;
|
|
12
13
|
exports.getCodexLifecycleDialog = getCodexLifecycleDialog;
|
|
14
|
+
exports.findOpenCodeChromeStart = findOpenCodeChromeStart;
|
|
15
|
+
exports.findOpenCodeUserEchoEnd = findOpenCodeUserEchoEnd;
|
|
16
|
+
exports.findOpenCodeComposerRows = findOpenCodeComposerRows;
|
|
17
|
+
exports.stripOpenCodeGutter = stripOpenCodeGutter;
|
|
18
|
+
exports.readCopilotStatusBar = readCopilotStatusBar;
|
|
19
|
+
exports.findCopilotChromeStart = findCopilotChromeStart;
|
|
20
|
+
exports.isCopilotSelectionFrame = isCopilotSelectionFrame;
|
|
21
|
+
exports.isCopilotFolderTrustDialog = isCopilotFolderTrustDialog;
|
|
13
22
|
exports.detectThinking = detectThinking;
|
|
14
23
|
exports.getCliToolPatterns = getCliToolPatterns;
|
|
15
24
|
exports.stripBoxDrawing = stripBoxDrawing;
|
|
16
25
|
exports.buildDetectPromptOptions = buildDetectPromptOptions;
|
|
17
26
|
const logger_1 = require("../../lib/logger");
|
|
18
27
|
const ansi_1 = require("./ansi");
|
|
28
|
+
const composer_text_1 = require("./composer-text");
|
|
19
29
|
const thinking_constants_1 = require("../../config/thinking-constants");
|
|
20
30
|
const logger = (0, logger_1.createLogger)('cli-patterns');
|
|
21
31
|
/**
|
|
@@ -160,10 +170,6 @@ exports.CLAUDE_PROMPT_PATTERN = /^[>❯](\s*$|\s+\S)/m;
|
|
|
160
170
|
* Claude separator pattern
|
|
161
171
|
*/
|
|
162
172
|
exports.CLAUDE_SEPARATOR_PATTERN = /^─{10,}$/m;
|
|
163
|
-
/** How far above the last line the input box's closing separator may sit. */
|
|
164
|
-
const CLAUDE_STATUS_BAR_MAX_ROWS = 4;
|
|
165
|
-
/** How many rows the input box may span before the block stops looking like the footer. */
|
|
166
|
-
const CLAUDE_INPUT_BOX_MAX_ROWS = 40;
|
|
167
173
|
/**
|
|
168
174
|
* Locate the start of Claude Code's bottom-pinned footer within a captured pane.
|
|
169
175
|
*
|
|
@@ -192,40 +198,16 @@ const CLAUDE_INPUT_BOX_MAX_ROWS = 40;
|
|
|
192
198
|
* @returns Index of the first footer row, or -1 when no footer is present
|
|
193
199
|
*/
|
|
194
200
|
function findClaudeChromeStart(lines) {
|
|
195
|
-
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
// The input box's closing separator sits just above the status bar.
|
|
203
|
-
let closingSeparator = -1;
|
|
204
|
-
for (let i = lastRow; i >= Math.max(0, lastRow - CLAUDE_STATUS_BAR_MAX_ROWS); i--) {
|
|
205
|
-
if (isSeparator(lines[i])) {
|
|
206
|
-
closingSeparator = i;
|
|
207
|
-
break;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
if (closingSeparator < 0)
|
|
211
|
-
return -1;
|
|
212
|
-
// Walk up over the input box to the opening separator.
|
|
213
|
-
let openingSeparator = -1;
|
|
214
|
-
for (let i = closingSeparator - 1; i >= Math.max(0, closingSeparator - CLAUDE_INPUT_BOX_MAX_ROWS); i--) {
|
|
215
|
-
if (isSeparator(lines[i])) {
|
|
216
|
-
openingSeparator = i;
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
if (openingSeparator < 0)
|
|
221
|
-
return -1;
|
|
222
|
-
// Confirm the rows between the separators really are the input box rather than
|
|
223
|
-
// a reply that happens to be fenced by two horizontal rules — truncating one of
|
|
224
|
-
// those would silently swallow the tail of a genuine response.
|
|
225
|
-
if (!/^[>❯]/.test((0, ansi_1.stripAnsi)(lines[openingSeparator + 1] ?? '')))
|
|
201
|
+
// Issue #1879: the structural search (closing separator → opening separator →
|
|
202
|
+
// prompt glyph, including the "is this really the input box and not a reply
|
|
203
|
+
// fenced by two horizontal rules?" check) moved to `findClaudeInputBox` so the
|
|
204
|
+
// composer reader locates the same box this trimmer does. Behaviour here is
|
|
205
|
+
// unchanged; only the caller of the search moved.
|
|
206
|
+
const box = (0, composer_text_1.findClaudeInputBox)(lines);
|
|
207
|
+
if (box === null)
|
|
226
208
|
return -1;
|
|
227
209
|
// Include the reserved hint row directly above the opening separator.
|
|
228
|
-
return Math.max(0, openingSeparator - 1);
|
|
210
|
+
return Math.max(0, box.openingSeparator - 1);
|
|
229
211
|
}
|
|
230
212
|
/**
|
|
231
213
|
* Claude trust dialog pattern (Issue #201)
|
|
@@ -670,6 +652,36 @@ exports.GEMINI_THINKING_PATTERN = /[\u2800-\u28FF]|Thinking\.\.\./;
|
|
|
670
652
|
* Unlike Claude/Codex (which use > or ❯), OpenCode uses a text-based prompt indicator.
|
|
671
653
|
*/
|
|
672
654
|
exports.OPENCODE_PROMPT_PATTERN = /Ask anything\.\.\./;
|
|
655
|
+
/**
|
|
656
|
+
* OpenCode idle composer pattern (Issue #1883).
|
|
657
|
+
*
|
|
658
|
+
* The `Ask anything...` placeholder as opencode actually draws it: **inside the
|
|
659
|
+
* input box**, behind the box's own gutter (`\u2503`, or `\u2502` on a lighter
|
|
660
|
+
* border style). Two measured facts make that row positive evidence that the
|
|
661
|
+
* composer is empty, rather than the mere absence of a busy marker (design
|
|
662
|
+
* principle D1 in `docs/design/multi-agent-state-architecture.md`):
|
|
663
|
+
*
|
|
664
|
+
* - opencode paints the placeholder **only while the input buffer is empty**.
|
|
665
|
+
* The first typed character replaces the whole row — measured live on
|
|
666
|
+
* opencode 1.18.20, pane 80x200 (`opencode-live-1883/composer-residual.txt`
|
|
667
|
+
* holds `\u2503 echo PREFILLED` where the idle frame holds the placeholder).
|
|
668
|
+
* - the gutter says the row belongs to the input box. `Ask anything...` printed
|
|
669
|
+
* in a response body has no gutter, and reading that as an idle composer is
|
|
670
|
+
* the "the phrase is on screen somewhere" inference D1 forbids.
|
|
671
|
+
*
|
|
672
|
+
* **Match this against the ANSI-stripped frame BEFORE {@link stripBoxDrawing}**,
|
|
673
|
+
* which strips the very gutter this pattern anchors on.
|
|
674
|
+
*
|
|
675
|
+
* The whitespace runs are `[^\S\n]` (horizontal only) on purpose: plain `\s`
|
|
676
|
+
* crosses newlines under the `m` flag, which let the gutter of one row pair up
|
|
677
|
+
* with the phrase several rows below it and matched frames that hold no
|
|
678
|
+
* composer at all (measured on `phrase-in-response.txt`).
|
|
679
|
+
*
|
|
680
|
+
* {@link OPENCODE_PROMPT_PATTERN} stays as it is: `response-checker` and
|
|
681
|
+
* `OPENCODE_SKIP_PATTERNS` want the bare phrase wherever it lands, because they
|
|
682
|
+
* are deleting the row from an extracted response, not judging a session.
|
|
683
|
+
*/
|
|
684
|
+
exports.OPENCODE_IDLE_COMPOSER_PATTERN = /^[^\S\n]*[\u2502\u2503][^\S\n]*Ask anything\.\.\./m;
|
|
673
685
|
/**
|
|
674
686
|
* OpenCode prompt pattern after response completion (Issue #379)
|
|
675
687
|
* Shows "tab agents ctrl+p commands" in the TUI status bar after a response finishes.
|
|
@@ -689,30 +701,410 @@ exports.OPENCODE_THINKING_PATTERN = /Thinking:/;
|
|
|
689
701
|
*/
|
|
690
702
|
exports.OPENCODE_LOADING_PATTERN = /\u2B1D{4,}/;
|
|
691
703
|
/**
|
|
692
|
-
* OpenCode
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
*
|
|
696
|
-
*
|
|
697
|
-
*
|
|
704
|
+
* OpenCode's Build summary LINE, in either of the two forms it is drawn in
|
|
705
|
+
* (Issue #379, corrected by Issue #1893).
|
|
706
|
+
*
|
|
707
|
+
* **This is a line filter, not completion evidence.** It matches
|
|
708
|
+
* `▣ <Action> · <model>` with the duration OPTIONAL, and opencode 1.18 draws
|
|
709
|
+
* that duration-less form on a step that is still in flight -- so a frame this
|
|
710
|
+
* pattern matches may be mid-turn, waiting on a permission dialog, or aborted.
|
|
711
|
+
* Use {@link OPENCODE_TURN_COMPLETE_PATTERN} to decide that a turn has finished.
|
|
712
|
+
*
|
|
713
|
+
* The docstring that stood here until #1893 claimed the opposite ("short
|
|
714
|
+
* responses may omit the timing portion"). Measured against opencode 1.18.21 at
|
|
715
|
+
* the production 80x200 geometry, that is wrong in both directions:
|
|
716
|
+
*
|
|
717
|
+
* - a 2.3-second answer still carries its duration
|
|
718
|
+
* (`▣ Build · GPT-5.6 Luna · 2.3s`, `opencode-live-1893/turn-complete-short.txt`),
|
|
719
|
+
* so no completed turn needs the duration-less branch;
|
|
720
|
+
* - the duration-less form is what opencode leaves on screen while a tool call
|
|
721
|
+
* waits for permission and after a rejected one
|
|
722
|
+
* (`opencode-live-1893/permission-bash.txt`, `…/turn-aborted-no-duration.txt`).
|
|
723
|
+
*
|
|
724
|
+
* Kept loose because three callers want the LINE rather than the verdict:
|
|
725
|
+
* `tui-accumulator.ts`, `response-cleaner.ts` and `polling/response-checker.ts`
|
|
726
|
+
* all use it to drop the summary row from an extracted response, and the
|
|
727
|
+
* mid-step row has to be dropped too. #1911 removed the one caller that used it
|
|
728
|
+
* as a turn BOUNDARY rather than a line filter (the "second-to-last ▣" anchor,
|
|
729
|
+
* replaced by {@link findOpenCodeUserEchoEnd}); the name is left alone because
|
|
730
|
+
* the remaining three callers all want the line.
|
|
698
731
|
*/
|
|
699
|
-
exports.OPENCODE_RESPONSE_COMPLETE = /\u25A3\s+\w+\s
|
|
732
|
+
exports.OPENCODE_RESPONSE_COMPLETE = /\u25A3\s+\w+\s+·\s+\S+(?:\s+·\s+(?:[\d]+h\s*)?(?:[\d]+m\s*)?[\d.]+s)?/;
|
|
700
733
|
/**
|
|
701
|
-
* OpenCode
|
|
702
|
-
*
|
|
703
|
-
*
|
|
734
|
+
* OpenCode's finished-turn marker: the Build summary line WITH its duration
|
|
735
|
+
* (Issue #1893).
|
|
736
|
+
*
|
|
737
|
+
* `▣ Build · GPT-5.6 Luna · 5.2s`. This is the one tool-specific completion
|
|
738
|
+
* marker design rule D1 recognises today
|
|
739
|
+
* (`docs/design/multi-agent-state-architecture.md` §4 D1 decision 1, item 1),
|
|
740
|
+
* and the duration is the whole of what makes it positive evidence: opencode
|
|
741
|
+
* prints the same row without a duration while a step is still open, which is
|
|
742
|
+
* how a session parked on a permission dialog was published as
|
|
743
|
+
* `ready`/`opencode_response_complete` (#1893) and how `isOpenCodeComplete`
|
|
744
|
+
* saved the dialog body as if it were an answer.
|
|
745
|
+
*
|
|
746
|
+
* The model segment is `[^·\n]+` rather than `\S+` because real model names
|
|
747
|
+
* carry spaces (`GPT-5.6 Luna`): with `\S+` the optional-duration group of
|
|
748
|
+
* {@link OPENCODE_RESPONSE_COMPLETE} could never reach the duration on a
|
|
749
|
+
* two-word model, so "with duration" and "without duration" were the same match
|
|
750
|
+
* there. Excluding the middle dot rather than allowing anything keeps the
|
|
751
|
+
* quantifier unable to swallow its own delimiter (no nested/ambiguous
|
|
752
|
+
* quantifier -- ReDoS safe), and `.`/`[^·\n]` never cross a line without the
|
|
753
|
+
* `m` flag, so the duration has to be on the marker's own row.
|
|
754
|
+
*
|
|
755
|
+
* Durations observed: `2.3s`, `5.2s`, `45.2s`; the `Nh`/`Nm` prefixes are
|
|
756
|
+
* inherited from the #379 pattern and kept for long turns.
|
|
757
|
+
*/
|
|
758
|
+
exports.OPENCODE_TURN_COMPLETE_PATTERN = /\u25A3\s+\w+\s+·\s+[^·\n]+·\s+(?:\d+h\s*)?(?:\d+m\s*)?[\d.]+s/;
|
|
759
|
+
/**
|
|
760
|
+
* OpenCode's permission dialog, anchored on its button row (Issue #1893).
|
|
761
|
+
*
|
|
762
|
+
* opencode 1.18 asks for tool permission with a bottom-anchored box whose last
|
|
763
|
+
* interactive row is a horizontal button strip:
|
|
764
|
+
*
|
|
765
|
+
* ```
|
|
766
|
+
* ┃ △ Permission required
|
|
767
|
+
* ┃ # Shell command
|
|
768
|
+
* ┃ $ ls -la
|
|
769
|
+
* ┃ Allow once Allow always Reject ctrl+f fullscreen ⇆ select enter con
|
|
770
|
+
* ```
|
|
771
|
+
*
|
|
772
|
+
* Nothing in the detection layer saw it before #1893: it carries no number, no
|
|
773
|
+
* `(y/n)`, and no "press enter to confirm" footer, so `detectPrompt` answers
|
|
774
|
+
* `isPrompt: false` and the status detector fell through to the Build marker
|
|
775
|
+
* above it. The row is matched as POSITIVE evidence that a decision is pending
|
|
776
|
+
* (design rule D1) -- it is the affordance itself, not the absence of a busy
|
|
777
|
+
* marker.
|
|
778
|
+
*
|
|
779
|
+
* **Match this against the ANSI-stripped frame BEFORE {@link stripBoxDrawing}**,
|
|
780
|
+
* exactly like {@link OPENCODE_IDLE_COMPOSER_PATTERN}: the leading `┃` (or
|
|
781
|
+
* `│` on a lighter border style) is what says the row belongs to the dialog box
|
|
782
|
+
* rather than to a response body that happens to quote the labels -- the
|
|
783
|
+
* "the phrase is on screen somewhere" inference #1883 had to remove.
|
|
784
|
+
*
|
|
785
|
+
* Deliberately NOT anchored on:
|
|
786
|
+
*
|
|
787
|
+
* - `enter confirm`, which is truncated to `enter con` at opencode's own 80
|
|
788
|
+
* column layout (measured);
|
|
789
|
+
* - `△ Permission required` alone, which is a heading rather than an
|
|
790
|
+
* affordance and survives in the fullscreen (`ctrl+f`) view whose key handling
|
|
791
|
+
* was not measured.
|
|
792
|
+
*
|
|
793
|
+
* The three labels are the same for the `bash` and the `edit` dialog (measured:
|
|
794
|
+
* `permission-bash.txt`, `permission-edit.txt`), and the strip is repainted away
|
|
795
|
+
* the moment the dialog is answered, so a matched row is never scrollback
|
|
796
|
+
* (`turn-aborted-no-duration.txt` holds no `Allow once`).
|
|
797
|
+
*
|
|
798
|
+
* The whitespace runs are `[^\S\n]` (horizontal only) for the reason #1883
|
|
799
|
+
* documents: plain `\s` crosses newlines under the `m` flag and would pair a
|
|
800
|
+
* gutter on one row with labels several rows below it.
|
|
801
|
+
*/
|
|
802
|
+
exports.OPENCODE_PERMISSION_PATTERN = /^[^\S\n]*[\u2502\u2503][^\S\n]*Allow once[^\S\n]+Allow always[^\S\n]+Reject\b/m;
|
|
803
|
+
/**
|
|
804
|
+
* OpenCode's busy footer, in BOTH of the spellings it is drawn in (Issue #379,
|
|
805
|
+
* widened by Issue #1894).
|
|
806
|
+
*
|
|
807
|
+
* opencode 1.18 needs Escape TWICE to abort a turn, and the first press does not
|
|
808
|
+
* abort anything -- it re-labels the footer:
|
|
809
|
+
*
|
|
810
|
+
* ```
|
|
811
|
+
* ⬝⬝⬝⬝⬝⬝⬝⬝ esc interrupt 6.5K (1%) · $0.00 ctrl+p commands
|
|
812
|
+
* ⬝■■■■■■⬝ esc again to interrupt 7.2K (1%) · $0.00 ctrl+p commands
|
|
813
|
+
* ```
|
|
814
|
+
*
|
|
815
|
+
* Measured on opencode 1.18.21 at the production 80x200 geometry, sampling the
|
|
816
|
+
* footer every ~360 ms after a single Escape: the second spelling is up from
|
|
817
|
+
* 0.31 s to 4.71 s and the row is back to `esc interrupt` at 5.07 s -- a
|
|
818
|
+
* five-second window, exactly as long as the second-press deadline
|
|
819
|
+
* ({@link OPENCODE_INTERRUPT_SECOND_ESCAPE_DELAY_MS} is sized against it). The
|
|
820
|
+
* generation continues throughout; the turn ran to a natural
|
|
821
|
+
* `▣ Build · GPT-5.6 Luna · 11.3s`, 3 runs out of 3.
|
|
822
|
+
*
|
|
823
|
+
* Before #1894 those five seconds matched nothing at all: `detectSessionStatus`
|
|
824
|
+
* lost branch A and fell through to `running`/`default` while the frame was
|
|
825
|
+
* fresh, and to `ready`/`no_recent_output` once the poller's
|
|
826
|
+
* `lastOutputTimestamp` aged past `STALE_OUTPUT_THRESHOLD_MS` -- both of them
|
|
827
|
+
* `statusEvidence: 'none'`, i.e. a generating session
|
|
828
|
+
* published with no evidence and, on the second path, as FINISHED. That is the
|
|
829
|
+
* "vocabulary changed, so `ready` came back" failure design rule D1 names
|
|
830
|
+
* (`docs/design/multi-agent-state-architecture.md` §4 D1, row #1894), and the
|
|
831
|
+
* row is the same positive busy evidence in either spelling.
|
|
832
|
+
*
|
|
833
|
+
* The optional group is `(?:again to )?` rather than a looser `.*` on purpose:
|
|
834
|
+
* it matches the two measured strings and nothing between an `esc` and an
|
|
835
|
+
* `interrupt` several words apart. Linear, no nested quantifiers -- ReDoS safe.
|
|
836
|
+
*
|
|
837
|
+
* Filtered from response extraction via OPENCODE_SKIP_PATTERNS, which shares
|
|
838
|
+
* this constant: the widened row is dropped from a saved answer for the same
|
|
839
|
+
* reason the narrow one was.
|
|
704
840
|
*/
|
|
705
|
-
exports.OPENCODE_PROCESSING_INDICATOR = /esc interrupt/;
|
|
841
|
+
exports.OPENCODE_PROCESSING_INDICATOR = /esc (?:again to )?interrupt/;
|
|
706
842
|
/**
|
|
707
|
-
* OpenCode
|
|
708
|
-
* Detects the fuzzy-search selection list overlay in OpenCode TUI
|
|
709
|
-
* (e.g., /models, /providers, /connect commands).
|
|
843
|
+
* OpenCode's composer bottom border: ` ╹▀▀▀▀▀▀…` (Issue #1911).
|
|
710
844
|
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
845
|
+
* `╹` (heavy up) is the corner opencode joins the input box's `┃`
|
|
846
|
+
* gutter to, and the `▀` run is the box's bottom edge. It is the one row of
|
|
847
|
+
* the bottom-anchored chrome that can never appear inside a response body, which
|
|
848
|
+
* makes it the anchor {@link findOpenCodeChromeStart} walks up from.
|
|
714
849
|
*/
|
|
715
|
-
exports.
|
|
850
|
+
exports.OPENCODE_COMPOSER_BOTTOM_BORDER = /^[^\S\n]*╹▀{4,}/;
|
|
851
|
+
/**
|
|
852
|
+
* A row that belongs to one of opencode's boxes, matched by its own gutter
|
|
853
|
+
* (Issue #1911).
|
|
854
|
+
*
|
|
855
|
+
* opencode draws three different boxes with the same `┃` gutter (`│`
|
|
856
|
+
* on a lighter border style): the echoed USER PROMPT in the transcript, the
|
|
857
|
+
* COMPOSER pinned to the bottom of the pane, and the PERMISSION DIALOG that
|
|
858
|
+
* replaces the composer. Which one a matched row belongs to is decided by where
|
|
859
|
+
* it sits, not by what it says — see {@link findOpenCodeChromeStart} and
|
|
860
|
+
* {@link findOpenCodeUserEchoEnd}.
|
|
861
|
+
*
|
|
862
|
+
* **Match against the ANSI-stripped frame BEFORE {@link stripBoxDrawing}**,
|
|
863
|
+
* which removes the very gutter this anchors on.
|
|
864
|
+
*/
|
|
865
|
+
exports.OPENCODE_GUTTER_ROW_PATTERN = /^[^\S\n]*[│┃]/;
|
|
866
|
+
/**
|
|
867
|
+
* An echoed user prompt row: a gutter row that carries text (Issue #1911).
|
|
868
|
+
*
|
|
869
|
+
* The echo block opencode draws for a submitted message is a blank gutter row,
|
|
870
|
+
* one or more gutter rows holding the message, and another blank gutter row.
|
|
871
|
+
* This matches the middle ones.
|
|
872
|
+
*/
|
|
873
|
+
exports.OPENCODE_USER_ECHO_PATTERN = /^[^\S\n]*[│┃][^\S\n]*\S/;
|
|
874
|
+
/**
|
|
875
|
+
* The status cell of opencode's bottom footer (Issue #1911).
|
|
876
|
+
*
|
|
877
|
+
* Measured at the production 80x200 geometry the footer reads
|
|
878
|
+
* `<cwd> 6.4K (1%) · $ctrl+p` / `commands` while idle and
|
|
879
|
+
* `⬝⬝⬝⬝⬝⬝⬝⬝ esc interrupt 6.3K (1%) · $0.00 ctrl+p commands` while running:
|
|
880
|
+
* a context-usage cell followed by the cost sigil. Neither
|
|
881
|
+
* {@link OPENCODE_PROMPT_AFTER_RESPONSE} (`tab agents ctrl+p commands`, which
|
|
882
|
+
* opencode only prints on the FIRST idle frame, before any turn has run) nor
|
|
883
|
+
* {@link OPENCODE_PROCESSING_INDICATOR} covers the idle form, so this row used
|
|
884
|
+
* to be saved as part of the assistant's reply.
|
|
885
|
+
*
|
|
886
|
+
* This is a SECONDARY net. The cwd that shares the row wraps over up to three
|
|
887
|
+
* further rows that carry no signature at all, so the footer is removed
|
|
888
|
+
* structurally by {@link findOpenCodeChromeStart}; this pattern only catches the
|
|
889
|
+
* signed row when that boundary is not available (e.g. a caller holding a
|
|
890
|
+
* fragment rather than a whole pane).
|
|
891
|
+
*
|
|
892
|
+
* Linear, no nested quantifiers — ReDoS safe.
|
|
893
|
+
*/
|
|
894
|
+
exports.OPENCODE_FOOTER_STATUS_PATTERN = /\d+(?:\.\d+)?[KMGT]?\s+\(\d+%\)\s+·\s+\$/;
|
|
895
|
+
/**
|
|
896
|
+
* Locate the start of opencode's bottom-anchored chrome within a captured pane
|
|
897
|
+
* (Issue #1911).
|
|
898
|
+
*
|
|
899
|
+
* opencode runs in the alternate screen and reserves the last rows of the pane
|
|
900
|
+
* for chrome that is never transcript content:
|
|
901
|
+
*
|
|
902
|
+
* ```
|
|
903
|
+
* ┃ ← composer box (blank rows + model row),
|
|
904
|
+
* ┃ Build · GPT-5.6 Luna … or the permission dialog that replaces it
|
|
905
|
+
* ╹▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ← composer bottom border
|
|
906
|
+
* /private/tmp/…-share- 6.4K (1%) · $ctrl+p ← footer, cwd wrapped
|
|
907
|
+
* work-github-kewton-… commands over up to three rows
|
|
908
|
+
* ```
|
|
909
|
+
*
|
|
910
|
+
* Everything from the returned index down is chrome. This is the opencode twin
|
|
911
|
+
* of {@link findClaudeChromeStart} and exists for the same reason (#1289): the
|
|
912
|
+
* footer's cwd rows and the composer's model row were reaching saved responses,
|
|
913
|
+
* which is defect 1 of #1911.
|
|
914
|
+
*
|
|
915
|
+
* Found structurally rather than by matching footer text, because the footer's
|
|
916
|
+
* text is opencode's to change and two of its four rows (the cwd continuations)
|
|
917
|
+
* are an arbitrary filesystem path with no signature at all.
|
|
918
|
+
*
|
|
919
|
+
* @param lines - Captured pane lines, ANSI-stripped, box drawing intact.
|
|
920
|
+
* Trailing blank rows are tolerated.
|
|
921
|
+
* @returns Index of the first chrome row, or -1 when no chrome is recognisable.
|
|
922
|
+
*/
|
|
923
|
+
function findOpenCodeChromeStart(lines) {
|
|
924
|
+
let last = lines.length - 1;
|
|
925
|
+
while (last >= 0 && lines[last].trim() === '')
|
|
926
|
+
last--;
|
|
927
|
+
if (last < 0)
|
|
928
|
+
return -1;
|
|
929
|
+
const walkUpGutter = (from) => {
|
|
930
|
+
let top = from;
|
|
931
|
+
while (top - 1 >= 0 && exports.OPENCODE_GUTTER_ROW_PATTERN.test(lines[top - 1]))
|
|
932
|
+
top--;
|
|
933
|
+
return top;
|
|
934
|
+
};
|
|
935
|
+
// The composer's bottom border. Searched from the last row upwards over the
|
|
936
|
+
// WHOLE pane rather than over the few rows the footer occupies: on the boot
|
|
937
|
+
// screen opencode centres the composer under its banner (row ~99 of 200) while
|
|
938
|
+
// the footer stays pinned to the bottom, so a window sized for the footer
|
|
939
|
+
// misses the border entirely (measured, `opencode-live-1883/boot-idle.txt`).
|
|
940
|
+
for (let i = last; i >= 0; i--) {
|
|
941
|
+
if (exports.OPENCODE_COMPOSER_BOTTOM_BORDER.test(lines[i])) {
|
|
942
|
+
return walkUpGutter(i);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
// No border: the permission dialog draws over the composer and its own box
|
|
946
|
+
// runs to the last row of the pane (measured, `opencode-live-1893/permission-*.txt`).
|
|
947
|
+
if (exports.OPENCODE_GUTTER_ROW_PATTERN.test(lines[last])) {
|
|
948
|
+
return walkUpGutter(last);
|
|
949
|
+
}
|
|
950
|
+
return -1;
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Locate the last row of the NEWEST echoed user prompt in a captured pane
|
|
954
|
+
* (Issue #1911).
|
|
955
|
+
*
|
|
956
|
+
* The turn currently being answered starts on the row after this one, so it is
|
|
957
|
+
* both the extraction anchor (`resolveExtractionStartIndex`'s opencode branch)
|
|
958
|
+
* and the floor the finished-turn marker has to sit below before a frame counts
|
|
959
|
+
* as a completed turn (`isOpenCodeComplete`).
|
|
960
|
+
*
|
|
961
|
+
* Before #1911 the anchor was "the second-to-last `▣ Build` row", which has two
|
|
962
|
+
* measured failure modes: on the first turn of a session there is no second row,
|
|
963
|
+
* so extraction fell back to line 0 and saved the whole pane; and the row it
|
|
964
|
+
* anchors on belongs to the PREVIOUS turn, so the echoed prompt of the current
|
|
965
|
+
* one was always included in the reply.
|
|
966
|
+
*
|
|
967
|
+
* @param lines - Captured pane lines, ANSI-stripped, box drawing intact.
|
|
968
|
+
* @param chromeStart - Result of {@link findOpenCodeChromeStart}; the search
|
|
969
|
+
* stops above it so the composer's and the permission dialog's own gutter rows
|
|
970
|
+
* are never read as an echoed prompt. Pass -1 when no chrome was found.
|
|
971
|
+
* @returns Index of the echo block's last row, or -1 when no echo is on screen
|
|
972
|
+
* (a turn whose head has scrolled out of the alternate-screen pane).
|
|
973
|
+
*/
|
|
974
|
+
function findOpenCodeUserEchoEnd(lines, chromeStart) {
|
|
975
|
+
const limit = chromeStart >= 0 ? chromeStart : lines.length;
|
|
976
|
+
for (let i = limit - 1; i >= 0; i--) {
|
|
977
|
+
if (!exports.OPENCODE_USER_ECHO_PATTERN.test(lines[i]))
|
|
978
|
+
continue;
|
|
979
|
+
// The block's trailing blank gutter row(s) belong to the echo, not to the reply.
|
|
980
|
+
let end = i;
|
|
981
|
+
while (end + 1 < limit && exports.OPENCODE_GUTTER_ROW_PATTERN.test(lines[end + 1]))
|
|
982
|
+
end++;
|
|
983
|
+
return end;
|
|
984
|
+
}
|
|
985
|
+
return -1;
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* The rows of opencode's composer that hold the INPUT BUFFER (Issue #1906).
|
|
989
|
+
*
|
|
990
|
+
* opencode has no prompt marker — no `>` / `❯` / `›` anywhere near its input —
|
|
991
|
+
* so "is the message still sitting in the composer?" cannot be asked the way it
|
|
992
|
+
* is asked of every other TUI. What opencode has instead is a box, and the box
|
|
993
|
+
* has a fixed shape, measured at the production 80x200 geometry across every
|
|
994
|
+
* frame in `opencode-live-1883/`, `opencode-live-1893/` and
|
|
995
|
+
* `opencode-live-1906/`:
|
|
996
|
+
*
|
|
997
|
+
* ```
|
|
998
|
+
* ┃ ← buffer rows: blank when empty,
|
|
999
|
+
* ┃ Review the send path. one row per (wrapped) line of the
|
|
1000
|
+
* ┃ Check newline handling. typed message, or the
|
|
1001
|
+
* ┃ Report findings. `Ask anything...` placeholder on a
|
|
1002
|
+
* ┃ session that has not answered yet
|
|
1003
|
+
* ┃ Build · GPT-5.6 Luna GitHub Copilot ← the agent/model row, ALWAYS last
|
|
1004
|
+
* ╹▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ← the box's bottom border
|
|
1005
|
+
* ```
|
|
1006
|
+
*
|
|
1007
|
+
* The agent/model row is what makes a naive "any guttered row with text" read
|
|
1008
|
+
* wrong: it always carries text, so the composer would never look empty. It is
|
|
1009
|
+
* identified structurally — the last gutter row before the border — rather than
|
|
1010
|
+
* by matching `Build ·` or a model name, both of which are opencode's to change
|
|
1011
|
+
* and neither of which is stable across agents (`Build`, `Plan`, a custom agent).
|
|
1012
|
+
*
|
|
1013
|
+
* Anchored on the border, not on the bottom of the pane, because opencode
|
|
1014
|
+
* centres the whole box under its banner before the first turn (row ~100 of 200)
|
|
1015
|
+
* and only pins it to the bottom afterwards — see {@link findOpenCodeChromeStart},
|
|
1016
|
+
* whose upward walk this shares.
|
|
1017
|
+
*
|
|
1018
|
+
* Returns `null` when no composer is on screen at all. That is the permission
|
|
1019
|
+
* dialog (it replaces the composer and draws no bottom border — measured,
|
|
1020
|
+
* `opencode-live-1893/permission-*.txt`), a full-screen overlay, or a session
|
|
1021
|
+
* still starting.
|
|
1022
|
+
*
|
|
1023
|
+
* @param lines - Captured pane lines, ANSI-stripped, box drawing intact. Must be
|
|
1024
|
+
* the WHOLE pane: a tail window sized for the other tools does not contain the
|
|
1025
|
+
* box on a pre-first-turn frame.
|
|
1026
|
+
* @returns The buffer rows with their gutters intact, or `null` when the
|
|
1027
|
+
* composer is not on screen. An empty array means a box with no buffer row,
|
|
1028
|
+
* which no measured frame produces.
|
|
1029
|
+
*/
|
|
1030
|
+
function findOpenCodeComposerRows(lines) {
|
|
1031
|
+
let border = -1;
|
|
1032
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
1033
|
+
if (exports.OPENCODE_COMPOSER_BOTTOM_BORDER.test(lines[i])) {
|
|
1034
|
+
border = i;
|
|
1035
|
+
break;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
if (border < 0)
|
|
1039
|
+
return null;
|
|
1040
|
+
let top = border;
|
|
1041
|
+
while (top - 1 >= 0 && exports.OPENCODE_GUTTER_ROW_PATTERN.test(lines[top - 1]))
|
|
1042
|
+
top--;
|
|
1043
|
+
// `top .. border - 1` are the box's gutter rows; the last of them is the
|
|
1044
|
+
// agent/model row, which belongs to the chrome rather than to the buffer.
|
|
1045
|
+
const modelRow = border - 1;
|
|
1046
|
+
if (modelRow < top)
|
|
1047
|
+
return null;
|
|
1048
|
+
return lines.slice(top, modelRow);
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* A composer row with its gutter (and the padding either side) removed
|
|
1052
|
+
* (Issue #1906). Blank for an empty buffer row.
|
|
1053
|
+
*/
|
|
1054
|
+
function stripOpenCodeGutter(row) {
|
|
1055
|
+
return row.replace(exports.OPENCODE_GUTTER_ROW_PATTERN, '').trim();
|
|
1056
|
+
}
|
|
1057
|
+
/**
|
|
1058
|
+
* OpenCode TUI selection list pattern (Issue #473, narrowed by Issue #1896).
|
|
1059
|
+
*
|
|
1060
|
+
* Detects the fuzzy-search picker overlay opencode draws for `/models`,
|
|
1061
|
+
* `/providers` and `/connect`, anchored on its HEADER ROW COMPLETE WITH the
|
|
1062
|
+
* right-aligned `esc` hatch:
|
|
1063
|
+
*
|
|
1064
|
+
* ```
|
|
1065
|
+
* Select model esc
|
|
1066
|
+
*
|
|
1067
|
+
* Search
|
|
1068
|
+
*
|
|
1069
|
+
* Recent
|
|
1070
|
+
* ● GPT-5.6 Luna GitHub Copilot
|
|
1071
|
+
* ```
|
|
1072
|
+
*
|
|
1073
|
+
* The `esc` is the picker's own dismiss affordance -- positive evidence that an
|
|
1074
|
+
* overlay is open (design rule D1), rather than the presence of two English
|
|
1075
|
+
* words somewhere on the pane. Until #1896 the pattern was the bare phrase, and
|
|
1076
|
+
* `status-detector.ts` tests it against the WHOLE content area (up to ~200 rows,
|
|
1077
|
+
* because the header can sit far above the last row when the list is long), so
|
|
1078
|
+
* an agent that merely wrote `Select model to continue:` in its answer parked the
|
|
1079
|
+
* session on `waiting` / `opencode_selection_list` for the rest of the session
|
|
1080
|
+
* -- measured live on opencode 1.18.21,
|
|
1081
|
+
* `opencode-live-1896/select-model-in-response.txt`.
|
|
1082
|
+
*
|
|
1083
|
+
* Requiring two or more spaces before `esc` is what separates the header row
|
|
1084
|
+
* from prose: the picker right-aligns the hatch across the overlay's width
|
|
1085
|
+
* (37 spaces in the measured frame), while a sentence that happens to end in
|
|
1086
|
+
* "esc" would not.
|
|
1087
|
+
*
|
|
1088
|
+
* NOT additionally anchored on the `Search` row below the header: its distance
|
|
1089
|
+
* from the header is unmeasured for the `Connect a provider` variant (that
|
|
1090
|
+
* overlay needs an unconfigured provider to open, which the live probe could not
|
|
1091
|
+
* produce without touching the operator's real credentials), and the header's
|
|
1092
|
+
* own hatch is already the affordance.
|
|
1093
|
+
*
|
|
1094
|
+
* The header allowlist is deliberately unchanged. opencode 1.18 draws the same
|
|
1095
|
+
* chrome for its ctrl+p command palette (`Commands … esc`), which this pattern
|
|
1096
|
+
* therefore still does not match; that frame lands on `running` / `default`
|
|
1097
|
+
* (measured, `opencode-live-1896/command-palette.txt`) -- i.e. on the
|
|
1098
|
+
* "no evidence" side, which #1708's unclassified-frame guard already covers.
|
|
1099
|
+
* Widening the allowlist is a separate change with its own live frames.
|
|
1100
|
+
*
|
|
1101
|
+
* The whitespace runs are `[^\S\n]` (horizontal only) for the reason Issue #1883
|
|
1102
|
+
* documents: plain `\s` crosses newlines under the `m` flag, which would let a
|
|
1103
|
+
* header on one row pair up with an `esc` several rows below it.
|
|
1104
|
+
*
|
|
1105
|
+
* Linear pattern, no nested quantifiers -- ReDoS safe (S4-001).
|
|
1106
|
+
*/
|
|
1107
|
+
exports.OPENCODE_SELECTION_LIST_PATTERN = /^[^\S\n]*(?:Select[^\S\n]+(?:model|provider)|Connect[^\S\n]+a[^\S\n]+provider)[^\S\n]{2,}esc[^\S\n]*$/m;
|
|
716
1108
|
/**
|
|
717
1109
|
* [Issue #1495] Footer signature of Claude Code's `/model` local-settings overlay.
|
|
718
1110
|
* Verified against a real Claude Code v2.1.218 capture, the footer reads:
|
|
@@ -758,7 +1150,8 @@ exports.OPENCODE_SEPARATOR_PATTERN = /^[\u2503\u2579\u25A3\u2580\u2500\u250C\u25
|
|
|
758
1150
|
* OpenCode skip patterns for response cleaning (Issue #379)
|
|
759
1151
|
* Lines matching any of these patterns are filtered from extracted responses.
|
|
760
1152
|
* Includes: TUI separators, loading indicators, Build summary prefix,
|
|
761
|
-
* status bar prompts, processing indicators, input prompt,
|
|
1153
|
+
* status bar prompts, processing indicators, input prompt, the footer's
|
|
1154
|
+
* context/cost status cell (Issue #1911), and pasted text markers.
|
|
762
1155
|
*/
|
|
763
1156
|
exports.OPENCODE_SKIP_PATTERNS = [
|
|
764
1157
|
exports.OPENCODE_SEPARATOR_PATTERN,
|
|
@@ -767,6 +1160,7 @@ exports.OPENCODE_SKIP_PATTERNS = [
|
|
|
767
1160
|
exports.OPENCODE_PROMPT_AFTER_RESPONSE,
|
|
768
1161
|
exports.OPENCODE_PROCESSING_INDICATOR,
|
|
769
1162
|
exports.OPENCODE_PROMPT_PATTERN,
|
|
1163
|
+
exports.OPENCODE_FOOTER_STATUS_PATTERN,
|
|
770
1164
|
exports.PASTED_TEXT_PATTERN,
|
|
771
1165
|
];
|
|
772
1166
|
/**
|
|
@@ -787,24 +1181,432 @@ exports.COPILOT_PROMPT_PATTERN = /^[>❯]\s|^\?\s+/m;
|
|
|
787
1181
|
* Note: "Esc to cancel" alone is not used because trust dialog footer also contains it.
|
|
788
1182
|
* Instead, match the action pattern with parenthesized context: "(Esc to cancel ·"
|
|
789
1183
|
* Braille spinner characters (U+2800-U+28FF) are also checked.
|
|
1184
|
+
*
|
|
1185
|
+
* Issue #1897: the bare words `Generating` and `Processing` were dropped. This
|
|
1186
|
+
* constant is also a member of {@link COPILOT_SKIP_PATTERNS}, so every
|
|
1187
|
+
* alternative here doubles as a "delete this line from the saved response" rule
|
|
1188
|
+
* and as the tail-window liveness test in `extractResponse`. Those two words are
|
|
1189
|
+
* ordinary English -- a reply whose last line reads "Processing complete." had
|
|
1190
|
+
* the line deleted AND pinned the turn to "still thinking" for as long as it was
|
|
1191
|
+
* on screen, so the response was never saved at all. The remaining alternatives
|
|
1192
|
+
* are all glyph- or punctuation-shaped and cannot occur in prose by accident.
|
|
1193
|
+
* Nothing is lost as a running signal either: #1885 measured 0 matches for this
|
|
1194
|
+
* whole pattern across 44 live generating frames of copilot 1.0.80, whose turn
|
|
1195
|
+
* state is read from the status bar by {@link readCopilotStatusBar} instead.
|
|
790
1196
|
*/
|
|
791
|
-
exports.COPILOT_THINKING_PATTERN = /[\u2800-\u28FF]|\(Esc to cancel|Reasoning\s+[■▪▮]|\.\.\.\s+Thinking
|
|
1197
|
+
exports.COPILOT_THINKING_PATTERN = /[\u2800-\u28FF]|\(Esc to cancel|Reasoning\s+[■▪▮]|\.\.\.\s+Thinking/;
|
|
1198
|
+
/**
|
|
1199
|
+
* Copilot CLI's bottom status bar while a turn is in flight (Issue #1885).
|
|
1200
|
+
*
|
|
1201
|
+
* Measured on copilot 1.0.80 at the production 200x1000 geometry
|
|
1202
|
+
* (`tests/unit/lib/detection/fixtures/copilot-live-1885/`). The bar is the
|
|
1203
|
+
* bottom row of the pane and reads, across 44 captured generating frames:
|
|
1204
|
+
*
|
|
1205
|
+
* " ● Working esc interrupt GPT-5.6 Terra"
|
|
1206
|
+
* " ◉ Working · 1.5 KiB esc interrupt GPT-5.6 Terra"
|
|
1207
|
+
*
|
|
1208
|
+
* The leading glyph cycles through ● ◉ ◎ ○ and the byte counter appears only
|
|
1209
|
+
* once the turn has produced output, so neither is anchored on. `esc interrupt`
|
|
1210
|
+
* is the affordance hint copilot draws for as long as the turn can be
|
|
1211
|
+
* interrupted -- it is on every generating frame and on every tool-execution
|
|
1212
|
+
* frame -- which makes it the same signal opencode's
|
|
1213
|
+
* {@link OPENCODE_PROCESSING_INDICATOR} rests on.
|
|
1214
|
+
*
|
|
1215
|
+
* It is matched against the STATUS BAR ROW ONLY, never a window
|
|
1216
|
+
* (see {@link readCopilotStatusBar}). `status-vocabulary-in-response.txt` is a
|
|
1217
|
+
* live frame where copilot was asked to print this vocabulary and answered
|
|
1218
|
+
* " ● Working esc interrupt" as body text: a window match would have pinned that
|
|
1219
|
+
* finished session to `running` for the rest of its life.
|
|
1220
|
+
*
|
|
1221
|
+
* No /g flag (S4-5: would make test() stateful). No quantifier over a
|
|
1222
|
+
* character class that can match its neighbour (SEC4-001: ReDoS safe).
|
|
1223
|
+
*/
|
|
1224
|
+
exports.COPILOT_WORKING_STATUS_PATTERN = /\besc\s+interrupt\b/;
|
|
1225
|
+
/**
|
|
1226
|
+
* Copilot CLI's bottom status bar while no turn is running (Issue #1885).
|
|
1227
|
+
*
|
|
1228
|
+
* The same row as {@link COPILOT_WORKING_STATUS_PATTERN}, in the state copilot
|
|
1229
|
+
* paints when it is NOT working:
|
|
1230
|
+
*
|
|
1231
|
+
* " ← open sidebar · / commands · ? help · tab next tab GPT-5.6 Terra"
|
|
1232
|
+
*
|
|
1233
|
+
* This is copilot's positive completion evidence under design rule D1
|
|
1234
|
+
* (`docs/design/multi-agent-state-architecture.md` §4 D1 decision 1, item 2):
|
|
1235
|
+
* the key-hint bar and the working bar are two renderings of one row, so seeing
|
|
1236
|
+
* the hints is an affirmative observation that the turn is over -- not the
|
|
1237
|
+
* absence of a busy marker somewhere on screen. The composer cannot carry that
|
|
1238
|
+
* evidence on copilot: `❯` between its two full-width rules is drawn during
|
|
1239
|
+
* generation too (measured on every frame of the running fixtures), which is
|
|
1240
|
+
* exactly why the always-visible prompt used to win at step 3 of
|
|
1241
|
+
* `detectSessionStatus` and report a generating session as ready.
|
|
1242
|
+
*
|
|
1243
|
+
* Two alternative spellings of one affordance, because copilot has reworded
|
|
1244
|
+
* this row before: 1.0.80 shows "? help", and the pre-1.0.79 wording survives
|
|
1245
|
+
* in {@link COPILOT_SKIP_PATTERNS} as "? for shortcuts". "/ commands" covers
|
|
1246
|
+
* the slash-command hint independently, so a rewording of either half alone
|
|
1247
|
+
* does not cost the tool its completion evidence.
|
|
1248
|
+
*
|
|
1249
|
+
* No /g flag (S4-5). Linear alternation, no nested quantifiers (SEC4-001).
|
|
1250
|
+
*/
|
|
1251
|
+
exports.COPILOT_IDLE_STATUS_PATTERN = /\/\s+commands\b|\?\s+(?:help\b|for\s+shortcuts\b)/;
|
|
1252
|
+
/**
|
|
1253
|
+
* Read copilot's bottom status bar out of a captured frame (Issue #1885).
|
|
1254
|
+
*
|
|
1255
|
+
* Takes the whole frame rather than a row so the positional anchor -- "the
|
|
1256
|
+
* status bar is the bottom row of the pane" -- cannot be lost at a call site.
|
|
1257
|
+
* The scan stops at the first non-blank row from the bottom: if that row is
|
|
1258
|
+
* neither state, this returns null and the caller has no evidence, which is the
|
|
1259
|
+
* D1-correct answer rather than a guess. Two measured frames rely on it:
|
|
1260
|
+
*
|
|
1261
|
+
* - a permission dialog replaces the whole bottom of the pane with its box, so
|
|
1262
|
+
* the bottom row is `╰───…` and neither pattern matches. The dialog then
|
|
1263
|
+
* reaches `detectPrompt` and is reported as `waiting`, unchanged.
|
|
1264
|
+
* - the `/model` picker ends in its own footer
|
|
1265
|
+
* ("↑/↓ to navigate · … · enter to select · esc to cancel"), which is not the
|
|
1266
|
+
* status bar either -- so this reports nothing about it and leaves that
|
|
1267
|
+
* screen to the selection-list branch (Issue #1895's subject).
|
|
1268
|
+
*
|
|
1269
|
+
* @param contentLines - Frame rows, ANSI already stripped, in pane order
|
|
1270
|
+
* @returns The state the bottom row announces, or null when it announces neither
|
|
1271
|
+
*/
|
|
1272
|
+
function readCopilotStatusBar(contentLines) {
|
|
1273
|
+
for (let i = contentLines.length - 1; i >= 0; i--) {
|
|
1274
|
+
const row = contentLines[i];
|
|
1275
|
+
if (row.trim() === '')
|
|
1276
|
+
continue;
|
|
1277
|
+
if (exports.COPILOT_WORKING_STATUS_PATTERN.test(row))
|
|
1278
|
+
return 'working';
|
|
1279
|
+
if (exports.COPILOT_IDLE_STATUS_PATTERN.test(row))
|
|
1280
|
+
return 'idle';
|
|
1281
|
+
return null;
|
|
1282
|
+
}
|
|
1283
|
+
return null;
|
|
1284
|
+
}
|
|
792
1285
|
/**
|
|
793
1286
|
* Copilot separator pattern (Issue #545)
|
|
794
1287
|
* Placeholder - to be updated after Phase 1 TUI investigation.
|
|
795
1288
|
*/
|
|
796
1289
|
exports.COPILOT_SEPARATOR_PATTERN = /^─{10,}$/m;
|
|
1290
|
+
/** How far above the bottom row copilot's closing rule may sit. */
|
|
1291
|
+
const COPILOT_STATUS_BAR_MAX_ROWS = 2;
|
|
1292
|
+
/** How many rows copilot's composer may span before the block stops looking like chrome. */
|
|
1293
|
+
const COPILOT_COMPOSER_MAX_ROWS = 40;
|
|
1294
|
+
/** A full-width horizontal rule, with or without the pane's leading padding. */
|
|
1295
|
+
const COPILOT_RULE_ROW = /^─{10,}$/;
|
|
1296
|
+
/** copilot's composer glyph: legacy `>` and current `❯`, at the pane's own indent. */
|
|
1297
|
+
const COPILOT_COMPOSER_GLYPH = /^ {0,2}[>❯]/;
|
|
797
1298
|
/**
|
|
798
|
-
*
|
|
799
|
-
*
|
|
800
|
-
*
|
|
801
|
-
*
|
|
802
|
-
*
|
|
1299
|
+
* Locate the start of copilot CLI's bottom-pinned chrome within a captured pane
|
|
1300
|
+
* (Issue #1897).
|
|
1301
|
+
*
|
|
1302
|
+
* copilot 1.0.80 runs on the alternate screen and reserves the last five rows of
|
|
1303
|
+
* the pane. Measured at the production 200x1000 geometry
|
|
1304
|
+
* (`tests/unit/lib/detection/fixtures/copilot-live-1885/`), with the transcript
|
|
1305
|
+
* ~970 rows above and nothing but padding in between:
|
|
1306
|
+
*
|
|
1307
|
+
* <cwd> [⎇ <branch>] Session: N AIC used
|
|
1308
|
+
* ──────────────────── ← opening rule
|
|
1309
|
+
* ❯ <composer>
|
|
1310
|
+
* ──────────────────── ← closing rule
|
|
1311
|
+
* ◉ Working · 1.5 KiB esc interrupt GPT-5.6 Terra ← status bar
|
|
1312
|
+
*
|
|
1313
|
+
* The boundary is found structurally -- closing rule, opening rule, composer
|
|
1314
|
+
* glyph -- and never by matching the status bar's wording. That is the same
|
|
1315
|
+
* reasoning {@link findClaudeChromeStart} records (#1289) plus the measurement
|
|
1316
|
+
* behind {@link COPILOT_WORKING_STATUS_PATTERN}: copilot will print its own
|
|
1317
|
+
* status-bar vocabulary as body text when asked to
|
|
1318
|
+
* (`status-vocabulary-in-response.txt` holds ` ● Working esc interrupt` as a
|
|
1319
|
+
* reply), so a vocabulary rule strong enough to delete the real bar also deletes
|
|
1320
|
+
* that reply. Position is the only thing that separates them.
|
|
1321
|
+
*
|
|
1322
|
+
* Without this trim the bar is transcript as far as every consumer is concerned:
|
|
1323
|
+
* it reached the TUI accumulator on every poll and was saved to History as the
|
|
1324
|
+
* agent's answer (#1897's headline symptom, ` Working esc interrupt GPT-5.6
|
|
1325
|
+
* Terra`), and its spinner glyph and byte counter change on every tick, so it
|
|
1326
|
+
* also defeats the content dedup the alternate-screen tools rely on (#1268).
|
|
1327
|
+
*
|
|
1328
|
+
* @param lines - Captured pane rows, ANSI-bearing or not; trailing blanks tolerated
|
|
1329
|
+
* @returns Index of the first chrome row, or -1 when the pane carries no chrome
|
|
1330
|
+
* (a permission dialog draws its box over the whole bottom of the pane, so
|
|
1331
|
+
* there is no composer and no bar -- those frames return -1 and are left to
|
|
1332
|
+
* `detectPrompt`, exactly as {@link readCopilotStatusBar} leaves them)
|
|
1333
|
+
*/
|
|
1334
|
+
function findCopilotChromeStart(lines) {
|
|
1335
|
+
const isRule = (line) => COPILOT_RULE_ROW.test((0, ansi_1.stripAnsi)(line).trim());
|
|
1336
|
+
let lastRow = lines.length - 1;
|
|
1337
|
+
while (lastRow >= 0 && (0, ansi_1.stripAnsi)(lines[lastRow]).trim() === '')
|
|
1338
|
+
lastRow--;
|
|
1339
|
+
if (lastRow < 0)
|
|
1340
|
+
return -1;
|
|
1341
|
+
let closingRule = -1;
|
|
1342
|
+
for (let i = lastRow; i >= Math.max(0, lastRow - COPILOT_STATUS_BAR_MAX_ROWS); i--) {
|
|
1343
|
+
if (isRule(lines[i])) {
|
|
1344
|
+
closingRule = i;
|
|
1345
|
+
break;
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
if (closingRule < 0)
|
|
1349
|
+
return -1;
|
|
1350
|
+
let openingRule = -1;
|
|
1351
|
+
for (let i = closingRule - 1; i >= Math.max(0, closingRule - COPILOT_COMPOSER_MAX_ROWS); i--) {
|
|
1352
|
+
if (isRule(lines[i])) {
|
|
1353
|
+
openingRule = i;
|
|
1354
|
+
break;
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
if (openingRule < 0)
|
|
1358
|
+
return -1;
|
|
1359
|
+
// Confirm the fenced rows are the composer rather than a reply that happens to
|
|
1360
|
+
// sit between two horizontal rules.
|
|
1361
|
+
if (!COPILOT_COMPOSER_GLYPH.test((0, ansi_1.stripAnsi)(lines[openingRule + 1] ?? '')))
|
|
1362
|
+
return -1;
|
|
1363
|
+
// The row above the opening rule is copilot's cwd/branch/session header, which
|
|
1364
|
+
// an overlay (the `/model` picker) replaces with a blank rather than with
|
|
1365
|
+
// transcript -- measured on all five non-dialog fixtures.
|
|
1366
|
+
return Math.max(0, openingRule - 1);
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* A row copilot draws as part of a box or a collapsed reasoning block
|
|
1370
|
+
* (Issue #1897).
|
|
1371
|
+
*
|
|
1372
|
+
* 1.0.80 renders the model's private reasoning as a `⌄ Thought for 41s` header
|
|
1373
|
+
* followed by rows that each begin `│ `, and draws dialogs inside `╭─╮`/`╰─╯`
|
|
1374
|
+
* frames. {@link COPILOT_SKIP_PATTERNS} already carries a `[╭╮╰╯│]` rule, but
|
|
1375
|
+
* `normalizeCopilotLine` deletes every U+2500..U+257F glyph *before* the skip
|
|
1376
|
+
* patterns are applied, so by the time that rule runs the row it is meant to
|
|
1377
|
+
* catch reads as ordinary prose -- which is how the TUI accumulator came to save
|
|
1378
|
+
* copilot's chain-of-thought as the reply. Matched against the ANSI-stripped row,
|
|
1379
|
+
* before normalisation.
|
|
1380
|
+
*
|
|
1381
|
+
* `─` is deliberately absent: a rule row is {@link COPILOT_SEPARATOR_PATTERN}'s
|
|
1382
|
+
* job, and `── heading ──` is content.
|
|
1383
|
+
*/
|
|
1384
|
+
exports.COPILOT_BOX_ROW_PATTERN = /^\s*[│└╰╭╮╯├┤┬┴┼]/;
|
|
1385
|
+
/**
|
|
1386
|
+
* copilot's collapsed-section header (Issue #1897).
|
|
803
1387
|
*
|
|
804
|
-
*
|
|
805
|
-
*
|
|
1388
|
+
* Measured on 1.0.80: `⌄ Thinking…` while the reasoning block is live, replaced
|
|
1389
|
+
* by `⌄ Thought for 41s` once the turn moves on. Anchored on the `⌄` disclosure
|
|
1390
|
+
* glyph rather than on the words, because "Thinking…" also occurs as body text
|
|
1391
|
+
* -- `status-vocabulary-in-response.txt` contains exactly that row as a reply,
|
|
1392
|
+
* and it must survive cleaning.
|
|
806
1393
|
*/
|
|
807
|
-
exports.
|
|
1394
|
+
exports.COPILOT_REASONING_HEADER_PATTERN = /^\s*⌄\s/;
|
|
1395
|
+
/**
|
|
1396
|
+
* copilot's echo of the operator's own prompt in the transcript (Issue #1897).
|
|
1397
|
+
*
|
|
1398
|
+
* 1.0.80 draws every transcript row at the pane's one-column indent -- ` ❯ Reply
|
|
1399
|
+
* with exactly the word: pong` -- while the composer at the bottom of the pane is
|
|
1400
|
+
* at column 0. The bare `^[>❯]` form therefore never matched the echo, so
|
|
1401
|
+
* `resolveExtractionStartIndex`'s copilot branch found no anchor, fell back to
|
|
1402
|
+
* line 0, and handed the launch banner to the cleaner as the turn's reply.
|
|
1403
|
+
*
|
|
1404
|
+
* Bounded to two leading spaces rather than `\s*` so a quoted `> …` line inside a
|
|
1405
|
+
* reply cannot be mistaken for a new turn boundary.
|
|
1406
|
+
*/
|
|
1407
|
+
exports.COPILOT_USER_ECHO_PATTERN = /^ {0,2}[>❯]\s+\S/;
|
|
1408
|
+
/**
|
|
1409
|
+
* A wrapped continuation of the copilot transcript row above it (Issue #1897).
|
|
1410
|
+
*
|
|
1411
|
+
* Marker rows (` ❯ `, ` ● `, ` $ `, ` ⌄ `) carry one leading space; the rows they
|
|
1412
|
+
* wrap onto are indented further and carry no marker, and a blank row separates
|
|
1413
|
+
* one block from the next (measured on 1.0.80 at 200x1000). Used to walk past the
|
|
1414
|
+
* tail of a long *user* prompt so the extracted reply does not open with the
|
|
1415
|
+
* second half of the operator's own question.
|
|
1416
|
+
*/
|
|
1417
|
+
exports.COPILOT_TRANSCRIPT_CONTINUATION_PATTERN = /^ {2,}\S/;
|
|
1418
|
+
/**
|
|
1419
|
+
* Rows that only copilot's first-launch screen draws (Issue #1897).
|
|
1420
|
+
*
|
|
1421
|
+
* The launch screen is a complete, idle frame: the composer is drawn, the status
|
|
1422
|
+
* bar shows key hints, and nothing about it says "no turn has happened yet". So
|
|
1423
|
+
* `extractResponse` classified it as a finished response and History opened with
|
|
1424
|
+
* the banner as the agent's first message -- before the operator's first prompt.
|
|
1425
|
+
*
|
|
1426
|
+
* These anchors are only ever consulted for a frame that carries no echoed user
|
|
1427
|
+
* prompt at all (see the copilot banner guard in `extractResponse`), which is
|
|
1428
|
+
* what keeps a reply that quotes any of this wording from being suppressed.
|
|
1429
|
+
*/
|
|
1430
|
+
exports.COPILOT_BOOT_BANNER_ANCHORS = [
|
|
1431
|
+
/No copilot-instructions\.md found/,
|
|
1432
|
+
/Copilot uses AI, so always check for mistakes\./,
|
|
1433
|
+
/Copilot v\d[\w.]*\s+uses AI/,
|
|
1434
|
+
/^\s*(?:●\s+)?GitHub Copilot\s+v\d/m,
|
|
1435
|
+
/^\s*(?:●\s+)?Tip:\s*\//m,
|
|
1436
|
+
/Describe a task to get started/,
|
|
1437
|
+
/Prefer a visual workspace\?/,
|
|
1438
|
+
];
|
|
1439
|
+
/**
|
|
1440
|
+
* The key-hint footer copilot draws under a picker, matched one ROW at a time
|
|
1441
|
+
* (Issue #547; rewritten against live 1.0.80 frames by Issue #1895).
|
|
1442
|
+
*
|
|
1443
|
+
* The pattern this replaced --
|
|
1444
|
+
* `/Search\s+\w+\.\.\.|Select\s+Model|to (?:navigate|select).*Enter to (?:select|confirm)/`
|
|
1445
|
+
* -- matched **none** of the eleven pickers 1.0.80 opens (measured; the frames
|
|
1446
|
+
* are in `tests/unit/lib/detection/fixtures/copilot-picker-1895/`, and #1885 /
|
|
1447
|
+
* #1886 / #1913 reached the same result independently). `/model` renders
|
|
1448
|
+
* `❯ Search models…` with U+2026 rather than three periods, no picker carries
|
|
1449
|
+
* the words `Select Model`, and every footer spells its verbs in lower case.
|
|
1450
|
+
*
|
|
1451
|
+
* What all eleven footers do share is the shape of a key-hint bar: `·`-separated
|
|
1452
|
+
* hints carrying either arrow-key navigation or a lower-case dismiss verb.
|
|
1453
|
+
* Measured verbatim, bottom-most first:
|
|
1454
|
+
*
|
|
1455
|
+
* /model ↑/↓ to navigate · ←/→ reasoning effort · tab context window ·
|
|
1456
|
+
* shift+tab group: recommended · enter to select · esc to cancel
|
|
1457
|
+
* /agent n new agent · ? learn more · esc cancel
|
|
1458
|
+
* /theme ↑/↓ to navigate · enter to select · esc to cancel
|
|
1459
|
+
* /permissions 1-2 to select · ↑/↓ to navigate · enter to confirm · esc to cancel
|
|
1460
|
+
* /skills ↑/↓ to navigate · enter to toggle · esc to close
|
|
1461
|
+
* /mcp ↑/↓ to select · enter to show · a to add · esc to close
|
|
1462
|
+
* /settings / search · ↑/↓ navigate · tab switch scope · enter edit ·
|
|
1463
|
+
* ctrl+r reset · ctrl+e editor · esc close
|
|
1464
|
+
* /statusline ↑/↓ nav · enter toggle · esc close
|
|
1465
|
+
* /subagents ↑/↓ to navigate · space on/off · r reset · enter to select · esc to cancel
|
|
1466
|
+
* /resume / search · ↑/↓ navigate · enter select · ←/→ switch tabs · r refresh ·
|
|
1467
|
+
* x delete · s sort:relevance · esc cancel
|
|
1468
|
+
* /session / search · ↑/↓ navigate · enter open · n new · tab switch tabs · a filter:all
|
|
1469
|
+
*
|
|
1470
|
+
* Neither half of the alternation is universal -- `/agent` has no list to walk
|
|
1471
|
+
* so it prints no `↑/↓`, and `/session` offers no `esc` -- but every footer has
|
|
1472
|
+
* one of them, so the union covers 11/11 while each individual disjunct stays
|
|
1473
|
+
* specific enough to be worth requiring. The slash in `↑/↓` is optional only as
|
|
1474
|
+
* a rewording tolerance: the synthetic frames pinned since Issue #547 spell it
|
|
1475
|
+
* `↑↓`, and whether copilot ever drew it that way is not something this Issue
|
|
1476
|
+
* measured. Every 1.0.80 footer above has the slash.
|
|
1477
|
+
*
|
|
1478
|
+
* Three deliberate narrowings keep this off ordinary text:
|
|
1479
|
+
* - the `·` lookahead, so a sentence such as "press esc to cancel" is not a
|
|
1480
|
+
* footer unless it is also a hint bar;
|
|
1481
|
+
* - lower case, which is what 1.0.80 draws. `(Esc to cancel · 2.3 KiB)` -- the
|
|
1482
|
+
* capitalised spelling in {@link COPILOT_THINKING_PATTERN} -- is a *progress*
|
|
1483
|
+
* row, and it would otherwise satisfy both halves of this pattern;
|
|
1484
|
+
* - `cancel|close` only, so the status bar's `esc interrupt`
|
|
1485
|
+
* ({@link COPILOT_WORKING_STATUS_PATTERN}) is not a footer either.
|
|
1486
|
+
*
|
|
1487
|
+
* The narrowings are defence in depth; the load-bearing guard is positional and
|
|
1488
|
+
* lives in {@link isCopilotSelectionFrame} -- copilot's own answer text can and
|
|
1489
|
+
* does contain these exact rows (`picker-vocabulary-in-response.txt` is a live
|
|
1490
|
+
* frame of it), so no window-scoped match on this vocabulary can be safe.
|
|
1491
|
+
*
|
|
1492
|
+
* No /g flag (S4-5: would make test() stateful). `[^\n]*` cannot cross a row and
|
|
1493
|
+
* no quantifier is nested inside another (SEC4-001: ReDoS safe).
|
|
1494
|
+
*/
|
|
1495
|
+
exports.COPILOT_SELECTION_FOOTER_PATTERN = /^(?=[^\n]*·)[^\n]*(?:↑\/?↓|\besc\s+(?:to\s+)?(?:cancel|close)\b)/m;
|
|
1496
|
+
/**
|
|
1497
|
+
* How many non-blank rows up from the bottom of the pane may carry the footer.
|
|
1498
|
+
*
|
|
1499
|
+
* Nine of the eleven pickers put it on the bottom row itself; `/agent` and
|
|
1500
|
+
* `/subagents` draw their panel with a closing full-width rule underneath it,
|
|
1501
|
+
* which puts the footer two non-blank rows up. Three is that measurement plus
|
|
1502
|
+
* one row of slack -- deliberately far short of a window that could reach the
|
|
1503
|
+
* transcript, which on the production 200x1000 geometry sits ~950 rows above.
|
|
1504
|
+
*/
|
|
1505
|
+
const COPILOT_SELECTION_FOOTER_SCAN_ROWS = 3;
|
|
1506
|
+
/**
|
|
1507
|
+
* Whether the pane is sitting on one of copilot's pickers (Issue #1895).
|
|
1508
|
+
*
|
|
1509
|
+
* Takes the whole frame rather than a window for the same reason
|
|
1510
|
+
* {@link readCopilotStatusBar} does: the evidence is positional, and a call site
|
|
1511
|
+
* cannot be trusted to preserve "near the bottom of the pane" on its own. Two
|
|
1512
|
+
* facts, both measured on 1.0.80, make the position sufficient:
|
|
1513
|
+
*
|
|
1514
|
+
* - **A picker replaces copilot's chrome.** In the idle and generating states
|
|
1515
|
+
* the bottom five rows are cwd / rule / composer / rule / status bar; while a
|
|
1516
|
+
* picker is up, none of them are drawn. So a frame whose bottom row is a
|
|
1517
|
+
* status bar is not a picker, whatever its transcript says -- which is the
|
|
1518
|
+
* whole of the false-positive half of Issue #1895. `detectSessionStatus`
|
|
1519
|
+
* reads the same row for the running verdict at step 0.5, so checking it
|
|
1520
|
+
* first here also fixes the order between the two branches: the status bar
|
|
1521
|
+
* wins, and the picker branch only speaks when copilot has taken it away.
|
|
1522
|
+
* - **An answerable dialog is drawn inside a box; a picker is not.** The
|
|
1523
|
+
* folder-trust and permission dialogs wear the same lower-case
|
|
1524
|
+
* `↑/↓ to navigate · enter to select · esc to cancel` footer, but every one of
|
|
1525
|
+
* their rows reads `│ … │` and the bottom row is `╰─…─╯`. Skipping boxed rows
|
|
1526
|
+
* keeps those on the prompt branch, where they belong: they are the agent
|
|
1527
|
+
* blocked on the human (`hasActivePrompt: true`, exit 10 for `wait`), not a
|
|
1528
|
+
* list the operator opened.
|
|
1529
|
+
*
|
|
1530
|
+
* @param contentLines - Frame rows, ANSI already stripped, in pane order
|
|
1531
|
+
* @returns True when the bottom of the pane is a picker's key-hint footer
|
|
1532
|
+
*/
|
|
1533
|
+
function isCopilotSelectionFrame(contentLines) {
|
|
1534
|
+
if (readCopilotStatusBar(contentLines) !== null)
|
|
1535
|
+
return false;
|
|
1536
|
+
let scanned = 0;
|
|
1537
|
+
for (let i = contentLines.length - 1; i >= 0; i--) {
|
|
1538
|
+
const row = contentLines[i];
|
|
1539
|
+
const trimmed = row.trim();
|
|
1540
|
+
if (trimmed === '')
|
|
1541
|
+
continue;
|
|
1542
|
+
if (++scanned > COPILOT_SELECTION_FOOTER_SCAN_ROWS)
|
|
1543
|
+
break;
|
|
1544
|
+
// A boxed row belongs to a dialog, not a picker (see above).
|
|
1545
|
+
if (trimmed.startsWith('│') || trimmed.endsWith('│'))
|
|
1546
|
+
continue;
|
|
1547
|
+
if (exports.COPILOT_SELECTION_FOOTER_PATTERN.test(row))
|
|
1548
|
+
return true;
|
|
1549
|
+
}
|
|
1550
|
+
return false;
|
|
1551
|
+
}
|
|
1552
|
+
/**
|
|
1553
|
+
* Anchors of Copilot CLI's first-launch "Confirm folder trust" dialog (Issue #1886).
|
|
1554
|
+
*
|
|
1555
|
+
* Recorded from copilot 1.0.80 (`tests/fixtures/copilot-folder-trust-1080.ts`):
|
|
1556
|
+
* copilot asks this once per untrusted git repository, before anything else runs,
|
|
1557
|
+
* and the whole dialog is drawn inside a box — every row reads `│ <content>`.
|
|
1558
|
+
* That is why `COPILOT_PROMPT_PATTERN` (`^[>❯]\s`) does not match the frame at
|
|
1559
|
+
* all and `waitForReady` used to spin its full 30-second window against it.
|
|
1560
|
+
*
|
|
1561
|
+
* Both anchors are required. One of them alone would also match this dialog's
|
|
1562
|
+
* text quoted back inside a model response, and a false positive here does not
|
|
1563
|
+
* merely mis-report a status: it sends a bare `1` into a live composer.
|
|
1564
|
+
*
|
|
1565
|
+
* The anchors live here rather than in `cli-tools/copilot` for the same reason
|
|
1566
|
+
* codex's do (Issue #1829): the Auto-Yes poller judges the same screen through
|
|
1567
|
+
* `detectPrompt`, and two copies of the wording would be two chances to disagree
|
|
1568
|
+
* about what this dialog is.
|
|
1569
|
+
*/
|
|
1570
|
+
exports.COPILOT_FOLDER_TRUST_ANCHORS = [
|
|
1571
|
+
'Confirm folder trust',
|
|
1572
|
+
'Do you trust the files in this folder?',
|
|
1573
|
+
];
|
|
1574
|
+
/**
|
|
1575
|
+
* The one option CommandMate may answer on the operator's behalf: `1. Yes`,
|
|
1576
|
+
* which grants trust for THIS SESSION only.
|
|
1577
|
+
*
|
|
1578
|
+
* Matching the option text — not just the dialog — is the fail-safe. Option 2
|
|
1579
|
+
* ("Yes, and remember this folder for future sessions") writes `trustedFolders`
|
|
1580
|
+
* into `~/.copilot/config.json`, one file shared by every checkout on the
|
|
1581
|
+
* machine (measured: answering `1` leaves that file byte-identical). If copilot
|
|
1582
|
+
* ever reorders the list so that `1` is the remembering variant, this stops
|
|
1583
|
+
* matching, nothing is sent, and the launch degrades to the pre-#1886 stall
|
|
1584
|
+
* instead of silently persisting a trust grant.
|
|
1585
|
+
*
|
|
1586
|
+
* Written against the box-stripped frame, where the row reads `❯ 1. Yes`.
|
|
1587
|
+
* `[ \t]*$` rather than `\s*$` so the trailing anchor cannot roll onto a later
|
|
1588
|
+
* line and accept `1. Yes, and remember ...`.
|
|
1589
|
+
*/
|
|
1590
|
+
exports.COPILOT_FOLDER_TRUST_SESSION_OPTION_PATTERN = /^[ \t]*(?:[>❯][ \t]*)?1\.[ \t]+Yes[ \t]*$/m;
|
|
1591
|
+
/**
|
|
1592
|
+
* Key that selects {@link COPILOT_FOLDER_TRUST_SESSION_OPTION_PATTERN}.
|
|
1593
|
+
* Measured on 1.0.80: the digit confirms on its own — sending a trailing Enter
|
|
1594
|
+
* would land on the composer that the dialog's dismissal reveals.
|
|
1595
|
+
*/
|
|
1596
|
+
exports.COPILOT_FOLDER_TRUST_ANSWER_KEY = '1';
|
|
1597
|
+
/**
|
|
1598
|
+
* Whether the pane is sitting on the folder-trust dialog with the session-only
|
|
1599
|
+
* option in first position.
|
|
1600
|
+
*
|
|
1601
|
+
* @param output - ANSI-stripped pane capture (box drawing still present)
|
|
1602
|
+
* @returns True when both anchors and the `1. Yes` option row are present
|
|
1603
|
+
*/
|
|
1604
|
+
function isCopilotFolderTrustDialog(output) {
|
|
1605
|
+
if (!exports.COPILOT_FOLDER_TRUST_ANCHORS.every((anchor) => output.includes(anchor))) {
|
|
1606
|
+
return false;
|
|
1607
|
+
}
|
|
1608
|
+
return exports.COPILOT_FOLDER_TRUST_SESSION_OPTION_PATTERN.test(stripBoxDrawing(output));
|
|
1609
|
+
}
|
|
808
1610
|
/**
|
|
809
1611
|
* Copilot skip patterns for response cleaning (Issue #545)
|
|
810
1612
|
* Placeholder patterns - to be refined after Phase 1 TUI investigation.
|
|
@@ -813,7 +1615,12 @@ exports.COPILOT_SKIP_PATTERNS = [
|
|
|
813
1615
|
exports.PASTED_TEXT_PATTERN,
|
|
814
1616
|
exports.COPILOT_SEPARATOR_PATTERN,
|
|
815
1617
|
exports.COPILOT_THINKING_PATTERN,
|
|
816
|
-
|
|
1618
|
+
// Issue #1895 replaced COPILOT_SELECTION_LIST_PATTERN with the row-scoped
|
|
1619
|
+
// picker footer; the vocabulary it carried (`Search \w+...` / `Select Model`)
|
|
1620
|
+
// is copilot's prose, not its chrome.
|
|
1621
|
+
exports.COPILOT_SELECTION_FOOTER_PATTERN,
|
|
1622
|
+
// Collapsed reasoning header (Issue #1897): "⌄ Thinking…" / "⌄ Thought for 41s"
|
|
1623
|
+
exports.COPILOT_REASONING_HEADER_PATTERN,
|
|
817
1624
|
// Logo/banner lines
|
|
818
1625
|
/^GitHub Copilot\s+v/,
|
|
819
1626
|
/[█▘▝▖▗▔▄▌▐]/,
|
|
@@ -1129,8 +1936,35 @@ function buildDetectPromptOptions(cliToolId) {
|
|
|
1129
1936
|
}
|
|
1130
1937
|
// [D2-006] OpenCode prompt "Ask anything..." does not use standard indicators (> / ❯),
|
|
1131
1938
|
// so requireDefaultIndicator must be false to avoid missing prompt detection.
|
|
1939
|
+
//
|
|
1940
|
+
// [Issue #1896] `hasNumberedDialogs: false` -- opencode 1.18 renders NO dialog
|
|
1941
|
+
// that a typed number drives, so the generic numbered-list inference has
|
|
1942
|
+
// nothing to find on its pane and every hit it scored was transcript text.
|
|
1943
|
+
// Its two interactive surfaces were both measured at the production 80x200
|
|
1944
|
+
// geometry and both are cursor-driven:
|
|
1945
|
+
//
|
|
1946
|
+
// - the permission dialog is a horizontal button strip
|
|
1947
|
+
// ({@link OPENCODE_PERMISSION_PATTERN}, Issue #1893) driven by ←/→ + Enter;
|
|
1948
|
+
// typing a number does nothing to it.
|
|
1949
|
+
// - the pickers (`/models`, `/providers`, `/connect`, and the ctrl+p command
|
|
1950
|
+
// palette) are fuzzy-search lists driven by ↑/↓ + Enter, with no numbers
|
|
1951
|
+
// drawn at all. The first three are what
|
|
1952
|
+
// {@link OPENCODE_SELECTION_LIST_PATTERN} names; the palette shares the
|
|
1953
|
+
// chrome but not the header allowlist, and lands on `running` / `default`.
|
|
1954
|
+
//
|
|
1955
|
+
// Both keep their own POSITIVE detection in `status-detector.ts`, so `wait`
|
|
1956
|
+
// still stops for them (exit 10 via `isSelectionListActive`) and the UI still
|
|
1957
|
+
// renders NavigationButtons: nothing that could be answered before stops being
|
|
1958
|
+
// answered. What ends is the false positive -- a response whose body ends in
|
|
1959
|
+
// `1. / 2. / 3.` + a question was published as
|
|
1960
|
+
// `waiting`/`prompt_detected`/`hasActivePrompt: true`, and Auto-Yes typed `1`
|
|
1961
|
+
// into the composer and SENT IT as a user utterance (Issue #1896).
|
|
1962
|
+
//
|
|
1963
|
+
// `requireDefaultIndicator` is kept at its D2-006 value: it is the correct
|
|
1964
|
+
// setting for opencode's ❯-less rendering should the numbered path ever be
|
|
1965
|
+
// re-enabled, and it still describes the tool.
|
|
1132
1966
|
if (cliToolId === 'opencode') {
|
|
1133
|
-
return { requireDefaultIndicator: false };
|
|
1967
|
+
return { requireDefaultIndicator: false, hasNumberedDialogs: false };
|
|
1134
1968
|
}
|
|
1135
1969
|
// [Issue #545] Copilot prompt pattern may not use standard indicators
|
|
1136
1970
|
if (cliToolId === 'copilot') {
|