commandmate 0.34.1 → 0.36.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 +365 -343
- package/.next/app-path-routes-manifest.json +29 -29
- package/.next/build-manifest.json +5 -5
- 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_client-reference-manifest.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.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 +1 -1
- 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.nft.json +1 -1
- package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js +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.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/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.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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/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.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/chat/page.js +2 -2
- package/.next/server/app/chat/page.js.nft.json +1 -1
- package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page.js +2 -2
- package/.next/server/app/more/page.js.nft.json +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page.js +1 -1
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page.js +2 -2
- package/.next/server/app/repositories/page.js.nft.json +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page.js +1 -1
- package/.next/server/app/review/page.js.nft.json +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +2 -2
- package/.next/server/app/sessions/page.js.nft.json +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page.js +2 -2
- package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page.js +2 -2
- package/.next/server/app/skills/installed/page.js.nft.json +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page.js +1 -1
- package/.next/server/app/skills/page.js.nft.json +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js +2 -2
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +9 -22
- 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 +29 -29
- package/.next/server/chunks/1210.js +1 -1
- package/.next/server/chunks/{6286.js → 1467.js} +6 -6
- package/.next/server/chunks/1707.js +14 -0
- package/.next/server/chunks/1886.js +1 -1
- package/.next/server/chunks/2980.js +1 -1
- package/.next/server/chunks/3077.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/3543.js +1 -1
- package/.next/server/chunks/364.js +1 -0
- package/.next/server/chunks/3945.js +1 -1
- package/.next/server/chunks/434.js +1 -1
- package/.next/server/chunks/4443.js +1 -1
- package/.next/server/chunks/450.js +1 -1
- package/.next/server/chunks/4802.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/650.js +1 -1
- package/.next/server/chunks/6677.js +3 -3
- package/.next/server/chunks/7004.js +1 -0
- package/.next/server/chunks/7075.js +1 -1
- package/.next/server/chunks/7506.js +1 -1
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8142.js +1 -0
- package/.next/server/chunks/8728.js +8 -0
- package/.next/server/chunks/8918.js +5 -5
- package/.next/server/chunks/9123.js +2 -2
- package/.next/server/chunks/9627.js +1 -1
- package/.next/server/chunks/9701.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/2039-117a361f795ddc4b.js +1 -0
- package/.next/static/chunks/2053-ce3fe896ad45e50f.js +1 -0
- package/.next/static/chunks/2407-6b8ca567e18ad583.js +1 -0
- package/.next/static/chunks/3160-79d24ca264a528b9.js +1 -0
- package/.next/static/chunks/{4322-dfd5a7119b5ba4fc.js → 4322-59a7dbd77a7763cc.js} +1 -1
- package/.next/static/chunks/4388-410b1d8ed0d8d98b.js +1 -0
- package/.next/static/chunks/4718-56ebb6e55073ed5e.js +1 -0
- package/.next/static/chunks/4949-d804db873cfd9310.js +1 -0
- package/.next/static/chunks/{6022-7a7d1760fc9814c7.js → 6022-d2d7bd9373ff3ae9.js} +1 -1
- package/.next/static/chunks/6983-3ed2099251793bdf.js +1 -0
- package/.next/static/chunks/934-a37509667baa86ee.js +1 -0
- package/.next/static/chunks/9526-4fe2fc64be44e5c1.js +1 -0
- package/.next/static/chunks/app/chat/page-bfc1f5bb17bd771d.js +1 -0
- package/.next/static/chunks/app/error-c1dc1038d0a84a33.js +1 -0
- package/.next/static/chunks/app/global-error-49f765ecb7fd6527.js +1 -0
- package/.next/static/chunks/app/{layout-4c2f21e3f653ee4c.js → layout-114dc6e93e332392.js} +1 -1
- package/.next/static/chunks/app/more/page-400ffa825f8f150e.js +1 -0
- package/.next/static/chunks/app/{page-26a42881c8648cd3.js → page-a4f03c188610c6c8.js} +1 -1
- package/.next/static/chunks/app/repositories/{page-2576158c8420fda0.js → page-a15efb4ce1d1721e.js} +1 -1
- package/.next/static/chunks/app/review/{page-35b99baaf3c93b38.js → page-90ac618489676cbc.js} +1 -1
- package/.next/static/chunks/app/sessions/page-366edfaa0b1faad2.js +1 -0
- package/.next/static/chunks/app/skills/[skillId]/{page-06799157652e8fa9.js → page-ce8f6fd9e4356580.js} +1 -1
- package/.next/static/chunks/app/skills/installed/{page-2f3987e3a131c8d0.js → page-566dfde26d7e63ba.js} +1 -1
- package/.next/static/chunks/app/skills/{page-e70bfcf5ed4e4865.js → page-7859540e8092aace.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/page-df482ec0c378c77b.js +1 -0
- package/.next/static/chunks/{webpack-1dc9eb5ebb4fa5ff.js → webpack-0281b30457d46ebc.js} +1 -1
- package/.next/static/css/c511ecdf1e7f18a0.css +1 -0
- package/.next/trace +14 -13
- package/dist/lib/detection/tools/verified-against.d.ts +20 -0
- package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
- package/dist/lib/detection/tools/verified-against.js +20 -0
- package/dist/server/src/config/websocket-config.js +67 -0
- package/dist/server/src/lib/auto-yes-poller.js +40 -7
- package/dist/server/src/lib/auto-yes-state.js +36 -0
- package/dist/server/src/lib/detection/selection-shape.js +361 -3
- package/dist/server/src/lib/detection/tools/command-code/detect.js +96 -0
- package/dist/server/src/lib/detection/tools/command-code/dialog.js +314 -0
- package/dist/server/src/lib/detection/tools/verified-against.js +20 -0
- package/dist/server/src/lib/polling/response-checker.js +48 -2
- package/dist/server/src/lib/ws-server.js +111 -1
- package/package.json +1 -1
- package/public/sw.js +12 -0
- package/.next/server/chunks/120.js +0 -1
- package/.next/server/chunks/595.js +0 -8
- package/.next/server/chunks/7593.js +0 -1
- package/.next/static/chunks/1191-b7dfdfe86b1d31d1.js +0 -1
- package/.next/static/chunks/2053-9ac860ab4e92ac89.js +0 -1
- package/.next/static/chunks/2652-18b8fea64413467e.js +0 -1
- package/.next/static/chunks/4718-29cfcfb806724d9a.js +0 -1
- package/.next/static/chunks/5542-b6457f305d724a6b.js +0 -1
- package/.next/static/chunks/8361-0142beb59be2abf3.js +0 -1
- package/.next/static/chunks/app/chat/page-e60d07c4c79602f0.js +0 -1
- package/.next/static/chunks/app/error-27ab04bce6545dae.js +0 -1
- package/.next/static/chunks/app/global-error-7b761b8e181ffc1f.js +0 -1
- package/.next/static/chunks/app/more/page-fc94f86aa881489e.js +0 -1
- package/.next/static/chunks/app/sessions/page-a3ab6f122ec60d5a.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-60eab4e24c37cb77.js +0 -1
- package/.next/static/css/b09bede85744e1cf.css +0 -1
- /package/.next/static/{oDWX0JcwfhUYrMnnqDWVC → zNNp00FuBenN_iZtIvIBP}/_buildManifest.js +0 -0
- /package/.next/static/{oDWX0JcwfhUYrMnnqDWVC → zNNp00FuBenN_iZtIvIBP}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Command Code's footer-less `AskUserQuestion`, read as an answerable prompt
|
|
4
|
+
* (Issue #2522).
|
|
5
|
+
*
|
|
6
|
+
* ## What Issue #2521 left here
|
|
7
|
+
*
|
|
8
|
+
* #2521 taught the status chain to RECOGNISE this screen. It draws a 200-column
|
|
9
|
+
* rule, a tab strip (`● Dispatch | ◯ Review`), a question and a strict `1.`…`N.`
|
|
10
|
+
* run with one `❯` on it — and no hint-bar footer at all — and when an option's
|
|
11
|
+
* description wraps, the continuation row begins with a SINGLE space:
|
|
12
|
+
*
|
|
13
|
+
* ────────────────────────────… (200 columns of U+2500)
|
|
14
|
+
* ● Dispatch | ◯ Review
|
|
15
|
+
*
|
|
16
|
+
* Approve proceeding from the plan into worktree creation and dispatch?
|
|
17
|
+
*
|
|
18
|
+
* ❯ 1. Prepare worktrees + dispatch (Recommended)
|
|
19
|
+
* I create the worktrees and pause for you to
|
|
20
|
+
* answer).
|
|
21
|
+
* 2. Worktrees only, then pause
|
|
22
|
+
* …
|
|
23
|
+
*
|
|
24
|
+
* `isContinuationLine` in the shared multiple-choice parser refuses ` answer).`
|
|
25
|
+
* (one leading space, five characters or more, no path shape), so the generic
|
|
26
|
+
* reverse scan stops there one row short of option 1, collects `[2,3,4]`, and
|
|
27
|
+
* rejects the block for not starting at `1`. #2521's answer was a manual-operation
|
|
28
|
+
* fallback: `waiting` / `COMMAND_CODE_SELECTION_LIST` / `hasActivePrompt: false`,
|
|
29
|
+
* which stops `wait` exiting 0 and raises a card a human drives with the arrows.
|
|
30
|
+
*
|
|
31
|
+
* This module is the other half. It reads the SAME region #2521 recognises
|
|
32
|
+
* ({@link readCommandCodeQuestionRegion}) and produces the `multiple_choice`
|
|
33
|
+
* payload that `respond`, the chat surface's answer buttons, the prompt-history
|
|
34
|
+
* rows, the push notification and Auto-Yes all consume — so a frame this reads
|
|
35
|
+
* is published as `PROMPT_DETECTED` and the fallback no longer applies to it.
|
|
36
|
+
*
|
|
37
|
+
* ## Three states, one reading
|
|
38
|
+
*
|
|
39
|
+
* {@link readCommandCodeQuestionDialog} answers a discriminated union rather
|
|
40
|
+
* than `PromptDetectionResult | null`, because "this is not that screen" and
|
|
41
|
+
* "this IS that screen and I cannot read it" need opposite handling and a `null`
|
|
42
|
+
* cannot tell them apart (Issue #2522 確定仕様 B):
|
|
43
|
+
*
|
|
44
|
+
* | `kind` | what it means | what the caller does |
|
|
45
|
+
* |---------------|--------------------------------------------|----------------------|
|
|
46
|
+
* | `none` | not Command Code's question screen | every existing tool-specific / generic path, unchanged |
|
|
47
|
+
* | `prompt` | read in full | use this prompt; do not let the generic parser overwrite it |
|
|
48
|
+
* | `unsupported` | the question UI is plainly up, and a gap / a duplicate / an over-tall region / an unreadable option run stopped the reading | #2521's manual-operation fallback. No `promptData`, no auto-answer, and NOT the generic parser's partial list |
|
|
49
|
+
*
|
|
50
|
+
* ## Why it is not "call the generic parser, fall back to this"
|
|
51
|
+
*
|
|
52
|
+
* Because the generic parser SUCCEEDS on the short spelling of this screen —
|
|
53
|
+
* one-line descriptions, nothing wrapped — and succeeds badly: `extractQuestionText`
|
|
54
|
+
* walks up to {@link QUESTION_CONTEXT_LINES} rows above the options and would
|
|
55
|
+
* take the tab strip, the rule and the transcript's TODOS row into the question.
|
|
56
|
+
* So this reader runs FIRST wherever it runs at all, and the question it produces
|
|
57
|
+
* is bounded by the tab row rather than by a row count.
|
|
58
|
+
*
|
|
59
|
+
* ## Input contract
|
|
60
|
+
*
|
|
61
|
+
* A frame with its BOX DRAWING INTACT — `capture-pane -p -e` output, or that
|
|
62
|
+
* with ANSI removed. The region is anchored on a pure-U+2500 rule row, and
|
|
63
|
+
* `stripBoxDrawing` blanks exactly that row, so a `captureAndCleanOutput`
|
|
64
|
+
* spelling reaches `none` here however plainly the dialog is on screen. That is
|
|
65
|
+
* the trap #2522 確定仕様 C is written against: the three consumers that clean
|
|
66
|
+
* their frames (`detectPromptWithOptions`, the Auto-Yes poller, `/prompt-response`)
|
|
67
|
+
* each keep the RAW capture from the same tick and hand it here, and hand the
|
|
68
|
+
* cleaned string to everything else. ANSI is stripped internally, per row, off
|
|
69
|
+
* the same split the region indices address, so either spelling reads alike.
|
|
70
|
+
*
|
|
71
|
+
* Pure and side-effect free: no status, no poller, no database, no UI.
|
|
72
|
+
*/
|
|
73
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
74
|
+
exports.COMMAND_CODE_QUESTION_MAX_REGION_ROWS = void 0;
|
|
75
|
+
exports.readCommandCodeQuestionDialog = readCommandCodeQuestionDialog;
|
|
76
|
+
exports.detectCommandCodeQuestionPrompt = detectCommandCodeQuestionPrompt;
|
|
77
|
+
const ansi_1 = require("../../ansi");
|
|
78
|
+
const prompt_detect_multiple_choice_1 = require("../../prompt-detect-multiple-choice");
|
|
79
|
+
const selection_shape_1 = require("../../selection-shape");
|
|
80
|
+
const dialog_block_1 = require("../dialog-block");
|
|
81
|
+
/**
|
|
82
|
+
* How many rows of dialog this reader will parse.
|
|
83
|
+
*
|
|
84
|
+
* 確定仕様 A forbids truncating to the 15-row detection window or the 40-row
|
|
85
|
+
* selection-shape tail — a wrapped description is exactly what pushes the
|
|
86
|
+
* question out of those — and equally forbids reporting a PARTIAL list as a
|
|
87
|
+
* success when a cap is hit. So the cap is stated here, generously, and hitting
|
|
88
|
+
* it is `unsupported` rather than "the options I managed to see".
|
|
89
|
+
*
|
|
90
|
+
* Sixty rows is the tallest this screen can plausibly be (a tab strip, a blank,
|
|
91
|
+
* a question wrapped over half a dozen rows, and nine options with four rows of
|
|
92
|
+
* description each) and equals {@link findNumberedOptionBlock}'s own
|
|
93
|
+
* `MAX_BLOCK_ROWS`, so the two cannot disagree about which one declined: the
|
|
94
|
+
* region is measured first and the block walk can no longer reach its limit.
|
|
95
|
+
*/
|
|
96
|
+
exports.COMMAND_CODE_QUESTION_MAX_REGION_ROWS = 60;
|
|
97
|
+
/**
|
|
98
|
+
* How many non-blank rows under the LAST option may be its own description.
|
|
99
|
+
*
|
|
100
|
+
* The region ends at the last row carrying content, so the rows
|
|
101
|
+
* {@link findNumberedOptionBlock} files as `footer` are not chrome — this screen
|
|
102
|
+
* draws none — they are the wrapped tail of the bottom option, and 確定仕様 A
|
|
103
|
+
* says a description under the last option folds into it exactly as one under
|
|
104
|
+
* any other option does. Same trade agy's reader makes for the same reason.
|
|
105
|
+
*/
|
|
106
|
+
const LAST_OPTION_TAIL_ROWS = 12;
|
|
107
|
+
/** The cursor glyph, restated from the region reader's own private constant. */
|
|
108
|
+
const COMMAND_CODE_CURSOR_GLYPH = '❯';
|
|
109
|
+
/**
|
|
110
|
+
* The cursor row's own option number, for the cross-check below.
|
|
111
|
+
*
|
|
112
|
+
* The region reading already proved there is exactly one `❯` in the region and
|
|
113
|
+
* that it sits on an option row; this recovers WHICH option it is, so the
|
|
114
|
+
* default can be pinned against {@link findNumberedOptionBlock}'s own answer
|
|
115
|
+
* instead of trusting a glyph union (`[❯›●>]`) that is wider than this screen's.
|
|
116
|
+
*/
|
|
117
|
+
const CURSOR_OPTION_NUMBER_PATTERN = /❯[^\S\n]*(\d{1,2})[.)]/;
|
|
118
|
+
/**
|
|
119
|
+
* The one option on this screen that is NOT answerable by its number
|
|
120
|
+
* (Issue #2522 確定仕様 A / D).
|
|
121
|
+
*
|
|
122
|
+
* Command Code draws `4. Type something...` as the last row of the list, and it
|
|
123
|
+
* is not a fourth choice: the measured `QuestionPrompt` gives the ordinary
|
|
124
|
+
* choices to a `SelectInput` and renders this one as a separate `TextInput`. It
|
|
125
|
+
* is kept as a displayed option — a human has to see that the screen offers free
|
|
126
|
+
* text — and marked `requiresTextInput`, which is what stops `resolveBaseAnswer`
|
|
127
|
+
* auto-selecting it and what makes the answer UIs open a text field instead of
|
|
128
|
+
* sending a bare `4`.
|
|
129
|
+
*
|
|
130
|
+
* Added to the shared builder's result rather than to `TEXT_INPUT_PATTERNS`,
|
|
131
|
+
* because that list is the GENERIC one every CLI is read through and 対象外
|
|
132
|
+
* forbids widening it: `/enter\s+/`-class patterns there already over-match, and
|
|
133
|
+
* one more entry would change what every other tool's options mean.
|
|
134
|
+
*
|
|
135
|
+
* Anchored at the start of the label so the fold-in of a description below the
|
|
136
|
+
* row (`Type something... Write your own answer.`) still matches.
|
|
137
|
+
*/
|
|
138
|
+
const COMMAND_CODE_FREE_TEXT_OPTION_PATTERN = /^[^\S\n]*type\s+something\b/i;
|
|
139
|
+
/**
|
|
140
|
+
* A checkbox option — the row shape of a MULTI-select question.
|
|
141
|
+
*
|
|
142
|
+
* The same expression `prompt-answer-sender` and `prompt-answer-semantic` use to
|
|
143
|
+
* recognise one, restated here (both are private to their modules) because this
|
|
144
|
+
* reader has to DECLINE the screen rather than answer it: 対象外 says Review,
|
|
145
|
+
* multi-select and free-text screens are not to be pushed through the
|
|
146
|
+
* single-select parser, and the reason is mechanical. On a checkbox list the
|
|
147
|
+
* digit TOGGLES a box and the confirm is a separate `Next` row, so a payload
|
|
148
|
+
* that claimed "option 2 is the answer" would have `respond 2` tick a box and
|
|
149
|
+
* stop — leaving the question up and the operator told it was answered.
|
|
150
|
+
*
|
|
151
|
+
* `unsupported` rather than `none`: the screen IS a live question and the human
|
|
152
|
+
* has to be sent to the pane for it, which is exactly #2521's fallback.
|
|
153
|
+
*/
|
|
154
|
+
const CHECKBOX_OPTION_PATTERN = /^\[[ x]\]\s/i;
|
|
155
|
+
/**
|
|
156
|
+
* The same tail limits `prompt-detector.ts` applies to `rawContent`
|
|
157
|
+
* (`RAW_CONTENT_MAX_LINES` / `RAW_CONTENT_MAX_CHARS`), restated because that
|
|
158
|
+
* helper is private to it. A prompt row stores this text as its message body.
|
|
159
|
+
*
|
|
160
|
+
* In practice neither bound binds here — the region is at most
|
|
161
|
+
* {@link COMMAND_CODE_QUESTION_MAX_REGION_ROWS} rows — which is the point: what
|
|
162
|
+
* used to reach these consumers for this screen was the whole 1000-row pane.
|
|
163
|
+
*/
|
|
164
|
+
const RAW_CONTENT_MAX_LINES = 200;
|
|
165
|
+
const RAW_CONTENT_MAX_CHARS = 5000;
|
|
166
|
+
function truncateRawContent(content) {
|
|
167
|
+
const lines = content.split('\n');
|
|
168
|
+
const tail = lines.length > RAW_CONTENT_MAX_LINES ? lines.slice(-RAW_CONTENT_MAX_LINES) : lines;
|
|
169
|
+
const joined = tail.join('\n');
|
|
170
|
+
return joined.length > RAW_CONTENT_MAX_CHARS ? joined.slice(-RAW_CONTENT_MAX_CHARS) : joined;
|
|
171
|
+
}
|
|
172
|
+
function unsupported(reason) {
|
|
173
|
+
return { kind: 'unsupported', reason };
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Read Command Code's `AskUserQuestion` off one capture (Issue #2522).
|
|
177
|
+
*
|
|
178
|
+
* @param frame - a capture with its box drawing intact (ANSI optional, CRLF
|
|
179
|
+
* tolerated). A `stripBoxDrawing`-ed string answers `none`; see the module
|
|
180
|
+
* docblock for why that is a contract and not a limitation to work around.
|
|
181
|
+
*/
|
|
182
|
+
function readCommandCodeQuestionDialog(frame) {
|
|
183
|
+
if (!frame)
|
|
184
|
+
return { kind: 'none' };
|
|
185
|
+
// The positive recognition is #2521's, unchanged and not re-derived: the last
|
|
186
|
+
// qualifying rule row, a tab strip under it, a question, a strict `1.`…`N.`
|
|
187
|
+
// run and exactly one `❯` on one of its rows, with the pickers and panels the
|
|
188
|
+
// other branches own excluded. Everything below is READING what it recognised.
|
|
189
|
+
const region = (0, selection_shape_1.readCommandCodeQuestionRegion)(frame);
|
|
190
|
+
if (region === null) {
|
|
191
|
+
// The strict reading declined. Two very different frames arrive here, and
|
|
192
|
+
// 確定仕様 B needs them told apart: one is any other screen in the world,
|
|
193
|
+
// the other is THIS screen with a gap in its numbering, a repeated row or a
|
|
194
|
+
// second cursor. `hasCommandCodeQuestionChrome` is the same structural scan
|
|
195
|
+
// with the two list-shaped conditions dropped, so it says which — and a
|
|
196
|
+
// question screen nobody can parse still stops `wait` instead of being
|
|
197
|
+
// handed back to the composer check that publishes `ready` off its own `❯`.
|
|
198
|
+
return (0, selection_shape_1.hasCommandCodeQuestionChrome)(frame)
|
|
199
|
+
? unsupported('numbering-unreadable')
|
|
200
|
+
: { kind: 'none' };
|
|
201
|
+
}
|
|
202
|
+
const lines = frame.replace(/\r\n/g, '\n').split('\n').map(ansi_1.stripAnsi);
|
|
203
|
+
const regionRows = lines.slice(region.firstLineIndex, region.lastLineIndex + 1);
|
|
204
|
+
if (regionRows.length > exports.COMMAND_CODE_QUESTION_MAX_REGION_ROWS) {
|
|
205
|
+
return unsupported('region-too-tall');
|
|
206
|
+
}
|
|
207
|
+
const tabOffset = region.tabLineIndex - region.firstLineIndex;
|
|
208
|
+
// The shared block reader, on the region alone. Walking UP from the bottom is
|
|
209
|
+
// what folds a wrapped description into the option ABOVE it — which is the
|
|
210
|
+
// rule 確定仕様 A states for indent 0, 1 and 2 alike, and the one the generic
|
|
211
|
+
// parser's `isContinuationLine` could not follow.
|
|
212
|
+
const block = (0, dialog_block_1.findNumberedOptionBlock)(regionRows, regionRows.length, LAST_OPTION_TAIL_ROWS);
|
|
213
|
+
if (block === null)
|
|
214
|
+
return unsupported('option-block-unreadable');
|
|
215
|
+
const labels = [...block.options];
|
|
216
|
+
if (block.footer !== '') {
|
|
217
|
+
// Rows below the bottom option. The region's lower edge is the last row with
|
|
218
|
+
// content and this screen draws no footer, so they are that option's own
|
|
219
|
+
// description.
|
|
220
|
+
const last = labels.length - 1;
|
|
221
|
+
labels[last] = [labels[last], ...block.footer.split('\n')].join(' ').trim();
|
|
222
|
+
}
|
|
223
|
+
if (labels.length !== region.optionCount)
|
|
224
|
+
return unsupported('option-count-mismatch');
|
|
225
|
+
if (labels.some((label) => CHECKBOX_OPTION_PATTERN.test(label)))
|
|
226
|
+
return unsupported('multi-select');
|
|
227
|
+
// The default. Not `selectedGlyph` alone: `findNumberedOptionBlock`'s glyph
|
|
228
|
+
// union is `[❯›●>]` because it serves every CLI, and `●` is this screen's TAB
|
|
229
|
+
// marker — so the answer is cross-checked against the row the region reading
|
|
230
|
+
// actually found the one `❯` on, and a disagreement declines rather than
|
|
231
|
+
// guessing which option a human is about to confirm.
|
|
232
|
+
const cursorRow = regionRows[region.cursorLineIndex - region.firstLineIndex] ?? '';
|
|
233
|
+
const cursorMatch = CURSOR_OPTION_NUMBER_PATTERN.exec(cursorRow);
|
|
234
|
+
if (block.selectedIndex < 0 ||
|
|
235
|
+
block.selectedGlyph !== COMMAND_CODE_CURSOR_GLYPH ||
|
|
236
|
+
cursorMatch === null ||
|
|
237
|
+
Number(cursorMatch[1]) !== block.selectedIndex + 1) {
|
|
238
|
+
return unsupported('default-unresolved');
|
|
239
|
+
}
|
|
240
|
+
// The question: everything between the tab strip and option 1, blanks dropped,
|
|
241
|
+
// wrapped rows joined with ONE space and in draw order. Bounded by the tab row
|
|
242
|
+
// rather than by a row count, so neither the rule, the TODOS row above it nor
|
|
243
|
+
// the tab strip itself can reach it — and not narrowed to "the last row ending
|
|
244
|
+
// in `?`", so a question wrapped over three rows keeps its first two. `?` is
|
|
245
|
+
// usable evidence elsewhere and is deliberately not required here.
|
|
246
|
+
const questionRows = regionRows
|
|
247
|
+
.slice(tabOffset + 1, block.firstRow)
|
|
248
|
+
.map((row) => row.trim())
|
|
249
|
+
.filter((row) => row !== '');
|
|
250
|
+
if (questionRows.length === 0)
|
|
251
|
+
return unsupported('question-missing');
|
|
252
|
+
const question = questionRows.join(' ');
|
|
253
|
+
// The dialog's own rows, and nothing above the rule. Both surfaces are built
|
|
254
|
+
// from the same slice on purpose: `instructionText` is what the answer panels
|
|
255
|
+
// show a human, `approvalTarget` is what the contract's deny patterns are
|
|
256
|
+
// matched against (#1699), and for THIS screen they are the same text — the
|
|
257
|
+
// region already excludes the previous turn, so there is no wider human-facing
|
|
258
|
+
// window to offer and no narrower machine-facing one to carve out. What
|
|
259
|
+
// matters is that the descriptions are inside both: a deny pattern has to see
|
|
260
|
+
// the sentence the option is actually promising.
|
|
261
|
+
const dialogText = (0, prompt_detect_multiple_choice_1.joinApprovalTarget)(regionRows, tabOffset + 1, regionRows.length);
|
|
262
|
+
const built = (0, prompt_detect_multiple_choice_1.buildMultipleChoiceResult)(question, labels.map((label, index) => ({
|
|
263
|
+
number: index + 1,
|
|
264
|
+
label,
|
|
265
|
+
isDefault: index === block.selectedIndex,
|
|
266
|
+
})), { instructionText: dialogText, approvalTarget: dialogText }, regionRows.join('\n'), truncateRawContent,
|
|
267
|
+
// 確定仕様 D. The measured `QuestionPrompt` hands the ordinary choices to a
|
|
268
|
+
// `SelectInput`, which calls `onSelect` on the DIGIT — so a trailing Enter
|
|
269
|
+
// would land on whatever the tool painted next (the following question, or
|
|
270
|
+
// Review), confirming a second operation nobody chose. `answer_only` is also
|
|
271
|
+
// the safe direction if that measurement is ever wrong for a build: a digit
|
|
272
|
+
// that selects nothing leaves the dialog exactly where it was, while the
|
|
273
|
+
// Enter it would otherwise be paired with cannot be taken back.
|
|
274
|
+
'answer_only',
|
|
275
|
+
// This IS an AskUserQuestion — a tab strip, a question and its own choices,
|
|
276
|
+
// not a permission prompt. It changes no keystroke for this tool (the cursor
|
|
277
|
+
// navigation arm of `sendPromptAnswer` is claude's and agy's), and it is what
|
|
278
|
+
// lets `/prompt-response` tell "the picker is up but unreadable" from "the
|
|
279
|
+
// prompt is gone".
|
|
280
|
+
true);
|
|
281
|
+
const promptData = built.promptData;
|
|
282
|
+
/* c8 ignore next -- buildMultipleChoiceResult always returns multiple_choice */
|
|
283
|
+
if (promptData === undefined || promptData.type !== 'multiple_choice') {
|
|
284
|
+
return unsupported('option-block-unreadable');
|
|
285
|
+
}
|
|
286
|
+
return {
|
|
287
|
+
kind: 'prompt',
|
|
288
|
+
region,
|
|
289
|
+
prompt: {
|
|
290
|
+
...built,
|
|
291
|
+
promptData: {
|
|
292
|
+
...promptData,
|
|
293
|
+
options: promptData.options.map((option) => option.requiresTextInput === true ||
|
|
294
|
+
COMMAND_CODE_FREE_TEXT_OPTION_PATTERN.test(option.label)
|
|
295
|
+
? { ...option, requiresTextInput: true }
|
|
296
|
+
: option),
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* The same reading as a `PromptDetectionResult | null`, for the call sites whose
|
|
303
|
+
* only question is "is there an answerable prompt here?".
|
|
304
|
+
*
|
|
305
|
+
* `null` for BOTH `none` and `unsupported`, which is safe exactly where the
|
|
306
|
+
* caller has already decided what to do about the second — the detector's
|
|
307
|
+
* `beforePrompt` publishes #2521's fallback for it, and `/prompt-response`
|
|
308
|
+
* refuses it with `unsupported_dialog_layout`. A caller that cannot tell the two
|
|
309
|
+
* apart must use {@link readCommandCodeQuestionDialog} instead.
|
|
310
|
+
*/
|
|
311
|
+
function detectCommandCodeQuestionPrompt(frame) {
|
|
312
|
+
const reading = readCommandCodeQuestionDialog(frame);
|
|
313
|
+
return reading.kind === 'prompt' ? reading.prompt : null;
|
|
314
|
+
}
|
|
@@ -112,6 +112,26 @@ exports.ANTIGRAVITY_VERIFIED_AGAINST = {
|
|
|
112
112
|
* tmux socket at the production geometry — the default pane size does not
|
|
113
113
|
* reproduce the 200-column rules that fence the composer, and the status row
|
|
114
114
|
* drops its `esc to interrupt` tail below 72 columns.
|
|
115
|
+
*
|
|
116
|
+
* ## Deliberately NOT advanced by Issues #2521 / #2522
|
|
117
|
+
*
|
|
118
|
+
* Both read the `AskUserQuestion` screen, and both did it from the anonymised
|
|
119
|
+
* capture in `tests/fixtures/command-code-askuserquestion-2521/` — whose rows
|
|
120
|
+
* 410-423 are verbatim from a live pane, but whose version is what the reporting
|
|
121
|
+
* session SAID it was (1.53.0) rather than something re-probed. #2522's own
|
|
122
|
+
* fixture directory is synthetic throughout, and the send mode
|
|
123
|
+
* (`submitMode: 'answer_only'`) was chosen from a STATIC reading of a locally
|
|
124
|
+
* installed 1.53.1 `QuestionPrompt` plus the safe-direction argument in
|
|
125
|
+
* `tools/command-code/dialog.ts` — not from a keystroke sent at a live pane.
|
|
126
|
+
*
|
|
127
|
+
* None of that is the measurement this stamp records. #2304 set the precedent in
|
|
128
|
+
* the other direction: seven frames re-captured live on 1.49.0 changed no rule,
|
|
129
|
+
* and the stamp still says 1.40.1 because that is the build the rules were READ
|
|
130
|
+
* OFF. Advancing it here on a reported version, a synthetic fixture and a
|
|
131
|
+
* package read off disk would make `getDetectorFreshness` claim a measurement
|
|
132
|
+
* nobody took. When a live 1.53.x session is probed — the question screen, the
|
|
133
|
+
* keys it accepts and what one of them advances — bump this to that exact
|
|
134
|
+
* version with its own `capturedAt`.
|
|
115
135
|
*/
|
|
116
136
|
exports.COMMAND_CODE_VERIFIED_AGAINST = {
|
|
117
137
|
version: '1.40.1',
|
|
@@ -18,6 +18,7 @@ const db_1 = require("../../lib/db");
|
|
|
18
18
|
const ws_server_1 = require("../../lib/ws-server");
|
|
19
19
|
const prompt_detector_1 = require("../../lib/detection/prompt-detector");
|
|
20
20
|
const dialog_1 = require("../../lib/detection/tools/antigravity/dialog");
|
|
21
|
+
const dialog_2 = require("../../lib/detection/tools/command-code/dialog");
|
|
21
22
|
const conversation_logger_1 = require("../../lib/conversation-logger");
|
|
22
23
|
const types_1 = require("../../lib/cli-tools/types");
|
|
23
24
|
const claude_output_1 = require("../../lib/claude-output");
|
|
@@ -205,13 +206,29 @@ function buildPromptExtractionResult(lines, lastCapturedLine, totalLines, buffer
|
|
|
205
206
|
* doubly-bordered row loses a second character on the second pass). Taking the
|
|
206
207
|
* already-clean frame here is what keeps the two callers reading identical text.
|
|
207
208
|
*
|
|
209
|
+
* ## The raw frame, and why it is a SECOND argument rather than a replacement
|
|
210
|
+
*
|
|
211
|
+
* Issue #2522. Command Code's `AskUserQuestion` is anchored on a 200-column
|
|
212
|
+
* U+2500 rule row, and `stripBoxDrawing` blanks exactly that row — so the
|
|
213
|
+
* reading that recognises the screen answers `null` on the spelling this
|
|
214
|
+
* function takes, however plainly the dialog is on the pane. The frame the
|
|
215
|
+
* cleaning started from is therefore passed alongside it: the caller has it in
|
|
216
|
+
* hand from the same tick, no second capture is taken, and `stripBoxDrawing`
|
|
217
|
+
* (which is not idempotent) still runs exactly once per tick, upstream.
|
|
218
|
+
*
|
|
219
|
+
* Omitting `rawFrame` is not an error and not a silent downgrade for anything
|
|
220
|
+
* else: only Command Code's reader consults it, and a caller that has no raw
|
|
221
|
+
* frame for this tool reaches the same `null` the old code did.
|
|
222
|
+
*
|
|
208
223
|
* @param cleanOutput - tmux output with ANSI **and** box drawing already removed
|
|
209
224
|
* @param cliToolId - CLI tool identifier for building detection options
|
|
210
225
|
* @param precomputedLines - `cleanOutput.split('\n')` when the caller already has it
|
|
211
226
|
* (Issue #499 Item 4); must be the split of THIS string, not of the raw capture
|
|
227
|
+
* @param rawFrame - the SAME tick's capture with its box drawing intact (ANSI
|
|
228
|
+
* optional), for the tool readers anchored on it (Issue #2522)
|
|
212
229
|
* @returns PromptDetectionResult with isPrompt, promptData, and cleanContent
|
|
213
230
|
*/
|
|
214
|
-
function detectPromptOnCleanFrame(cleanOutput, cliToolId, precomputedLines) {
|
|
231
|
+
function detectPromptOnCleanFrame(cleanOutput, cliToolId, precomputedLines, rawFrame) {
|
|
215
232
|
// Issue #2364: agy's `↑/↓ Navigate` dialogs are read by agy's own reader
|
|
216
233
|
// before the generic pass, on the same spelling `tools/antigravity/detect.ts`
|
|
217
234
|
// reads them on. The generic multiple-choice parser takes one row per option
|
|
@@ -232,6 +249,31 @@ function detectPromptOnCleanFrame(cleanOutput, cliToolId, precomputedLines) {
|
|
|
232
249
|
if (dialog !== null)
|
|
233
250
|
return dialog;
|
|
234
251
|
}
|
|
252
|
+
// Issue #2522: Command Code's footer-less `AskUserQuestion`, read by the same
|
|
253
|
+
// module `tools/command-code/detect.ts` publishes its status from — so the
|
|
254
|
+
// status API, the row this poller stores, the push notification's excerpt and
|
|
255
|
+
// `/prompt-response`'s re-verification all describe ONE screen with one
|
|
256
|
+
// question, one option list and one default.
|
|
257
|
+
//
|
|
258
|
+
// Ahead of the generic pass rather than after it, and both halves matter:
|
|
259
|
+
//
|
|
260
|
+
// - `prompt` — the generic parser SUCCEEDS on the short, unwrapped spelling
|
|
261
|
+
// of this screen and drags the tab strip and the transcript row above it
|
|
262
|
+
// into the question, so "fall back to the reader" would leave the frames
|
|
263
|
+
// that look fine looking wrong;
|
|
264
|
+
// - `unsupported` — the question UI is up and the reading declined (a gap in
|
|
265
|
+
// the numbering, an over-tall region). 確定仕様 B: no `promptData`, and
|
|
266
|
+
// explicitly NOT the generic parser's partial list either. The status path
|
|
267
|
+
// publishes #2521's manual-operation fallback for the same frame, so a
|
|
268
|
+
// human is still told to answer it at the pane.
|
|
269
|
+
if (cliToolId === 'command-code' && rawFrame !== undefined) {
|
|
270
|
+
const reading = (0, dialog_2.readCommandCodeQuestionDialog)(rawFrame);
|
|
271
|
+
if (reading.kind === 'prompt')
|
|
272
|
+
return reading.prompt;
|
|
273
|
+
if (reading.kind === 'unsupported') {
|
|
274
|
+
return { isPrompt: false, cleanContent: cleanOutput.trim() };
|
|
275
|
+
}
|
|
276
|
+
}
|
|
235
277
|
const promptOptions = (0, cli_patterns_1.buildDetectPromptOptions)(cliToolId);
|
|
236
278
|
return (0, prompt_detector_1.detectPrompt)(cleanOutput, precomputedLines ? { ...promptOptions, precomputedLines } : promptOptions);
|
|
237
279
|
}
|
|
@@ -295,7 +337,11 @@ function isNumberedDialogVouched(cliToolId, promptDetection, frame) {
|
|
|
295
337
|
* @returns PromptDetectionResult with isPrompt, promptData, and cleanContent
|
|
296
338
|
*/
|
|
297
339
|
function detectPromptWithOptions(output, cliToolId) {
|
|
298
|
-
|
|
340
|
+
// Issue #2522: `output` is the capture, so the box-drawing-bearing spelling is
|
|
341
|
+
// right here and is handed on as `rawFrame`. Nothing is captured twice and
|
|
342
|
+
// nothing is cleaned twice — the fourth argument is the string the first one
|
|
343
|
+
// was DERIVED from.
|
|
344
|
+
return detectPromptOnCleanFrame((0, cli_patterns_1.stripBoxDrawing)((0, cli_patterns_1.stripAnsi)(output)), cliToolId, undefined, output);
|
|
299
345
|
}
|
|
300
346
|
// ============================================================================
|
|
301
347
|
// extractResponse (internal)
|
|
@@ -40,6 +40,7 @@ const waiting_broadcast_1 = require("../lib/realtime/waiting-broadcast");
|
|
|
40
40
|
// build has two instances of it (`dist/server` + a `.next/server/chunks` copy).
|
|
41
41
|
// The registry is how a route handler's copy reaches the one holding sockets.
|
|
42
42
|
const publisher_registry_1 = require("../lib/realtime/publisher-registry");
|
|
43
|
+
const websocket_config_1 = require("../config/websocket-config");
|
|
43
44
|
const logger_1 = require("../lib/logger");
|
|
44
45
|
const logger = (0, logger_1.createLogger)('ws-server');
|
|
45
46
|
// Global state
|
|
@@ -54,6 +55,14 @@ const rooms = new Map();
|
|
|
54
55
|
* bare "clear the registry" would let a torn-down instance silence a newer one.
|
|
55
56
|
*/
|
|
56
57
|
let publisherHandle = null;
|
|
58
|
+
/**
|
|
59
|
+
* Issue #2502: the heartbeat sweep's interval, or null while no server is up.
|
|
60
|
+
*
|
|
61
|
+
* Module-scoped like `wss` and torn down with it — a timer that outlived
|
|
62
|
+
* `closeWebSocket` would go on pinging a `clients` map nobody reads, and CI
|
|
63
|
+
* shares one process across the whole suite.
|
|
64
|
+
*/
|
|
65
|
+
let heartbeatTimer = null;
|
|
57
66
|
const MAX_TERMINAL_INPUT_LENGTH = 4096;
|
|
58
67
|
const MAX_TERMINAL_SUBSCRIBERS_PER_SESSION = 4;
|
|
59
68
|
const TERMINAL_FALLBACK_CAPTURE_LINES = -200;
|
|
@@ -289,6 +298,79 @@ function isExpectedWebSocketError(error) {
|
|
|
289
298
|
error.message?.includes('ECONNRESET') ||
|
|
290
299
|
error.message?.includes('EPIPE'));
|
|
291
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* One heartbeat sweep over every connected client (Issue #2502).
|
|
303
|
+
*
|
|
304
|
+
* The `ws` library's standard liveness recipe, with one addition. The recipe:
|
|
305
|
+
* a connection that has not ponged since the previous sweep is gone — the peer
|
|
306
|
+
* crashed, or the path between us is half-open — so `terminate()` it rather
|
|
307
|
+
* than `close()` it. A close handshake needs a live peer to answer, which is
|
|
308
|
+
* exactly what is in question, so `close()` on a dead path just parks the
|
|
309
|
+
* socket in CLOSING until the OS TCP timeout fires, minutes later, with the
|
|
310
|
+
* room membership and any terminal subscription still held open the whole time.
|
|
311
|
+
*
|
|
312
|
+
* The addition is the application-level beat. A browser answers protocol pings
|
|
313
|
+
* for free but exposes neither the ping nor its own pong to page JavaScript, so
|
|
314
|
+
* the ping alone only ever teaches the SERVER that a client is gone. The extra
|
|
315
|
+
* frame is what lets the tab reach the same conclusion about us
|
|
316
|
+
* (`useWebSocket`'s liveness check).
|
|
317
|
+
*
|
|
318
|
+
* Exported through `__internal` so the behaviour can be tested without waiting
|
|
319
|
+
* {@link WS_SERVER_HEARTBEAT_INTERVAL_MS} for a real interval to fire.
|
|
320
|
+
*/
|
|
321
|
+
function runHeartbeatSweep() {
|
|
322
|
+
clients.forEach((clientInfo, ws) => {
|
|
323
|
+
if (!clientInfo.isAlive) {
|
|
324
|
+
logger.warn('heartbeat:terminate', { rooms: clientInfo.worktreeIds.size });
|
|
325
|
+
try {
|
|
326
|
+
ws.terminate();
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
// Already destroyed; the disconnect bookkeeping below still has to run.
|
|
330
|
+
}
|
|
331
|
+
// `terminate()` emits 'close' and that handler cleans up too, but this is
|
|
332
|
+
// not belt-and-braces: on an already-destroyed socket no event fires at
|
|
333
|
+
// all, and `handleDisconnect` is idempotent (it returns early for a ws it
|
|
334
|
+
// no longer knows). Deleting the current key mid-`forEach` is defined
|
|
335
|
+
// behaviour for a Map.
|
|
336
|
+
handleDisconnect(ws);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
clientInfo.isAlive = false;
|
|
340
|
+
try {
|
|
341
|
+
ws.ping();
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
logger.error('heartbeat:ping-failed', {
|
|
345
|
+
error: error instanceof Error ? error.message : String(error),
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
if (ws.readyState !== ws_1.WebSocket.OPEN)
|
|
349
|
+
return;
|
|
350
|
+
try {
|
|
351
|
+
ws.send(JSON.stringify({ type: websocket_config_1.WS_HEARTBEAT_MESSAGE_TYPE, at: Date.now() }));
|
|
352
|
+
}
|
|
353
|
+
catch {
|
|
354
|
+
// Best-effort: a failing send means the socket is already going away, and
|
|
355
|
+
// the next sweep terminates it.
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
/** Start the heartbeat sweep, replacing any previous one. */
|
|
360
|
+
function startHeartbeat() {
|
|
361
|
+
stopHeartbeat();
|
|
362
|
+
heartbeatTimer = setInterval(runHeartbeatSweep, websocket_config_1.WS_SERVER_HEARTBEAT_INTERVAL_MS);
|
|
363
|
+
// Never the reason the process stays alive: `commandmate stop` and the CLI's
|
|
364
|
+
// short-lived server should not have to wait out a 30s tick.
|
|
365
|
+
heartbeatTimer.unref?.();
|
|
366
|
+
}
|
|
367
|
+
/** Stop the heartbeat sweep. Safe to call when none is running. */
|
|
368
|
+
function stopHeartbeat() {
|
|
369
|
+
if (heartbeatTimer !== null) {
|
|
370
|
+
clearInterval(heartbeatTimer);
|
|
371
|
+
heartbeatTimer = null;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
292
374
|
/**
|
|
293
375
|
* Setup WebSocket server on HTTP or HTTPS server
|
|
294
376
|
* Issue #331: Added auth check on WebSocket upgrade
|
|
@@ -317,6 +399,9 @@ function setupWebSocket(server, options) {
|
|
|
317
399
|
// — and so the closure it registers is the one holding *this* bundle's `rooms`
|
|
318
400
|
// map, which is what a broadcast has to reach.
|
|
319
401
|
(0, waiting_broadcast_1.startWaitingStatusBroadcast)(handleBroadcast);
|
|
402
|
+
// Issue #2502: and the liveness sweep, for the same lifetime reason — it has
|
|
403
|
+
// to die with this `wss`, not with the process.
|
|
404
|
+
startHeartbeat();
|
|
320
405
|
// Handle upgrade requests - only accept app WebSocket connections, not Next.js HMR
|
|
321
406
|
const handleUpgrade = (request, socket, head) => {
|
|
322
407
|
const pathname = request.url || '/';
|
|
@@ -415,8 +500,17 @@ function setupWebSocket(server, options) {
|
|
|
415
500
|
ws,
|
|
416
501
|
worktreeIds: new Set(),
|
|
417
502
|
terminalSubscription: null,
|
|
503
|
+
isAlive: true,
|
|
418
504
|
};
|
|
419
505
|
clients.set(ws, clientInfo);
|
|
506
|
+
// Issue #2502: the other half of the liveness recipe. Browsers answer a
|
|
507
|
+
// protocol ping automatically, so a client needs no code for this to work —
|
|
508
|
+
// silence here is evidence about the path, not about the page.
|
|
509
|
+
ws.on('pong', () => {
|
|
510
|
+
const info = clients.get(ws);
|
|
511
|
+
if (info)
|
|
512
|
+
info.isAlive = true;
|
|
513
|
+
});
|
|
420
514
|
// Issue #573: Removed _socket direct access (as unknown as pattern).
|
|
421
515
|
// ws.on('error') handler below covers socket-level errors because the ws library
|
|
422
516
|
// internally propagates underlying socket errors to the WebSocket 'error' event
|
|
@@ -1105,6 +1199,10 @@ function closeWebSocket() {
|
|
|
1105
1199
|
if (wasOwner || (0, publisher_registry_1.getRoomPublisher)() === null) {
|
|
1106
1200
|
(0, waiting_broadcast_1.stopWaitingStatusBroadcast)();
|
|
1107
1201
|
}
|
|
1202
|
+
// Issue #2502: unconditionally — unlike the waiting-edge subscription this is
|
|
1203
|
+
// a plain module-local timer, not a `globalThis` slot, so a superseded
|
|
1204
|
+
// instance clearing it cannot reach a live server's sweep.
|
|
1205
|
+
stopHeartbeat();
|
|
1108
1206
|
if (wss) {
|
|
1109
1207
|
// Close all client connections
|
|
1110
1208
|
clients.forEach((clientInfo) => {
|
|
@@ -1121,6 +1219,9 @@ function closeWebSocket() {
|
|
|
1121
1219
|
}
|
|
1122
1220
|
exports.__internal = {
|
|
1123
1221
|
handleMessage,
|
|
1222
|
+
runHeartbeatSweep,
|
|
1223
|
+
startHeartbeat,
|
|
1224
|
+
stopHeartbeat,
|
|
1124
1225
|
handleClientVersion,
|
|
1125
1226
|
handleProxyUpgrade,
|
|
1126
1227
|
handleTerminalSubscribe,
|
|
@@ -1128,17 +1229,26 @@ exports.__internal = {
|
|
|
1128
1229
|
handleTerminalResize,
|
|
1129
1230
|
handleTerminalUnsubscribe,
|
|
1130
1231
|
handleDisconnect,
|
|
1131
|
-
registerClientForTest(ws) {
|
|
1232
|
+
registerClientForTest(ws, isAlive = true) {
|
|
1132
1233
|
clients.set(ws, {
|
|
1133
1234
|
ws,
|
|
1134
1235
|
worktreeIds: new Set(),
|
|
1135
1236
|
terminalSubscription: null,
|
|
1237
|
+
isAlive,
|
|
1136
1238
|
});
|
|
1137
1239
|
},
|
|
1138
1240
|
getClientInfoForTest(ws) {
|
|
1139
1241
|
return clients.get(ws);
|
|
1140
1242
|
},
|
|
1243
|
+
/**
|
|
1244
|
+
* Every live client, for tests that hold the *client* end of a real socket and
|
|
1245
|
+
* therefore have no handle on the server-side `WebSocket` to look up by.
|
|
1246
|
+
*/
|
|
1247
|
+
listClientsForTest() {
|
|
1248
|
+
return Array.from(clients.values());
|
|
1249
|
+
},
|
|
1141
1250
|
resetStateForTest() {
|
|
1251
|
+
stopHeartbeat();
|
|
1142
1252
|
clients.clear();
|
|
1143
1253
|
rooms.clear();
|
|
1144
1254
|
},
|
package/package.json
CHANGED
package/public/sw.js
CHANGED
|
@@ -26,6 +26,18 @@ const OFFLINE_URL = '/offline';
|
|
|
26
26
|
const PRECACHE_URLS = [OFFLINE_URL];
|
|
27
27
|
|
|
28
28
|
// Denylist — never cached (mirror of EXCLUDED_PATH_PREFIXES).
|
|
29
|
+
//
|
|
30
|
+
// `/api` is load-bearing and is not a default anyone forgot to revisit: Issue
|
|
31
|
+
// #2504 asked for two of its GETs to be served from cache while revalidating,
|
|
32
|
+
// and was closed wontfix. The short reason is that a cache read in this file
|
|
33
|
+
// cannot be authenticated — the auth cookie is httpOnly and invisible here, the
|
|
34
|
+
// server sends no `Vary: Cookie`, and the token is one server-wide secret, so
|
|
35
|
+
// there is no identity to key a cache on. Whatever lands in the Cache API is
|
|
36
|
+
// readable by anyone who can open this origin in this browser profile.
|
|
37
|
+
// Note also that `matchesPrefix` below is a PREFIX match: `/api/worktrees` is
|
|
38
|
+
// 36 routes, among them current-output, files, env, messages and terminal.
|
|
39
|
+
// The rest of the reasoning is in src/lib/pwa/cache-policy.ts; the full argument
|
|
40
|
+
// is the design policy filed on Issue #2504.
|
|
29
41
|
const EXCLUDED_PATH_PREFIXES = ['/api', '/login', '/proxy'];
|
|
30
42
|
// Allowlist — cache-first (mirror of STATIC_CACHE_PREFIXES / STATIC_CACHE_EXACT).
|
|
31
43
|
const STATIC_CACHE_PREFIXES = ['/_next/static/', '/icons/'];
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
exports.id=120,exports.ids=[120],exports.modules={29701:(a,b,c)=>{"use strict";c.d(b,{A:()=>n});var d=c(86723),e=c(14549),f=c(46831);let g={}.hasOwnProperty;function h(a,b){if(b&&"object"==typeof b)switch("string"==typeof b.type?b.type:""){case"comment":var c=a,d=b;if(c.schema.allowComments){let a="string"==typeof d.value?d.value:"",b=a.indexOf("--\x3e"),c={type:"comment",value:b<0?a:a.slice(0,b)};return l(c,d),c}return;case"doctype":var e=a,f=b;if(e.schema.allowDoctypes){let a={type:"doctype"};return l(a,f),a}return;case"element":return function(a,b){let c="string"==typeof b.tagName?b.tagName:"";a.stack.push(c);let d=i(a,b.children),e=function(a,b){let c,d=a.stack[a.stack.length-1],e=a.schema.attributes,f=a.schema.required,h=e&&g.call(e,d)?e[d]:void 0,i=e&&g.call(e,"*")?e["*"]:void 0,k=b&&"object"==typeof b?b:{},l={};for(c in k)if(g.call(k,c)){let b=k[c],d=j(a,m(h,c),c,b);null==d&&(d=j(a,m(i,c),c,b)),null!=d&&(l[c]=d)}if(f&&g.call(f,d)){let a=f[d];for(c in a)g.call(a,c)&&!g.call(l,c)&&(l[c]=a[c])}return l}(a,b.properties);a.stack.pop();let f=!1;if(c&&"*"!==c&&(!a.schema.tagNames||a.schema.tagNames.includes(c))&&(f=!0,a.schema.ancestors&&g.call(a.schema.ancestors,c))){let b=a.schema.ancestors[c],d=-1;for(f=!1;++d<b.length;)a.stack.includes(b[d])&&(f=!0)}if(!f)return a.schema.strip&&!a.schema.strip.includes(c)?d:void 0;let h={type:"element",tagName:c,properties:e,children:d};return l(h,b),h}(a,b);case"root":var h=a,k=b;let n={type:"root",children:i(h,k.children)};return l(n,k),n;case"text":var o=b;let p={type:"text",value:"string"==typeof o.value?o.value:""};return l(p,o),p}}function i(a,b){let c=[];if(Array.isArray(b)){let d=-1;for(;++d<b.length;){let e=h(a,b[d]);e&&(Array.isArray(e)?c.push(...e):c.push(e))}}return c}function j(a,b,c,d){return b?Array.isArray(d)?function(a,b,c,d){let e=-1,f=[];for(;++e<d.length;){let g=k(a,b,c,d[e]);("number"==typeof g||"string"==typeof g)&&f.push(g)}return f}(a,b,c,d):k(a,b,c,d):void 0}function k(a,b,c,d){if(("boolean"==typeof d||"number"==typeof d||"string"==typeof d)&&function(a,b,c){let d=a.schema.protocols&&g.call(a.schema.protocols,b)?a.schema.protocols[b]:void 0;if(!d||0===d.length)return!0;let e=String(c),f=e.indexOf(":"),h=e.indexOf("?"),i=e.indexOf("#"),j=e.indexOf("/");if(f<0||j>-1&&f>j||h>-1&&f>h||i>-1&&f>i)return!0;let k=-1;for(;++k<d.length;){let a=d[k];if(f===a.length&&e.slice(0,a.length)===a)return!0}return!1}(a,c,d)){if("object"==typeof b&&b.length>1){let a=!1,c=0;for(;++c<b.length;){let e=b[c];if(e&&"object"==typeof e&&"flags"in e){if(e.test(String(d))){a=!0;break}}else if(e===d){a=!0;break}}if(!a)return}return a.schema.clobber&&a.schema.clobberPrefix&&a.schema.clobber.includes(c)?a.schema.clobberPrefix+d:d}}function l(a,b){let c=(0,e.G1)(b);b.data&&(a.data=(0,d.Ay)(b.data)),c&&(a.position=c)}function m(a,b){let c,d=-1;if(a)for(;++d<a.length;){let e=a[d],f="string"==typeof e?e:e[0];if(f===b)return e;"data*"===f&&(c=e)}if(b.length>4&&"data"===b.slice(0,4).toLowerCase())return c}function n(a){return function(b){var c=b,d=a;let e={type:"root",children:[]},g=h({schema:d?{...f.j,...d}:f.j,stack:[]},c);return g&&(Array.isArray(g)?1===g.length?e=g[0]:e.children=g:e=g),e}}},31230:()=>{},46831:(a,b,c)=>{"use strict";c.d(b,{j:()=>e});let d=["ariaDescribedBy","ariaLabel","ariaLabelledBy"],e={ancestors:{tbody:["table"],td:["table"],th:["table"],thead:["table"],tfoot:["table"],tr:["table"]},attributes:{a:[...d,"dataFootnoteBackref","dataFootnoteRef",["className","data-footnote-backref"],"href"],blockquote:["cite"],code:[["className",/^language-./]],del:["cite"],div:["itemScope","itemType"],dl:[...d],h2:[["className","sr-only"]],img:[...d,"longDesc","src"],input:[["disabled",!0],["type","checkbox"]],ins:["cite"],li:[["className","task-list-item"]],ol:[...d,["className","contains-task-list"]],q:["cite"],section:["dataFootnotes",["className","footnotes"]],source:["srcSet"],summary:[...d],table:[...d],ul:[...d,["className","contains-task-list"]],"*":["abbr","accept","acceptCharset","accessKey","action","align","alt","axis","border","cellPadding","cellSpacing","char","charOff","charSet","checked","clear","colSpan","color","cols","compact","coords","dateTime","dir","encType","frame","hSpace","headers","height","hrefLang","htmlFor","id","isMap","itemProp","label","lang","maxLength","media","method","multiple","name","noHref","noShade","noWrap","open","prompt","readOnly","rev","rowSpan","rows","rules","scope","selected","shape","size","span","start","summary","tabIndex","title","useMap","vAlign","value","width"]},clobber:["ariaDescribedBy","ariaLabelledBy","id","name"],clobberPrefix:"user-content-",protocols:{cite:["http","https"],href:["http","https","irc","ircs","mailto","xmpp"],longDesc:["http","https"],src:["http","https"]},required:{input:{disabled:!0,type:"checkbox"}},strip:["script"],tagNames:["a","b","blockquote","br","code","dd","del","details","div","dl","dt","em","h1","h2","h3","h4","h5","h6","hr","i","img","input","ins","kbd","li","ol","p","picture","pre","q","rp","rt","ruby","s","samp","section","source","span","strike","strong","sub","summary","sup","table","tbody","td","tfoot","th","thead","tr","tt","ul","var"]}}};
|