commandmate 0.33.2 → 0.34.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 +160 -160
- package/.next/app-path-routes-manifest.json +28 -28
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +12 -12
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.js +1 -1
- package/.next/server/app/api/app/update-check/route.js.nft.json +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 +2 -2
- 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 +3 -3
- package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -1
- package/.next/server/app/api/capabilities/route.js.nft.json +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route.js +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/route.js +1 -1
- package/.next/server/app/api/relays/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route.js +1 -1
- package/.next/server/app/api/skills/installations/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route.js +1 -1
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +2 -2
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route.js +2 -2
- package/.next/server/app/api/worktrees/[id]/tasks/route.js.nft.json +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 +2 -2
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.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]/cancel/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +10 -10
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +28 -28
- package/.next/server/chunks/1049.js +1 -0
- package/.next/server/chunks/1501.js +6 -2
- package/.next/server/chunks/1886.js +3 -3
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/3123.js +1 -1
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3323.js +1 -1
- package/.next/server/chunks/3480.js +2 -2
- package/.next/server/chunks/4443.js +1 -1
- package/.next/server/chunks/4802.js +1 -1
- package/.next/server/chunks/5164.js +1 -1
- package/.next/server/chunks/5571.js +1 -1
- package/.next/server/chunks/595.js +2 -2
- package/.next/server/chunks/6130.js +1 -0
- package/.next/server/chunks/6285.js +1 -1
- package/.next/server/chunks/6286.js +7 -7
- package/.next/server/chunks/6337.js +1 -1
- package/.next/server/chunks/650.js +1 -1
- package/.next/server/chunks/663.js +1 -1
- package/.next/server/chunks/6661.js +1 -1
- package/.next/server/chunks/6677.js +25 -0
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/7075.js +1 -0
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8583.js +1 -0
- package/.next/server/chunks/8918.js +7 -5
- package/.next/server/chunks/9080.js +1 -0
- package/.next/server/chunks/9627.js +1 -1
- package/.next/server/chunks/964.js +1 -0
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/2053-9ac860ab4e92ac89.js +1 -0
- package/.next/static/chunks/2652-18b8fea64413467e.js +1 -0
- package/.next/static/chunks/{4718-441a2af91f0374e9.js → 4718-2d9f0397a8f931c4.js} +1 -1
- package/.next/static/chunks/6022-7a7d1760fc9814c7.js +1 -0
- package/.next/static/chunks/{8361-9bb887203c456edb.js → 8361-0142beb59be2abf3.js} +1 -1
- package/.next/static/chunks/app/{page-022090bf6f932818.js → page-26a42881c8648cd3.js} +1 -1
- package/.next/static/chunks/app/sessions/page-a3ab6f122ec60d5a.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-a39ec2a0732d11a6.js +1 -0
- package/.next/static/css/b09bede85744e1cf.css +1 -0
- package/.next/trace +13 -13
- package/dist/cli/commands/ask.d.ts.map +1 -1
- package/dist/cli/commands/ask.js +11 -2
- package/dist/cli/commands/respond.d.ts.map +1 -1
- package/dist/cli/commands/respond.js +8 -4
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +18 -0
- package/dist/cli/commands/wait.d.ts +18 -3
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +137 -2
- package/dist/cli/docs/agent-operations.d.ts +2 -2
- package/dist/cli/docs/agent-operations.d.ts.map +1 -1
- package/dist/cli/docs/agent-operations.js +41 -1
- package/dist/cli/utils/session-target.d.ts +23 -6
- package/dist/cli/utils/session-target.d.ts.map +1 -1
- package/dist/cli/utils/session-target.js +33 -5
- package/dist/server/locales/en/worktree.json +30 -4
- package/dist/server/locales/ja/worktree.json +30 -4
- package/dist/server/src/config/schedule-config.js +45 -3
- package/dist/server/src/lib/cli-tools/antigravity.js +95 -10
- package/dist/server/src/lib/cli-tools/submit-verified-sender.js +377 -16
- package/dist/server/src/lib/cli-tools/vibe-local.js +10 -0
- package/dist/server/src/lib/cmate-parser.js +8 -1
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +140 -19
- package/dist/server/src/lib/detection/tools/claude/detect.js +13 -2
- package/dist/server/src/lib/detection/tools/claude/picker-chrome.js +239 -0
- package/dist/server/src/lib/detection/tools/claude/prompt.js +74 -6
- package/dist/server/src/lib/hooks/hook-settings-generator.js +61 -1
- package/dist/server/src/lib/hooks/sources/antigravity/history.js +302 -27
- package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +103 -0
- package/dist/server/src/lib/hooks/sources/claude/history.js +391 -34
- package/dist/server/src/lib/hooks/sources/claude/transcript.js +91 -0
- package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +114 -11
- package/dist/server/src/lib/polling/response-checker.js +82 -3
- package/dist/server/src/lib/polling/structured-history-gate.js +68 -4
- package/dist/server/src/lib/schedule-manager.js +178 -19
- package/dist/server/src/lib/session/agent-session-lifecycle.js +31 -1
- package/dist/server/src/lib/session/ask-user-question-prompt.js +4 -2
- package/dist/server/src/lib/session/claude-executor.js +33 -2
- package/dist/server/src/lib/session/resolve-session-target.js +37 -9
- package/dist/server/src/lib/session/session-generation-archive.js +194 -0
- package/dist/server/src/lib/tasks/contract-message.js +83 -9
- package/dist/server/src/lib/tasks/contract-parser.js +2 -0
- package/dist/server/src/lib/verification/env-clean-gate.js +81 -4
- package/dist/server/src/types/agent-transcript.js +143 -1
- package/package.json +1 -1
- package/.next/server/chunks/1068.js +0 -1
- package/.next/server/chunks/153.js +0 -1
- package/.next/server/chunks/4299.js +0 -1
- package/.next/server/chunks/6808.js +0 -1
- package/.next/server/chunks/6838.js +0 -1
- package/.next/server/chunks/7366.js +0 -5
- package/.next/server/chunks/7875.js +0 -25
- package/.next/static/chunks/2053-3f299a7a2c7d6767.js +0 -1
- package/.next/static/chunks/6022-2fa0b5a82d4ce7b6.js +0 -1
- package/.next/static/chunks/8772-9be53a530950d804.js +0 -1
- package/.next/static/chunks/app/sessions/page-584adf11ae51df10.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-38edcd53e51f53b0.js +0 -1
- package/.next/static/css/acd46e25427a2080.css +0 -1
- /package/.next/static/{0a4qrU8WdUwQrlO4mfLMu → gniPBCKoXtbIOQey8kNcx}/_buildManifest.js +0 -0
- /package/.next/static/{0a4qrU8WdUwQrlO4mfLMu → gniPBCKoXtbIOQey8kNcx}/_ssgManifest.js +0 -0
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.APPROVAL_TARGET_MAX_LOOKBACK = void 0;
|
|
5
5
|
exports.findClaudeTaskPanelLines = findClaudeTaskPanelLines;
|
|
6
|
+
exports.findClaudeChrome = findClaudeChrome;
|
|
7
|
+
exports.maskClaudeChrome = maskClaudeChrome;
|
|
6
8
|
exports.findApprovalContextStart = findApprovalContextStart;
|
|
7
9
|
exports.joinApprovalTarget = joinApprovalTarget;
|
|
8
10
|
exports.buildMultipleChoiceResult = buildMultipleChoiceResult;
|
|
9
11
|
exports.detectMultipleChoicePrompt = detectMultipleChoicePrompt;
|
|
10
12
|
const tui_detection_frame_1 = require("./tui-detection-frame");
|
|
11
13
|
const cli_patterns_1 = require("./cli-patterns");
|
|
14
|
+
const picker_chrome_1 = require("./tools/claude/picker-chrome");
|
|
12
15
|
// ============================================================================
|
|
13
16
|
// Constants
|
|
14
17
|
// ============================================================================
|
|
@@ -114,11 +117,45 @@ const CLAUDE_TASK_PANEL_HEADER_PATTERN = /^\s*\d{1,3}\s+tasks?\s+\(\d+\s+done\b/
|
|
|
114
117
|
*/
|
|
115
118
|
const CLAUDE_TASK_PANEL_ROW_PATTERN = /^\s*[◼◻]\s/;
|
|
116
119
|
/**
|
|
117
|
-
*
|
|
120
|
+
* [Issue #2468] Claude Code 2.1.267's session-diff HUD row, in the two
|
|
121
|
+
* spellings measured on a live pane (tests/fixtures/claude-live-2468):
|
|
122
|
+
* "No changes this session"
|
|
123
|
+
* "+28 files edited before this session (show)"
|
|
124
|
+
*
|
|
125
|
+
* Chrome like the task panel, but a single row and RIGHT-aligned: on a
|
|
126
|
+
* 200-column pane it is ~110 columns of padding and then the text. It is
|
|
127
|
+
* therefore matched on the trimmed row — a reader that slices the row from the
|
|
128
|
+
* left sees nothing but blanks.
|
|
129
|
+
*
|
|
130
|
+
* It broke two readers. Pass 2 below parses `+2 files edited …` as option 2,
|
|
131
|
+
* which poisons the real `1. / 2.` above it the way `… +2 completed` did in
|
|
132
|
+
* #1708. And `findClaudeTranscriptTail` took it for the last transcript row, so
|
|
133
|
+
* `detectClaudeDialog` read it as the footer of the AskUserQuestion
|
|
134
|
+
* confirmation screen — a dialog that draws no footer — and refused a dialog
|
|
135
|
+
* that was open on screen: Auto-Yes, the UI's answer and `commandmate respond`
|
|
136
|
+
* all got `prompt_no_longer_active`.
|
|
137
|
+
*
|
|
138
|
+
* `files?` is the one spelling not seen on a pane: a one-file session was not
|
|
139
|
+
* captured, and the singular is accepted so that it is not the case that
|
|
140
|
+
* regresses. Everything else is literal, for the same reason the glyph set
|
|
141
|
+
* above is an allowlist. Anchored at both ends, no nested quantifiers — ReDoS
|
|
142
|
+
* safe (S4-001).
|
|
143
|
+
*/
|
|
144
|
+
const CLAUDE_SESSION_DIFF_HUD_PATTERN = /^(?:No changes this session|\+\d+ files? edited before this session \(show\))$/;
|
|
145
|
+
/**
|
|
146
|
+
* Line indices belonging to Claude's bottom-pinned panels within [start, end).
|
|
147
|
+
*
|
|
148
|
+
* Two panels, both chrome rather than transcript or prompt:
|
|
149
|
+
* - the task panel (#1708). Walks down from each header row for as long as
|
|
150
|
+
* rows keep looking like panel content (task rows or the collapsed `… +N …`
|
|
151
|
+
* summary). The first line that is neither ends the block, so a panel that
|
|
152
|
+
* abuts other content cannot swallow it.
|
|
153
|
+
* - the session-diff HUD (#2468), a single row claimed on its own.
|
|
118
154
|
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
155
|
+
* Pass 2 here, `findClaudeTranscriptTail` and `detectClaudeDialog`'s footer
|
|
156
|
+
* guard all read this one set — through {@link findClaudeChrome}, which adds an
|
|
157
|
+
* AskUserQuestion preview pane to it (Issue #2486) — so they cannot disagree
|
|
158
|
+
* about which rows are chrome.
|
|
122
159
|
*
|
|
123
160
|
* @param lines - Full frame, already ANSI/box stripped
|
|
124
161
|
* @param start - First index to consider (inclusive)
|
|
@@ -128,6 +165,10 @@ const CLAUDE_TASK_PANEL_ROW_PATTERN = /^\s*[◼◻]\s/;
|
|
|
128
165
|
function findClaudeTaskPanelLines(lines, start, end) {
|
|
129
166
|
const panelLines = new Set();
|
|
130
167
|
for (let i = Math.max(0, start); i < Math.min(end, lines.length); i++) {
|
|
168
|
+
if (CLAUDE_SESSION_DIFF_HUD_PATTERN.test(lines[i].trim())) {
|
|
169
|
+
panelLines.add(i);
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
131
172
|
if (!CLAUDE_TASK_PANEL_HEADER_PATTERN.test(lines[i]))
|
|
132
173
|
continue;
|
|
133
174
|
panelLines.add(i);
|
|
@@ -140,6 +181,43 @@ function findClaudeTaskPanelLines(lines, start, end) {
|
|
|
140
181
|
}
|
|
141
182
|
return panelLines;
|
|
142
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Claude's chrome within [start, end). See {@link ClaudeChrome}.
|
|
186
|
+
*
|
|
187
|
+
* @param lines - Full frame, ANSI stripped; box drawing optional
|
|
188
|
+
* @param start - First index to consider (inclusive)
|
|
189
|
+
* @param end - Last index to consider (exclusive)
|
|
190
|
+
*/
|
|
191
|
+
function findClaudeChrome(lines, start, end) {
|
|
192
|
+
const rows = findClaudeTaskPanelLines(lines, start, end);
|
|
193
|
+
const panes = (0, picker_chrome_1.findClaudePreviewPanes)(lines, start, end);
|
|
194
|
+
for (const row of panes.rows)
|
|
195
|
+
rows.add(row);
|
|
196
|
+
return { rows, cuts: panes.cuts };
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* The frame with Claude's chrome taken out: chrome rows blank, rows shared with
|
|
200
|
+
* the preview pane cut back to the options column. Row indices are unchanged,
|
|
201
|
+
* so a reader of the result can report positions in the original frame.
|
|
202
|
+
*/
|
|
203
|
+
function maskClaudeChrome(lines, chrome) {
|
|
204
|
+
return lines.map((line, i) => {
|
|
205
|
+
if (chrome.rows.has(i))
|
|
206
|
+
return '';
|
|
207
|
+
const cut = chrome.cuts.get(i);
|
|
208
|
+
return cut === undefined ? line : line.slice(0, cut).trimEnd();
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* [Issue #2486] An indented row in the options column beside a preview pane.
|
|
213
|
+
*
|
|
214
|
+
* The column is ~30 wide there and draws no descriptions (the pane replaces
|
|
215
|
+
* them), so such a row is the wrapped tail of the label above it —
|
|
216
|
+
* `❯ 1. 整えた状態で続行` / ` (Recommended)` on the live capture. Option rows
|
|
217
|
+
* start within two columns (`❯ 1.` / ` 2.`); three or more spaces is a wrap.
|
|
218
|
+
* Anchored, no nested quantifiers — ReDoS safe (S4-001).
|
|
219
|
+
*/
|
|
220
|
+
const PANE_WRAPPED_LABEL_PATTERN = /^\s{3,}\S/;
|
|
143
221
|
/**
|
|
144
222
|
* Pattern for separator lines (horizontal rules).
|
|
145
223
|
* Matches lines consisting only of dash (-) or em-dash (─) characters.
|
|
@@ -238,8 +316,11 @@ const CLAUDE_PROMPT_FOOTER_PATTERN = /Esc\s+to\s+cancel\s*[·•]\s*Tab\s+to\s+a
|
|
|
238
316
|
*
|
|
239
317
|
* Linear pattern, single unbounded quantifier between literal anchors —
|
|
240
318
|
* ReDoS safe (S4-001).
|
|
319
|
+
*
|
|
320
|
+
* [Issue #2486] Defined in `tools/claude/picker-chrome.ts`, whose preview-pane
|
|
321
|
+
* finder anchors a pane on this same footer.
|
|
241
322
|
*/
|
|
242
|
-
const CLAUDE_ASK_USER_QUESTION_FOOTER_PATTERN =
|
|
323
|
+
const CLAUDE_ASK_USER_QUESTION_FOOTER_PATTERN = picker_chrome_1.ASK_USER_QUESTION_PICKER_FOOTER_PATTERN;
|
|
243
324
|
/**
|
|
244
325
|
* Codex/OpenAI TUI confirmation footer shown beneath interactive choices.
|
|
245
326
|
* When this footer is present, numbered options form an active prompt even if
|
|
@@ -556,14 +637,17 @@ function isContinuationLine(rawLine, line) {
|
|
|
556
637
|
*
|
|
557
638
|
* @param lines - Array of output lines
|
|
558
639
|
* @param questionEndIndex - Index of the last line before options, or -1 if not found
|
|
640
|
+
* @param floor - First row the question may start at. Issue #2486: one below an
|
|
641
|
+
* AskUserQuestion picker's tab row, so neither that row nor the transcript
|
|
642
|
+
* above it becomes part of the question; 0 when there is none.
|
|
559
643
|
* @returns Extracted question text, or generic fallback if questionEndIndex is -1
|
|
560
644
|
*/
|
|
561
|
-
function extractQuestionText(lines, questionEndIndex) {
|
|
645
|
+
function extractQuestionText(lines, questionEndIndex, floor = 0) {
|
|
562
646
|
if (questionEndIndex < 0) {
|
|
563
647
|
return 'Please select an option:';
|
|
564
648
|
}
|
|
565
649
|
const questionLines = [];
|
|
566
|
-
for (let i = Math.max(
|
|
650
|
+
for (let i = Math.max(floor, questionEndIndex - QUESTION_CONTEXT_LINES); i <= questionEndIndex; i++) {
|
|
567
651
|
const line = lines[i].trim();
|
|
568
652
|
if (line && !SEPARATOR_LINE_PATTERN.test(line)) {
|
|
569
653
|
questionLines.push(line);
|
|
@@ -682,16 +766,22 @@ function joinApprovalTarget(lines, start, end) {
|
|
|
682
766
|
* of the deny surface. Narrowing that would change prompt dedup keys and what
|
|
683
767
|
* the UI renders, and it is bounded by the options below it either way.
|
|
684
768
|
*
|
|
769
|
+
* [Issue #2486] One exception to both: neither reaches above an AskUserQuestion
|
|
770
|
+
* picker's tab row. Everything up there is the transcript — the Bash call Claude
|
|
771
|
+
* ran just before asking, on the Issue's pane — and a question is not the
|
|
772
|
+
* command that happened to precede it.
|
|
773
|
+
*
|
|
685
774
|
* @param lines - Array of output lines
|
|
686
775
|
* @param questionEndIndex - Index of the last line before options, or -1 if not found
|
|
687
776
|
* @param effectiveEnd - End index of non-trailing-empty lines
|
|
777
|
+
* @param floor - First row the block may start at (Issue #2486); 0 for none
|
|
688
778
|
* @returns Approval target string, or undefined if no question line found
|
|
689
779
|
*/
|
|
690
|
-
function extractApprovalTarget(lines, questionEndIndex, effectiveEnd) {
|
|
780
|
+
function extractApprovalTarget(lines, questionEndIndex, effectiveEnd, floor = 0) {
|
|
691
781
|
if (questionEndIndex < 0) {
|
|
692
782
|
return undefined;
|
|
693
783
|
}
|
|
694
|
-
return joinApprovalTarget(lines, findApprovalContextStart(lines, questionEndIndex), effectiveEnd);
|
|
784
|
+
return joinApprovalTarget(lines, Math.max(floor, findApprovalContextStart(lines, questionEndIndex)), effectiveEnd);
|
|
695
785
|
}
|
|
696
786
|
/**
|
|
697
787
|
* Build the final PromptDetectionResult for a multiple choice prompt.
|
|
@@ -878,13 +968,33 @@ function detectMultipleChoicePrompt(output, options, truncateRawContentFn) {
|
|
|
878
968
|
// [Issue #1708] Claude's bottom-anchored task panel is an overlay, not part of
|
|
879
969
|
// the prompt frame. Resolved as a block up front because the reverse scan meets
|
|
880
970
|
// its rows before its header and so cannot recognise them one at a time.
|
|
881
|
-
|
|
971
|
+
//
|
|
972
|
+
// [Issue #2486] The same reading carries an AskUserQuestion preview pane, whose
|
|
973
|
+
// rows the scan likewise meets before the top border that identifies it — and
|
|
974
|
+
// some of which it shares with the options column.
|
|
975
|
+
const chrome = findClaudeChrome(lines, scanStart, effectiveEnd);
|
|
976
|
+
// [Issue #2486] Wrapped label rows beside a preview pane, held for the option
|
|
977
|
+
// ABOVE them, which the reverse scan has not reached yet.
|
|
978
|
+
let paneWrap = [];
|
|
882
979
|
for (let i = effectiveEnd - 1; i >= scanStart; i--) {
|
|
883
|
-
|
|
884
|
-
// [Issue #1708] Task-panel rows are metadata. Same handling as the
|
|
980
|
+
// [Issue #1708] Chrome rows are metadata. Same handling as the
|
|
885
981
|
// COLLAPSED_OUTPUT / SUMMARY guards below: skip without ending the scan, so
|
|
886
|
-
// the options rendered ABOVE the panel are still
|
|
887
|
-
|
|
982
|
+
// the options rendered ABOVE the panel (or beside the pane) are still
|
|
983
|
+
// reachable.
|
|
984
|
+
if (chrome.rows.has(i)) {
|
|
985
|
+
continuationLineCount++;
|
|
986
|
+
continue;
|
|
987
|
+
}
|
|
988
|
+
// [Issue #2486] A row the preview pane shares with the options column is
|
|
989
|
+
// read as the options column alone. Unread, `❯ 1. 整えた状態で続行 ┌───┐`
|
|
990
|
+
// became the option label `整えた状態で続行 ┌───┐`.
|
|
991
|
+
const paneCut = chrome.cuts.get(i);
|
|
992
|
+
// Original indentation preserved; only the pane is cut off.
|
|
993
|
+
const rawLine = paneCut === undefined ? lines[i] : lines[i].slice(0, paneCut).trimEnd();
|
|
994
|
+
const line = rawLine.trim();
|
|
995
|
+
// [Issue #2486] See PANE_WRAPPED_LABEL_PATTERN: the tail of the label above.
|
|
996
|
+
if (paneCut !== undefined && PANE_WRAPPED_LABEL_PATTERN.test(rawLine)) {
|
|
997
|
+
paneWrap.unshift(line);
|
|
888
998
|
continuationLineCount++;
|
|
889
999
|
continue;
|
|
890
1000
|
}
|
|
@@ -918,7 +1028,9 @@ function detectMultipleChoicePrompt(output, options, truncateRawContentFn) {
|
|
|
918
1028
|
if (defaultMatch) {
|
|
919
1029
|
const number = parseInt(defaultMatch[1], 10);
|
|
920
1030
|
if (number <= 20 && isValidPrecedingOption(number, collectedOptions)) {
|
|
921
|
-
|
|
1031
|
+
// [Issue #2486] A label that wrapped beside a preview pane is whole again.
|
|
1032
|
+
const label = [defaultMatch[2].trim(), ...paneWrap].join(' ');
|
|
1033
|
+
paneWrap = [];
|
|
922
1034
|
collectedOptions.unshift({ number, label, isDefault: true });
|
|
923
1035
|
continuationLineCount = 0;
|
|
924
1036
|
continue;
|
|
@@ -937,7 +1049,8 @@ function detectMultipleChoicePrompt(output, options, truncateRawContentFn) {
|
|
|
937
1049
|
// Treat as non-option line (e.g., diff line numbers from Codex approval prompts)
|
|
938
1050
|
}
|
|
939
1051
|
else {
|
|
940
|
-
const label = normalMatch[2].trim();
|
|
1052
|
+
const label = [normalMatch[2].trim(), ...paneWrap].join(' ');
|
|
1053
|
+
paneWrap = [];
|
|
941
1054
|
collectedOptions.unshift({ number, label, isDefault: false });
|
|
942
1055
|
continuationLineCount = 0;
|
|
943
1056
|
continue;
|
|
@@ -954,7 +1067,6 @@ function detectMultipleChoicePrompt(output, options, truncateRawContentFn) {
|
|
|
954
1067
|
}
|
|
955
1068
|
// Non-option line handling
|
|
956
1069
|
if (collectedOptions.length > 0 && line && !SEPARATOR_LINE_PATTERN.test(line)) {
|
|
957
|
-
const rawLine = lines[i]; // Original line with indentation preserved
|
|
958
1070
|
// [Issue #460] For deeply indented lines (4+ leading spaces), check
|
|
959
1071
|
// continuation BEFORE question keywords. These are option description
|
|
960
1072
|
// lines (e.g., " Let Gemini CLI decide the best model...") that may
|
|
@@ -1054,11 +1166,20 @@ function detectMultipleChoicePrompt(output, options, truncateRawContentFn) {
|
|
|
1054
1166
|
}
|
|
1055
1167
|
}
|
|
1056
1168
|
}
|
|
1057
|
-
|
|
1169
|
+
// [Issue #2486] An AskUserQuestion picker's tab row is the dialog's top edge:
|
|
1170
|
+
// the row is chrome and everything above it is transcript. Found once so
|
|
1171
|
+
// `question` and `approvalTarget` start at the same row; 0 on a frame with no
|
|
1172
|
+
// tab row, which leaves every other prompt exactly as it was. `instructionText`
|
|
1173
|
+
// keeps its wide window — it is the human's view, and on a preview picker the
|
|
1174
|
+
// pane it carries is what the question asks the human to look at.
|
|
1175
|
+
const pickerTop = questionEndIndex < 0
|
|
1176
|
+
? 0
|
|
1177
|
+
: (0, picker_chrome_1.findAskUserQuestionTabRow)(lines, questionEndIndex, exports.APPROVAL_TARGET_MAX_LOOKBACK) + 1;
|
|
1178
|
+
const question = extractQuestionText(lines, questionEndIndex, pickerTop);
|
|
1058
1179
|
const instructionText = extractInstructionText(lines, questionEndIndex, effectiveEnd);
|
|
1059
1180
|
// Issue #1699: the same block, cut at the previous turn's boundary. Display
|
|
1060
1181
|
// keeps the wide window; deny patterns are judged against this one.
|
|
1061
|
-
const approvalTarget = extractApprovalTarget(lines, questionEndIndex, effectiveEnd);
|
|
1182
|
+
const approvalTarget = extractApprovalTarget(lines, questionEndIndex, effectiveEnd, pickerTop);
|
|
1062
1183
|
// Issue #616: Determine submitMode from confirmation footer (detected in single-pass above)
|
|
1063
1184
|
const submitMode = hasConfirmationFooter
|
|
1064
1185
|
? (hasNumberFooter ? 'answer_only' : 'answer_then_enter')
|
|
@@ -28,6 +28,17 @@ const patterns_1 = require("./patterns");
|
|
|
28
28
|
* them, which after `compactBlankRows` is a handful of rows up even when the
|
|
29
29
|
* live pane put ~870 blank rows in between.
|
|
30
30
|
*
|
|
31
|
+
* The same finder claims the right-aligned session-diff HUD row
|
|
32
|
+
* (`+N files edited before this session (show)`, Issue #2468). On the
|
|
33
|
+
* AskUserQuestion confirmation screen, which has no input box and no footer,
|
|
34
|
+
* that row is the bottom of the frame; before the finder knew it, it WAS the
|
|
35
|
+
* tail, and the dialog above it read as finished output.
|
|
36
|
+
*
|
|
37
|
+
* It is read through `findClaudeChrome`, the one reading `detectClaudeDialog`
|
|
38
|
+
* and the generic parser use too — which since Issue #2486 includes the
|
|
39
|
+
* AskUserQuestion preview pane — so the three cannot disagree about which rows
|
|
40
|
+
* are chrome.
|
|
41
|
+
*
|
|
31
42
|
* Returning an index rather than a boolean keeps this usable by anything else
|
|
32
43
|
* that needs "the last thing Claude actually said".
|
|
33
44
|
*/
|
|
@@ -35,11 +46,11 @@ function findClaudeTranscriptTail(contentLines) {
|
|
|
35
46
|
const lines = contentLines;
|
|
36
47
|
const box = (0, composer_text_1.findClaudeInputBox)(lines);
|
|
37
48
|
const end = box ? box.openingSeparator : lines.length;
|
|
38
|
-
const
|
|
49
|
+
const chromeRows = (0, prompt_detect_multiple_choice_1.findClaudeChrome)(lines, 0, end).rows;
|
|
39
50
|
let index = end - 1;
|
|
40
51
|
while (index >= 0 &&
|
|
41
52
|
(lines[index].trim() === '' ||
|
|
42
|
-
|
|
53
|
+
chromeRows.has(index) ||
|
|
43
54
|
patterns_1.CLAUDE_EFFORT_CHIP_PATTERN.test(lines[index]))) {
|
|
44
55
|
index--;
|
|
45
56
|
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The AskUserQuestion picker's own chrome, as claude-cli 2.1.268 draws it
|
|
4
|
+
* (Issue #2486).
|
|
5
|
+
*
|
|
6
|
+
* Two parts of the picker are drawn AROUND the dialog rather than as part of it,
|
|
7
|
+
* and the detectors read both as if they were the dialog:
|
|
8
|
+
*
|
|
9
|
+
* - **The tab row** above the question: `← ☐ 権限モード ☐ Goal/範囲 ✔ Submit →`
|
|
10
|
+
* for a multi-question call, ` ☐ 権限モード ` for a single question. The upward
|
|
11
|
+
* scans that build `question` and `approvalTarget` swept it up, together with
|
|
12
|
+
* whatever the transcript showed above it (the previous tool's row).
|
|
13
|
+
* - **The preview pane.** When an option carries a `preview`, the options column
|
|
14
|
+
* narrows to ~32 columns and a box opens to its right: `┌─…─┐` at the end of
|
|
15
|
+
* option 1's row, `│ … │` rows under it, `└─…─┘`, and `Notes: press n to add
|
|
16
|
+
* notes` at the box's indent below that. Its ~20 rows sit between the options
|
|
17
|
+
* and the footer, which put the options out of reach of the dialog reader's
|
|
18
|
+
* footer scan — `detectClaudeDialog` found no block, and `/prompt-response`
|
|
19
|
+
* refused the open dialog as `prompt_no_longer_active` (the refusal #2486
|
|
20
|
+
* reported). Its text also rode along on the option rows it shares a line with.
|
|
21
|
+
*
|
|
22
|
+
* Measured on a private tmux socket at the production 200x1000 geometry
|
|
23
|
+
* (`tests/fixtures/claude-live-2486/`): the tab row alone did not stop
|
|
24
|
+
* `detectClaudeDialog`; the pane did, with or without a tab row.
|
|
25
|
+
*
|
|
26
|
+
* ## A leaf on purpose
|
|
27
|
+
*
|
|
28
|
+
* Imports nothing, so `lib/chat/chat-tool-approvals.ts` — which client
|
|
29
|
+
* components reach — takes its tab-bar pattern from here rather than keeping a
|
|
30
|
+
* second copy of what the bar looks like (#2460 strips it from rows stored before
|
|
31
|
+
* this Issue stopped the detector from putting it there).
|
|
32
|
+
*
|
|
33
|
+
* ## Why characters and not columns
|
|
34
|
+
*
|
|
35
|
+
* Every reader sees one of two spellings of these rows: the capture with its box
|
|
36
|
+
* drawing, or the same capture after `stripBoxDrawing` (the Auto-Yes poller and
|
|
37
|
+
* every `detectPrompt` caller). `stripBoxDrawing` removes a leading `│` with the
|
|
38
|
+
* whitespace in front of it, so a pane row with nothing in the options column
|
|
39
|
+
* loses its left border and slides to column 0, while a row that shares its
|
|
40
|
+
* line with an option keeps the border in the middle. A column position cannot
|
|
41
|
+
* follow that — and `terminal-columns.ts` deliberately counts a CJK character as
|
|
42
|
+
* one column — so the pane is found by structure instead: its top border on
|
|
43
|
+
* option 1's row, a bottom border of the same width, the FIRST `│` on each row
|
|
44
|
+
* in between, and the picker's footer under it all. That reads the same in both
|
|
45
|
+
* spellings.
|
|
46
|
+
*/
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.ASK_USER_QUESTION_PICKER_FOOTER_PATTERN = exports.ASK_USER_QUESTION_TAB_BAR_PREFIX_PATTERN = void 0;
|
|
49
|
+
exports.isAskUserQuestionTabRow = isAskUserQuestionTabRow;
|
|
50
|
+
exports.findAskUserQuestionTabRow = findAskUserQuestionTabRow;
|
|
51
|
+
exports.findClaudePreviewPanes = findClaudePreviewPanes;
|
|
52
|
+
/**
|
|
53
|
+
* The multi-question tab bar: `←`, one checkbox per question, `✔ Submit`, `→`.
|
|
54
|
+
*
|
|
55
|
+
* A tab name may hold spaces, Japanese or `/` (`Goal/範囲`); the class excludes
|
|
56
|
+
* only the bar's own glyphs. `(?:[☐☒☑][^…☐☒☑…]*)+` cannot backtrack: every
|
|
57
|
+
* repetition starts with a checkbox the inner class excludes. ReDoS-safe.
|
|
58
|
+
*/
|
|
59
|
+
const TAB_BAR_SOURCE = String.raw `←\s*(?:[☐☒☑][^←→☐☒☑✔]*)+✔\s*Submit\s*→`;
|
|
60
|
+
/**
|
|
61
|
+
* The tab bar at the FRONT of a string an upward scan swept it into (#2460).
|
|
62
|
+
*
|
|
63
|
+
* Stored `question` values from before #2486 start with it; the chat surface
|
|
64
|
+
* strips it at display time. Unanchored at the end on purpose — the question
|
|
65
|
+
* follows it.
|
|
66
|
+
*/
|
|
67
|
+
exports.ASK_USER_QUESTION_TAB_BAR_PREFIX_PATTERN = new RegExp(`^${TAB_BAR_SOURCE}\\s*`);
|
|
68
|
+
/**
|
|
69
|
+
* The tab bar as a whole pane row.
|
|
70
|
+
*
|
|
71
|
+
* At most one leading space: Claude draws it at column 0, and a row the
|
|
72
|
+
* transcript indents (tool output, a quoted reply) is not the picker's.
|
|
73
|
+
*/
|
|
74
|
+
const TAB_BAR_ROW_PATTERN = new RegExp(`^\\s?${TAB_BAR_SOURCE}$`);
|
|
75
|
+
/**
|
|
76
|
+
* A single question's tab: ` ☐ 権限モード `.
|
|
77
|
+
*
|
|
78
|
+
* - At most one leading space, like the bar. TodoWrite's `☐ task` rows sit under
|
|
79
|
+
* `⎿` and are indented further, so they do not match.
|
|
80
|
+
* - The header may not begin with a digit: `☐ 1. Blue` is how a multi-select
|
|
81
|
+
* option would read, and an option row must never be taken for chrome.
|
|
82
|
+
* - AskUserQuestion caps a header at 12 characters, so 40 is generous and keeps a
|
|
83
|
+
* row of prose that happens to start with a checkbox from qualifying.
|
|
84
|
+
*/
|
|
85
|
+
const SINGLE_TAB_ROW_PATTERN = /^\s?[☐☒☑] [^\s\d←→☐☒☑✔][^←→☐☒☑✔]{0,40}$/;
|
|
86
|
+
/**
|
|
87
|
+
* The picker's footer: `Enter to select · ↑/↓ to navigate · … · Esc to cancel`.
|
|
88
|
+
*
|
|
89
|
+
* The generic parser trims its scan at it and flags `isAskUserQuestion` from it
|
|
90
|
+
* (#807); the pane finder below requires it under a pane (#2486). One pattern for
|
|
91
|
+
* both, so "this is a live picker" means the same thing to each. A single
|
|
92
|
+
* unbounded quantifier between literal anchors — ReDoS safe.
|
|
93
|
+
*/
|
|
94
|
+
exports.ASK_USER_QUESTION_PICKER_FOOTER_PATTERN = /Enter\s+to\s+select\b.*\bnavigate\b/i;
|
|
95
|
+
/** Whether `row` is an AskUserQuestion picker's tab row, in either form. */
|
|
96
|
+
function isAskUserQuestionTabRow(row) {
|
|
97
|
+
const text = row.trimEnd();
|
|
98
|
+
return TAB_BAR_ROW_PATTERN.test(text) || SINGLE_TAB_ROW_PATTERN.test(text);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The tab row above the question whose last row is `questionRow`, or -1.
|
|
102
|
+
*
|
|
103
|
+
* Only ever asked from a question or an option block upward, so the tab row is
|
|
104
|
+
* found where the picker draws it — above its own question — and nowhere else.
|
|
105
|
+
*
|
|
106
|
+
* @param lines - ANSI-stripped rows, box drawing optional
|
|
107
|
+
* @param questionRow - The question's last row (or the options' first row)
|
|
108
|
+
* @param lookback - How many rows above `questionRow` the tab row may sit
|
|
109
|
+
*/
|
|
110
|
+
function findAskUserQuestionTabRow(lines, questionRow, lookback) {
|
|
111
|
+
const floor = Math.max(0, questionRow - lookback);
|
|
112
|
+
for (let i = questionRow - 1; i >= floor; i--) {
|
|
113
|
+
if (isAskUserQuestionTabRow(lines[i] ?? ''))
|
|
114
|
+
return i;
|
|
115
|
+
}
|
|
116
|
+
return -1;
|
|
117
|
+
}
|
|
118
|
+
/** The pane's top border, closing option 1's row: `❯ 1. label ┌───┐`. */
|
|
119
|
+
const PREVIEW_TOP_BORDER_PATTERN = /┌(─+)┐\s*$/;
|
|
120
|
+
/**
|
|
121
|
+
* What must precede the top border on its row: option 1, cursor or not.
|
|
122
|
+
*
|
|
123
|
+
* One of the two anchors that keep a box Claude renders in the TRANSCRIPT — a
|
|
124
|
+
* Markdown table, a diagram in a reply — from being taken for a pane: those
|
|
125
|
+
* start at the transcript's own indent, not on a numbered option row. The other
|
|
126
|
+
* is the picker footer ({@link hasPickerFooterBelow}).
|
|
127
|
+
*/
|
|
128
|
+
const PREVIEW_ANCHOR_OPTION_PATTERN = /^\s*(?:[❯›>]\s*)?1\.\s+\S/;
|
|
129
|
+
/** The pane's bottom border, alone on its row; the indent is the pane's column. */
|
|
130
|
+
const PREVIEW_BOTTOM_BORDER_PATTERN = /^( *)└(─+)┘\s*$/;
|
|
131
|
+
/** The pane's left border. The first one on a row is the border, never content. */
|
|
132
|
+
const PREVIEW_LEFT_BORDER = '│';
|
|
133
|
+
/**
|
|
134
|
+
* What the options column may hold beside the pane: an option row, or the
|
|
135
|
+
* wrapped tail of a label (` (Recommended)`). Anything else to the left of a
|
|
136
|
+
* `│` is pane content that `stripBoxDrawing` slid left, and the row is pane.
|
|
137
|
+
*/
|
|
138
|
+
const OPTION_COLUMN_PATTERN = /^\s*(?:[❯›>]\s*)?\d{1,2}\.\s+\S|^\s{2,}\S/;
|
|
139
|
+
/** How far below its top border a pane's bottom border may be looked for. */
|
|
140
|
+
const MAX_PREVIEW_ROWS = 80;
|
|
141
|
+
/**
|
|
142
|
+
* How many non-blank rows may separate a pane (and its notes) from the picker
|
|
143
|
+
* footer. Measured: the separator rule and the unnumbered `Chat about this`.
|
|
144
|
+
*/
|
|
145
|
+
const PICKER_FOOTER_LOOKAHEAD_ROWS = 4;
|
|
146
|
+
function leadingSpaces(row) {
|
|
147
|
+
return row.length - row.trimStart().length;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Whether the picker's footer follows `from` within a few rows.
|
|
151
|
+
*
|
|
152
|
+
* A pane belongs to a LIVE picker, whose footer sits right under it. A reply
|
|
153
|
+
* that quotes a preview picker — box, cursor and all — has no footer under it;
|
|
154
|
+
* claiming its rows as chrome would hand the dialog reader the quoted options
|
|
155
|
+
* as if nothing followed them. Read past the caller's region on purpose: the
|
|
156
|
+
* generic parser's region ENDS at this footer.
|
|
157
|
+
*/
|
|
158
|
+
function hasPickerFooterBelow(lines, from) {
|
|
159
|
+
let seen = 0;
|
|
160
|
+
for (let i = from; i < lines.length && seen < PICKER_FOOTER_LOOKAHEAD_ROWS; i++) {
|
|
161
|
+
const row = lines[i];
|
|
162
|
+
if (row.trim() === '')
|
|
163
|
+
continue;
|
|
164
|
+
if (exports.ASK_USER_QUESTION_PICKER_FOOTER_PATTERN.test(row))
|
|
165
|
+
return true;
|
|
166
|
+
seen++;
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Find the AskUserQuestion preview pane(s) in [start, end).
|
|
172
|
+
*
|
|
173
|
+
* A pane is claimed only when all of it is on screen: a top border on option
|
|
174
|
+
* 1's row, a bottom border of exactly the same width below it, and the picker's
|
|
175
|
+
* footer under that. Anything less — a pane caught mid-draw, a quoted one — is
|
|
176
|
+
* left alone, which is the safe direction: its rows are read as they were before
|
|
177
|
+
* this Issue, and the dialog reader declines the frame rather than trusting half
|
|
178
|
+
* a box.
|
|
179
|
+
*
|
|
180
|
+
* @param lines - ANSI-stripped rows, box drawing optional
|
|
181
|
+
* @param start - First index to consider (inclusive)
|
|
182
|
+
* @param end - Last index to consider (exclusive)
|
|
183
|
+
*/
|
|
184
|
+
function findClaudePreviewPanes(lines, start, end) {
|
|
185
|
+
const rows = new Set();
|
|
186
|
+
const cuts = new Map();
|
|
187
|
+
const last = Math.min(end, lines.length);
|
|
188
|
+
for (let top = Math.max(0, start); top < last; top++) {
|
|
189
|
+
const row = lines[top];
|
|
190
|
+
if (!row.includes('┌'))
|
|
191
|
+
continue;
|
|
192
|
+
const topBorder = PREVIEW_TOP_BORDER_PATTERN.exec(row);
|
|
193
|
+
if (!topBorder || !PREVIEW_ANCHOR_OPTION_PATTERN.test(row.slice(0, topBorder.index)))
|
|
194
|
+
continue;
|
|
195
|
+
let bottom = -1;
|
|
196
|
+
let indent = 0;
|
|
197
|
+
for (let i = top + 1; i < Math.min(last, top + MAX_PREVIEW_ROWS); i++) {
|
|
198
|
+
const bottomBorder = PREVIEW_BOTTOM_BORDER_PATTERN.exec(lines[i]);
|
|
199
|
+
if (bottomBorder && bottomBorder[2].length === topBorder[1].length) {
|
|
200
|
+
bottom = i;
|
|
201
|
+
indent = bottomBorder[1].length;
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (bottom < 0)
|
|
206
|
+
continue;
|
|
207
|
+
const paneRows = [bottom];
|
|
208
|
+
const paneCuts = [[top, topBorder.index]];
|
|
209
|
+
for (let i = top + 1; i < bottom; i++) {
|
|
210
|
+
const border = lines[i].indexOf(PREVIEW_LEFT_BORDER);
|
|
211
|
+
const optionColumn = border > 0 ? lines[i].slice(0, border) : '';
|
|
212
|
+
if (optionColumn.trim() !== '' && OPTION_COLUMN_PATTERN.test(optionColumn)) {
|
|
213
|
+
paneCuts.push([i, border]);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
paneRows.push(i);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// `Notes: press n to add notes` — the pane's column continues under the box
|
|
220
|
+
// at the box's own indent, which no row of the dialog shares.
|
|
221
|
+
let next = bottom + 1;
|
|
222
|
+
for (; next < last; next++) {
|
|
223
|
+
const below = lines[next];
|
|
224
|
+
if (below.trim() === '')
|
|
225
|
+
continue;
|
|
226
|
+
if (leadingSpaces(below) !== indent)
|
|
227
|
+
break;
|
|
228
|
+
paneRows.push(next);
|
|
229
|
+
}
|
|
230
|
+
if (!hasPickerFooterBelow(lines, next))
|
|
231
|
+
continue;
|
|
232
|
+
for (const paneRow of paneRows)
|
|
233
|
+
rows.add(paneRow);
|
|
234
|
+
for (const [cutRow, index] of paneCuts)
|
|
235
|
+
cuts.set(cutRow, index);
|
|
236
|
+
top = next - 1;
|
|
237
|
+
}
|
|
238
|
+
return { rows, cuts };
|
|
239
|
+
}
|
|
@@ -35,11 +35,35 @@
|
|
|
35
35
|
* bullet — ` ● Which color scheme do you prefer?` is a live row of
|
|
36
36
|
* `askuserquestion-submit-taskpanel.txt`. Accepting it here would let Claude's
|
|
37
37
|
* own prose vouch for itself, which is the #1896 failure with a different glyph.
|
|
38
|
+
*
|
|
39
|
+
* ## Claude's pinned panels are not a footer (Issue #2468)
|
|
40
|
+
*
|
|
41
|
+
* claude-cli 2.1.267 draws a right-aligned HUD row at the bottom of the pane
|
|
42
|
+
* (`+28 files edited before this session (show)` / `No changes this session`,
|
|
43
|
+
* `tests/fixtures/claude-live-2468/`). Under the footer-less AskUserQuestion
|
|
44
|
+
* screen it was read as that screen's footer, failed the footer test, and the
|
|
45
|
+
* open dialog was refused. The footer guard therefore reads the rows under the
|
|
46
|
+
* options through `findClaudeTaskPanelLines` — the same set the transcript-tail
|
|
47
|
+
* walk steps over — and a footer made only of panel rows is no footer.
|
|
48
|
+
*
|
|
49
|
+
* ## An AskUserQuestion preview pane is chrome too (Issue #2486)
|
|
50
|
+
*
|
|
51
|
+
* claude-cli 2.1.268 opens a box to the right of the options when an option
|
|
52
|
+
* carries a `preview` (`tests/fixtures/claude-live-2486/`). Its ~20 rows sit
|
|
53
|
+
* between the last option and the footer, so the block reader's footer scan —
|
|
54
|
+
* eight non-blank rows — ran out on pane rows, found no option, and an open
|
|
55
|
+
* picker was refused as `prompt_no_longer_active`. The region is therefore read
|
|
56
|
+
* with Claude's chrome masked out (`findClaudeChrome` / `maskClaudeChrome`):
|
|
57
|
+
* the reading the transcript-tail walk and the generic parser use as well. The
|
|
58
|
+
* picker's tab row bounds the context scan above the options for the same
|
|
59
|
+
* reason in the other direction.
|
|
38
60
|
*/
|
|
39
61
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
62
|
exports.detectClaudeDialog = detectClaudeDialog;
|
|
41
63
|
const cli_patterns_1 = require("../../cli-patterns");
|
|
64
|
+
const prompt_detect_multiple_choice_1 = require("../../prompt-detect-multiple-choice");
|
|
42
65
|
const dialog_block_1 = require("../dialog-block");
|
|
66
|
+
const picker_chrome_1 = require("./picker-chrome");
|
|
43
67
|
/**
|
|
44
68
|
* Claude's dialog footers, in every spelling measured.
|
|
45
69
|
*
|
|
@@ -62,10 +86,16 @@ const CLAUDE_PERMISSION_QUESTION_PATTERN = /do you want to\b|allow\b.*\?$/i;
|
|
|
62
86
|
const CLAUDE_ASK_USER_QUESTION_PATTERN = /ready to submit your answers\?|review your answers/i;
|
|
63
87
|
/** The `/model` overlay's footer verb (Issue #1495). */
|
|
64
88
|
const CLAUDE_PICKER_FOOTER_PATTERN = /set\s+as\s+default/i;
|
|
65
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* The non-blank rows immediately above `firstRow`, nearest first — up to an
|
|
91
|
+
* AskUserQuestion picker's tab row, which is the dialog's top edge (Issue
|
|
92
|
+
* #2486). Above it is the transcript, whose rows have no say in what kind of
|
|
93
|
+
* dialog this is.
|
|
94
|
+
*/
|
|
66
95
|
function readContextAbove(lines, firstRow) {
|
|
96
|
+
const tabRow = (0, picker_chrome_1.findAskUserQuestionTabRow)(lines, firstRow, prompt_detect_multiple_choice_1.APPROVAL_TARGET_MAX_LOOKBACK);
|
|
67
97
|
const rows = [];
|
|
68
|
-
for (let i = firstRow - 1; i
|
|
98
|
+
for (let i = firstRow - 1; i > tabRow && rows.length < QUESTION_SCAN_ROWS; i--) {
|
|
69
99
|
const row = lines[i].trim();
|
|
70
100
|
if (row === '')
|
|
71
101
|
continue;
|
|
@@ -73,6 +103,26 @@ function readContextAbove(lines, firstRow) {
|
|
|
73
103
|
}
|
|
74
104
|
return rows.join('\n');
|
|
75
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* The non-blank rows in [from, end) — the block's footer — without Claude's
|
|
108
|
+
* chrome (Issue #2468).
|
|
109
|
+
*
|
|
110
|
+
* `findClaudeTranscriptTail` already steps over the panels, so normally none is
|
|
111
|
+
* in range. #2468 is what "normally" cost: a HUD row the tail walk did not know
|
|
112
|
+
* became the tail, then the footer, and the one dialog with no footer of its own
|
|
113
|
+
* was refused over a row of chrome. Reading the range through the same chrome
|
|
114
|
+
* the tail walk uses keeps the two rules from disagreeing about what is chrome —
|
|
115
|
+
* and since #2486 that includes the preview pane, whose rows sit exactly here.
|
|
116
|
+
*/
|
|
117
|
+
function readFooter(lines, chromeRows, from, end) {
|
|
118
|
+
const rows = [];
|
|
119
|
+
for (let i = from; i < Math.min(end, lines.length); i++) {
|
|
120
|
+
const row = lines[i].trim();
|
|
121
|
+
if (row !== '' && !chromeRows.has(i))
|
|
122
|
+
rows.push(row);
|
|
123
|
+
}
|
|
124
|
+
return rows.join('\n');
|
|
125
|
+
}
|
|
76
126
|
function classify(context, footer) {
|
|
77
127
|
if (CLAUDE_ASK_USER_QUESTION_PATTERN.test(context))
|
|
78
128
|
return 'ask_user';
|
|
@@ -97,7 +147,23 @@ function detectClaudeDialog(frame, context) {
|
|
|
97
147
|
// `frame.contentLines` is valid here too — and a frame whose gutter the
|
|
98
148
|
// Auto-Yes poller already removed parses to the same rows.
|
|
99
149
|
const lines = (0, cli_patterns_1.stripBoxDrawing)(frame.clean).split('\n');
|
|
100
|
-
const
|
|
150
|
+
const end = context.transcriptTail + 1;
|
|
151
|
+
// Issue #2486: read the region with Claude's chrome taken out. An
|
|
152
|
+
// AskUserQuestion preview pane puts ~20 rows between the options and the
|
|
153
|
+
// footer and shares its top rows with the options; unmasked, the block reader's
|
|
154
|
+
// footer scan ran out on pane rows before it reached an option, and the open
|
|
155
|
+
// dialog was refused. Masking keeps row indices, so everything below reports
|
|
156
|
+
// positions in `lines` unchanged.
|
|
157
|
+
//
|
|
158
|
+
// The chrome is measured on the rows as they ARRIVED, not on `lines`: the
|
|
159
|
+
// Auto-Yes poller hands this a frame it already box-stripped, and a second
|
|
160
|
+
// `stripBoxDrawing` removes the pane border an option row is left ending with
|
|
161
|
+
// (` 2. ファイル読取のみで続行 │`) — the one mark that the row shares its
|
|
162
|
+
// line with the pane. The cuts carry over, because a strip only ever shortens
|
|
163
|
+
// such a row from the right.
|
|
164
|
+
const chrome = (0, prompt_detect_multiple_choice_1.findClaudeChrome)(frame.contentLines, 0, end);
|
|
165
|
+
const visible = (0, prompt_detect_multiple_choice_1.maskClaudeChrome)(lines, chrome);
|
|
166
|
+
const block = (0, dialog_block_1.findNumberedOptionBlock)(visible, end);
|
|
101
167
|
if (!block)
|
|
102
168
|
return null;
|
|
103
169
|
// Guard 1: the selection cursor. Claude puts it on the highlighted option of
|
|
@@ -108,12 +174,14 @@ function detectClaudeDialog(frame, context) {
|
|
|
108
174
|
// Guard 2: whatever sits between the options and the end of the transcript
|
|
109
175
|
// must be one of Claude's dialog footers, or nothing at all. A completion
|
|
110
176
|
// marker (`✻ Brewed for 24s`) or a fresh line of prose there means the block
|
|
111
|
-
// is finished output with something after it, not an open dialog.
|
|
112
|
-
|
|
177
|
+
// is finished output with something after it, not an open dialog. Claude's
|
|
178
|
+
// chrome is neither, so it is read out of it first (Issue #2468; an
|
|
179
|
+
// AskUserQuestion preview pane since #2486).
|
|
180
|
+
const footer = readFooter(visible, chrome.rows, block.lastRow + 1, end);
|
|
113
181
|
if (footer !== '' && !CLAUDE_DIALOG_FOOTER_PATTERN.test(footer))
|
|
114
182
|
return null;
|
|
115
183
|
return {
|
|
116
|
-
kind: classify(readContextAbove(
|
|
184
|
+
kind: classify(readContextAbove(visible, block.firstRow), footer),
|
|
117
185
|
options: block.options,
|
|
118
186
|
// Claude's menus take ↑/↓ + Enter, and `sendPromptAnswer` already knows
|
|
119
187
|
// that: it NAVIGATES to the numbered option for claude rather than typing
|