commandmate 0.30.0 → 0.30.2
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 +158 -158
- package/.next/app-path-routes-manifest.json +34 -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/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.js +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route.js +1 -1
- package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route.js +2 -2
- package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/terminal/route.js +2 -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.nft.json +1 -1
- package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js +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/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.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.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.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.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.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js.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 +12 -12
- 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 +34 -34
- package/.next/server/chunks/1058.js +1 -1
- 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/3099.js +5 -0
- package/.next/server/chunks/5017.js +1 -1
- package/.next/server/chunks/5043.js +1 -0
- package/.next/server/chunks/552.js +25 -0
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6894.js +1 -1
- package/.next/server/chunks/9696.js +2 -2
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{6381-28d0e95620aa018e.js → 6381-147dde2a967e9458.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/page-2f73d69187936627.js +1 -0
- package/.next/static/css/23f9c40ecc458c77.css +1 -0
- package/.next/trace +13 -13
- package/dist/server/src/lib/history/user-turn-recorder.js +9 -4
- package/dist/server/src/lib/hooks/agent-event-service.js +40 -6
- package/dist/server/src/lib/hooks/sources/antigravity/history.js +125 -18
- package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +39 -0
- package/dist/server/src/lib/hooks/sources/claude/history.js +312 -21
- package/dist/server/src/lib/hooks/sources/claude/transcript.js +175 -13
- package/dist/server/src/lib/hooks/sources/codex/history.js +100 -13
- package/dist/server/src/lib/hooks/stop-history-capture.js +194 -0
- package/dist/server/src/lib/polling/response-checker.js +43 -3
- package/dist/server/src/lib/polling/structured-history-gate.js +131 -6
- package/dist/server/src/lib/session/current-output-builder.js +118 -16
- package/package.json +1 -1
- package/.next/server/chunks/2827.js +0 -29
- package/.next/server/chunks/6781.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-d48b95ed554bcd13.js +0 -1
- package/.next/static/css/61e10d4b1b11b193.css +0 -1
- /package/.next/static/{7K0XXFu_ty4wRSkl4X21E → QXxQbXWoo7ldUyOcv7PCZ}/_buildManifest.js +0 -0
- /package/.next/static/{7K0XXFu_ty4wRSkl4X21E → QXxQbXWoo7ldUyOcv7PCZ}/_ssgManifest.js +0 -0
|
@@ -148,8 +148,9 @@ function describe(target) {
|
|
|
148
148
|
* re-read of the log and a `/clear`.
|
|
149
149
|
* @param content - The prompt, as the agent recorded it
|
|
150
150
|
* @param timestampMs - When the agent says it was prompted, epoch ms
|
|
151
|
+
* @param options - See {@link RecordUserTurnOptions}; the defaults are #2196's
|
|
151
152
|
*/
|
|
152
|
-
async function recordUserTurn(target, key, content, timestampMs) {
|
|
153
|
+
async function recordUserTurn(target, key, content, timestampMs, options = {}) {
|
|
153
154
|
const instanceId = target.instanceId ?? target.cliToolId;
|
|
154
155
|
const normalized = normalizeUserTurnContent(content);
|
|
155
156
|
if (key.length === 0 || normalized.length === 0) {
|
|
@@ -171,7 +172,7 @@ async function recordUserTurn(target, key, content, timestampMs) {
|
|
|
171
172
|
};
|
|
172
173
|
}
|
|
173
174
|
const at = timestampMs > 0 ? timestampMs : Date.now();
|
|
174
|
-
const adopted = adoptExistingRow(chatDb, db, target, instanceId, key, normalized, at);
|
|
175
|
+
const adopted = adoptExistingRow(chatDb, db, target, instanceId, key, normalized, at, options);
|
|
175
176
|
if (adopted)
|
|
176
177
|
return adopted;
|
|
177
178
|
const message = chatDb.createMessage(db, {
|
|
@@ -217,13 +218,17 @@ async function recordUserTurn(target, key, content, timestampMs) {
|
|
|
217
218
|
*
|
|
218
219
|
* @returns The claimed row, or null when nothing here belongs to this prompt
|
|
219
220
|
*/
|
|
220
|
-
function adoptExistingRow(chatDb, db, target, instanceId, key, normalized, at) {
|
|
221
|
+
function adoptExistingRow(chatDb, db, target, instanceId, key, normalized, at, options) {
|
|
222
|
+
// `Math.min` and not a replacement: {@link RecordUserTurnOptions} may widen
|
|
223
|
+
// the search backwards and may never narrow it, so a caller that supplies a
|
|
224
|
+
// bound *inside* the standard window changes nothing.
|
|
225
|
+
const fromMs = Math.min(at - exports.USER_TURN_ADOPTION_WINDOW_MS, options.adoptionFromMs ?? Number.POSITIVE_INFINITY);
|
|
221
226
|
const candidates = chatDb
|
|
222
227
|
.findUnkeyedUserMessages(db, {
|
|
223
228
|
worktreeId: target.worktreeId,
|
|
224
229
|
cliToolId: target.cliToolId,
|
|
225
230
|
instanceId,
|
|
226
|
-
fromMs
|
|
231
|
+
fromMs,
|
|
227
232
|
toMs: at + exports.USER_TURN_ADOPTION_WINDOW_MS,
|
|
228
233
|
})
|
|
229
234
|
.filter((row) => normalizeUserTurnContent(row.content) === normalized)
|
|
@@ -30,6 +30,7 @@ const path_validator_1 = require("../../lib/security/path-validator");
|
|
|
30
30
|
const task_transition_service_1 = require("../../lib/tasks/task-transition-service");
|
|
31
31
|
const gate_runner_1 = require("../../lib/verification/gate-runner");
|
|
32
32
|
const agent_event_state_1 = require("../../lib/session/agent-event-state");
|
|
33
|
+
const stop_history_capture_1 = require("../../lib/hooks/stop-history-capture");
|
|
33
34
|
const logger_1 = require("../../lib/logger");
|
|
34
35
|
const logger = (0, logger_1.createLogger)('lib/hooks/agent-event-service');
|
|
35
36
|
/**
|
|
@@ -144,14 +145,32 @@ function safeRealpath(target) {
|
|
|
144
145
|
* Apply a `stop` event to whatever the worktree is currently doing.
|
|
145
146
|
*
|
|
146
147
|
* The no-op is the load-bearing case. Sessions with no contract, and therefore
|
|
147
|
-
* no task, are the overwhelming majority; for them this records the timestamp
|
|
148
|
-
*
|
|
148
|
+
* no task, are the overwhelming majority; for them this records the timestamp,
|
|
149
|
+
* asks the transcript reader for the turn, and returns.
|
|
150
|
+
*
|
|
151
|
+
* ## Why the history read is here (Issue #2246)
|
|
152
|
+
*
|
|
153
|
+
* Because it must happen for *every* stop event and not only for the ones that
|
|
154
|
+
* govern a task — the majority case above is exactly the session whose replies
|
|
155
|
+
* this is trying not to lose — and because both callers of this function are
|
|
156
|
+
* stop receivers (`/api/hooks/agent-event` and the compatibility
|
|
157
|
+
* `/api/hooks/claude-done`). Putting it in one of the routes would have left the
|
|
158
|
+
* other one on the old behaviour.
|
|
159
|
+
*
|
|
160
|
+
* It runs **before** the task lookup so that the two early returns below cannot
|
|
161
|
+
* skip it, and after `recordAgentStopEvent` because the reader resolves its
|
|
162
|
+
* transcript through the session pointer that call refreshes.
|
|
163
|
+
*
|
|
164
|
+
* It is awaited rather than detached. The turn has already ended, so the cost is
|
|
165
|
+
* paid by nobody who is waiting for an answer, and a detached promise here would
|
|
166
|
+
* be one whose failures nothing observes.
|
|
149
167
|
*
|
|
150
168
|
* Never throws. A hook is fire-and-forget from a CLI's stop handler, and a
|
|
151
169
|
* failure here must not become the agent's problem.
|
|
152
170
|
*/
|
|
153
171
|
async function applyAgentStopEvent(db, worktree, cliToolId, instanceId) {
|
|
154
172
|
(0, agent_event_state_1.recordAgentStopEvent)(worktree.id, cliToolId, instanceId);
|
|
173
|
+
const structuredHistoryCaptured = await (0, stop_history_capture_1.captureTranscriptTurnOnStop)(worktree, cliToolId, instanceId);
|
|
155
174
|
let task;
|
|
156
175
|
try {
|
|
157
176
|
task = (0, tasks_db_1.getActiveTaskForInstance)(db, worktree.id, cliToolId, instanceId);
|
|
@@ -161,10 +180,20 @@ async function applyAgentStopEvent(db, worktree, cliToolId, instanceId) {
|
|
|
161
180
|
worktreeId: worktree.id,
|
|
162
181
|
error: error instanceof Error ? error.message : String(error),
|
|
163
182
|
});
|
|
164
|
-
return {
|
|
183
|
+
return {
|
|
184
|
+
taskId: null,
|
|
185
|
+
taskEventApplied: false,
|
|
186
|
+
verificationRunId: null,
|
|
187
|
+
structuredHistoryCaptured,
|
|
188
|
+
};
|
|
165
189
|
}
|
|
166
190
|
if (!task) {
|
|
167
|
-
return {
|
|
191
|
+
return {
|
|
192
|
+
taskId: null,
|
|
193
|
+
taskEventApplied: false,
|
|
194
|
+
verificationRunId: null,
|
|
195
|
+
structuredHistoryCaptured,
|
|
196
|
+
};
|
|
168
197
|
}
|
|
169
198
|
let taskEventApplied = false;
|
|
170
199
|
try {
|
|
@@ -178,7 +207,12 @@ async function applyAgentStopEvent(db, worktree, cliToolId, instanceId) {
|
|
|
178
207
|
});
|
|
179
208
|
}
|
|
180
209
|
if (!task.contract.success.autoVerifyOnStop) {
|
|
181
|
-
return {
|
|
210
|
+
return {
|
|
211
|
+
taskId: task.id,
|
|
212
|
+
taskEventApplied,
|
|
213
|
+
verificationRunId: null,
|
|
214
|
+
structuredHistoryCaptured,
|
|
215
|
+
};
|
|
182
216
|
}
|
|
183
217
|
let verificationRunId = null;
|
|
184
218
|
try {
|
|
@@ -201,5 +235,5 @@ async function applyAgentStopEvent(db, worktree, cliToolId, instanceId) {
|
|
|
201
235
|
});
|
|
202
236
|
}
|
|
203
237
|
}
|
|
204
|
-
return { taskId: task.id, taskEventApplied, verificationRunId };
|
|
238
|
+
return { taskId: task.id, taskEventApplied, verificationRunId, structuredHistoryCaptured };
|
|
205
239
|
}
|
|
@@ -99,6 +99,7 @@ exports.antigravityBrainRoot = antigravityBrainRoot;
|
|
|
99
99
|
exports.antigravityTranscriptPath = antigravityTranscriptPath;
|
|
100
100
|
exports.acceptAntigravityTranscriptPath = acceptAntigravityTranscriptPath;
|
|
101
101
|
exports.captureAntigravityTranscriptTurn = captureAntigravityTranscriptTurn;
|
|
102
|
+
exports.resolveAntigravityTranscriptPath = resolveAntigravityTranscriptPath;
|
|
102
103
|
const promises_1 = require("fs/promises");
|
|
103
104
|
const os_1 = require("os");
|
|
104
105
|
const path_1 = require("path");
|
|
@@ -256,15 +257,21 @@ function acceptAntigravityTranscriptPath(agyHome, candidate) {
|
|
|
256
257
|
return resolved;
|
|
257
258
|
}
|
|
258
259
|
/**
|
|
259
|
-
* Read
|
|
260
|
+
* Read this instance's unwritten turns out of its transcript and write them.
|
|
260
261
|
*
|
|
261
|
-
* **
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
262
|
+
* **Every turn in the window that is not already a row**, oldest first, which is
|
|
263
|
+
* the shape Issue #2246 gave all three pull readers and the reasoning for it is
|
|
264
|
+
* written out once on `../claude/history`'s
|
|
265
|
+
* {@link captureClaudeTranscriptTurn}. The short version: this reader only runs
|
|
266
|
+
* when the poller judges a turn finished, so a missed judgement used to lose a
|
|
267
|
+
* turn permanently — by the next judgement "the newest turn" had moved on.
|
|
266
268
|
*
|
|
267
|
-
*
|
|
269
|
+
* #2121's one-row-per-turn argument is preserved by the **anchor**: the newest
|
|
270
|
+
* turn in the window this reader has already written is where the backfill
|
|
271
|
+
* starts, and a window with no anchor falls back to the newest turn alone.
|
|
272
|
+
*
|
|
273
|
+
* The return value is the poller's instruction, and it is about the **newest**
|
|
274
|
+
* turn whatever else was written on the way. **True** means History holds
|
|
268
275
|
* this turn as the agent's own Markdown and the scrape must be dropped. **False**
|
|
269
276
|
* means it does not, for any reason at all — no conversation pointer, no file, an
|
|
270
277
|
* unreadable file, a window with no prompt in it — and the scrape must be saved.
|
|
@@ -313,8 +320,7 @@ async function captureAntigravityTranscriptTurn(target, capture = {}) {
|
|
|
313
320
|
return false;
|
|
314
321
|
const parsed = (0, transcript_1.parseAntigravityTranscript)(text);
|
|
315
322
|
const built = (0, transcript_1.buildAntigravityTurns)(parsed.records, conversationId);
|
|
316
|
-
|
|
317
|
-
if (!turn) {
|
|
323
|
+
if (built.turns.length === 0) {
|
|
318
324
|
// No `USER_INPUT` in the window. Two ordinary causes, both fail-open: the
|
|
319
325
|
// 4 MiB window cut mid-conversation, and `transcript_full.jsonl` can hold
|
|
320
326
|
// less than the whole history — one of the 41 files in the corpus held a
|
|
@@ -341,8 +347,33 @@ async function captureAntigravityTranscriptTurn(target, capture = {}) {
|
|
|
341
347
|
preludeRecords: built.preludeRecords,
|
|
342
348
|
});
|
|
343
349
|
}
|
|
344
|
-
const
|
|
345
|
-
|
|
350
|
+
const pending = await selectUnwrittenAntigravityTurns(target, built.turns);
|
|
351
|
+
if (pending.turns.length === 0) {
|
|
352
|
+
logger.debug('antigravity-transcript-turns-already-saved', {
|
|
353
|
+
worktreeId: target.worktreeId,
|
|
354
|
+
instanceId,
|
|
355
|
+
turnsInWindow: built.turns.length,
|
|
356
|
+
});
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
if (pending.turns.length > 1) {
|
|
360
|
+
logger.info('antigravity-transcript-backfilling-turns', {
|
|
361
|
+
worktreeId: target.worktreeId,
|
|
362
|
+
instanceId,
|
|
363
|
+
path,
|
|
364
|
+
pendingTurns: pending.turns.length,
|
|
365
|
+
turnsInWindow: built.turns.length,
|
|
366
|
+
anchored: pending.anchored,
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
let captured = false;
|
|
370
|
+
for (let index = 0; index < pending.turns.length; index += 1) {
|
|
371
|
+
const turn = pending.turns[index];
|
|
372
|
+
const previousStartedAt = index === 0 ? pending.previousStartedAt : pending.turns[index - 1].startedAt;
|
|
373
|
+
const userRow = await recordAntigravityUserTurn(target, turn, previousStartedAt);
|
|
374
|
+
captured = await writeAntigravityTurn(target, turn, (0, transcript_1.renderAntigravityTurn)(turn), resolveAssistantTimestampMs(turn, userRow), path);
|
|
375
|
+
}
|
|
376
|
+
return captured;
|
|
346
377
|
}
|
|
347
378
|
catch (error) {
|
|
348
379
|
logger.error('antigravity-transcript-capture-failed', {
|
|
@@ -353,6 +384,59 @@ async function captureAntigravityTranscriptTurn(target, capture = {}) {
|
|
|
353
384
|
return false;
|
|
354
385
|
}
|
|
355
386
|
}
|
|
387
|
+
/**
|
|
388
|
+
* The transcript file this instance would be read from, or null (Issue #2246).
|
|
389
|
+
*
|
|
390
|
+
* The same two steps {@link captureAntigravityTranscriptTurn} opens with, asked
|
|
391
|
+
* without reading or writing anything; see `../claude/history`'s
|
|
392
|
+
* {@link resolveClaudeTranscriptPath} for what the Stop receiver does with it.
|
|
393
|
+
*
|
|
394
|
+
* Never throws.
|
|
395
|
+
*/
|
|
396
|
+
async function resolveAntigravityTranscriptPath(target, capture = {}) {
|
|
397
|
+
try {
|
|
398
|
+
const conversationId = await resolveAntigravityConversationId(target);
|
|
399
|
+
if (!conversationId)
|
|
400
|
+
return null;
|
|
401
|
+
return await locateAntigravityTranscript(capture.antigravityHome ?? resolveAntigravityHome(), conversationId);
|
|
402
|
+
}
|
|
403
|
+
catch {
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* The turns {@link captureAntigravityTranscriptTurn} still has to write (#2246).
|
|
409
|
+
*
|
|
410
|
+
* The same rule as `../claude/history`'s, on agy's own key: search backwards
|
|
411
|
+
* from the newest turn for one that is already a row, and take everything after
|
|
412
|
+
* it. Record order and never a timestamp — agy stamps `created_at` at
|
|
413
|
+
* second resolution, so a turn and its own reply routinely share an instant.
|
|
414
|
+
*
|
|
415
|
+
* @param turns - Every turn in the window, oldest first
|
|
416
|
+
*/
|
|
417
|
+
async function selectUnwrittenAntigravityTurns(target, turns) {
|
|
418
|
+
const [{ getDbInstance }, { findMessageByRequestId }] = await Promise.all([
|
|
419
|
+
Promise.resolve().then(() => __importStar(require('../../../../lib/db/db-instance'))),
|
|
420
|
+
Promise.resolve().then(() => __importStar(require('../../../../lib/db'))),
|
|
421
|
+
]);
|
|
422
|
+
const db = getDbInstance();
|
|
423
|
+
for (let index = turns.length - 1; index >= 0; index -= 1) {
|
|
424
|
+
const turn = turns[index];
|
|
425
|
+
const requestId = (0, agent_transcript_1.antigravityTurnRequestId)(turn.conversationId, turn.stepIndex);
|
|
426
|
+
if (!findMessageByRequestId(db, target.worktreeId, requestId))
|
|
427
|
+
continue;
|
|
428
|
+
return {
|
|
429
|
+
turns: turns.slice(index + 1),
|
|
430
|
+
previousStartedAt: turn.startedAt,
|
|
431
|
+
anchored: true,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
return {
|
|
435
|
+
turns: turns.slice(-1),
|
|
436
|
+
previousStartedAt: turns.length > 1 ? turns[turns.length - 2].startedAt : 0,
|
|
437
|
+
anchored: false,
|
|
438
|
+
};
|
|
439
|
+
}
|
|
356
440
|
/**
|
|
357
441
|
* The transcript file for this conversation, or null.
|
|
358
442
|
*
|
|
@@ -392,12 +476,16 @@ async function isReadableFile(path) {
|
|
|
392
476
|
*
|
|
393
477
|
* Never throws; `recordUserTurn` reports its failures in the return value.
|
|
394
478
|
*/
|
|
395
|
-
async function recordAntigravityUserTurn(target, turn) {
|
|
479
|
+
async function recordAntigravityUserTurn(target, turn, previousStartedAt = 0) {
|
|
396
480
|
const skipped = { outcome: 'skipped', messageId: null, timestampMs: null };
|
|
397
481
|
const prompt = turn.prompt;
|
|
398
482
|
if (!prompt)
|
|
399
483
|
return skipped;
|
|
400
|
-
|
|
484
|
+
// Issue #2246: a turn read late is a turn whose `/send` row may be older than
|
|
485
|
+
// #2196's symmetric window reaches. The previous turn's start is the tightest
|
|
486
|
+
// honest bound, and it only ever widens the search.
|
|
487
|
+
const adoption = previousStartedAt > 0 ? { adoptionFromMs: previousStartedAt } : {};
|
|
488
|
+
const recorded = await (0, user_turn_recorder_1.recordUserTurn)(target, (0, agent_transcript_1.antigravityPromptRequestId)(turn.conversationId, prompt.stepIndex), prompt.text, prompt.timestampMs, adoption);
|
|
401
489
|
if (recorded.outcome === 'failed') {
|
|
402
490
|
logger.warn('antigravity-transcript-user-turn-failed', {
|
|
403
491
|
worktreeId: target.worktreeId,
|
|
@@ -444,12 +532,31 @@ function resolveAssistantTimestampMs(turn, userRow) {
|
|
|
444
532
|
*/
|
|
445
533
|
async function writeAntigravityTurn(target, turn, rendered, timestampMs, path) {
|
|
446
534
|
const instanceId = target.instanceId ?? target.cliToolId;
|
|
535
|
+
if (!(0, transcript_1.isAntigravityTurnWritable)(turn)) {
|
|
536
|
+
// agy has not finished this answer and no later prompt has taken over, so
|
|
537
|
+
// what is in the file is a turn in progress. Writing it would put a reply
|
|
538
|
+
// with its last paragraph missing into History permanently — the row is
|
|
539
|
+
// keyed on `(conversationId, step_index)`, so every later read finds it and
|
|
540
|
+
// answers "already saved". That is Issue #2264, reported against claude and
|
|
541
|
+
// structurally identical here: a turn cut off after its `tool_calls` renders
|
|
542
|
+
// a *non-empty* body, so the emptiness guard below cannot see it.
|
|
543
|
+
logger.info('antigravity-transcript-turn-open', {
|
|
544
|
+
worktreeId: target.worktreeId,
|
|
545
|
+
instanceId,
|
|
546
|
+
conversationId: rendered.conversationId,
|
|
547
|
+
stepIndex: rendered.stepIndex,
|
|
548
|
+
records: turn.records.length,
|
|
549
|
+
textBlocks: rendered.textBlocks,
|
|
550
|
+
toolBlocks: rendered.toolBlocks,
|
|
551
|
+
});
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
447
554
|
if (rendered.body.length === 0) {
|
|
448
|
-
// A turn that said nothing
|
|
449
|
-
//
|
|
450
|
-
//
|
|
451
|
-
//
|
|
452
|
-
//
|
|
555
|
+
// A turn that said nothing. agy has no `task_complete`, so a closed turn
|
|
556
|
+
// that rendered to nothing and an interrupted one look alike here — and
|
|
557
|
+
// answering false is right for both readings: the scraper keeps the reply if
|
|
558
|
+
// there was one, and an empty row that would show as a blank answer forever
|
|
559
|
+
// is never written.
|
|
453
560
|
logger.info('antigravity-transcript-turn-empty', {
|
|
454
561
|
worktreeId: target.worktreeId,
|
|
455
562
|
instanceId,
|
|
@@ -72,6 +72,8 @@ exports.readAntigravityTranscriptRecord = readAntigravityTranscriptRecord;
|
|
|
72
72
|
exports.parseAntigravityTranscript = parseAntigravityTranscript;
|
|
73
73
|
exports.extractAntigravityUserRequest = extractAntigravityUserRequest;
|
|
74
74
|
exports.buildAntigravityTurns = buildAntigravityTurns;
|
|
75
|
+
exports.isAntigravityTurnClosingRecord = isAntigravityTurnClosingRecord;
|
|
76
|
+
exports.isAntigravityTurnWritable = isAntigravityTurnWritable;
|
|
75
77
|
exports.isAntigravityPromptRecord = isAntigravityPromptRecord;
|
|
76
78
|
exports.renderAntigravityTurn = renderAntigravityTurn;
|
|
77
79
|
const event_mapper_1 = require("../event-mapper");
|
|
@@ -298,6 +300,8 @@ function buildAntigravityTurns(records, conversationId) {
|
|
|
298
300
|
? { stepIndex: record.stepIndex, text, timestampMs: record.timestampMs ?? startedAt }
|
|
299
301
|
: null,
|
|
300
302
|
records: [],
|
|
303
|
+
closed: false,
|
|
304
|
+
superseded: false,
|
|
301
305
|
overflowed: false,
|
|
302
306
|
});
|
|
303
307
|
continue;
|
|
@@ -307,14 +311,49 @@ function buildAntigravityTurns(records, conversationId) {
|
|
|
307
311
|
preludeRecords += 1;
|
|
308
312
|
continue;
|
|
309
313
|
}
|
|
314
|
+
// Assigned rather than or-ed, so what survives is the last `MODEL` record's
|
|
315
|
+
// answer. `SYSTEM` records are ignored here for the same reason they render
|
|
316
|
+
// to nothing: agy injected them, they are not agy speaking.
|
|
317
|
+
if (record.source === exports.ANTIGRAVITY_MODEL_SOURCE) {
|
|
318
|
+
turn.closed = isAntigravityTurnClosingRecord(record);
|
|
319
|
+
}
|
|
310
320
|
if (turn.records.length >= exports.MAX_ANTIGRAVITY_TURN_RECORDS) {
|
|
311
321
|
turn.overflowed = true;
|
|
312
322
|
continue;
|
|
313
323
|
}
|
|
314
324
|
turn.records.push(record);
|
|
315
325
|
}
|
|
326
|
+
// Every turn but the last has a later prompt behind it, and a prompt is proof
|
|
327
|
+
// agy moved on. See {@link AntigravityTurnAccumulator.superseded}.
|
|
328
|
+
for (let index = 0; index < turns.length - 1; index += 1) {
|
|
329
|
+
turns[index].superseded = true;
|
|
330
|
+
}
|
|
316
331
|
return { turns, preludeRecords };
|
|
317
332
|
}
|
|
333
|
+
/**
|
|
334
|
+
* Whether this `MODEL` record is agy finishing its answer (Issue #2264).
|
|
335
|
+
*
|
|
336
|
+
* See {@link AntigravityTurnAccumulator.closed} for the argument; the emptiness
|
|
337
|
+
* test is the one {@link renderAntigravityTurn} applies to `content`, so a
|
|
338
|
+
* record that renders to nothing cannot be what makes a turn look finished.
|
|
339
|
+
*/
|
|
340
|
+
function isAntigravityTurnClosingRecord(record) {
|
|
341
|
+
if (record.source !== exports.ANTIGRAVITY_MODEL_SOURCE)
|
|
342
|
+
return false;
|
|
343
|
+
if (record.type !== exports.ANTIGRAVITY_PLANNER_TYPE)
|
|
344
|
+
return false;
|
|
345
|
+
if (record.toolCalls.length > 0)
|
|
346
|
+
return false;
|
|
347
|
+
return (record.content ?? '').trim().length > 0;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Whether a writer may record this turn (Issue #2264).
|
|
351
|
+
*
|
|
352
|
+
* Either proof that nothing more is coming — agy answered, or it moved on.
|
|
353
|
+
*/
|
|
354
|
+
function isAntigravityTurnWritable(turn) {
|
|
355
|
+
return turn.closed || turn.superseded;
|
|
356
|
+
}
|
|
318
357
|
/** Whether this record is the one the operator's own text arrived on. */
|
|
319
358
|
function isAntigravityPromptRecord(record) {
|
|
320
359
|
return record.source === exports.ANTIGRAVITY_USER_SOURCE && record.type === exports.ANTIGRAVITY_USER_TYPE;
|