commandmate 0.29.2 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +271 -264
- package/.next/app-path-routes-manifest.json +35 -34
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.json +1 -1
- package/.next/routes-manifest.json +8 -8
- 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 +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 +18 -18
- 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 +19 -19
- package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route.js +1 -1
- package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route.js +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route.js +1 -0
- package/.next/server/app/api/settings/default-surface-mode/route.js.nft.json +1 -0
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -0
- 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]/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.js +1 -0
- package/.next/server/app/api/worktrees/[id]/cli-reference/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -0
- 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_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/opencode/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_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 +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page.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_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 +11 -11
- 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.js +3 -3
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +35 -34
- package/.next/server/chunks/1058.js +1 -1
- package/.next/server/chunks/1068.js +1 -1
- package/.next/server/chunks/1191.js +1 -1
- package/.next/server/chunks/1341.js +1 -1
- package/.next/server/chunks/1886.js +3 -3
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/261.js +1 -0
- package/.next/server/chunks/2739.js +1 -0
- package/.next/server/chunks/2816.js +1 -1
- package/.next/server/chunks/3099.js +5 -0
- package/.next/server/chunks/3123.js +1 -0
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3543.js +1 -1
- package/.next/server/chunks/3945.js +1 -1
- package/.next/server/chunks/4325.js +1 -0
- package/.next/server/chunks/4390.js +1 -1
- package/.next/server/chunks/4393.js +1 -1
- package/.next/server/chunks/4443.js +6 -0
- package/.next/server/chunks/5017.js +1 -1
- package/.next/server/chunks/5043.js +1 -0
- package/.next/server/chunks/5120.js +1 -0
- package/.next/server/chunks/552.js +25 -0
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6337.js +1 -1
- package/.next/server/chunks/663.js +1 -1
- package/.next/server/chunks/6894.js +8 -0
- package/.next/server/chunks/7685.js +1 -1
- package/.next/server/chunks/7836.js +1 -0
- package/.next/server/chunks/8356.js +1 -1
- package/.next/server/chunks/880.js +1 -1
- package/.next/server/chunks/8807.js +1 -1
- package/.next/server/chunks/9123.js +2 -2
- package/.next/server/chunks/9130.js +3 -3
- package/.next/server/chunks/9627.js +48 -26
- package/.next/server/chunks/9696.js +3 -0
- package/.next/server/chunks/9798.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/server/src/middleware.js +1 -1
- package/.next/server/src/middleware.js.map +1 -1
- package/.next/static/chunks/{4882-388e94fe0a03c2ba.js → 3916-0e929d089282dc5d.js} +1 -1
- package/.next/static/chunks/{5229-b2a81bb8fb5c19e9.js → 5229-6c89475b61bd2c8b.js} +1 -1
- package/.next/static/chunks/6022-7a7d1760fc9814c7.js +1 -0
- package/.next/static/chunks/6381-dbf04a99647f6018.js +1 -0
- package/.next/static/chunks/app/api/agents/update/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/agents/versions/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/app/update/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/app/update-check/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/conversation/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/current-output/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/messages/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/session/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/start/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/terminal/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/tools/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/auth/login/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/auth/status/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/capabilities/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/status/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/external-apps/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/fs/browse/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/fs/recent-paths/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/hooks/agent-event/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/hooks/claude-done/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/hooks/permission-request/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/metrics/vibe/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/ollama/models/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/push/escalation/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/push/subscriptions/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/push/vapid/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/remote/pair/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/excluded/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/restore/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/scan/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/sync/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/validate-path/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/settings/default-agents/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/settings/default-surface-mode/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/sidebar/group-order/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/skills/[id]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/skills/installations/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/skills/operations/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/skills/reindex/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/skills/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/slash-commands/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/templates/[id]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/templates/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/todos/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/manifest.webmanifest/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/more/{page-75d3783da0d49a25.js → page-333bba1c8bbc9c11.js} +1 -1
- package/.next/static/chunks/app/proxy/[...path]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/layout-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-aac399392ec8c273.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/terminal/page-2631bc5c4b0a9fb8.js +1 -0
- package/.next/static/css/23f9c40ecc458c77.css +1 -0
- package/.next/static/pcpB4K6KreMzu2qbhvuRY/_buildManifest.js +1 -0
- package/.next/trace +13 -13
- package/.next/types/app/api/settings/default-surface-mode/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/{start-polling → cli-reference}/route.ts +3 -3
- package/.next/types/routes.d.ts +3 -2
- package/.next/types/validator.ts +18 -9
- package/dist/server/server.js +58 -0
- package/dist/server/src/lib/claude-output.js +1 -0
- package/dist/server/src/lib/db/app-settings-db.js +60 -0
- package/dist/server/src/lib/db/chat-db.js +120 -7
- package/dist/server/src/lib/detection/status-detector.js +3 -2
- package/dist/server/src/lib/env.js +122 -0
- package/dist/server/src/lib/git/worktrees.js +154 -0
- package/dist/server/src/lib/history/transcript-tail.js +80 -0
- package/dist/server/src/lib/history/user-turn-recorder.js +252 -0
- package/dist/server/src/lib/hooks/agent-event-service.js +40 -6
- package/dist/server/src/lib/hooks/permission-decision-service.js +85 -1
- package/dist/server/src/lib/hooks/sources/antigravity/history.js +607 -0
- package/dist/server/src/lib/hooks/sources/antigravity/source.js +7 -0
- package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +407 -0
- package/dist/server/src/lib/hooks/sources/claude/history.js +797 -0
- package/dist/server/src/lib/hooks/sources/claude/source.js +4 -0
- package/dist/server/src/lib/hooks/sources/claude/transcript.js +518 -0
- package/dist/server/src/lib/hooks/sources/codex/history.js +663 -0
- package/dist/server/src/lib/hooks/sources/codex/source.js +4 -0
- package/dist/server/src/lib/hooks/sources/codex/transcript.js +448 -0
- package/dist/server/src/lib/hooks/sources/copilot/source.js +2 -0
- package/dist/server/src/lib/hooks/sources/gemini/source.js +2 -0
- package/dist/server/src/lib/hooks/sources/legacy-relay.js +3 -0
- package/dist/server/src/lib/hooks/sources/opencode/history.js +57 -0
- package/dist/server/src/lib/hooks/sources/opencode/source.js +4 -0
- package/dist/server/src/lib/hooks/sources/opencode/transcript.js +10 -28
- package/dist/server/src/lib/hooks/sources/turn-body.js +118 -0
- package/dist/server/src/lib/hooks/stop-history-capture.js +161 -0
- package/dist/server/src/lib/polling/prompt-dedup.js +2 -4
- package/dist/server/src/lib/polling/response-checker.js +87 -6
- package/dist/server/src/lib/polling/response-dedup.js +2 -4
- package/dist/server/src/lib/polling/response-poller-core.js +191 -29
- package/dist/server/src/lib/polling/structured-history-gate.js +272 -16
- package/dist/server/src/lib/push/push-sender.js +21 -1
- package/dist/server/src/lib/push/waiting-push-notifier.js +126 -8
- package/dist/server/src/lib/realtime/publisher-registry.js +171 -0
- package/dist/server/src/lib/realtime/terminal-broadcast.js +14 -1
- package/dist/server/src/lib/realtime/types.js +96 -1
- package/dist/server/src/lib/session/current-output-builder.js +365 -4
- package/dist/server/src/lib/session/send-user-message.js +90 -2
- package/dist/server/src/lib/tui-accumulator.js +2 -8
- package/dist/server/src/lib/ws-server.js +143 -6
- package/dist/server/src/types/agent-transcript.js +241 -5
- package/dist/server/src/types/ui-state.js +24 -1
- package/package.json +1 -1
- package/public/sw.js +15 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js +0 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +0 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +0 -1
- package/.next/server/chunks/1714.js +0 -7
- package/.next/server/chunks/2198.js +0 -1
- package/.next/server/chunks/221.js +0 -25
- package/.next/server/chunks/2759.js +0 -8
- package/.next/server/chunks/3558.js +0 -1
- package/.next/server/chunks/6781.js +0 -1
- package/.next/server/chunks/9508.js +0 -1
- package/.next/static/0YoRrahue4Vchxg1z83IQ/_buildManifest.js +0 -1
- package/.next/static/chunks/1379-af7af9e08f47c979.js +0 -1
- package/.next/static/chunks/6381-9ba5198c0a6ff197.js +0 -1
- package/.next/static/chunks/app/api/agents/update/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/agents/versions/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/app/update/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/app/update-check/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/conversation/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/current-output/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/messages/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/session/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/start/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/terminal/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/tools/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/auth/login/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/auth/status/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/capabilities/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/status/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/external-apps/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/fs/browse/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/fs/recent-paths/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/hooks/agent-event/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/hooks/claude-done/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/hooks/permission-request/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/metrics/vibe/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/ollama/models/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/push/escalation/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/push/subscriptions/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/push/vapid/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/remote/pair/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/excluded/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/restore/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/scan/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/sync/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/validate-path/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/settings/default-agents/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/sidebar/group-order/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/skills/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/skills/installations/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/skills/operations/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/skills/reindex/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/skills/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/slash-commands/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/templates/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/templates/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/todos/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/proxy/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/layout-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-ce6279d581d1df95.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/terminal/page-00ad5d9a62a71cab.js +0 -1
- package/.next/static/css/b326c8a734e1928e.css +0 -1
- /package/.next/static/{0YoRrahue4Vchxg1z83IQ → pcpB4K6KreMzu2qbhvuRY}/_ssgManifest.js +0 -0
|
@@ -1,32 +1,62 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Whether somebody better-informed is already recording this turn (Issue #2041
|
|
3
|
+
* Whether somebody better-informed is already recording this turn (Issue #2041,
|
|
4
|
+
* extended for Claude Code in #2121, codex in #2197 and antigravity in #2198).
|
|
4
5
|
*
|
|
5
6
|
* The poller's job has always been to be the only writer of conversation
|
|
6
|
-
* history, because for
|
|
7
|
-
* reply exists.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* drew it — so one of them has to stand
|
|
12
|
-
* screen.
|
|
7
|
+
* history, because for most of the six tools the terminal is the only place the
|
|
8
|
+
* reply exists. Four of them now have a second writer: opencode publishes its
|
|
9
|
+
* replies over the SSE stream CommandMate subscribes to (#1763/#2041), and
|
|
10
|
+
* claude, codex and antigravity each keep their own transcript file on disk.
|
|
11
|
+
* Two writers for one turn would put the same answer in History twice — once as
|
|
12
|
+
* the agent wrote it and once as its TUI drew it — so one of them has to stand
|
|
13
|
+
* down, and it is the one reading the screen.
|
|
13
14
|
*
|
|
14
15
|
* ## Why this is a module and not an `if`
|
|
15
16
|
*
|
|
16
17
|
* Two reasons, and the second is the one that matters. The obvious one is that
|
|
17
18
|
* `response-checker` is 1,000 lines with a single tool-agnostic spine, and a
|
|
18
19
|
* `cliToolId === 'opencode' && …` in the middle of the save path is exactly the
|
|
19
|
-
* kind of branch that gets copied to the next tool that grows a
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* kind of branch that gets copied to the next tool that grows a reader. The real
|
|
21
|
+
* one is the import: `@/lib/hooks/sources/opencode/subscription` reaches the
|
|
22
|
+
* whole opencode client through its module graph, and the poller's tests replace
|
|
23
|
+
* that graph wholesale. One named seam is one thing to stub.
|
|
24
|
+
*
|
|
25
|
+
* ## The tool names are gone (Issue #2197)
|
|
26
|
+
*
|
|
27
|
+
* Until this Issue the two functions below opened with `if (cliToolId !==
|
|
28
|
+
* 'opencode')` and `if (cliToolId !== CLAUDE_CLI_TOOL_ID)`, which is the branch
|
|
29
|
+
* the module comment above says it exists to prevent — the third tool arrived
|
|
30
|
+
* and the third `!==` was about to be written. What replaces them is a value the
|
|
31
|
+
* source declares about itself:
|
|
32
|
+
* `AgentSourceCapabilities.transcriptHistory` (`'pull' | 'push' | null`, see
|
|
33
|
+
* `lib/hooks/agent-event-types`). A tool with no second writer says `null` and
|
|
34
|
+
* both questions below answer false for it without naming it — which is what let
|
|
35
|
+
* #2198 add antigravity by editing its own `source.ts` and this file's reader
|
|
36
|
+
* table and nothing else, and what leaves gemini and copilot on the scraper
|
|
37
|
+
* without a line of code mentioning them.
|
|
38
|
+
*
|
|
39
|
+
* The word has three values rather than two because the two shapes are asked
|
|
40
|
+
* *different questions*:
|
|
41
|
+
*
|
|
42
|
+
* - **push** — a subscription is already receiving the reply, so the only thing
|
|
43
|
+
* to ask is whether that connection is live
|
|
44
|
+
* ({@link isStructuredHistoryWriterLive}).
|
|
45
|
+
* - **pull** — there is no connection, only a file, and nothing reads it until
|
|
46
|
+
* something asks. So the question is not "is anyone recording?" but "record
|
|
47
|
+
* it now, and tell me whether you did"
|
|
48
|
+
* ({@link captureStructuredHistoryTurn}). The call has to be here rather than
|
|
49
|
+
* in the hook receiver for a reason beyond tidiness: a hook post is answered
|
|
50
|
+
* and forgotten, so the only moment CommandMate knows a turn is *finished and
|
|
51
|
+
* about to be written* is this one, and doing the handover at the point of
|
|
52
|
+
* the write is what makes it impossible for both writers to run.
|
|
23
53
|
*
|
|
24
54
|
* ## What is NOT gated
|
|
25
55
|
*
|
|
26
56
|
* Only the two calls that *record the reply* — the `chat_messages` row and the
|
|
27
57
|
* Markdown conversation log. Prompt rows, Auto-Yes, the waiting-episode edges,
|
|
28
58
|
* push notifications, task events and the session-state cursor all stay on the
|
|
29
|
-
* scraper, because none of them are things the
|
|
59
|
+
* scraper, because none of them are things the second writer duplicates: a
|
|
30
60
|
* `permission.asked` becomes a pending decision, never a history row, and the
|
|
31
61
|
* push fan-out has no second producer at all. Gating them would trade a
|
|
32
62
|
* duplicated reply for a silent notification, which is the worse failure.
|
|
@@ -34,15 +64,147 @@
|
|
|
34
64
|
* @module lib/polling/structured-history-gate
|
|
35
65
|
*/
|
|
36
66
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
67
|
+
exports.resetStructuredHistoryCaptureQueue = resetStructuredHistoryCaptureQueue;
|
|
68
|
+
exports.isPullTranscriptHistory = isPullTranscriptHistory;
|
|
37
69
|
exports.isStructuredHistoryWriterLive = isStructuredHistoryWriterLive;
|
|
70
|
+
exports.captureStructuredHistoryTurn = captureStructuredHistoryTurn;
|
|
71
|
+
exports.hasStructuredHistoryTranscript = hasStructuredHistoryTranscript;
|
|
38
72
|
const logger_1 = require("../../lib/logger");
|
|
39
73
|
const subscription_1 = require("../../lib/hooks/sources/opencode/subscription");
|
|
74
|
+
const history_1 = require("../../lib/hooks/sources/claude/history");
|
|
75
|
+
const history_2 = require("../../lib/hooks/sources/codex/history");
|
|
76
|
+
const history_3 = require("../../lib/hooks/sources/antigravity/history");
|
|
77
|
+
const tool_id_1 = require("../../lib/hooks/sources/claude/tool-id");
|
|
78
|
+
const tool_id_2 = require("../../lib/hooks/sources/codex/tool-id");
|
|
79
|
+
const tool_id_3 = require("../../lib/hooks/sources/antigravity/tool-id");
|
|
80
|
+
const registry_1 = require("../../lib/hooks/sources/registry");
|
|
40
81
|
const logger = (0, logger_1.createLogger)('lib/polling/structured-history-gate');
|
|
82
|
+
/**
|
|
83
|
+
* One in-flight capture per instance (Issue #2246).
|
|
84
|
+
*
|
|
85
|
+
* Until this Issue there was one caller — the poller's save path, whose ticks do
|
|
86
|
+
* not overlap — and the Stop hook receiver is now a second one, arriving at
|
|
87
|
+
* exactly the moment the poller is most likely to be inside the same turn. Two
|
|
88
|
+
* things follow, and it is worth separating them because #2246's own text runs
|
|
89
|
+
* them together.
|
|
90
|
+
*
|
|
91
|
+
* **The duplicate-row race it describes is not open today, and this is what
|
|
92
|
+
* keeps it shut.** The readers are idempotent through `findMessageByRequestId`,
|
|
93
|
+
* which is a check-then-write over a *non-unique* index — but the check and the
|
|
94
|
+
* write are adjacent and synchronous (`better-sqlite3` is), and the only `await`
|
|
95
|
+
* in that stretch is the dynamic import *before* the check. So there is no point
|
|
96
|
+
* for a second caller to interleave at, and two concurrent captures of one turn
|
|
97
|
+
* already end in one row. That is a property of two adjacent statements, which
|
|
98
|
+
* is exactly the kind of property a later refactor removes without noticing: an
|
|
99
|
+
* `await` inserted between them re-opens the window silently, and the row it
|
|
100
|
+
* costs is a duplicated reply nobody sees until an operator reports it.
|
|
101
|
+
*
|
|
102
|
+
* **What it saves today is the work.** Both triggers otherwise read, parse and
|
|
103
|
+
* render the same 4 MiB tail at the same time, and the second one throws all of
|
|
104
|
+
* it away.
|
|
105
|
+
*
|
|
106
|
+
* A queue rather than a shared result: the second caller runs the read again
|
|
107
|
+
* after the first finishes, because it may be asking about a newer turn and
|
|
108
|
+
* because the answer it needs is about the file as it is *now*. Re-running is
|
|
109
|
+
* cheap and, after the first call, finds the row and answers true.
|
|
110
|
+
*
|
|
111
|
+
* On `globalThis` for the reason every shared map in this subsystem is (#1736):
|
|
112
|
+
* under `next dev` the poller's bundle and the hook receiver's bundle would each
|
|
113
|
+
* get a private copy of a module-scoped map, and a lock only one of two bundles
|
|
114
|
+
* can see is not a lock.
|
|
115
|
+
*/
|
|
116
|
+
const captureQueue = (globalThis.__structuredHistoryCaptureQueue ??= new Map());
|
|
117
|
+
/** Forget every instance's in-flight capture. Test seam. */
|
|
118
|
+
function resetStructuredHistoryCaptureQueue() {
|
|
119
|
+
captureQueue.clear();
|
|
120
|
+
}
|
|
121
|
+
/** The queue key; the same triple `buildCompositeKey` spells everywhere else. */
|
|
122
|
+
function captureKeyOf(worktreeId, cliToolId, instanceId) {
|
|
123
|
+
return `${worktreeId}\u0000${cliToolId}\u0000${instanceId}`;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Run `work` after whatever is already running for this instance.
|
|
127
|
+
*
|
|
128
|
+
* The stored promise is a settled-only shadow of the real one, so a caller that
|
|
129
|
+
* throws cannot reject the next caller's chain, and the entry is removed only by
|
|
130
|
+
* whoever put it there — a later call that has already replaced it must not have
|
|
131
|
+
* its own lock deleted underneath it.
|
|
132
|
+
*/
|
|
133
|
+
function serializePerInstance(key, work) {
|
|
134
|
+
const previous = captureQueue.get(key) ?? Promise.resolve();
|
|
135
|
+
const result = previous.then(work, work);
|
|
136
|
+
const settled = result.then(() => undefined, () => undefined);
|
|
137
|
+
captureQueue.set(key, settled);
|
|
138
|
+
void settled.then(() => {
|
|
139
|
+
if (captureQueue.get(key) === settled)
|
|
140
|
+
captureQueue.delete(key);
|
|
141
|
+
});
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Which reader answers for which tool.
|
|
146
|
+
*
|
|
147
|
+
* The one place a tool id still appears, and it is a dispatch table rather than
|
|
148
|
+
* a decision: *whether* to ask is
|
|
149
|
+
* `AgentSourceCapabilities.transcriptHistory === 'pull'`, and this only says who
|
|
150
|
+
* to ask. It cannot be folded into the capability itself because #1921 D3
|
|
151
|
+
* requires every declared capability to be JSON-serialisable — the block is
|
|
152
|
+
* copied onto the wire in `structuredEvents.source`, so a capability that were a
|
|
153
|
+
* function would vanish silently on the way out.
|
|
154
|
+
*
|
|
155
|
+
* A tool that declares `'pull'` and is missing here is a bug, and a loud one:
|
|
156
|
+
* {@link captureStructuredHistoryTurn} logs it and falls back to the scraper.
|
|
157
|
+
*/
|
|
158
|
+
const PULL_TRANSCRIPT_READERS = {
|
|
159
|
+
[tool_id_1.CLAUDE_CLI_TOOL_ID]: {
|
|
160
|
+
capture: (target, capture) => (0, history_1.captureClaudeTranscriptTurn)(target, capture),
|
|
161
|
+
locate: (target, capture) => (0, history_1.resolveClaudeTranscriptPath)(target, capture),
|
|
162
|
+
},
|
|
163
|
+
[tool_id_2.CODEX_CLI_TOOL_ID]: {
|
|
164
|
+
capture: (target, capture) => (0, history_2.captureCodexTranscriptTurn)(target, capture),
|
|
165
|
+
locate: (target, capture) => (0, history_2.resolveCodexTranscriptPath)(target, capture),
|
|
166
|
+
},
|
|
167
|
+
[tool_id_3.ANTIGRAVITY_CLI_TOOL_ID]: {
|
|
168
|
+
capture: (target, capture) => (0, history_3.captureAntigravityTranscriptTurn)(target, capture),
|
|
169
|
+
locate: (target, capture) => (0, history_3.resolveAntigravityTranscriptPath)(target, capture),
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* What this tool's source says about who records its replies.
|
|
174
|
+
*
|
|
175
|
+
* Never throws: a registry that cannot be reached is one that declares nothing,
|
|
176
|
+
* and nothing means the scraper keeps writing — the safe direction, as
|
|
177
|
+
* everywhere else in this module.
|
|
178
|
+
*/
|
|
179
|
+
function transcriptHistoryModeOf(cliToolId) {
|
|
180
|
+
try {
|
|
181
|
+
return (0, registry_1.getAgentEventSource)(cliToolId).capabilities.transcriptHistory ?? null;
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
logger.warn('structured-history-capability-unavailable', {
|
|
185
|
+
cliToolId,
|
|
186
|
+
error: error instanceof Error ? error.message : String(error),
|
|
187
|
+
});
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Whether this tool keeps a transcript a reader can be asked to pull from.
|
|
193
|
+
*
|
|
194
|
+
* Exported for the Stop receiver (Issue #2246), which has to decide whether the
|
|
195
|
+
* *retry* below is worth waiting for before it answers the agent's hook. It is
|
|
196
|
+
* the same question {@link captureStructuredHistoryTurn} opens with, asked
|
|
197
|
+
* without doing the read — never a tool id comparison, here or there.
|
|
198
|
+
*/
|
|
199
|
+
function isPullTranscriptHistory(cliToolId) {
|
|
200
|
+
return transcriptHistoryModeOf(cliToolId) === 'pull';
|
|
201
|
+
}
|
|
41
202
|
/**
|
|
42
203
|
* Whether the agent's own server is recording this instance's replies.
|
|
43
204
|
*
|
|
44
|
-
* False for every tool
|
|
45
|
-
*
|
|
205
|
+
* False for every tool whose source does not declare `transcriptHistory: 'push'`
|
|
206
|
+
* — today that is all of them but opencode — and false for an opencode instance
|
|
207
|
+
* whose subscription is anything other than `live`; see
|
|
46
208
|
* {@link isOpencodeStructuredHistoryLive} for why `lost` counts as "nobody is
|
|
47
209
|
* writing this down" rather than as "somebody will". The fallback direction is
|
|
48
210
|
* the safe one: two writers duplicate a reply, no writer loses it.
|
|
@@ -54,9 +216,12 @@ const logger = (0, logger_1.createLogger)('lib/polling/structured-history-gate')
|
|
|
54
216
|
* @param instanceId - The agent instance; defaults to the primary
|
|
55
217
|
*/
|
|
56
218
|
function isStructuredHistoryWriterLive(worktreeId, cliToolId, instanceId) {
|
|
57
|
-
if (cliToolId !== '
|
|
219
|
+
if (transcriptHistoryModeOf(cliToolId) !== 'push')
|
|
58
220
|
return false;
|
|
59
221
|
try {
|
|
222
|
+
// One probe, because there is one push source. A second one adds a table
|
|
223
|
+
// here of the shape `PULL_TRANSCRIPT_READERS` already has; it does not add
|
|
224
|
+
// another `cliToolId ===`.
|
|
60
225
|
return (0, subscription_1.isOpencodeStructuredHistoryLive)({
|
|
61
226
|
worktreeId,
|
|
62
227
|
cliToolId,
|
|
@@ -73,3 +238,94 @@ function isStructuredHistoryWriterLive(worktreeId, cliToolId, instanceId) {
|
|
|
73
238
|
return false;
|
|
74
239
|
}
|
|
75
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Ask the pull-mode structured writer to record this turn now (#2121, #2197).
|
|
243
|
+
*
|
|
244
|
+
* The file-backed half of the stand-down. Returns true when `chat_messages`
|
|
245
|
+
* holds this turn as the agent's own Markdown — because this call wrote it, or
|
|
246
|
+
* because an earlier poll of the same finished turn already did — and the caller
|
|
247
|
+
* must therefore drop the scraped copy.
|
|
248
|
+
*
|
|
249
|
+
* False for every tool that does not declare `transcriptHistory: 'pull'`, and
|
|
250
|
+
* false for one that does whenever anything at all prevented the write: no
|
|
251
|
+
* session pointer (a pane started without hooks, or with hooks codex has not
|
|
252
|
+
* been told to trust), no transcript file, an unreadable one, a window with no
|
|
253
|
+
* prompt in it, or a turn the agent has not finished writing. That is the
|
|
254
|
+
* fail-open every one of these Issues' acceptance criteria asks for in as many
|
|
255
|
+
* words — 転写ファイルが無い / 読めない場合は従来のスクレイプ経路にフォール
|
|
256
|
+
* バックする. Two writers duplicate a reply; no writer loses one.
|
|
257
|
+
*
|
|
258
|
+
* Never throws, for the same reason {@link isStructuredHistoryWriterLive} does
|
|
259
|
+
* not: this runs inside the poller's save path, and an exception here would cost
|
|
260
|
+
* the scraped reply as well as the structured one.
|
|
261
|
+
*
|
|
262
|
+
* @param worktreeId - The worktree
|
|
263
|
+
* @param cliToolId - The tool driving the pane
|
|
264
|
+
* @param instanceId - The agent instance; defaults to the primary
|
|
265
|
+
* @param capture - Where to look; see {@link StructuredHistoryCapture}
|
|
266
|
+
*/
|
|
267
|
+
async function captureStructuredHistoryTurn(worktreeId, cliToolId, instanceId, capture) {
|
|
268
|
+
if (!isPullTranscriptHistory(cliToolId))
|
|
269
|
+
return false;
|
|
270
|
+
const reader = PULL_TRANSCRIPT_READERS[cliToolId];
|
|
271
|
+
if (!reader) {
|
|
272
|
+
logger.warn('structured-history-reader-missing', {
|
|
273
|
+
worktreeId,
|
|
274
|
+
cliToolId,
|
|
275
|
+
instanceId: instanceId ?? cliToolId,
|
|
276
|
+
});
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
const resolvedInstanceId = instanceId ?? cliToolId;
|
|
280
|
+
return serializePerInstance(captureKeyOf(worktreeId, cliToolId, resolvedInstanceId), async () => {
|
|
281
|
+
try {
|
|
282
|
+
return await reader.capture({ worktreeId, cliToolId, instanceId: resolvedInstanceId }, capture);
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
logger.warn('structured-history-capture-unavailable', {
|
|
286
|
+
worktreeId,
|
|
287
|
+
cliToolId,
|
|
288
|
+
instanceId: resolvedInstanceId,
|
|
289
|
+
error: error instanceof Error ? error.message : String(error),
|
|
290
|
+
});
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Whether a pull reader can name a transcript for this instance (Issue #2246).
|
|
297
|
+
*
|
|
298
|
+
* Not "is there a turn to write" and not "did anything get written" — only
|
|
299
|
+
* whether the file the reader would open exists right now. The one caller is
|
|
300
|
+
* `lib/hooks/stop-history-capture`, which asks it after a capture answered
|
|
301
|
+
* false, to decide whether waiting half a second and asking again could help.
|
|
302
|
+
* An instance with no transcript will not have one in half a second, and the
|
|
303
|
+
* delay would be paid on every `stop` of every session without hooks.
|
|
304
|
+
*
|
|
305
|
+
* False for every tool that does not declare `transcriptHistory: 'pull'`, and
|
|
306
|
+
* never throws — an unanswerable question is one whose answer is "no file",
|
|
307
|
+
* which costs the retry and nothing else.
|
|
308
|
+
*
|
|
309
|
+
* @param worktreeId - The worktree
|
|
310
|
+
* @param cliToolId - The tool driving the pane
|
|
311
|
+
* @param instanceId - The agent instance; defaults to the primary
|
|
312
|
+
* @param capture - Where to look; see {@link StructuredHistoryCapture}
|
|
313
|
+
*/
|
|
314
|
+
async function hasStructuredHistoryTranscript(worktreeId, cliToolId, instanceId, capture) {
|
|
315
|
+
const reader = isPullTranscriptHistory(cliToolId) ? PULL_TRANSCRIPT_READERS[cliToolId] : undefined;
|
|
316
|
+
if (!reader)
|
|
317
|
+
return false;
|
|
318
|
+
try {
|
|
319
|
+
const path = await reader.locate({ worktreeId, cliToolId, instanceId: instanceId ?? cliToolId }, capture);
|
|
320
|
+
return path !== null;
|
|
321
|
+
}
|
|
322
|
+
catch (error) {
|
|
323
|
+
logger.warn('structured-history-locate-unavailable', {
|
|
324
|
+
worktreeId,
|
|
325
|
+
cliToolId,
|
|
326
|
+
instanceId: instanceId ?? cliToolId,
|
|
327
|
+
error: error instanceof Error ? error.message : String(error),
|
|
328
|
+
});
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
@@ -317,9 +317,29 @@ async function notifyPushSubscribers(event, now = Date.now()) {
|
|
|
317
317
|
// from one that was never attempted — `push-send-failed` is per device and
|
|
318
318
|
// sits below the default log level's attention, and success said nothing at
|
|
319
319
|
// all. One line per fan-out names both halves, and no endpoint.
|
|
320
|
+
//
|
|
321
|
+
// Issue #2133: it also names *whose* fan-out it was. Without the subject,
|
|
322
|
+
// two worktrees notifying in the same second print two identical lines, so
|
|
323
|
+
// the UAT steps that pass by counting zero notifications
|
|
324
|
+
// (`docs/qa/2001-cross-device-dismissal-uat.md` T-4 / T-6 / T-7) read a
|
|
325
|
+
// neighbour's push as their own — which is what the Epic #2002 run hit on
|
|
326
|
+
// 2026-08-29, and only the co-timed `resolution-push-sent` (which does carry
|
|
327
|
+
// `worktreeId`) rescued the reading. A waiting push has no such partner.
|
|
328
|
+
//
|
|
329
|
+
// The key names match `resolution-push-notifier`'s context on purpose, so
|
|
330
|
+
// both halves of one episode grep together. `instanceId` resolves exactly as
|
|
331
|
+
// the episode dedup key above does, and is left absent — `JSON.stringify`
|
|
332
|
+
// drops `undefined` — rather than logged as an empty string when no producer
|
|
333
|
+
// named an instance.
|
|
320
334
|
const delivered = outcomes.filter(Boolean).length;
|
|
321
335
|
const failed = outcomes.length - delivered;
|
|
322
|
-
logger.info('push-fanout-complete', {
|
|
336
|
+
logger.info('push-fanout-complete', {
|
|
337
|
+
kind: event.kind,
|
|
338
|
+
worktreeId: event.worktreeId,
|
|
339
|
+
instanceId: event.instanceId ?? event.agentName,
|
|
340
|
+
delivered,
|
|
341
|
+
failed,
|
|
342
|
+
});
|
|
323
343
|
}
|
|
324
344
|
catch (err) {
|
|
325
345
|
logger.warn('push-fanout-error', {
|
|
@@ -39,19 +39,31 @@
|
|
|
39
39
|
* closes — so an install with nothing waiting has no timer, and one that never
|
|
40
40
|
* configured VAPID never even gets that far.
|
|
41
41
|
*
|
|
42
|
+
* ## Holding a wait that has not named itself
|
|
43
|
+
*
|
|
44
|
+
* The edge fires once, and for a dialog drawn between two probes it fires
|
|
45
|
+
* before anything on the pane can be classified — so #2156's `AskUserQuestion`
|
|
46
|
+
* arrived here as `unclassified` and was announced as "check the terminal"
|
|
47
|
+
* although the app could answer it. The kind is refreshed in place afterwards
|
|
48
|
+
* and that refresh is deliberately not an edge, so the fix is on this side:
|
|
49
|
+
* an unnamed wait is held for {@link CLASSIFICATION_GRACE_MS} and then sent
|
|
50
|
+
* under whatever the episode is called at that point. One notification either
|
|
51
|
+
* way — no correction push, and nothing at all if the wait ended meanwhile.
|
|
52
|
+
*
|
|
42
53
|
* Everything here is advisory: a failure must not disturb the status read that
|
|
43
54
|
* observed the edge (`emit` contains listener throws) nor the poller.
|
|
44
55
|
*
|
|
45
56
|
* @module lib/push/waiting-push-notifier
|
|
46
57
|
*/
|
|
47
58
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
-
exports.ESCALATION_TICK_MS = void 0;
|
|
59
|
+
exports.CLASSIFICATION_GRACE_MS = exports.ESCALATION_TICK_MS = void 0;
|
|
49
60
|
exports.handleWaitingTransition = handleWaitingTransition;
|
|
50
61
|
exports.runEscalationTick = runEscalationTick;
|
|
51
62
|
exports.startWaitingPushNotifier = startWaitingPushNotifier;
|
|
52
63
|
exports.stopWaitingPushNotifier = stopWaitingPushNotifier;
|
|
53
64
|
exports.isWaitingPushNotifierActive = isWaitingPushNotifierActive;
|
|
54
65
|
exports.pendingEscalationCount = pendingEscalationCount;
|
|
66
|
+
exports.heldWaitCount = heldWaitCount;
|
|
55
67
|
const auto_yes_state_1 = require("../../lib/auto-yes-state");
|
|
56
68
|
const db_instance_1 = require("../../lib/db/db-instance");
|
|
57
69
|
const worktree_db_1 = require("../../lib/db/worktree-db");
|
|
@@ -65,8 +77,33 @@ const vapid_1 = require("./vapid");
|
|
|
65
77
|
const logger = (0, logger_1.createLogger)('push/waiting-notifier');
|
|
66
78
|
/** How often outstanding waits are re-checked. Minute granularity is enough. */
|
|
67
79
|
exports.ESCALATION_TICK_MS = 60_000;
|
|
80
|
+
/**
|
|
81
|
+
* How long a wait that has not named itself yet is held before it notifies
|
|
82
|
+
* (Issue #2156).
|
|
83
|
+
*
|
|
84
|
+
* `AskUserQuestion` opens the episode before the pane carries anything the
|
|
85
|
+
* screen scraper can read, so the *first* classification of that wait is
|
|
86
|
+
* `unclassified` and the body would say "check the terminal" about a dialog the
|
|
87
|
+
* app can answer. `waiting-episode-state` refreshes the kind in place on the
|
|
88
|
+
* next probe and deliberately emits nothing for it (a wait that changes
|
|
89
|
+
* character is still one wait), so the notifier only ever saw the provisional
|
|
90
|
+
* verdict.
|
|
91
|
+
*
|
|
92
|
+
* Measured on the session in the Issue: the edge opened at 00:08:38.837 with no
|
|
93
|
+
* usable classification and the next status probe refined it to `prompt` at
|
|
94
|
+
* 00:08:44.863 — 6.03 s later; 8 s is that measurement plus one probe's jitter
|
|
95
|
+
* and nothing more, because the hold is silence on the phone and it is meant to
|
|
96
|
+
* buy exactly one reclassification.
|
|
97
|
+
*
|
|
98
|
+
* Only an unnamed wait pays it: `prompt` and `menu` are positive verdicts and
|
|
99
|
+
* still notify on the edge itself.
|
|
100
|
+
*/
|
|
101
|
+
exports.CLASSIFICATION_GRACE_MS = 8_000;
|
|
68
102
|
const pending = globalThis.__waitingPushPending ??
|
|
69
103
|
(globalThis.__waitingPushPending = new Map());
|
|
104
|
+
/** Composite key -> the timer holding that wait's first notification (#2156). */
|
|
105
|
+
const graceTimers = globalThis.__waitingPushGraceTimers ??
|
|
106
|
+
(globalThis.__waitingPushGraceTimers = new Map());
|
|
70
107
|
/**
|
|
71
108
|
* The worktree's display name, for the notification title.
|
|
72
109
|
*
|
|
@@ -109,6 +146,73 @@ async function sendWaitingPush(wait, escalated, now) {
|
|
|
109
146
|
});
|
|
110
147
|
}
|
|
111
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Whether this classification is still provisional (Issue #2156).
|
|
151
|
+
*
|
|
152
|
+
* `unclassified` is what `deriveWaitingKind` returns for a frame the scraper
|
|
153
|
+
* could not read at all, and a null kind is the same admission from a producer
|
|
154
|
+
* that passed none — both mean "waiting, but nobody has said what for" and both
|
|
155
|
+
* are the verdict that arrives first when a dialog is drawn between two probes.
|
|
156
|
+
* `prompt` and `menu` are positive readings of the pane and are taken at once.
|
|
157
|
+
*/
|
|
158
|
+
function isUnnamedWait(kind) {
|
|
159
|
+
return kind === null || kind === undefined || kind === 'unclassified';
|
|
160
|
+
}
|
|
161
|
+
/** Drop the hold on this wait without sending anything. */
|
|
162
|
+
function cancelGrace(key) {
|
|
163
|
+
const timer = graceTimers.get(key);
|
|
164
|
+
if (timer === undefined)
|
|
165
|
+
return;
|
|
166
|
+
clearTimeout(timer);
|
|
167
|
+
graceTimers.delete(key);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The Auto-Yes gate, then the fan-out.
|
|
171
|
+
*
|
|
172
|
+
* In that order because `shouldSendWaitingPush` records the episode at the
|
|
173
|
+
* moment it decides to send, so a notification dropped after the fan-out began
|
|
174
|
+
* would still consume the episode's one slot — see `prompt-push-gate`.
|
|
175
|
+
*/
|
|
176
|
+
function gateAndSend(wait, now) {
|
|
177
|
+
if ((0, prompt_push_gate_1.isPromptPushSuppressed)({
|
|
178
|
+
worktreeId: wait.worktreeId,
|
|
179
|
+
cliToolId: wait.cliToolId,
|
|
180
|
+
instanceId: wait.instanceId,
|
|
181
|
+
waitingSince: wait.since,
|
|
182
|
+
})) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
void sendWaitingPush(wait, false, now);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* The grace elapsed: send the held wait with whatever it is called *now*
|
|
189
|
+
* (Issue #2156).
|
|
190
|
+
*
|
|
191
|
+
* The episode store is the authority here for the same reason it is in
|
|
192
|
+
* {@link runEscalationTick}: it carries the classification every later probe
|
|
193
|
+
* refined, and its absence is the wait having ended. Nothing is sent in that
|
|
194
|
+
* case — a wait answered inside the grace never needed a notification, and
|
|
195
|
+
* dropping it is the direction #1999/#2000 asked for rather than a correction
|
|
196
|
+
* push chasing one that was already wrong.
|
|
197
|
+
*/
|
|
198
|
+
function releaseHeldWait(key) {
|
|
199
|
+
graceTimers.delete(key);
|
|
200
|
+
const held = pending.get(key);
|
|
201
|
+
// Gone means the closing edge dropped it, or a reminder already claimed it.
|
|
202
|
+
if (held === undefined)
|
|
203
|
+
return;
|
|
204
|
+
const episode = (0, waiting_episode_state_1.getWaitingEpisode)(held.worktreeId, held.cliToolId, held.instanceId);
|
|
205
|
+
if (episode === null || episode.since !== held.since) {
|
|
206
|
+
pending.delete(key);
|
|
207
|
+
stopEscalationTimerIfIdle();
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
// Written back so the reminder quotes the settled kind even if the episode is
|
|
211
|
+
// gone by the time it runs.
|
|
212
|
+
const settled = { ...held, kind: episode.kind };
|
|
213
|
+
pending.set(key, settled);
|
|
214
|
+
gateAndSend(settled, Date.now());
|
|
215
|
+
}
|
|
112
216
|
function startEscalationTimer() {
|
|
113
217
|
if (globalThis.__waitingPushEscalationTimer !== undefined)
|
|
114
218
|
return;
|
|
@@ -143,6 +247,8 @@ function handleWaitingTransition(transition) {
|
|
|
143
247
|
return;
|
|
144
248
|
const key = (0, auto_yes_state_1.buildCompositeKey)(transition.worktreeId, transition.cliToolId, transition.instanceId);
|
|
145
249
|
if (!transition.waiting || transition.since === null) {
|
|
250
|
+
// Issue #2156: a wait still inside its grace is answered, not notified.
|
|
251
|
+
cancelGrace(key);
|
|
146
252
|
pending.delete(key);
|
|
147
253
|
stopEscalationTimerIfIdle();
|
|
148
254
|
// Issue #2001: this is the moment the notification on every *other* device
|
|
@@ -180,15 +286,20 @@ function handleWaitingTransition(transition) {
|
|
|
180
286
|
// episode at the moment it decides to send.
|
|
181
287
|
pending.set(key, wait);
|
|
182
288
|
startEscalationTimer();
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
289
|
+
// Issue #2156: a wait nobody has named yet is held for one probe interval so
|
|
290
|
+
// it can notify under the kind it turns out to be, rather than under the
|
|
291
|
+
// placeholder it opened with. A named wait notifies on the edge, as before.
|
|
292
|
+
if (isUnnamedWait(wait.kind)) {
|
|
293
|
+
cancelGrace(key);
|
|
294
|
+
const timer = setTimeout(() => {
|
|
295
|
+
releaseHeldWait(key);
|
|
296
|
+
}, exports.CLASSIFICATION_GRACE_MS);
|
|
297
|
+
// Same reasoning as the escalation interval: never hold the process open.
|
|
298
|
+
timer.unref?.();
|
|
299
|
+
graceTimers.set(key, timer);
|
|
189
300
|
return;
|
|
190
301
|
}
|
|
191
|
-
|
|
302
|
+
gateAndSend(wait, transition.at);
|
|
192
303
|
}
|
|
193
304
|
/**
|
|
194
305
|
* Re-notify every wait that has outlived the threshold, once each.
|
|
@@ -267,6 +378,9 @@ function stopWaitingPushNotifier() {
|
|
|
267
378
|
existing();
|
|
268
379
|
globalThis.__waitingPushUnsubscribe = undefined;
|
|
269
380
|
}
|
|
381
|
+
for (const timer of graceTimers.values())
|
|
382
|
+
clearTimeout(timer);
|
|
383
|
+
graceTimers.clear();
|
|
270
384
|
pending.clear();
|
|
271
385
|
stopEscalationTimerIfIdle();
|
|
272
386
|
}
|
|
@@ -278,3 +392,7 @@ function isWaitingPushNotifierActive() {
|
|
|
278
392
|
function pendingEscalationCount() {
|
|
279
393
|
return pending.size;
|
|
280
394
|
}
|
|
395
|
+
/** How many waits are held waiting to be classified (#2156). Test seam. */
|
|
396
|
+
function heldWaitCount() {
|
|
397
|
+
return graceTimers.size;
|
|
398
|
+
}
|