commandmate 0.33.1 → 0.33.3
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 +307 -307
- package/.next/app-path-routes-manifest.json +28 -28
- package/.next/build-manifest.json +5 -5
- package/.next/diagnostics/framework.json +1 -1
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +15 -15
- package/.next/required-server-files.json +1 -2
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.js +1 -1
- package/.next/server/app/api/app/update-check/route.js.nft.json +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route.js +1 -1
- package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route.js +32 -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 +33 -2
- package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -1
- package/.next/server/app/api/capabilities/route.js.nft.json +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/route.js +1 -1
- package/.next/server/app/api/relays/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route.js +1 -1
- package/.next/server/app/api/skills/installations/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route.js +1 -1
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route.js +2 -2
- package/.next/server/app/api/worktrees/[id]/tasks/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +103 -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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page_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 +10 -10
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +28 -28
- package/.next/server/chunks/1068.js +1 -0
- package/.next/server/chunks/1210.js +1 -1
- package/.next/server/chunks/1331.js +2 -2
- package/.next/server/chunks/1366.js +5 -3
- package/.next/server/chunks/1501.js +6 -2
- package/.next/server/chunks/1886.js +2 -2
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/2839.js +1 -0
- package/.next/server/chunks/3123.js +1 -1
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3323.js +1 -0
- package/.next/server/chunks/3707.js +1 -1
- package/.next/server/chunks/3708.js +1 -1
- package/.next/server/chunks/4443.js +1 -1
- package/.next/server/chunks/5220.js +1 -1
- package/.next/server/chunks/595.js +2 -2
- package/.next/server/chunks/6130.js +1 -0
- package/.next/server/chunks/650.js +1 -0
- package/.next/server/chunks/6661.js +1 -1
- package/.next/server/chunks/6781.js +1 -0
- package/.next/server/chunks/6808.js +1 -0
- package/.next/server/chunks/7875.js +3 -3
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8918.js +107 -5
- package/.next/server/chunks/9553.js +1 -0
- package/.next/server/chunks/9627.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/server/src/middleware.js.map +1 -1
- package/.next/static/chunks/1255-7e5873f06b25e129.js +1 -0
- package/.next/static/chunks/{4718-2bc5cdf06573bf54.js → 4718-814f4ecfd7fcc513.js} +1 -1
- package/.next/static/chunks/6022-7a7d1760fc9814c7.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-3af707e74a75172b.js +1 -0
- package/.next/static/chunks/{main-6092074a0dc78280.js → main-ac91ed6e71380841.js} +1 -1
- package/.next/trace +13 -14
- package/dist/server/locales/en/worktree.json +9 -2
- package/dist/server/locales/ja/worktree.json +9 -2
- package/dist/server/src/lib/assistant-response-saver.js +168 -12
- package/dist/server/src/lib/cli-tools/vibe-local.js +10 -0
- package/dist/server/src/lib/hooks/hook-settings-generator.js +61 -1
- package/dist/server/src/lib/hooks/sources/antigravity/history.js +497 -27
- package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +103 -0
- package/dist/server/src/lib/hooks/sources/claude/history.js +29 -3
- package/dist/server/src/lib/hooks/sources/codex/history.js +29 -3
- package/dist/server/src/lib/hooks/sources/command-code/history.js +29 -3
- package/dist/server/src/lib/hooks/stop-history-capture.js +30 -4
- package/dist/server/src/lib/polling/response-checker.js +258 -9
- package/dist/server/src/lib/polling/response-poller-core.js +20 -0
- package/dist/server/src/lib/polling/structured-history-gate.js +94 -10
- package/dist/server/src/lib/response-cleaner.js +84 -0
- package/dist/server/src/lib/session/agent-session-lifecycle.js +31 -1
- package/dist/server/src/lib/session/session-generation-archive.js +194 -0
- package/dist/server/src/lib/tasks/contract-message.js +83 -9
- package/dist/server/src/lib/tasks/contract-parser.js +2 -0
- package/package.json +2 -2
- package/.next/server/chunks/153.js +0 -1
- package/.next/server/chunks/21.js +0 -1
- package/.next/server/chunks/3086.js +0 -1
- package/.next/server/chunks/3270.js +0 -1
- package/.next/server/chunks/3925.js +0 -1
- package/.next/server/chunks/4299.js +0 -1
- package/.next/server/chunks/5043.js +0 -1
- package/.next/server/chunks/6306.js +0 -1
- package/.next/server/chunks/6363.js +0 -1
- package/.next/server/chunks/6491.js +0 -103
- package/.next/server/chunks/6838.js +0 -1
- package/.next/server/chunks/7366.js +0 -5
- package/.next/server/chunks/7890.js +0 -1
- package/.next/server/chunks/8063.js +0 -32
- package/.next/server/chunks/8687.js +0 -1
- package/.next/static/chunks/1255-8cb587d9170b45ed.js +0 -1
- package/.next/static/chunks/6022-2fa0b5a82d4ce7b6.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-13ca0ba551fe5cfb.js +0 -1
- /package/.next/static/{9lgw9hA727UMyFhXryGWG → 9x6U1h52hH_r6pOsGwI_p}/_buildManifest.js +0 -0
- /package/.next/static/{9lgw9hA727UMyFhXryGWG → 9x6U1h52hH_r6pOsGwI_p}/_ssgManifest.js +0 -0
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/** Response checking and extraction logic for CLI tool polling (Issue #575 split from response-poller.ts). */
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.PENDING_SCRAPE_HOLD_MS = void 0;
|
|
4
5
|
exports.incompleteResult = incompleteResult;
|
|
5
6
|
exports.buildPromptExtractionResult = buildPromptExtractionResult;
|
|
6
7
|
exports.detectPromptOnCleanFrame = detectPromptOnCleanFrame;
|
|
7
8
|
exports.detectPromptWithOptions = detectPromptWithOptions;
|
|
8
9
|
exports.extractResponse = extractResponse;
|
|
10
|
+
exports.resetPendingScrapedResponses = resetPendingScrapedResponses;
|
|
11
|
+
exports.hasPendingScrapedResponse = hasPendingScrapedResponse;
|
|
12
|
+
exports.flushPendingScrapedResponse = flushPendingScrapedResponse;
|
|
9
13
|
exports.checkForResponse = checkForResponse;
|
|
10
14
|
const cli_session_1 = require("../../lib/session/cli-session");
|
|
11
15
|
const db_instance_1 = require("../../lib/db/db-instance");
|
|
@@ -30,6 +34,7 @@ const prompt_dedup_1 = require("./prompt-dedup");
|
|
|
30
34
|
const prompt_dedup_state_1 = require("./prompt-dedup-state");
|
|
31
35
|
const response_dedup_1 = require("./response-dedup");
|
|
32
36
|
const structured_history_gate_1 = require("./structured-history-gate");
|
|
37
|
+
const stop_history_capture_1 = require("../../lib/hooks/stop-history-capture");
|
|
33
38
|
const relay_triggers_1 = require("../../lib/relay/relay-triggers");
|
|
34
39
|
// Issue #2317 Phase D: while a human holds the pane's geometry, the frame is
|
|
35
40
|
// their terminal (44 rows), not the 1000-row canvas every rule below was
|
|
@@ -735,6 +740,176 @@ function extractResponse(output, lastCapturedLine, cliToolId, captureWindowLines
|
|
|
735
740
|
// ============================================================================
|
|
736
741
|
// checkForResponse (exported for response-poller-core.ts)
|
|
737
742
|
// ============================================================================
|
|
743
|
+
// ============================================================================
|
|
744
|
+
// The held scrape (Issue #2436)
|
|
745
|
+
// ============================================================================
|
|
746
|
+
/**
|
|
747
|
+
* How long a scraped reply is held while its transcript finishes closing.
|
|
748
|
+
*
|
|
749
|
+
* Derived from `STOP_TRANSCRIPT_DEFERRED_DELAYS_MS`, not spelled again: those
|
|
750
|
+
* are the instants the Stop receiver re-reads the transcript at after it has
|
|
751
|
+
* answered the agent (#2398), so their SUM is the moment after which nobody is
|
|
752
|
+
* still trying. Holding past it would be holding for a row that has no producer
|
|
753
|
+
* left; stopping short of it would race the producer that is still running.
|
|
754
|
+
*
|
|
755
|
+
* The measured gap this covers is under a second — codex 2026-09-08 appended
|
|
756
|
+
* `task_complete` ~700 ms after the frame went quiet — so the budget is roughly
|
|
757
|
+
* ten times the case it exists for, spent only on turns that ask for it.
|
|
758
|
+
*/
|
|
759
|
+
exports.PENDING_SCRAPE_HOLD_MS = stop_history_capture_1.STOP_TRANSCRIPT_DEFERRED_DELAYS_MS.reduce((total, delay) => total + delay, 0);
|
|
760
|
+
/**
|
|
761
|
+
* Held scrapes, by poller key.
|
|
762
|
+
*
|
|
763
|
+
* **Deliberately not in `./response-dedup`.** That module's two caches are
|
|
764
|
+
* cleared by `stopPollingByKey` — `clearResponseHashCache` is called from
|
|
765
|
+
* inside it — so a held reply parked beside them would be dropped by the very
|
|
766
|
+
* event that has to write it (Issue #2436, requirement B). It lives here, next
|
|
767
|
+
* to the code that fills it and the code that writes it out, and
|
|
768
|
+
* `flushPendingScrapedResponse` is what the poller calls before it clears
|
|
769
|
+
* anything.
|
|
770
|
+
*
|
|
771
|
+
* On `globalThis` for the reason every shared map in this subsystem is (#1736):
|
|
772
|
+
* under `next dev` the poller's bundle and each route's bundle would otherwise
|
|
773
|
+
* hold a private copy, and a held reply only one bundle can see is a lost one.
|
|
774
|
+
*/
|
|
775
|
+
const pendingScrapedResponses = (globalThis.__pendingScrapedResponses ??= new Map());
|
|
776
|
+
/** Forget every held scrape. Test seam. */
|
|
777
|
+
function resetPendingScrapedResponses() {
|
|
778
|
+
pendingScrapedResponses.clear();
|
|
779
|
+
}
|
|
780
|
+
/** Whether a scrape is being held for this poller key. Test seam / diagnostics. */
|
|
781
|
+
function hasPendingScrapedResponse(pollerKey) {
|
|
782
|
+
return pendingScrapedResponses.has(pollerKey);
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Hold this tick's scraped reply instead of writing it (Issue #2436).
|
|
786
|
+
*
|
|
787
|
+
* Called when the transcript reader has said `not_yet_closed`: the agent's own
|
|
788
|
+
* Markdown for this turn is coming, and writing the pane's copy now is what put
|
|
789
|
+
* 234,323 characters of prompt echo, intermediate output and footer into
|
|
790
|
+
* History beside the real answer.
|
|
791
|
+
*
|
|
792
|
+
* A second hold for the same key REPLACES the content and keeps the original
|
|
793
|
+
* deadline. Replaces, because a frame that moved on is a better copy of the
|
|
794
|
+
* same turn; keeps, because a pane that redraws every tick would otherwise push
|
|
795
|
+
* its own deadline forward forever and the hold would stop being bounded.
|
|
796
|
+
*/
|
|
797
|
+
function holdScrapedResponse(pollerKey, pending) {
|
|
798
|
+
const existing = pendingScrapedResponses.get(pollerKey);
|
|
799
|
+
if (existing) {
|
|
800
|
+
existing.content = pending.content;
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
pendingScrapedResponses.set(pollerKey, pending);
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* Drop a held scrape without writing it (Issue #2436).
|
|
807
|
+
*
|
|
808
|
+
* The one thing that justifies dropping it: the transcript reader has since
|
|
809
|
+
* written the turn as the agent's own Markdown, so the pane's copy is the
|
|
810
|
+
* duplicate this Issue exists to stop.
|
|
811
|
+
*/
|
|
812
|
+
function discardPendingScrapedResponse(pollerKey) {
|
|
813
|
+
pendingScrapedResponses.delete(pollerKey);
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Write a held scrape now, whatever the clock says (Issue #2436).
|
|
817
|
+
*
|
|
818
|
+
* Exported because `response-poller-core` calls it from `stopPollingByKey`,
|
|
819
|
+
* which is every way a polling cycle ends: an explicit stop, the session going
|
|
820
|
+
* away, `MAX_POLLING_DURATION`, and the restart that opens the NEXT turn. A
|
|
821
|
+
* held reply must not be able to outlive the cycle that holds it — the caches
|
|
822
|
+
* that key it are cleared in that same function, and a reply nobody writes is
|
|
823
|
+
* strictly worse than the duplicate row this Issue is trading against.
|
|
824
|
+
*
|
|
825
|
+
* **Deliberately bypasses `isDuplicateResponse`.** The hash for this content was
|
|
826
|
+
* registered by the tick that decided to hold it (the dedup guard's check is
|
|
827
|
+
* also its write), so a re-check here would answer "duplicate" for the reply
|
|
828
|
+
* that has never been saved. That is requirement A of the Issue in one line.
|
|
829
|
+
*
|
|
830
|
+
* Synchronous through the row: `better-sqlite3` is, and this runs on shutdown
|
|
831
|
+
* paths where an awaited continuation may never be reached. The Markdown
|
|
832
|
+
* conversation log is fired afterwards and not waited for, because it is a
|
|
833
|
+
* secondary record and the row is the one History reads.
|
|
834
|
+
*
|
|
835
|
+
* @param pollerKey - Poller key ("worktreeId:instanceId")
|
|
836
|
+
* @param reason - What ended the hold; logged, for the operator reading back
|
|
837
|
+
* @returns Whether a held reply was written
|
|
838
|
+
*/
|
|
839
|
+
function flushPendingScrapedResponse(pollerKey, reason) {
|
|
840
|
+
const pending = pendingScrapedResponses.get(pollerKey);
|
|
841
|
+
if (!pending)
|
|
842
|
+
return false;
|
|
843
|
+
pendingScrapedResponses.delete(pollerKey);
|
|
844
|
+
try {
|
|
845
|
+
const db = (0, db_instance_1.getDbInstance)();
|
|
846
|
+
const message = (0, db_1.createMessage)(db, {
|
|
847
|
+
worktreeId: pending.worktreeId,
|
|
848
|
+
role: 'assistant',
|
|
849
|
+
content: pending.content,
|
|
850
|
+
messageType: 'normal',
|
|
851
|
+
timestamp: pending.timestamp,
|
|
852
|
+
cliToolId: pending.cliToolId,
|
|
853
|
+
instanceId: pending.instanceId,
|
|
854
|
+
summary: pending.summary,
|
|
855
|
+
logFileName: pending.logFileName,
|
|
856
|
+
requestId: pending.requestId,
|
|
857
|
+
});
|
|
858
|
+
(0, ws_server_1.broadcastMessage)('message', { worktreeId: pending.worktreeId, message });
|
|
859
|
+
logger.info('pending-scrape-flushed', {
|
|
860
|
+
worktreeId: pending.worktreeId,
|
|
861
|
+
cliToolId: pending.cliToolId,
|
|
862
|
+
instanceId: pending.instanceId,
|
|
863
|
+
reason,
|
|
864
|
+
scrapedLength: pending.content.length,
|
|
865
|
+
heldForMs: Date.now() - pending.timestamp.getTime(),
|
|
866
|
+
});
|
|
867
|
+
void (0, conversation_logger_1.recordClaudeConversation)(db, pending.worktreeId, pending.content, pending.cliToolId).catch(() => { });
|
|
868
|
+
return true;
|
|
869
|
+
}
|
|
870
|
+
catch (error) {
|
|
871
|
+
logger.warn('pending-scrape-flush-failed', {
|
|
872
|
+
worktreeId: pending.worktreeId,
|
|
873
|
+
cliToolId: pending.cliToolId,
|
|
874
|
+
instanceId: pending.instanceId,
|
|
875
|
+
reason,
|
|
876
|
+
error: error instanceof Error ? error.message : String(error),
|
|
877
|
+
});
|
|
878
|
+
return false;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* End a hold whose deadline has passed, one way or the other (Issue #2436).
|
|
883
|
+
*
|
|
884
|
+
* Run at the top of every tick, because the tick that has to notice an expiry
|
|
885
|
+
* is very often one that returns early — a static frame yields no new lines for
|
|
886
|
+
* a scrollback tool and is a duplicate for an alternate-screen one, and neither
|
|
887
|
+
* of those paths reaches the save block at the bottom of `checkForResponse`.
|
|
888
|
+
*
|
|
889
|
+
* The reader is asked ONE more time before the row is written. By the deadline
|
|
890
|
+
* the throttled recheck (#2399) has usually already captured the turn and
|
|
891
|
+
* dropped the hold, but the two are not in step — the recheck is every third
|
|
892
|
+
* duplicate tick and this is a wall clock — and a last read costs one tail
|
|
893
|
+
* parse against writing a pane dump that is about to be superseded.
|
|
894
|
+
*/
|
|
895
|
+
async function settleExpiredPendingScrapedResponse(pollerKey) {
|
|
896
|
+
const pending = pendingScrapedResponses.get(pollerKey);
|
|
897
|
+
if (!pending || Date.now() < pending.expiresAt)
|
|
898
|
+
return;
|
|
899
|
+
const captured = await (0, structured_history_gate_1.captureStructuredHistoryTurn)(pending.worktreeId, pending.cliToolId, pending.instanceId, { worktreePath: pending.worktreePath, transcriptPathHint: pending.transcriptPathHint });
|
|
900
|
+
if (captured) {
|
|
901
|
+
discardPendingScrapedResponse(pollerKey);
|
|
902
|
+
(0, response_dedup_1.settleStructuredHistoryRecheck)(pollerKey);
|
|
903
|
+
logger.info('pending-scrape-superseded', {
|
|
904
|
+
worktreeId: pending.worktreeId,
|
|
905
|
+
cliToolId: pending.cliToolId,
|
|
906
|
+
instanceId: pending.instanceId,
|
|
907
|
+
heldForMs: Date.now() - pending.timestamp.getTime(),
|
|
908
|
+
});
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
flushPendingScrapedResponse(pollerKey, 'hold-expired');
|
|
912
|
+
}
|
|
738
913
|
/**
|
|
739
914
|
* Record what the structured writers said about this turn, for the ticks that
|
|
740
915
|
* will not get to ask (Issue #2399).
|
|
@@ -784,9 +959,20 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
784
959
|
const running = await (0, cli_session_1.isSessionRunning)(worktreeId, cliToolId, instanceId);
|
|
785
960
|
if (!running) {
|
|
786
961
|
logger.info('session-not-running');
|
|
962
|
+
// `stopPolling` is what confirms a held scrape here; see
|
|
963
|
+
// `flushPendingScrapedResponse` and `stopPollingByKey`. Requirement B of
|
|
964
|
+
// Issue #2436: this return is ~300 lines above the save path, so a hold
|
|
965
|
+
// released only down there would never be released at all.
|
|
787
966
|
(0, response_poller_core_1.stopPolling)(worktreeId, cliToolId, instanceId);
|
|
788
967
|
return false;
|
|
789
968
|
}
|
|
969
|
+
const pollerKey = (0, response_poller_core_1.getPollerKey)(worktreeId, cliToolId, instanceId);
|
|
970
|
+
// Issue #2436: a scrape held by an earlier tick, whose transcript has now
|
|
971
|
+
// had its whole budget to close. Ahead of everything below because most
|
|
972
|
+
// ticks of a finished turn never reach the save path — a static frame is a
|
|
973
|
+
// duplicate for an alternate-screen tool and yields no new lines for a
|
|
974
|
+
// scrollback one, and both of those return early.
|
|
975
|
+
await settleExpiredPendingScrapedResponse(pollerKey);
|
|
790
976
|
// Issue #2317 Phase D: is a human reading this pane at their own terminal
|
|
791
977
|
// size right now, and did they just stop?
|
|
792
978
|
//
|
|
@@ -831,7 +1017,6 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
831
1017
|
// Layer 2: Accumulate TUI content for full-screen TUI tools, so a turn that
|
|
832
1018
|
// outgrows the alternate-screen pane keeps the head that has scrolled away.
|
|
833
1019
|
if (cliToolId === 'opencode' || cliToolId === 'copilot') {
|
|
834
|
-
const pollerKey = (0, response_poller_core_1.getPollerKey)(worktreeId, cliToolId, instanceId);
|
|
835
1020
|
// Issue #1911: opencode is accumulated from the CURRENT TURN'S REGION
|
|
836
1021
|
// rather than the whole frame. Feeding the raw pane seeded the accumulator
|
|
837
1022
|
// with the previous turn's transcript, the echoed prompt and the bottom
|
|
@@ -885,7 +1070,6 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
885
1070
|
if (promptDetection.isPrompt) {
|
|
886
1071
|
// Issue #565: Content hash-based duplicate prompt prevention
|
|
887
1072
|
const promptContent = promptDetection.rawContent || promptDetection.cleanContent;
|
|
888
|
-
const pollerKey = (0, response_poller_core_1.getPollerKey)(worktreeId, cliToolId, instanceId);
|
|
889
1073
|
const normalizedForDedup = (0, prompt_dedup_1.normalizePromptForDedup)(promptContent, cliToolId);
|
|
890
1074
|
if ((0, prompt_dedup_1.isDuplicatePrompt)(pollerKey, normalizedForDedup)) {
|
|
891
1075
|
// Issue #1695: the log line below is invisible to `commandmate capture
|
|
@@ -995,7 +1179,6 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
995
1179
|
cleanedResponse = (0, response_cleaner_1.cleanClaudeResponse)(result.response);
|
|
996
1180
|
}
|
|
997
1181
|
else if (cliToolId === 'copilot') {
|
|
998
|
-
const pollerKey = (0, response_poller_core_1.getPollerKey)(worktreeId, cliToolId, instanceId);
|
|
999
1182
|
const accumulatedContent = (0, tui_accumulator_1.getAccumulatedContent)(pollerKey);
|
|
1000
1183
|
const sourceContent = accumulatedContent || result.response;
|
|
1001
1184
|
cleanedResponse = (0, response_cleaner_1.cleanCopilotResponse)(sourceContent);
|
|
@@ -1003,7 +1186,6 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
1003
1186
|
(0, tui_accumulator_1.clearTuiAccumulator)(pollerKey);
|
|
1004
1187
|
}
|
|
1005
1188
|
else if (cliToolId === 'opencode') {
|
|
1006
|
-
const pollerKey = (0, response_poller_core_1.getPollerKey)(worktreeId, cliToolId, instanceId);
|
|
1007
1189
|
// Issue #1911 defect 3: opencode wrote to the Layer-2 accumulator but never
|
|
1008
1190
|
// read it, so any turn longer than the pane was saved without its head.
|
|
1009
1191
|
//
|
|
@@ -1042,7 +1224,6 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
1042
1224
|
// Without this the disabled cursor would leave nothing suppressing re-saves and
|
|
1043
1225
|
// the poller would append the same finished reply every 2 s.
|
|
1044
1226
|
if (!lineCountIsCursor) {
|
|
1045
|
-
const pollerKey = (0, response_poller_core_1.getPollerKey)(worktreeId, cliToolId, instanceId);
|
|
1046
1227
|
if ((0, response_dedup_1.isDuplicateResponse)(pollerKey, cleanedResponse)) {
|
|
1047
1228
|
// Issue #1695: this branch used to drop the response silently — the
|
|
1048
1229
|
// prompt-side guard above has logged its skip since #565, this one
|
|
@@ -1092,6 +1273,16 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
1092
1273
|
// is neither. Two rows for one turn is the failure this trades for, and
|
|
1093
1274
|
// #2401 has already stopped the junk one being picked as a relay's
|
|
1094
1275
|
// answer.
|
|
1276
|
+
//
|
|
1277
|
+
// Issue #2436 narrowed what that trade costs, without changing the
|
|
1278
|
+
// decision above. The row this skip cannot retract is now only ever one
|
|
1279
|
+
// the poller had no reason to hold: a turn whose reader said
|
|
1280
|
+
// `not_yet_closed` is held at the save path below rather than written,
|
|
1281
|
+
// so on the ordinary codex turn there is no earlier row here to regret.
|
|
1282
|
+
// What remains is the case the three reasons above are actually about —
|
|
1283
|
+
// a scrape written when the reader could tell us nothing, and a
|
|
1284
|
+
// transcript that closed later anyway — and for that the row stays,
|
|
1285
|
+
// folded rather than deleted on the chat surface (`ChatMessageBubble`).
|
|
1095
1286
|
if ((0, response_dedup_1.claimStructuredHistoryRecheck)(pollerKey)) {
|
|
1096
1287
|
const recaptured = await (0, structured_history_gate_1.captureStructuredHistoryTurn)(worktreeId, cliToolId, instanceId, {
|
|
1097
1288
|
worktreePath: worktree.path,
|
|
@@ -1099,6 +1290,11 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
1099
1290
|
});
|
|
1100
1291
|
if (recaptured) {
|
|
1101
1292
|
(0, response_dedup_1.settleStructuredHistoryRecheck)(pollerKey);
|
|
1293
|
+
// Issue #2436: the turn is now the agent's own Markdown, so a
|
|
1294
|
+
// scrape held for it is exactly the second row this Issue exists
|
|
1295
|
+
// to stop. Dropped, not written — the only case where dropping a
|
|
1296
|
+
// held reply loses nothing.
|
|
1297
|
+
discardPendingScrapedResponse(pollerKey);
|
|
1102
1298
|
logger.info('structured-history-recheck-captured', {
|
|
1103
1299
|
worktreeId,
|
|
1104
1300
|
cliToolId,
|
|
@@ -1132,18 +1328,24 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
1132
1328
|
// Markdown and answers true, or answers false and leaves the scrape below to
|
|
1133
1329
|
// be the only record. `||` and not `&&`: the two are different tools'
|
|
1134
1330
|
// answers to the same question, and each one is false for the other's tool.
|
|
1331
|
+
//
|
|
1332
|
+
// Issue #2436 adds the third answer. `captureReport.outcome` distinguishes
|
|
1333
|
+
// "the agent has not closed this turn yet" from "there is nothing to read
|
|
1334
|
+
// here", which the boolean could not: both arrived as `false`, and `false`
|
|
1335
|
+
// meant "save the pane's copy". See {@link StructuredHistoryCaptureOutcome}.
|
|
1336
|
+
const captureReport = {};
|
|
1135
1337
|
const structuredHistoryLive = (0, structured_history_gate_1.isStructuredHistoryWriterLive)(worktreeId, cliToolId, instanceId) ||
|
|
1136
1338
|
(await (0, structured_history_gate_1.captureStructuredHistoryTurn)(worktreeId, cliToolId, instanceId, {
|
|
1137
1339
|
worktreePath: worktree.path,
|
|
1138
1340
|
transcriptPathHint: claudeMetadata?.logFilePath ?? null,
|
|
1139
|
-
}));
|
|
1341
|
+
}, captureReport));
|
|
1140
1342
|
// Issue #2399: remember which way that went, because the next tick may not
|
|
1141
1343
|
// get here. A `false` is the reader saying "not yet, or not mine", and the
|
|
1142
1344
|
// dedup guard above turns every following poll of the same static frame into
|
|
1143
1345
|
// a return — so unless the fact is written down now, the ask never happens
|
|
1144
1346
|
// again. A `true` settles it: the turn is recorded and there is nothing left
|
|
1145
1347
|
// to re-ask about.
|
|
1146
|
-
markOrSettleStructuredHistoryRecheck(
|
|
1348
|
+
markOrSettleStructuredHistoryRecheck(pollerKey, structuredHistoryLive);
|
|
1147
1349
|
// Issue #2317 Phase D: the scrape is dropped while the geometry is
|
|
1148
1350
|
// delegated, and the transcript capture above is what makes that safe.
|
|
1149
1351
|
//
|
|
@@ -1161,8 +1363,20 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
1161
1363
|
// deliberate trade: a missing row is recoverable, a truncated reply saved as
|
|
1162
1364
|
// the agent's answer is not.
|
|
1163
1365
|
const suppressScrapedHistory = structuredHistoryLive || delegation.delegated;
|
|
1366
|
+
// Issue #2436: not suppressed — HELD. The reader has read the transcript,
|
|
1367
|
+
// found the newest turn still open and said so, which means the agent's own
|
|
1368
|
+
// Markdown for this turn is on its way. Writing the pane's copy now is what
|
|
1369
|
+
// put a 234,323-character dump of prompt echo, intermediate output and
|
|
1370
|
+
// footer into History beside the real answer, and #2399 explicitly accepted
|
|
1371
|
+
// that trade because the boolean it had could not tell "not yet" from
|
|
1372
|
+
// "never". It can now.
|
|
1373
|
+
//
|
|
1374
|
+
// Everything else this tick does still happens: the cursor advances, the
|
|
1375
|
+
// prompts are marked answered, the waiting episode closes, the push goes
|
|
1376
|
+
// out. Only the two writes that RECORD THE REPLY wait.
|
|
1377
|
+
const holdScrapedHistory = !suppressScrapedHistory && captureReport.outcome === 'not_yet_closed';
|
|
1164
1378
|
// Create Markdown log file for the conversation pair
|
|
1165
|
-
if (cleanedResponse && !suppressScrapedHistory) {
|
|
1379
|
+
if (cleanedResponse && !suppressScrapedHistory && !holdScrapedHistory) {
|
|
1166
1380
|
await (0, conversation_logger_1.recordClaudeConversation)(db, worktreeId, cleanedResponse, cliToolId);
|
|
1167
1381
|
}
|
|
1168
1382
|
// Mark any pending prompts as answered
|
|
@@ -1183,7 +1397,38 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
1183
1397
|
// are not byte-comparable — the pane's copy is hard-wrapped at the pane
|
|
1184
1398
|
// width and gutter-prefixed, so no content check could ever recognise them
|
|
1185
1399
|
// as the same reply.
|
|
1186
|
-
if (
|
|
1400
|
+
if (holdScrapedHistory) {
|
|
1401
|
+
holdScrapedResponse(pollerKey, {
|
|
1402
|
+
worktreeId,
|
|
1403
|
+
cliToolId,
|
|
1404
|
+
instanceId: resolvedInstanceId,
|
|
1405
|
+
content: cleanedResponse,
|
|
1406
|
+
// The instant the turn was JUDGED finished, not the instant the row is
|
|
1407
|
+
// written. History sorts on this, and a row dated at the end of the
|
|
1408
|
+
// hold would sort under the NEXT turn's prompt.
|
|
1409
|
+
timestamp: new Date(),
|
|
1410
|
+
summary: claudeMetadata?.summary,
|
|
1411
|
+
logFileName: claudeMetadata?.logFileName,
|
|
1412
|
+
requestId: claudeMetadata?.requestId,
|
|
1413
|
+
worktreePath: worktree.path,
|
|
1414
|
+
transcriptPathHint: claudeMetadata?.logFilePath ?? null,
|
|
1415
|
+
expiresAt: Date.now() + exports.PENDING_SCRAPE_HOLD_MS,
|
|
1416
|
+
});
|
|
1417
|
+
logger.info('structured-history-scrape-held', {
|
|
1418
|
+
worktreeId,
|
|
1419
|
+
cliToolId,
|
|
1420
|
+
instanceId: resolvedInstanceId,
|
|
1421
|
+
scrapedLength: cleanedResponse.length,
|
|
1422
|
+
holdMs: exports.PENDING_SCRAPE_HOLD_MS,
|
|
1423
|
+
});
|
|
1424
|
+
// The completion edge is announced HERE and not at the flush, because the
|
|
1425
|
+
// turn finished now. A relay waiting on this session gets #2401's grace
|
|
1426
|
+
// window to find a turn-keyed row, which is exactly the row the hold is
|
|
1427
|
+
// waiting for; delaying the announcement by the hold would delay every
|
|
1428
|
+
// delivery by it too.
|
|
1429
|
+
(0, relay_triggers_1.onRelayTurnCompleted)(worktreeId, cliToolId, resolvedInstanceId, false);
|
|
1430
|
+
}
|
|
1431
|
+
else if (!suppressScrapedHistory) {
|
|
1187
1432
|
// Create new CLI tool message in database
|
|
1188
1433
|
const message = (0, db_1.createMessage)(db, {
|
|
1189
1434
|
worktreeId,
|
|
@@ -1209,6 +1454,10 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
|
|
|
1209
1454
|
(0, relay_triggers_1.onRelayTurnCompleted)(worktreeId, cliToolId, resolvedInstanceId, false);
|
|
1210
1455
|
}
|
|
1211
1456
|
else {
|
|
1457
|
+
// Issue #2436: a hold from an earlier tick of this same turn is now moot
|
|
1458
|
+
// — the row it was waiting for exists.
|
|
1459
|
+
if (structuredHistoryLive)
|
|
1460
|
+
discardPendingScrapedResponse(pollerKey);
|
|
1212
1461
|
logger.info('structured-history-scrape-suppressed', {
|
|
1213
1462
|
worktreeId,
|
|
1214
1463
|
cliToolId,
|
|
@@ -365,6 +365,26 @@ function stopPollingByKey(pollerKey, options = {}) {
|
|
|
365
365
|
});
|
|
366
366
|
return;
|
|
367
367
|
}
|
|
368
|
+
// Issue #2436: a scraped reply this cycle decided to HOLD — because the
|
|
369
|
+
// agent's transcript had not closed the turn yet — is confirmed here, before
|
|
370
|
+
// anything that keys it is dropped. Every way a cycle ends comes through this
|
|
371
|
+
// function: an explicit stop, `checkForResponse` finding the session gone,
|
|
372
|
+
// `MAX_POLLING_DURATION`, and the restart that opens the next turn. A hold
|
|
373
|
+
// that outlived its cycle would be a reply nobody ever writes, which is worse
|
|
374
|
+
// than the duplicate row the hold is trading against.
|
|
375
|
+
//
|
|
376
|
+
// Ahead of `clearResponseHashCache` below, and that ordering is the whole
|
|
377
|
+
// reason the held reply does not live in `./response-dedup` beside the hash:
|
|
378
|
+
// it would be cleared by the same call that has to write it.
|
|
379
|
+
//
|
|
380
|
+
// `resume` is the one exception, and for the same reason the response hash
|
|
381
|
+
// survives it: the cycle is not ending, it is being picked up where a prompt
|
|
382
|
+
// paused it, and the turn the hold belongs to is still the current one. The
|
|
383
|
+
// hold stays bounded regardless — the first tick of the resumed chain runs
|
|
384
|
+
// `settleExpiredPendingScrapedResponse`, and by then the deadline has almost
|
|
385
|
+
// certainly passed.
|
|
386
|
+
if (!options.resume)
|
|
387
|
+
(0, response_checker_1.flushPendingScrapedResponse)(pollerKey, 'poller-stopped');
|
|
368
388
|
const owner = coordinator.owners.get(pollerKey);
|
|
369
389
|
// The live owner stopping itself from inside its own tick. Identity, not key
|
|
370
390
|
// equality: a stale generation with the same key was turned away above.
|
|
@@ -118,9 +118,41 @@ const logger = (0, logger_1.createLogger)('lib/polling/structured-history-gate')
|
|
|
118
118
|
* can see is not a lock.
|
|
119
119
|
*/
|
|
120
120
|
const captureQueue = (globalThis.__structuredHistoryCaptureQueue ??= new Map());
|
|
121
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* The last completion each instance was announced for (Issue #2443).
|
|
123
|
+
*
|
|
124
|
+
* Keyed by the same triple as {@link captureQueue}, holding whatever
|
|
125
|
+
* `StructuredHistoryCaptureReport.completionKey` the reader minted. Its only job
|
|
126
|
+
* is to make the completion edge an *edge*: the poller re-reads a finished turn
|
|
127
|
+
* every couple of seconds, and #2443 forbids adding a path that re-delivers a
|
|
128
|
+
* body somebody already has.
|
|
129
|
+
*
|
|
130
|
+
* On `globalThis` for the reason {@link captureQueue} is, and in memory for the
|
|
131
|
+
* reason `session/agent-event-state` gives: the value describes a live session,
|
|
132
|
+
* and a restart that forgets it costs at most one extra announcement into a
|
|
133
|
+
* relay whose own stash guard already refuses a second payload.
|
|
134
|
+
*/
|
|
135
|
+
const announcedCompletions = (globalThis.__structuredHistoryAnnouncedCompletions ??= new Map());
|
|
136
|
+
/** Forget every instance's in-flight capture and announced completion. Test seam. */
|
|
122
137
|
function resetStructuredHistoryCaptureQueue() {
|
|
123
138
|
captureQueue.clear();
|
|
139
|
+
announcedCompletions.clear();
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Whether this completion has already been announced for this instance (#2443).
|
|
143
|
+
*
|
|
144
|
+
* A reader that minted no key is always announced — the pre-#2443 behaviour, and
|
|
145
|
+
* the behaviour claude, codex and command-code keep. Records the key as a side
|
|
146
|
+
* effect when the answer is "no", because the two steps must not be separable:
|
|
147
|
+
* an announcement that forgot to record would repeat on the next poll.
|
|
148
|
+
*/
|
|
149
|
+
function claimCompletionAnnouncement(key, completionKey) {
|
|
150
|
+
if (completionKey === undefined)
|
|
151
|
+
return true;
|
|
152
|
+
if (announcedCompletions.get(key) === completionKey)
|
|
153
|
+
return false;
|
|
154
|
+
announcedCompletions.set(key, completionKey);
|
|
155
|
+
return true;
|
|
124
156
|
}
|
|
125
157
|
/** The queue key; the same triple `buildCompositeKey` spells everywhere else. */
|
|
126
158
|
function captureKeyOf(worktreeId, cliToolId, instanceId) {
|
|
@@ -161,19 +193,19 @@ function serializePerInstance(key, work) {
|
|
|
161
193
|
*/
|
|
162
194
|
const PULL_TRANSCRIPT_READERS = {
|
|
163
195
|
[tool_id_1.CLAUDE_CLI_TOOL_ID]: {
|
|
164
|
-
capture: (target, capture) => (0, history_1.captureClaudeTranscriptTurn)(target, capture),
|
|
196
|
+
capture: (target, capture, report) => (0, history_1.captureClaudeTranscriptTurn)(target, capture, report),
|
|
165
197
|
locate: (target, capture) => (0, history_1.resolveClaudeTranscriptPath)(target, capture),
|
|
166
198
|
},
|
|
167
199
|
[tool_id_2.CODEX_CLI_TOOL_ID]: {
|
|
168
|
-
capture: (target, capture) => (0, history_2.captureCodexTranscriptTurn)(target, capture),
|
|
200
|
+
capture: (target, capture, report) => (0, history_2.captureCodexTranscriptTurn)(target, capture, report),
|
|
169
201
|
locate: (target, capture) => (0, history_2.resolveCodexTranscriptPath)(target, capture),
|
|
170
202
|
},
|
|
171
203
|
[tool_id_3.ANTIGRAVITY_CLI_TOOL_ID]: {
|
|
172
|
-
capture: (target, capture) => (0, history_3.captureAntigravityTranscriptTurn)(target, capture),
|
|
204
|
+
capture: (target, capture, report) => (0, history_3.captureAntigravityTranscriptTurn)(target, capture, report),
|
|
173
205
|
locate: (target, capture) => (0, history_3.resolveAntigravityTranscriptPath)(target, capture),
|
|
174
206
|
},
|
|
175
207
|
[tool_id_4.COMMAND_CODE_CLI_TOOL_ID]: {
|
|
176
|
-
capture: (target, capture) => (0, history_4.captureCommandCodeTranscriptTurn)(target, capture),
|
|
208
|
+
capture: (target, capture, report) => (0, history_4.captureCommandCodeTranscriptTurn)(target, capture, report),
|
|
177
209
|
locate: (target, capture) => (0, history_4.resolveCommandCodeTranscriptPath)(target, capture),
|
|
178
210
|
},
|
|
179
211
|
};
|
|
@@ -267,12 +299,23 @@ function isStructuredHistoryWriterLive(worktreeId, cliToolId, instanceId) {
|
|
|
267
299
|
* not: this runs inside the poller's save path, and an exception here would cost
|
|
268
300
|
* the scraped reply as well as the structured one.
|
|
269
301
|
*
|
|
302
|
+
* Since Issue #2436 the `false` can be asked to explain itself: pass a
|
|
303
|
+
* {@link StructuredHistoryCaptureReport} and `outcome` says whether the turn is
|
|
304
|
+
* merely still open — the row is coming, and a caller holding the pane's copy
|
|
305
|
+
* should wait — or whether nothing will ever be written for it. The boolean is
|
|
306
|
+
* unchanged in meaning and in value; see
|
|
307
|
+
* {@link StructuredHistoryCaptureOutcome} for why the third value is reported
|
|
308
|
+
* beside it rather than in it.
|
|
309
|
+
*
|
|
270
310
|
* @param worktreeId - The worktree
|
|
271
311
|
* @param cliToolId - The tool driving the pane
|
|
272
312
|
* @param instanceId - The agent instance; defaults to the primary
|
|
273
313
|
* @param capture - Where to look; see {@link StructuredHistoryCapture}
|
|
314
|
+
* @param report - Optional out-parameter; see {@link StructuredHistoryCaptureReport}
|
|
274
315
|
*/
|
|
275
|
-
async function captureStructuredHistoryTurn(worktreeId, cliToolId, instanceId, capture) {
|
|
316
|
+
async function captureStructuredHistoryTurn(worktreeId, cliToolId, instanceId, capture, report) {
|
|
317
|
+
if (report)
|
|
318
|
+
report.outcome = 'unavailable';
|
|
276
319
|
if (!isPullTranscriptHistory(cliToolId))
|
|
277
320
|
return false;
|
|
278
321
|
const reader = PULL_TRANSCRIPT_READERS[cliToolId];
|
|
@@ -285,9 +328,25 @@ async function captureStructuredHistoryTurn(worktreeId, cliToolId, instanceId, c
|
|
|
285
328
|
return false;
|
|
286
329
|
}
|
|
287
330
|
const resolvedInstanceId = instanceId ?? cliToolId;
|
|
288
|
-
|
|
331
|
+
const captureKey = captureKeyOf(worktreeId, cliToolId, resolvedInstanceId);
|
|
332
|
+
return serializePerInstance(captureKey, async () => {
|
|
333
|
+
// The reader's own report, kept local and copied out below: `report` is
|
|
334
|
+
// the caller's object and must end up holding one verdict, not whatever
|
|
335
|
+
// the last reader to touch it happened to leave there.
|
|
336
|
+
const readerReport = {};
|
|
289
337
|
try {
|
|
290
|
-
const captured = await reader.capture({ worktreeId, cliToolId, instanceId: resolvedInstanceId }, capture);
|
|
338
|
+
const captured = await reader.capture({ worktreeId, cliToolId, instanceId: resolvedInstanceId }, capture, readerReport);
|
|
339
|
+
// Issue #2443: absent means `settled`, which is what leaves the three
|
|
340
|
+
// readers that have a turn-closing record exactly where they were.
|
|
341
|
+
const completion = readerReport.completion ?? 'settled';
|
|
342
|
+
if (report) {
|
|
343
|
+
// A reader that says nothing is read as `unavailable` — the pre-#2436
|
|
344
|
+
// behaviour, and the safe direction: the scraper keeps the turn.
|
|
345
|
+
report.outcome = captured ? 'captured' : readerReport.outcome ?? 'unavailable';
|
|
346
|
+
report.completion = completion;
|
|
347
|
+
report.completionKey = readerReport.completionKey;
|
|
348
|
+
report.completionReason = readerReport.completionReason;
|
|
349
|
+
}
|
|
291
350
|
// Issue #2377: the moment a relay is waiting for. This is the single
|
|
292
351
|
// point BOTH triggers of a pull capture pass through — the poller's save
|
|
293
352
|
// path and the Stop hook receiver — which is why the relay needs one
|
|
@@ -297,8 +356,33 @@ async function captureStructuredHistoryTurn(worktreeId, cliToolId, instanceId, c
|
|
|
297
356
|
// Announced only when the capture actually wrote something: a `false`
|
|
298
357
|
// means the scraper is still the writer for this turn, and the poller's
|
|
299
358
|
// own call below will announce it.
|
|
300
|
-
|
|
301
|
-
|
|
359
|
+
//
|
|
360
|
+
// Issue #2443 adds the second condition, and it is the whole Issue.
|
|
361
|
+
// `captured` means History holds the newest turn; it does **not** mean
|
|
362
|
+
// the agent is finished with it, because antigravity has no record that
|
|
363
|
+
// closes a turn and an interim report is saved under the same key the
|
|
364
|
+
// conclusion will land on. Announcing here would hand a relay the
|
|
365
|
+
// interim body as the answer, and `broadcastMessage('message_updated',
|
|
366
|
+
// …)` — the repair #2438 added — does not take a delivered message
|
|
367
|
+
// back. So a provisional capture announces nothing at all; the relay
|
|
368
|
+
// keeps waiting on the deadline it already has, and the settled capture
|
|
369
|
+
// that follows announces the finished body.
|
|
370
|
+
if (captured && completion === 'settled') {
|
|
371
|
+
if (claimCompletionAnnouncement(captureKey, readerReport.completionKey)) {
|
|
372
|
+
(0, relay_triggers_1.onRelayTurnCompleted)(worktreeId, cliToolId, resolvedInstanceId, true);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
else if (captured) {
|
|
376
|
+
logger.info('structured-history-capture-provisional', {
|
|
377
|
+
worktreeId,
|
|
378
|
+
cliToolId,
|
|
379
|
+
instanceId: resolvedInstanceId,
|
|
380
|
+
// The reader's own word for what is missing; see
|
|
381
|
+
// `AntigravityTurnCompletionReason`. This is the line #2443 asks for
|
|
382
|
+
// — the reason left on the relay's waiting path.
|
|
383
|
+
reason: readerReport.completionReason ?? 'unknown',
|
|
384
|
+
});
|
|
385
|
+
}
|
|
302
386
|
return captured;
|
|
303
387
|
}
|
|
304
388
|
catch (error) {
|