commandmate 0.21.4 → 0.22.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 +247 -240
- package/.next/app-path-routes-manifest.json +33 -32
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +9 -9
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.js +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route.js +1 -1
- package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route.js +1 -1
- package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/terminal/route.js +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 +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/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route.js +2 -2
- package/.next/server/app/api/fs/browse/route.js.nft.json +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route_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 +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 +1 -0
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -0
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -0
- 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/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route.js +1 -1
- package/.next/server/app/api/push/vapid/route.js.nft.json +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_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.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_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]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +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]/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]/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]/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]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route.js +2 -6
- 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 +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/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_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/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_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +9 -9
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +33 -32
- package/.next/server/chunks/1068.js +1 -1
- package/.next/server/chunks/1356.js +4 -0
- package/.next/server/chunks/1841.js +1 -0
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/2816.js +1 -1
- package/.next/server/chunks/3022.js +1 -0
- package/.next/server/chunks/3736.js +1 -1
- package/.next/server/chunks/5959.js +5 -4
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6274.js +8 -12
- package/.next/server/chunks/6919.js +1 -0
- package/.next/server/chunks/7685.js +1 -1
- package/.next/server/chunks/8856.js +1 -1
- package/.next/server/chunks/9067.js +1 -1
- package/.next/server/chunks/9373.js +8 -0
- package/.next/server/chunks/9687.js +2 -2
- 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/server/src/middleware.js.map +1 -1
- package/.next/static/b69eWhjC1rRrFTa-g3lMS/_buildManifest.js +1 -0
- package/.next/static/chunks/{6488-675c07e04e6e5a2e.js → 6488-2ad4f67779f8d00a.js} +1 -1
- package/.next/static/chunks/app/api/app/update/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/app/update-check/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/assistant/conversation/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/assistant/current-output/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/assistant/messages/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/assistant/session/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/assistant/start/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/assistant/terminal/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/assistant/tools/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/auth/login/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/auth/status/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/status/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/external-apps/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/fs/browse/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/fs/recent-paths/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/hooks/agent-event/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/hooks/claude-done/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/hooks/permission-request/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/metrics/vibe/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/ollama/models/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/push/subscriptions/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/push/vapid/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/repositories/excluded/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/repositories/restore/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/repositories/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/repositories/scan/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/repositories/sync/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/repositories/validate-path/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/sidebar/group-order/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/skills/[id]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/skills/installations/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/skills/operations/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/skills/reindex/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/skills/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/slash-commands/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/templates/[id]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/templates/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/todos/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/manifest.webmanifest/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/proxy/[...path]/route-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/layout-973ec48531555712.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-70704fe257e0cccc.js +1 -0
- package/.next/trace +12 -12
- package/.next/types/app/api/hooks/permission-request/route.ts +347 -0
- package/.next/types/routes.d.ts +2 -1
- package/.next/types/validator.ts +9 -0
- package/dist/cli/commands/capture.d.ts.map +1 -1
- package/dist/cli/commands/capture.js +27 -1
- package/dist/cli/commands/respond.d.ts.map +1 -1
- package/dist/cli/commands/respond.js +9 -3
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +35 -0
- package/dist/cli/commands/wait.d.ts +4 -1
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +109 -2
- package/dist/cli/docs/agent-operations.d.ts +1 -1
- package/dist/cli/docs/agent-operations.d.ts.map +1 -1
- package/dist/cli/docs/agent-operations.js +39 -0
- package/dist/cli/types/api-responses.d.ts +69 -4
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/types/index.d.ts +6 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +105 -1
- package/dist/server/src/lib/detection/unclassified-frame-tracker.js +96 -0
- package/dist/server/src/lib/env.js +27 -1
- package/dist/server/src/lib/hooks/agent-event-types.js +131 -0
- package/dist/server/src/lib/hooks/ask-user-question-payload.js +156 -0
- package/dist/server/src/lib/hooks/hook-settings-generator.js +411 -0
- package/dist/server/src/lib/hooks/permission-request-payload.js +144 -0
- package/dist/server/src/lib/polling/auto-yes-resolver.js +25 -10
- package/dist/server/src/lib/polling/auto-yes-suppression-state.js +2 -1
- package/dist/server/src/lib/session/agent-event-state.js +612 -11
- package/dist/server/src/lib/session/ask-user-question-prompt.js +295 -0
- package/dist/server/src/lib/session/claude-session.js +41 -2
- package/dist/server/src/lib/session/current-output-builder.js +375 -8
- package/dist/server/src/lib/session/prompt-waiting-composition.js +178 -0
- package/dist/server/src/lib/session/prompt-waiting-guard.js +147 -0
- package/dist/server/src/lib/session/send-user-message.js +35 -0
- package/dist/server/src/lib/session/status-mapping.js +121 -0
- package/dist/server/src/lib/session/structured-prompt.js +109 -0
- package/dist/server/src/types/models.js +30 -0
- package/package.json +3 -2
- package/scripts/hooks/cmate-agent-event.sh +44 -3
- package/.next/server/chunks/1355.js +0 -1
- package/.next/server/chunks/1598.js +0 -4
- package/.next/server/chunks/2366.js +0 -1
- package/.next/static/Yr3HhIDgtWJeOPqvqxsug/_buildManifest.js +0 -1
- package/.next/static/chunks/app/api/app/update/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/app/update-check/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/assistant/conversation/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/assistant/current-output/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/assistant/messages/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/assistant/session/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/assistant/start/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/assistant/terminal/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/assistant/tools/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/auth/login/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/auth/status/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/status/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/external-apps/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/fs/browse/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/fs/recent-paths/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/hooks/agent-event/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/hooks/claude-done/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/metrics/vibe/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/ollama/models/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/push/subscriptions/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/push/vapid/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/repositories/excluded/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/repositories/restore/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/repositories/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/repositories/scan/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/repositories/sync/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/repositories/validate-path/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/sidebar/group-order/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/skills/[id]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/skills/installations/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/skills/operations/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/skills/reindex/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/skills/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/slash-commands/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/templates/[id]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/templates/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/todos/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/proxy/[...path]/route-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/layout-be21650964d61b1d.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-9f78fcce8ee9fe00.js +0 -1
- /package/.next/static/{Yr3HhIDgtWJeOPqvqxsug → b69eWhjC1rRrFTa-g3lMS}/_ssgManifest.js +0 -0
|
@@ -8,8 +8,12 @@
|
|
|
8
8
|
* paths byte-for-byte consistent (DRY).
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.mergeStructuredStatus = mergeStructuredStatus;
|
|
11
12
|
exports.buildCurrentOutput = buildCurrentOutput;
|
|
12
13
|
const db_1 = require("../../lib/db");
|
|
14
|
+
const unclassified_frame_tracker_1 = require("../../lib/detection/unclassified-frame-tracker");
|
|
15
|
+
const models_1 = require("../../types/models");
|
|
16
|
+
const logger_1 = require("../../lib/logger");
|
|
13
17
|
const manager_1 = require("../../lib/cli-tools/manager");
|
|
14
18
|
const cli_session_1 = require("../../lib/session/cli-session");
|
|
15
19
|
const status_detector_1 = require("../../lib/detection/status-detector");
|
|
@@ -18,6 +22,244 @@ const auto_yes_suppression_state_1 = require("../../lib/polling/auto-yes-suppres
|
|
|
18
22
|
const status_capture_config_1 = require("../../config/status-capture-config");
|
|
19
23
|
const tmux_capture_cache_1 = require("../../lib/tmux/tmux-capture-cache");
|
|
20
24
|
const agent_event_state_1 = require("../../lib/session/agent-event-state");
|
|
25
|
+
const prompt_waiting_composition_1 = require("../../lib/session/prompt-waiting-composition");
|
|
26
|
+
const ask_user_question_prompt_1 = require("../../lib/session/ask-user-question-prompt");
|
|
27
|
+
const structured_prompt_1 = require("../../lib/session/structured-prompt");
|
|
28
|
+
const logger = (0, logger_1.createLogger)('current-output-builder');
|
|
29
|
+
/**
|
|
30
|
+
* Write the "detection failed on this frame" row (Issue #1708).
|
|
31
|
+
*
|
|
32
|
+
* Stored as a `prompt` message so `capture --prompts` — the audit trail that
|
|
33
|
+
* exists precisely to answer "why did this stall?" — lists it alongside the
|
|
34
|
+
* prompts that WERE detected. It must never read as one of them, so the
|
|
35
|
+
* promptData carries `type: 'unclassified'` and `status: 'unclassified'`; the
|
|
36
|
+
* latter is also what keeps it out of `markPendingPromptsAsAnswered()`, whose
|
|
37
|
+
* SQL selects `status = 'pending'`. A frame nobody could read must not end up
|
|
38
|
+
* stamped "(answered via terminal)" the moment the flag clears.
|
|
39
|
+
*
|
|
40
|
+
* Not broadcast: this is a record for after the fact, and the prompt-answering
|
|
41
|
+
* UI has nothing to render for a frame with no parsed options.
|
|
42
|
+
*
|
|
43
|
+
* REACH, stated plainly because it is a real limit: this is driven by
|
|
44
|
+
* observation, not by the server's own loops. `buildCurrentOutput` has exactly
|
|
45
|
+
* two callers — the current-output route and `broadcastTerminalSnapshot`, which
|
|
46
|
+
* returns immediately when the room has no subscribers. So a row is written
|
|
47
|
+
* while `commandmate wait` is polling (every POLL_INTERVAL_MS), while a browser
|
|
48
|
+
* has the terminal open, or on a `capture --json`. A stall that nobody is
|
|
49
|
+
* watching at all writes nothing, and `capture --prompts` afterwards will not
|
|
50
|
+
* show it. That is tolerable because the stalls this exists to explain are the
|
|
51
|
+
* ones something WAS waiting on — but it means the Auto-Yes poller running
|
|
52
|
+
* alone is not enough. Feeding the tracker from that loop would need a second
|
|
53
|
+
* producer of `isUnclassifiedActive`, i.e. either duplicating its definition or
|
|
54
|
+
* adding a detectSessionStatus pass to a hot path; deliberately not done here.
|
|
55
|
+
*
|
|
56
|
+
* Best effort — a failed insert must never break the payload the caller is
|
|
57
|
+
* waiting on. The tracker has already marked the run as recorded, so a failure
|
|
58
|
+
* costs this one row, not a retry storm.
|
|
59
|
+
*/
|
|
60
|
+
function recordUnclassifiedFrame(db, params) {
|
|
61
|
+
const dwellSeconds = Math.round(params.dwellMs / 1000);
|
|
62
|
+
const statusReason = `${params.sessionStatus}/${params.sessionStatusReason}`;
|
|
63
|
+
const question = `Unclassified interactive frame (${statusReason}) held for ${dwellSeconds}s. ` +
|
|
64
|
+
`The detection layer could not parse it, so no prompt was published and ` +
|
|
65
|
+
`nothing could answer it. Inspect the raw pane with ` +
|
|
66
|
+
`\`commandmate capture ${params.worktreeId} --pane\`.`;
|
|
67
|
+
const record = {
|
|
68
|
+
type: models_1.UNCLASSIFIED_PROMPT_TYPE,
|
|
69
|
+
status: 'unclassified',
|
|
70
|
+
question,
|
|
71
|
+
options: [],
|
|
72
|
+
dwellSeconds,
|
|
73
|
+
sessionStatusReason: statusReason,
|
|
74
|
+
};
|
|
75
|
+
try {
|
|
76
|
+
(0, db_1.createMessage)(db, {
|
|
77
|
+
worktreeId: params.worktreeId,
|
|
78
|
+
role: 'assistant',
|
|
79
|
+
content: question,
|
|
80
|
+
messageType: 'prompt',
|
|
81
|
+
// Not a PromptData: nothing may answer this row, which is why the record
|
|
82
|
+
// type is kept out of that union (see UnclassifiedFrameRecord). The column
|
|
83
|
+
// is shared, so the cast is confined to this one write.
|
|
84
|
+
promptData: record,
|
|
85
|
+
timestamp: new Date(),
|
|
86
|
+
cliToolId: params.cliToolId,
|
|
87
|
+
instanceId: params.instanceId,
|
|
88
|
+
});
|
|
89
|
+
logger.info('unclassified-frame-recorded', {
|
|
90
|
+
worktreeId: params.worktreeId,
|
|
91
|
+
cliToolId: params.cliToolId,
|
|
92
|
+
dwellSeconds,
|
|
93
|
+
statusReason,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
logger.warn('unclassified-frame-record-failed', {
|
|
98
|
+
worktreeId: params.worktreeId,
|
|
99
|
+
error: error instanceof Error ? error.message : String(error),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Write the "the agent said a dialog is open and we could not read it" row
|
|
105
|
+
* (Issue #1725, continuing #1708's proposal 2).
|
|
106
|
+
*
|
|
107
|
+
* Written once per waiting episode, and ONLY while the scraper is publishing no
|
|
108
|
+
* prompt of its own. Both halves matter:
|
|
109
|
+
*
|
|
110
|
+
* - once, because `buildCurrentOutput` runs on every poll and a row per poll
|
|
111
|
+
* would turn one blocked dialog into a wall of identical history;
|
|
112
|
+
* - only when the scraper is blind, because when it is not, the existing
|
|
113
|
+
* prompt writers already record that prompt with its options and its answer.
|
|
114
|
+
* A second row would double-count the audit trail `capture --prompts` prints
|
|
115
|
+
* and put a "nobody could read this" line next to the parsed prompt that
|
|
116
|
+
* proves somebody could.
|
|
117
|
+
*
|
|
118
|
+
* So a row here means exactly one thing, which is the thing #1708 asked to be
|
|
119
|
+
* recorded: a prompt existed and the detection layer did not see it.
|
|
120
|
+
*
|
|
121
|
+
* Best effort, for the same reason as {@link recordUnclassifiedFrame}: the
|
|
122
|
+
* caller is waiting on a payload, and a failed insert must cost this row and
|
|
123
|
+
* nothing else.
|
|
124
|
+
*/
|
|
125
|
+
function recordStructuredPrompt(db, params) {
|
|
126
|
+
const record = (0, structured_prompt_1.buildStructuredPromptHistoryRecord)(params.worktreeId, params.facts);
|
|
127
|
+
try {
|
|
128
|
+
(0, db_1.createMessage)(db, {
|
|
129
|
+
worktreeId: params.worktreeId,
|
|
130
|
+
role: 'assistant',
|
|
131
|
+
content: record.question,
|
|
132
|
+
summary: `structured prompt · source=${params.state.source}${params.state.toolName ? ` · tool=${params.state.toolName}` : ''}`,
|
|
133
|
+
messageType: 'prompt',
|
|
134
|
+
// Not a PromptData: it has no options and nothing may answer it by
|
|
135
|
+
// number. The column is shared, so the cast is confined to this write —
|
|
136
|
+
// the same arrangement UnclassifiedFrameRecord uses.
|
|
137
|
+
promptData: record,
|
|
138
|
+
timestamp: new Date(),
|
|
139
|
+
cliToolId: params.cliToolId,
|
|
140
|
+
instanceId: params.instanceId,
|
|
141
|
+
});
|
|
142
|
+
logger.info('structured-prompt-recorded', {
|
|
143
|
+
worktreeId: params.worktreeId,
|
|
144
|
+
cliToolId: params.cliToolId,
|
|
145
|
+
instanceId: params.instanceId,
|
|
146
|
+
source: params.state.source,
|
|
147
|
+
toolName: params.state.toolName,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
logger.warn('structured-prompt-record-failed', {
|
|
152
|
+
worktreeId: params.worktreeId,
|
|
153
|
+
error: error instanceof Error ? error.message : String(error),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The `AskUserQuestion` call as the degraded prompt can describe it
|
|
159
|
+
* (Issue #1726).
|
|
160
|
+
*
|
|
161
|
+
* Only the first question, and no option numbers — see
|
|
162
|
+
* {@link StructuredAskUserQuestionSummary} for why a layer that cannot see the
|
|
163
|
+
* screen must not publish numbers for it.
|
|
164
|
+
*/
|
|
165
|
+
function summarizeAskUserQuestion(episode) {
|
|
166
|
+
const first = episode?.spec.questions[0];
|
|
167
|
+
if (!first)
|
|
168
|
+
return null;
|
|
169
|
+
return {
|
|
170
|
+
question: first.question,
|
|
171
|
+
labels: first.choices.map((choice) => choice.label),
|
|
172
|
+
questionCount: episode.spec.questions.length,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Prefer the agent's own account of what it is doing over the screen scrape
|
|
177
|
+
* (Issue #1723).
|
|
178
|
+
*
|
|
179
|
+
* Pure, and exported so the whole precedence table can be tested without a tmux
|
|
180
|
+
* session behind it.
|
|
181
|
+
*
|
|
182
|
+
* ## Why the scraper still wins in two cases
|
|
183
|
+
*
|
|
184
|
+
* **`waiting` on the scraper's side always wins.** A frame the detector reads
|
|
185
|
+
* as a prompt, a selection list or a pager is a frame a human has to act on,
|
|
186
|
+
* and this Issue deliberately does not touch `isPromptWaiting` / `promptData` /
|
|
187
|
+
* `isSelectionListActive` (they are #1725's). Letting a structured `running`
|
|
188
|
+
* overwrite `sessionStatus` while those three still said "answer me" would
|
|
189
|
+
* publish a self-contradicting payload. It is also the empirically necessary
|
|
190
|
+
* rule: the live capture found that Claude emits **no event at all** while an
|
|
191
|
+
* `AskUserQuestion` selection or "Ready to submit your answers?" screen is up
|
|
192
|
+
* (`agent-hooks-live-verification.md` §5.6), so the newest structured fact
|
|
193
|
+
* there is the `user_prompt_submit` that opened the turn — `running` — while
|
|
194
|
+
* the truth on screen is "waiting for a human". That is precisely the #1708
|
|
195
|
+
* stall, and the scraper is the only layer that can see it.
|
|
196
|
+
*
|
|
197
|
+
* **A structured `waiting` is applied only through the prompt-waiting state**
|
|
198
|
+
* (Issue #1725). #1723 recorded `Notification(permission_prompt)` and stopped
|
|
199
|
+
* there, for a reason that had to be answered before it could be promoted:
|
|
200
|
+
* nothing marks a permission prompt as *answered*, so a verdict read off the
|
|
201
|
+
* last event alone would stick until the next `Stop` and describe a session
|
|
202
|
+
* that went back to work minutes ago. `getStructuredPromptWaiting` is that
|
|
203
|
+
* answer — it is released by `Stop` / `user_prompt_submit` / a generation
|
|
204
|
+
* change, by the scraper reporting the frame it corroborated has cleared, and
|
|
205
|
+
* by expiry. So the `waiting` promoted here is the one that survives all of
|
|
206
|
+
* those, passed in explicitly; the raw `structured.status === 'waiting'` still
|
|
207
|
+
* decides nothing on its own.
|
|
208
|
+
*
|
|
209
|
+
* ## The one flag this touches beyond `sessionStatus`
|
|
210
|
+
*
|
|
211
|
+
* `isUnclassifiedActive` is cleared only for the `Stop`-arrived-but-the-pane-
|
|
212
|
+
* still-looks-busy case (structured `ready` over scraper `running`). That case
|
|
213
|
+
* is the entire point of the Issue for `commandmate wait`, whose completion
|
|
214
|
+
* check is `sessionStatus === 'ready' && isUnclassifiedActive !== true` — leave
|
|
215
|
+
* the flag up and the structured `ready` buys nothing.
|
|
216
|
+
*
|
|
217
|
+
* Everywhere else the flag is left exactly as the scraper set it, which is not
|
|
218
|
+
* timidity but two specific behaviours that must survive:
|
|
219
|
+
*
|
|
220
|
+
* - a static overlay left on screen after a turn (`/help`, #1497) reads as
|
|
221
|
+
* `ready`/`no_recent_output` while the structured layer also says `ready` —
|
|
222
|
+
* the two agree, the structured layer adds nothing, and clearing the flag
|
|
223
|
+
* would take away the navigation hatch the user needs to escape;
|
|
224
|
+
* - a frame nobody can classify while the structured layer says `running` is
|
|
225
|
+
* still a frame nobody can classify. `wait`'s unclassified dwell (exit 10)
|
|
226
|
+
* is the last hatch for a screen that produces no events at all, and #1708
|
|
227
|
+
* exists because it was missing. A structured `running` does not prove a
|
|
228
|
+
* human is not needed — see the AskUserQuestion case above.
|
|
229
|
+
*/
|
|
230
|
+
function mergeStructuredStatus(scraper, structured, promptWaiting = null) {
|
|
231
|
+
if (scraper.status === 'waiting') {
|
|
232
|
+
return { ...scraper, structuredApplied: false };
|
|
233
|
+
}
|
|
234
|
+
// Issue #1725, the OR rule at the status level: the scraper reads this frame
|
|
235
|
+
// as running or ready, and the agent has told us a dialog is in front of it.
|
|
236
|
+
// Publishing `running` next to `isPromptWaiting: true` would be a payload
|
|
237
|
+
// that contradicts itself, and every consumer of `sessionStatus` — the
|
|
238
|
+
// sidebar dot, `deriveSessionStatus`, the worktrees API — would show a worker
|
|
239
|
+
// that needs a human as one that is busy.
|
|
240
|
+
if (promptWaiting !== null) {
|
|
241
|
+
return {
|
|
242
|
+
status: 'waiting',
|
|
243
|
+
reason: (0, prompt_waiting_composition_1.structuredWaitingReason)(promptWaiting),
|
|
244
|
+
thinking: false,
|
|
245
|
+
isUnclassifiedActive: scraper.isUnclassifiedActive,
|
|
246
|
+
structuredApplied: true,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
if (structured === null || structured.status === 'waiting') {
|
|
250
|
+
return { ...scraper, structuredApplied: false };
|
|
251
|
+
}
|
|
252
|
+
const thinking = structured.status === 'running';
|
|
253
|
+
return {
|
|
254
|
+
status: structured.status,
|
|
255
|
+
reason: structured.reason,
|
|
256
|
+
thinking,
|
|
257
|
+
isUnclassifiedActive: structured.status === 'ready' && scraper.status === 'running'
|
|
258
|
+
? false
|
|
259
|
+
: scraper.isUnclassifiedActive,
|
|
260
|
+
structuredApplied: true,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
21
263
|
/**
|
|
22
264
|
* Build the current-output payload for a worktree session.
|
|
23
265
|
*
|
|
@@ -31,6 +273,14 @@ async function buildCurrentOutput(db, worktreeId, cliToolId, instanceId) {
|
|
|
31
273
|
const manager = manager_1.CLIToolManager.getInstance();
|
|
32
274
|
const cliTool = manager.getTool(cliToolId);
|
|
33
275
|
const stopEventAt = (0, agent_event_state_1.getLastStopEventAt)(worktreeId, cliToolId, instanceId);
|
|
276
|
+
const lastEvent = (0, agent_event_state_1.getLastAgentEvent)(worktreeId, cliToolId, instanceId);
|
|
277
|
+
const structuredEvents = {
|
|
278
|
+
lastEventType: lastEvent?.event ?? null,
|
|
279
|
+
lastEventAt: lastEvent?.at ?? null,
|
|
280
|
+
lastEventDetail: lastEvent?.detail ?? null,
|
|
281
|
+
promptWaitingSince: null,
|
|
282
|
+
promptWaitingSource: null,
|
|
283
|
+
};
|
|
34
284
|
const running = await cliTool.isRunning(worktreeId, instanceId);
|
|
35
285
|
if (!running) {
|
|
36
286
|
return {
|
|
@@ -41,6 +291,7 @@ async function buildCurrentOutput(db, worktreeId, cliToolId, instanceId) {
|
|
|
41
291
|
sessionStatus: 'idle',
|
|
42
292
|
sessionStatusReason: 'session_not_running',
|
|
43
293
|
lastStopEventAt: stopEventAt,
|
|
294
|
+
structuredEvents,
|
|
44
295
|
};
|
|
45
296
|
}
|
|
46
297
|
const sessionState = (0, db_1.getSessionState)(db, worktreeId, resolvedInstanceId);
|
|
@@ -67,7 +318,7 @@ async function buildCurrentOutput(db, worktreeId, cliToolId, instanceId) {
|
|
|
67
318
|
const lastOutputTimestamp = lastServerResponseTimestamp ? new Date(lastServerResponseTimestamp) : undefined;
|
|
68
319
|
const statusResult = (0, status_detector_1.detectSessionStatus)(output, cliToolId, lastOutputTimestamp);
|
|
69
320
|
const thinking = statusResult.status === 'running' && statusResult.reason === status_detector_1.STATUS_REASON.THINKING_INDICATOR;
|
|
70
|
-
const
|
|
321
|
+
const scraperPromptWaiting = statusResult.hasActivePrompt;
|
|
71
322
|
const isSelectionListActive = statusResult.status === 'waiting' && status_detector_1.SELECTION_LIST_REASONS.has(statusResult.reason);
|
|
72
323
|
const isPagerActive = statusResult.reason === status_detector_1.STATUS_REASON.CODEX_PAGER;
|
|
73
324
|
// Issue #1497: the detection-independent nav hatch (#1017/#1494) is gated on
|
|
@@ -80,24 +331,139 @@ async function buildCurrentOutput(db, worktreeId, cliToolId, instanceId) {
|
|
|
80
331
|
// as unclassified too and keep the hatch open instead of stranding the user.
|
|
81
332
|
const isUnclassifiedActive = (statusResult.status === 'running' && statusResult.reason === status_detector_1.STATUS_REASON.DEFAULT) ||
|
|
82
333
|
(statusResult.status === 'ready' && statusResult.reason === status_detector_1.STATUS_REASON.NO_RECENT_OUTPUT);
|
|
334
|
+
// Issue #1723: the two-layer merge. Everything above this line is the string
|
|
335
|
+
// analysis, unchanged and still the only source on a machine where no hook
|
|
336
|
+
// ever fires — `getStructuredSessionState` answers null there, and
|
|
337
|
+
// `mergeStructuredStatus` then returns the scraper's verdict untouched.
|
|
338
|
+
const structured = (0, agent_event_state_1.getStructuredSessionState)(worktreeId, cliToolId, instanceId);
|
|
339
|
+
// Issue #1725: the open-dialog half of the same merge, resolved before the
|
|
340
|
+
// status merge because it decides one of its inputs. The rule itself — the
|
|
341
|
+
// asymmetric release and the OR below — lives in `prompt-waiting-composition`
|
|
342
|
+
// since Issue #1737, because the `send` guard has to reach the same verdict
|
|
343
|
+
// and a second copy here is exactly how the two answers diverged.
|
|
344
|
+
const promptResolution = (0, prompt_waiting_composition_1.resolvePromptWaiting)({
|
|
345
|
+
worktreeId,
|
|
346
|
+
cliToolId,
|
|
347
|
+
instanceId,
|
|
348
|
+
scraper: {
|
|
349
|
+
status: statusResult.status,
|
|
350
|
+
reason: statusResult.reason,
|
|
351
|
+
hasActivePrompt: scraperPromptWaiting,
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
const promptWaiting = promptResolution.structured;
|
|
355
|
+
if (promptWaiting !== null) {
|
|
356
|
+
structuredEvents.promptWaitingSince = promptWaiting.at;
|
|
357
|
+
structuredEvents.promptWaitingSource = promptWaiting.source;
|
|
358
|
+
}
|
|
359
|
+
const merged = mergeStructuredStatus({ status: statusResult.status, reason: statusResult.reason, thinking, isUnclassifiedActive }, structured, promptWaiting);
|
|
360
|
+
// The OR rule, computed once for the whole server (Issue #1737): this is the
|
|
361
|
+
// same `resolvePromptWaiting` call the `send` guard makes, so the payload and
|
|
362
|
+
// the guard cannot disagree about whether a prompt is open. What they are
|
|
363
|
+
// still allowed to differ on is what to DO about it — see `blocksSend`, which
|
|
364
|
+
// bounds the structured layer's veto over sends and leaves this flag alone.
|
|
365
|
+
const isPromptWaiting = promptResolution.waiting;
|
|
366
|
+
// Issue #1726: the agent's own account of what it asked. It contributes only
|
|
367
|
+
// where some other layer has already established that a dialog is on screen —
|
|
368
|
+
// this record decides no status of its own, because Claude emits nothing at
|
|
369
|
+
// all while an AskUserQuestion picker is up (§5.6) and a record that asserted
|
|
370
|
+
// `waiting` from the invocation would go on asserting it long after a human
|
|
371
|
+
// answered in the terminal.
|
|
372
|
+
const askUserQuestion = (0, agent_event_state_1.getAskUserQuestion)(worktreeId, cliToolId, instanceId);
|
|
373
|
+
const scraperPromptData = statusResult.promptDetection.promptData;
|
|
374
|
+
const correctedPromptData = scraperPromptData && askUserQuestion
|
|
375
|
+
? (0, ask_user_question_prompt_1.applyAskUserQuestion)(scraperPromptData, askUserQuestion.spec)
|
|
376
|
+
: null;
|
|
377
|
+
// The degraded form, for a dialog only the structured layer can see. Enriched
|
|
378
|
+
// with the question text when one is in flight — that turns "a dialog is open
|
|
379
|
+
// and nobody could read it" into "a dialog is open and here is what it asks".
|
|
380
|
+
const structuredFacts = promptWaiting === null
|
|
381
|
+
? null
|
|
382
|
+
: { ...promptWaiting, askUserQuestion: summarizeAskUserQuestion(askUserQuestion) };
|
|
383
|
+
const promptData = scraperPromptWaiting
|
|
384
|
+
? correctedPromptData ??
|
|
385
|
+
scraperPromptData ??
|
|
386
|
+
(structuredFacts ? (0, structured_prompt_1.buildStructuredPromptData)(worktreeId, structuredFacts) : null)
|
|
387
|
+
: structuredFacts
|
|
388
|
+
? (0, structured_prompt_1.buildStructuredPromptData)(worktreeId, structuredFacts)
|
|
389
|
+
: null;
|
|
390
|
+
// Issue #1723 §3: the field data this Epic is being built on. Every line is
|
|
391
|
+
// one poll where the screen and the agent disagreed about what the agent was
|
|
392
|
+
// doing, which is the only way to answer "how wrong was the scraper?" with a
|
|
393
|
+
// number instead of an anecdote. Emitted only on disagreement — a session
|
|
394
|
+
// where the two layers agree is silent — and including the disagreements this
|
|
395
|
+
// merge deliberately does NOT act on (`applied: false`), because those are
|
|
396
|
+
// exactly the cases the next Issues in the Epic have to decide about.
|
|
397
|
+
if (structured !== null && structured.status !== statusResult.status) {
|
|
398
|
+
logger.info('detection-divergence', {
|
|
399
|
+
worktreeId,
|
|
400
|
+
cliToolId,
|
|
401
|
+
instanceId: resolvedInstanceId,
|
|
402
|
+
scraperStatus: statusResult.status,
|
|
403
|
+
scraperReason: statusResult.reason,
|
|
404
|
+
structuredStatus: structured.status,
|
|
405
|
+
structuredReason: structured.reason,
|
|
406
|
+
structuredEvent: structured.event,
|
|
407
|
+
structuredEventAt: structured.at,
|
|
408
|
+
applied: merged.structuredApplied,
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
// Issue #1708: a frame nothing could classify left no trace anywhere. Both
|
|
412
|
+
// prompt-history writers (response-checker's pending row and
|
|
413
|
+
// recordAnsweredPrompt) are gated on `promptDetection.isPrompt === true`, so
|
|
414
|
+
// the only evidence a worker had stalled was the live pane — and `capture
|
|
415
|
+
// --prompts` answered "No prompt history." for a session that had been stuck
|
|
416
|
+
// for 900s. Record the failure itself, once, after it has persisted.
|
|
417
|
+
//
|
|
418
|
+
// Recorded here because this is the one place the flag is computed, and both
|
|
419
|
+
// the HTTP pull and the WebSocket push run through it, so the row appears at
|
|
420
|
+
// whatever cadence the session is actually being watched at.
|
|
421
|
+
//
|
|
422
|
+
// Fed the MERGED flag (#1723): a frame the structured layer classified is not
|
|
423
|
+
// an unclassified frame, and writing a "detection failed" row for a turn the
|
|
424
|
+
// agent itself told us had ended would put a false stall into the audit trail
|
|
425
|
+
// `capture --prompts` prints.
|
|
426
|
+
const unclassifiedVerdict = (0, unclassified_frame_tracker_1.observeUnclassifiedFrame)(compositeKey, merged.isUnclassifiedActive);
|
|
427
|
+
if (unclassifiedVerdict.shouldRecord) {
|
|
428
|
+
recordUnclassifiedFrame(db, {
|
|
429
|
+
worktreeId,
|
|
430
|
+
cliToolId,
|
|
431
|
+
instanceId: resolvedInstanceId,
|
|
432
|
+
dwellMs: unclassifiedVerdict.dwellMs,
|
|
433
|
+
sessionStatus: merged.status,
|
|
434
|
+
sessionStatusReason: merged.reason,
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
// Issue #1725: the structured layer saw a dialog the scraper did not. That
|
|
438
|
+
// gap is the fact worth keeping — see recordStructuredPrompt.
|
|
439
|
+
if (promptWaiting !== null && structuredFacts !== null && !scraperPromptWaiting && !promptWaiting.recorded) {
|
|
440
|
+
(0, agent_event_state_1.markStructuredPromptRecorded)(worktreeId, cliToolId, instanceId);
|
|
441
|
+
recordStructuredPrompt(db, {
|
|
442
|
+
worktreeId,
|
|
443
|
+
cliToolId,
|
|
444
|
+
instanceId: resolvedInstanceId,
|
|
445
|
+
state: promptWaiting,
|
|
446
|
+
facts: structuredFacts,
|
|
447
|
+
});
|
|
448
|
+
}
|
|
83
449
|
const realtimeSnippet = lines.slice(-100).join('\n');
|
|
84
450
|
const autoYesState = (0, auto_yes_manager_1.getAutoYesState)(worktreeId, cliToolId, instanceId);
|
|
85
451
|
return {
|
|
86
452
|
isRunning: true,
|
|
87
453
|
cliToolId,
|
|
88
|
-
sessionStatus:
|
|
89
|
-
sessionStatusReason:
|
|
454
|
+
sessionStatus: merged.status,
|
|
455
|
+
sessionStatusReason: merged.reason,
|
|
90
456
|
content: newContent,
|
|
91
457
|
fullOutput: output,
|
|
92
458
|
realtimeSnippet,
|
|
93
459
|
lineCount: totalLines,
|
|
94
460
|
lastCapturedLine,
|
|
95
461
|
isComplete: isPromptWaiting,
|
|
96
|
-
isGenerating: thinking,
|
|
97
|
-
thinking,
|
|
98
|
-
thinkingMessage: thinking ? 'Claude is thinking...' : null,
|
|
462
|
+
isGenerating: merged.thinking,
|
|
463
|
+
thinking: merged.thinking,
|
|
464
|
+
thinkingMessage: merged.thinking ? 'Claude is thinking...' : null,
|
|
99
465
|
isPromptWaiting,
|
|
100
|
-
promptData
|
|
466
|
+
promptData,
|
|
101
467
|
autoYes: {
|
|
102
468
|
enabled: autoYesState?.enabled ?? false,
|
|
103
469
|
expiresAt: autoYesState?.enabled ? autoYesState.expiresAt : null,
|
|
@@ -106,9 +472,10 @@ async function buildCurrentOutput(db, worktreeId, cliToolId, instanceId) {
|
|
|
106
472
|
},
|
|
107
473
|
isSelectionListActive,
|
|
108
474
|
isPagerActive,
|
|
109
|
-
isUnclassifiedActive,
|
|
475
|
+
isUnclassifiedActive: merged.isUnclassifiedActive,
|
|
110
476
|
lastServerResponseTimestamp,
|
|
111
477
|
serverPollerActive: (0, auto_yes_manager_1.isPollerActive)(compositeKey),
|
|
112
478
|
lastStopEventAt: stopEventAt,
|
|
479
|
+
structuredEvents,
|
|
113
480
|
};
|
|
114
481
|
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The single answer to "is a prompt waiting on this session?" (Issue #1737).
|
|
4
|
+
*
|
|
5
|
+
* Two layers can see a dialog: the screen scraper (`detectSessionStatus`) and
|
|
6
|
+
* the agent's own structured events (`agent-event-state`). Issue #1725 composed
|
|
7
|
+
* them with OR inside `buildCurrentOutput` — and the `send` guard added by
|
|
8
|
+
* #1708 asked the scraper directly, so the same question had two answers and
|
|
9
|
+
* the guard let a structured-only dialog through. This module holds the
|
|
10
|
+
* composition once; `current-output-builder` and `prompt-waiting-guard` both
|
|
11
|
+
* read it and neither reimplements it.
|
|
12
|
+
*
|
|
13
|
+
* ## Two verdicts, deliberately, from one resolution
|
|
14
|
+
*
|
|
15
|
+
* `waiting` is what the payload publishes. `blocksSend` is what refuses a send.
|
|
16
|
+
* They are not the same question because they do not cost the same thing when
|
|
17
|
+
* they are wrong:
|
|
18
|
+
*
|
|
19
|
+
* - a wrong `waiting` costs a user a prompt panel they can dismiss, and costs
|
|
20
|
+
* `wait --on-prompt agent` an early exit 10 — bounded, visible, recoverable;
|
|
21
|
+
* - a wrong `blocksSend` costs the session its writability. Nobody can talk to
|
|
22
|
+
* the agent, including the operator trying to unstick it. That is the
|
|
23
|
+
* failure #1725's author declined to risk ("a provisional record making a
|
|
24
|
+
* session unwritable is a worse failure than the one it would prevent"), and
|
|
25
|
+
* it is the reason this module exists rather than a one-line OR in the guard.
|
|
26
|
+
*
|
|
27
|
+
* So the structured layer's veto over sends — and only that veto — is bounded
|
|
28
|
+
* three ways: {@link STRUCTURED_SEND_BLOCK_MAX_AGE_MS}, a server-wide env
|
|
29
|
+
* switch, and a per-send opt-out. The scraper's half is bounded by nothing,
|
|
30
|
+
* because it re-reads the live frame every time and releases itself.
|
|
31
|
+
*
|
|
32
|
+
* @module lib/session/prompt-waiting-composition
|
|
33
|
+
*/
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.STRUCTURED_SEND_GUARD_ENV = exports.STRUCTURED_SEND_BLOCK_MAX_AGE_MS = void 0;
|
|
36
|
+
exports.structuredWaitingReason = structuredWaitingReason;
|
|
37
|
+
exports.resolvePromptWaiting = resolvePromptWaiting;
|
|
38
|
+
const agent_event_state_1 = require("../../lib/session/agent-event-state");
|
|
39
|
+
const status_mapping_1 = require("../../lib/session/status-mapping");
|
|
40
|
+
/**
|
|
41
|
+
* How long a structured-only dialog may keep refusing sends (Issue #1737).
|
|
42
|
+
*
|
|
43
|
+
* The structured record is released by `Stop`, `user_prompt_submit`,
|
|
44
|
+
* `post_tool_use`, `Notification(idle_prompt)`, a generation change, and by the
|
|
45
|
+
* scraper watching the frame it corroborated clear. Every one of those is an
|
|
46
|
+
* event that may simply never arrive: hooks are fail-open by design, a `Stop`
|
|
47
|
+
* can be lost to a timeout, and the case this whole feature exists for is the
|
|
48
|
+
* scraper being blind to the dialog and therefore unable to report it gone. Put
|
|
49
|
+
* those together and a record can outlive its dialog with nothing left to
|
|
50
|
+
* release it — until {@link
|
|
51
|
+
* agent-event-state!STRUCTURED_STATE_MAX_AGE_MS} at 30 minutes, which is far too
|
|
52
|
+
* long to leave a session unwritable.
|
|
53
|
+
*
|
|
54
|
+
* Five minutes is chosen against what it costs in each direction. Losing the
|
|
55
|
+
* veto early costs the pre-#1737 behaviour for a dialog *the scraper cannot
|
|
56
|
+
* see* — a narrow slice of the #1708 hazard, since a dialog the scraper CAN see
|
|
57
|
+
* still blocks with no time bound at all. Holding it too long costs an operator
|
|
58
|
+
* every route to their own agent. The first is a missed guard; the second is an
|
|
59
|
+
* outage.
|
|
60
|
+
*
|
|
61
|
+
* Measured from the record's `at` — when the human was first reported blocked —
|
|
62
|
+
* for the same reason the other bounds are: that is the instant the fact was
|
|
63
|
+
* created, and refreshing it on corroboration would let a scraper that keeps
|
|
64
|
+
* misreading a frame extend the veto indefinitely.
|
|
65
|
+
*/
|
|
66
|
+
exports.STRUCTURED_SEND_BLOCK_MAX_AGE_MS = 5 * 60 * 1000;
|
|
67
|
+
/**
|
|
68
|
+
* Server-wide off switch for the structured half of the send guard.
|
|
69
|
+
*
|
|
70
|
+
* Set to `off` (or `0` / `false`) to make `send` consult only the scraper, i.e.
|
|
71
|
+
* exactly the #1708 guard. The escape hatch of last resort: it needs a server
|
|
72
|
+
* restart, which by itself already clears the in-memory record, so the per-send
|
|
73
|
+
* opt-out is the one an operator reaches for first. This exists for the fleet
|
|
74
|
+
* that decides it does not want the structured veto at all.
|
|
75
|
+
*/
|
|
76
|
+
exports.STRUCTURED_SEND_GUARD_ENV = 'CM_STRUCTURED_SEND_GUARD';
|
|
77
|
+
/**
|
|
78
|
+
* The status reason a structured-only dialog publishes.
|
|
79
|
+
*
|
|
80
|
+
* Shared so `sessionStatusReason` in the payload and the reason logged by the
|
|
81
|
+
* send refusal cannot drift apart — an operator reading `hook_permission_prompt`
|
|
82
|
+
* in one surface should find the same word in the other.
|
|
83
|
+
*/
|
|
84
|
+
function structuredWaitingReason(state) {
|
|
85
|
+
return state.source === 'notification'
|
|
86
|
+
? status_mapping_1.HOOK_STATUS_REASON.PERMISSION_PROMPT
|
|
87
|
+
: status_mapping_1.HOOK_STATUS_REASON.PERMISSION_REQUEST;
|
|
88
|
+
}
|
|
89
|
+
/** Whether {@link STRUCTURED_SEND_GUARD_ENV} turns the structured veto off. */
|
|
90
|
+
function isStructuredSendGuardDisabled() {
|
|
91
|
+
const raw = process.env[exports.STRUCTURED_SEND_GUARD_ENV]?.trim().toLowerCase();
|
|
92
|
+
return raw === 'off' || raw === '0' || raw === 'false';
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Resolve both layers into one verdict, applying the release rule on the way.
|
|
96
|
+
*
|
|
97
|
+
* Has side effects on the structured record, by design: this is the only place
|
|
98
|
+
* the scraper's observations reach it, so every caller that captured a frame
|
|
99
|
+
* must feed it here or the release rule simply stops running for that path.
|
|
100
|
+
*
|
|
101
|
+
* The release rule is asymmetric on purpose (Issue #1725). The scraper is
|
|
102
|
+
* allowed to say "that prompt is gone" only about a prompt it once saw, because
|
|
103
|
+
* the case this exists for is the scraper being BLIND to the dialog: if "the
|
|
104
|
+
* scraper reports no prompt" released the state on its own, the structured
|
|
105
|
+
* layer would be silenced in exactly the situation it was added for. So a frame
|
|
106
|
+
* the scraper reads as `waiting` arms the release (and confirms a provisional
|
|
107
|
+
* record), and only after that does a non-waiting frame clear it.
|
|
108
|
+
*
|
|
109
|
+
* This is also what the push/pull timing demands. The structured fact arrives
|
|
110
|
+
* over HTTP the moment the agent posts it, while the scraper reads a pane
|
|
111
|
+
* through a 5 s capture cache (`CACHE_TTL_MS`), so "the event is here and the
|
|
112
|
+
* scraper has not seen the dialog yet" is a state that always exists — and
|
|
113
|
+
* under a rule that let the scraper's silence win, that state would be a lost
|
|
114
|
+
* detection every single time.
|
|
115
|
+
*/
|
|
116
|
+
function resolvePromptWaiting({ worktreeId, cliToolId, instanceId, scraper, ignoreStructured = false, now = Date.now(), }) {
|
|
117
|
+
let structured = (0, agent_event_state_1.getStructuredPromptWaiting)(worktreeId, cliToolId, instanceId, now);
|
|
118
|
+
if (structured !== null) {
|
|
119
|
+
if (scraper.status === 'waiting') {
|
|
120
|
+
(0, agent_event_state_1.corroborateStructuredPromptWaiting)(worktreeId, cliToolId, instanceId, now);
|
|
121
|
+
}
|
|
122
|
+
else if (structured.scraperCorroborated) {
|
|
123
|
+
(0, agent_event_state_1.clearStructuredPromptWaiting)(worktreeId, cliToolId, instanceId);
|
|
124
|
+
structured = null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const waiting = scraper.hasActivePrompt || structured !== null;
|
|
128
|
+
// The scraper is reading the frame in front of it right now, so its verdict
|
|
129
|
+
// needs no bound: the next capture releases it.
|
|
130
|
+
if (scraper.hasActivePrompt) {
|
|
131
|
+
return {
|
|
132
|
+
waiting,
|
|
133
|
+
scraperWaiting: true,
|
|
134
|
+
structured,
|
|
135
|
+
blocksSend: true,
|
|
136
|
+
blockedBy: 'scraper',
|
|
137
|
+
blockReason: scraper.reason,
|
|
138
|
+
structuredSendBlockSuppressed: null,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (structured === null) {
|
|
142
|
+
return {
|
|
143
|
+
waiting,
|
|
144
|
+
scraperWaiting: false,
|
|
145
|
+
structured: null,
|
|
146
|
+
blocksSend: false,
|
|
147
|
+
blockedBy: null,
|
|
148
|
+
blockReason: null,
|
|
149
|
+
structuredSendBlockSuppressed: null,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
const suppressed = structuredSendBlockSuppression(structured, ignoreStructured, now);
|
|
153
|
+
return {
|
|
154
|
+
waiting,
|
|
155
|
+
scraperWaiting: false,
|
|
156
|
+
structured,
|
|
157
|
+
blocksSend: suppressed === null,
|
|
158
|
+
blockedBy: suppressed === null ? 'structured' : null,
|
|
159
|
+
blockReason: suppressed === null ? structuredWaitingReason(structured) : null,
|
|
160
|
+
structuredSendBlockSuppressed: suppressed,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Why this structured record may not refuse a send, or null when it may.
|
|
165
|
+
*
|
|
166
|
+
* Ordered so the answer names the operator's own action first: someone who
|
|
167
|
+
* passed the opt-out should be told that is what happened, not that the record
|
|
168
|
+
* had also aged out.
|
|
169
|
+
*/
|
|
170
|
+
function structuredSendBlockSuppression(state, ignoreStructured, now) {
|
|
171
|
+
if (ignoreStructured)
|
|
172
|
+
return 'caller_opt_out';
|
|
173
|
+
if (isStructuredSendGuardDisabled())
|
|
174
|
+
return 'disabled';
|
|
175
|
+
if (now - state.at >= exports.STRUCTURED_SEND_BLOCK_MAX_AGE_MS)
|
|
176
|
+
return 'expired';
|
|
177
|
+
return null;
|
|
178
|
+
}
|