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
|
@@ -434,10 +434,36 @@ function extractResponse(output, lastCapturedLine, cliToolId, captureWindowLines
|
|
|
434
434
|
// CRITICAL FIX: Detect and skip Claude Code startup banner/screen
|
|
435
435
|
if (cliToolId === 'claude') {
|
|
436
436
|
const cleanResponse = (0, cli_patterns_1.stripAnsi)(response);
|
|
437
|
-
|
|
438
|
-
|
|
437
|
+
// Issue #2247: `│` is what Claude Code draws markdown TABLES with -- the
|
|
438
|
+
// live frame in `tests/fixtures/claude-live-2247/turn-table.txt` is a
|
|
439
|
+
// two-row table and nothing else -- so it identified a reply, not a banner.
|
|
440
|
+
// The banner's own frame glyphs are the rounded corners and the block
|
|
441
|
+
// shading; those stay.
|
|
442
|
+
const hasBannerArt = /[╭╮╰╯]/.test(cleanResponse) || /░{3,}/.test(cleanResponse) || /▓{3,}/.test(cleanResponse);
|
|
443
|
+
// Issue #2247: the bare `v\d+\.\d+` alternative matched any version string a
|
|
444
|
+
// reply happens to mention. The frame that lost a turn on 2026-09-02 was
|
|
445
|
+
// "GitHub Release v0.30.0 を公開しました" (148 chars, well under the 2000
|
|
446
|
+
// below). What the banner actually prints is the tool's own name and
|
|
447
|
+
// version on one row -- `Claude Code v2.1.258` -- so that is what is
|
|
448
|
+
// matched now, plus the `claude/` form older banners used.
|
|
449
|
+
const hasVersionInfo = /Claude Code v\d+\.\d+|claude\//.test(cleanResponse);
|
|
439
450
|
const hasStartupTips = /Tip:|for shortcuts|\?\s*for help/.test(cleanResponse);
|
|
440
451
|
const hasProjectInit = /^\s*\/Users\/.*$/m.test(cleanResponse) && cleanResponse.split('\n').length < 30;
|
|
452
|
+
// Issue #2247: the anchors above are only evidence of a banner on a pane
|
|
453
|
+
// that has not had a single turn yet -- the same shape as the #1897 copilot
|
|
454
|
+
// fix below. Claude echoes every prompt into the transcript as `❯ <text>`,
|
|
455
|
+
// and the startup screen has none, so an echo anywhere in the transcript
|
|
456
|
+
// rules the banner out no matter what the reply quotes.
|
|
457
|
+
//
|
|
458
|
+
// The search is `findRecentUserPromptIndex`, deliberately: it is the same
|
|
459
|
+
// `/^[>❯]\s+\S/` this file already anchors extraction on, and it stops at
|
|
460
|
+
// `contentEnd`. That bound is load-bearing rather than incidental -- the
|
|
461
|
+
// footer's composer draws a DIM ghost suggestion (`❯ Try "write a test for
|
|
462
|
+
// <filepath>"`, see `boot-banner.txt`) whose stripped bytes are identical
|
|
463
|
+
// to a real echo (#1879), so a scan over the whole pane would read the
|
|
464
|
+
// startup screen as "already had a turn" and put the banner back in
|
|
465
|
+
// History.
|
|
466
|
+
const hasTurnEcho = findRecentUserPromptIndex(totalLines) >= 0;
|
|
441
467
|
const userPromptMatch = cleanResponse.match(/^[>❯]\s+(\S.*)$/m);
|
|
442
468
|
if (userPromptMatch) {
|
|
443
469
|
const userPromptIndex = cleanResponse.indexOf(userPromptMatch[0]);
|
|
@@ -452,7 +478,21 @@ function extractResponse(output, lastCapturedLine, cliToolId, captureWindowLines
|
|
|
452
478
|
return incompleteResult(totalLines);
|
|
453
479
|
}
|
|
454
480
|
}
|
|
455
|
-
else if (
|
|
481
|
+
else if (!hasTurnEcho &&
|
|
482
|
+
(hasBannerArt || hasVersionInfo || hasStartupTips || hasProjectInit) &&
|
|
483
|
+
response.length < 2000) {
|
|
484
|
+
// Issue #2247: this branch used to swallow the turn in silence -- the
|
|
485
|
+
// poller kept ticking every 2s and `response-poller` logged nothing at
|
|
486
|
+
// all, so the only way to tell a lost turn from an idle session was to
|
|
487
|
+
// re-run `extractResponse` on a saved pane by hand. It is reached only
|
|
488
|
+
// before the first echo lands, so it cannot become a per-tick flood.
|
|
489
|
+
logger.info('Claude startup banner suppressed, response not saved', {
|
|
490
|
+
responseLength: response.length,
|
|
491
|
+
hasBannerArt,
|
|
492
|
+
hasVersionInfo,
|
|
493
|
+
hasStartupTips,
|
|
494
|
+
hasProjectInit,
|
|
495
|
+
});
|
|
456
496
|
return incompleteResult(totalLines);
|
|
457
497
|
}
|
|
458
498
|
}
|
|
@@ -64,8 +64,11 @@
|
|
|
64
64
|
* @module lib/polling/structured-history-gate
|
|
65
65
|
*/
|
|
66
66
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
67
|
+
exports.resetStructuredHistoryCaptureQueue = resetStructuredHistoryCaptureQueue;
|
|
68
|
+
exports.isPullTranscriptHistory = isPullTranscriptHistory;
|
|
67
69
|
exports.isStructuredHistoryWriterLive = isStructuredHistoryWriterLive;
|
|
68
70
|
exports.captureStructuredHistoryTurn = captureStructuredHistoryTurn;
|
|
71
|
+
exports.hasStructuredHistoryTranscript = hasStructuredHistoryTranscript;
|
|
69
72
|
const logger_1 = require("../../lib/logger");
|
|
70
73
|
const subscription_1 = require("../../lib/hooks/sources/opencode/subscription");
|
|
71
74
|
const history_1 = require("../../lib/hooks/sources/claude/history");
|
|
@@ -76,6 +79,68 @@ const tool_id_2 = require("../../lib/hooks/sources/codex/tool-id");
|
|
|
76
79
|
const tool_id_3 = require("../../lib/hooks/sources/antigravity/tool-id");
|
|
77
80
|
const registry_1 = require("../../lib/hooks/sources/registry");
|
|
78
81
|
const logger = (0, logger_1.createLogger)('lib/polling/structured-history-gate');
|
|
82
|
+
/**
|
|
83
|
+
* One in-flight capture per instance (Issue #2246).
|
|
84
|
+
*
|
|
85
|
+
* Until this Issue there was one caller — the poller's save path, whose ticks do
|
|
86
|
+
* not overlap — and the Stop hook receiver is now a second one, arriving at
|
|
87
|
+
* exactly the moment the poller is most likely to be inside the same turn. Two
|
|
88
|
+
* things follow, and it is worth separating them because #2246's own text runs
|
|
89
|
+
* them together.
|
|
90
|
+
*
|
|
91
|
+
* **The duplicate-row race it describes is not open today, and this is what
|
|
92
|
+
* keeps it shut.** The readers are idempotent through `findMessageByRequestId`,
|
|
93
|
+
* which is a check-then-write over a *non-unique* index — but the check and the
|
|
94
|
+
* write are adjacent and synchronous (`better-sqlite3` is), and the only `await`
|
|
95
|
+
* in that stretch is the dynamic import *before* the check. So there is no point
|
|
96
|
+
* for a second caller to interleave at, and two concurrent captures of one turn
|
|
97
|
+
* already end in one row. That is a property of two adjacent statements, which
|
|
98
|
+
* is exactly the kind of property a later refactor removes without noticing: an
|
|
99
|
+
* `await` inserted between them re-opens the window silently, and the row it
|
|
100
|
+
* costs is a duplicated reply nobody sees until an operator reports it.
|
|
101
|
+
*
|
|
102
|
+
* **What it saves today is the work.** Both triggers otherwise read, parse and
|
|
103
|
+
* render the same 4 MiB tail at the same time, and the second one throws all of
|
|
104
|
+
* it away.
|
|
105
|
+
*
|
|
106
|
+
* A queue rather than a shared result: the second caller runs the read again
|
|
107
|
+
* after the first finishes, because it may be asking about a newer turn and
|
|
108
|
+
* because the answer it needs is about the file as it is *now*. Re-running is
|
|
109
|
+
* cheap and, after the first call, finds the row and answers true.
|
|
110
|
+
*
|
|
111
|
+
* On `globalThis` for the reason every shared map in this subsystem is (#1736):
|
|
112
|
+
* under `next dev` the poller's bundle and the hook receiver's bundle would each
|
|
113
|
+
* get a private copy of a module-scoped map, and a lock only one of two bundles
|
|
114
|
+
* can see is not a lock.
|
|
115
|
+
*/
|
|
116
|
+
const captureQueue = (globalThis.__structuredHistoryCaptureQueue ??= new Map());
|
|
117
|
+
/** Forget every instance's in-flight capture. Test seam. */
|
|
118
|
+
function resetStructuredHistoryCaptureQueue() {
|
|
119
|
+
captureQueue.clear();
|
|
120
|
+
}
|
|
121
|
+
/** The queue key; the same triple `buildCompositeKey` spells everywhere else. */
|
|
122
|
+
function captureKeyOf(worktreeId, cliToolId, instanceId) {
|
|
123
|
+
return `${worktreeId}\u0000${cliToolId}\u0000${instanceId}`;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Run `work` after whatever is already running for this instance.
|
|
127
|
+
*
|
|
128
|
+
* The stored promise is a settled-only shadow of the real one, so a caller that
|
|
129
|
+
* throws cannot reject the next caller's chain, and the entry is removed only by
|
|
130
|
+
* whoever put it there — a later call that has already replaced it must not have
|
|
131
|
+
* its own lock deleted underneath it.
|
|
132
|
+
*/
|
|
133
|
+
function serializePerInstance(key, work) {
|
|
134
|
+
const previous = captureQueue.get(key) ?? Promise.resolve();
|
|
135
|
+
const result = previous.then(work, work);
|
|
136
|
+
const settled = result.then(() => undefined, () => undefined);
|
|
137
|
+
captureQueue.set(key, settled);
|
|
138
|
+
void settled.then(() => {
|
|
139
|
+
if (captureQueue.get(key) === settled)
|
|
140
|
+
captureQueue.delete(key);
|
|
141
|
+
});
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
79
144
|
/**
|
|
80
145
|
* Which reader answers for which tool.
|
|
81
146
|
*
|
|
@@ -91,9 +156,18 @@ const logger = (0, logger_1.createLogger)('lib/polling/structured-history-gate')
|
|
|
91
156
|
* {@link captureStructuredHistoryTurn} logs it and falls back to the scraper.
|
|
92
157
|
*/
|
|
93
158
|
const PULL_TRANSCRIPT_READERS = {
|
|
94
|
-
[tool_id_1.CLAUDE_CLI_TOOL_ID]:
|
|
95
|
-
|
|
96
|
-
|
|
159
|
+
[tool_id_1.CLAUDE_CLI_TOOL_ID]: {
|
|
160
|
+
capture: (target, capture) => (0, history_1.captureClaudeTranscriptTurn)(target, capture),
|
|
161
|
+
locate: (target, capture) => (0, history_1.resolveClaudeTranscriptPath)(target, capture),
|
|
162
|
+
},
|
|
163
|
+
[tool_id_2.CODEX_CLI_TOOL_ID]: {
|
|
164
|
+
capture: (target, capture) => (0, history_2.captureCodexTranscriptTurn)(target, capture),
|
|
165
|
+
locate: (target, capture) => (0, history_2.resolveCodexTranscriptPath)(target, capture),
|
|
166
|
+
},
|
|
167
|
+
[tool_id_3.ANTIGRAVITY_CLI_TOOL_ID]: {
|
|
168
|
+
capture: (target, capture) => (0, history_3.captureAntigravityTranscriptTurn)(target, capture),
|
|
169
|
+
locate: (target, capture) => (0, history_3.resolveAntigravityTranscriptPath)(target, capture),
|
|
170
|
+
},
|
|
97
171
|
};
|
|
98
172
|
/**
|
|
99
173
|
* What this tool's source says about who records its replies.
|
|
@@ -114,6 +188,17 @@ function transcriptHistoryModeOf(cliToolId) {
|
|
|
114
188
|
return null;
|
|
115
189
|
}
|
|
116
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Whether this tool keeps a transcript a reader can be asked to pull from.
|
|
193
|
+
*
|
|
194
|
+
* Exported for the Stop receiver (Issue #2246), which has to decide whether the
|
|
195
|
+
* *retry* below is worth waiting for before it answers the agent's hook. It is
|
|
196
|
+
* the same question {@link captureStructuredHistoryTurn} opens with, asked
|
|
197
|
+
* without doing the read — never a tool id comparison, here or there.
|
|
198
|
+
*/
|
|
199
|
+
function isPullTranscriptHistory(cliToolId) {
|
|
200
|
+
return transcriptHistoryModeOf(cliToolId) === 'pull';
|
|
201
|
+
}
|
|
117
202
|
/**
|
|
118
203
|
* Whether the agent's own server is recording this instance's replies.
|
|
119
204
|
*
|
|
@@ -180,7 +265,7 @@ function isStructuredHistoryWriterLive(worktreeId, cliToolId, instanceId) {
|
|
|
180
265
|
* @param capture - Where to look; see {@link StructuredHistoryCapture}
|
|
181
266
|
*/
|
|
182
267
|
async function captureStructuredHistoryTurn(worktreeId, cliToolId, instanceId, capture) {
|
|
183
|
-
if (
|
|
268
|
+
if (!isPullTranscriptHistory(cliToolId))
|
|
184
269
|
return false;
|
|
185
270
|
const reader = PULL_TRANSCRIPT_READERS[cliToolId];
|
|
186
271
|
if (!reader) {
|
|
@@ -191,11 +276,51 @@ async function captureStructuredHistoryTurn(worktreeId, cliToolId, instanceId, c
|
|
|
191
276
|
});
|
|
192
277
|
return false;
|
|
193
278
|
}
|
|
279
|
+
const resolvedInstanceId = instanceId ?? cliToolId;
|
|
280
|
+
return serializePerInstance(captureKeyOf(worktreeId, cliToolId, resolvedInstanceId), async () => {
|
|
281
|
+
try {
|
|
282
|
+
return await reader.capture({ worktreeId, cliToolId, instanceId: resolvedInstanceId }, capture);
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
logger.warn('structured-history-capture-unavailable', {
|
|
286
|
+
worktreeId,
|
|
287
|
+
cliToolId,
|
|
288
|
+
instanceId: resolvedInstanceId,
|
|
289
|
+
error: error instanceof Error ? error.message : String(error),
|
|
290
|
+
});
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Whether a pull reader can name a transcript for this instance (Issue #2246).
|
|
297
|
+
*
|
|
298
|
+
* Not "is there a turn to write" and not "did anything get written" — only
|
|
299
|
+
* whether the file the reader would open exists right now. The one caller is
|
|
300
|
+
* `lib/hooks/stop-history-capture`, which asks it after a capture answered
|
|
301
|
+
* false, to decide whether waiting half a second and asking again could help.
|
|
302
|
+
* An instance with no transcript will not have one in half a second, and the
|
|
303
|
+
* delay would be paid on every `stop` of every session without hooks.
|
|
304
|
+
*
|
|
305
|
+
* False for every tool that does not declare `transcriptHistory: 'pull'`, and
|
|
306
|
+
* never throws — an unanswerable question is one whose answer is "no file",
|
|
307
|
+
* which costs the retry and nothing else.
|
|
308
|
+
*
|
|
309
|
+
* @param worktreeId - The worktree
|
|
310
|
+
* @param cliToolId - The tool driving the pane
|
|
311
|
+
* @param instanceId - The agent instance; defaults to the primary
|
|
312
|
+
* @param capture - Where to look; see {@link StructuredHistoryCapture}
|
|
313
|
+
*/
|
|
314
|
+
async function hasStructuredHistoryTranscript(worktreeId, cliToolId, instanceId, capture) {
|
|
315
|
+
const reader = isPullTranscriptHistory(cliToolId) ? PULL_TRANSCRIPT_READERS[cliToolId] : undefined;
|
|
316
|
+
if (!reader)
|
|
317
|
+
return false;
|
|
194
318
|
try {
|
|
195
|
-
|
|
319
|
+
const path = await reader.locate({ worktreeId, cliToolId, instanceId: instanceId ?? cliToolId }, capture);
|
|
320
|
+
return path !== null;
|
|
196
321
|
}
|
|
197
322
|
catch (error) {
|
|
198
|
-
logger.warn('structured-history-
|
|
323
|
+
logger.warn('structured-history-locate-unavailable', {
|
|
199
324
|
worktreeId,
|
|
200
325
|
cliToolId,
|
|
201
326
|
instanceId: instanceId ?? cliToolId,
|
|
@@ -460,7 +460,12 @@ async function buildCurrentOutput(db, worktreeId, cliToolId, instanceId, resolut
|
|
|
460
460
|
// terminal snapshot already has. Gated on the merged verdict (`'running'`, not
|
|
461
461
|
// the tmux-session-exists `isRunning`) so an idle pane reads no transcript.
|
|
462
462
|
if (payload.isRunning && payload.sessionStatus === 'running') {
|
|
463
|
-
|
|
463
|
+
// Issue #2248 made this an `await`, and it buys less than it looks like: the
|
|
464
|
+
// expensive half — the transcript read and the broadcast — is detached
|
|
465
|
+
// inside, so what is waited for is a worktree row and a Map lookup. What it
|
|
466
|
+
// buys is that the frame's outcome is logged against the tick that produced
|
|
467
|
+
// it rather than whenever the event loop got round to the detached tail.
|
|
468
|
+
await publishChatTurnProgress(db, worktreeId, cliToolId, instanceId);
|
|
464
469
|
}
|
|
465
470
|
if (!resolution)
|
|
466
471
|
return payload;
|
|
@@ -1037,6 +1042,16 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
1037
1042
|
composerState: composer.state,
|
|
1038
1043
|
};
|
|
1039
1044
|
}
|
|
1045
|
+
function newChatTurnProgressState() {
|
|
1046
|
+
return {
|
|
1047
|
+
version: 0,
|
|
1048
|
+
askedAt: Number.NEGATIVE_INFINITY,
|
|
1049
|
+
turnKey: null,
|
|
1050
|
+
body: null,
|
|
1051
|
+
loggedOutcome: null,
|
|
1052
|
+
loggedTurnKey: null,
|
|
1053
|
+
};
|
|
1054
|
+
}
|
|
1040
1055
|
/**
|
|
1041
1056
|
* On `globalThis` for the reason every shared map in this subsystem is (#1736):
|
|
1042
1057
|
* under `next dev` the poller's bundle and the opencode subscription's bundle
|
|
@@ -1051,6 +1066,63 @@ function chatTurnProgressKey(target) {
|
|
|
1051
1066
|
function resetChatTurnProgressState() {
|
|
1052
1067
|
chatTurnProgressState.clear();
|
|
1053
1068
|
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Say once, at info, what happened to this instance's progress frames (Issue #2248).
|
|
1071
|
+
*
|
|
1072
|
+
* ## Why info, and why this file had none
|
|
1073
|
+
*
|
|
1074
|
+
* Every outcome here was `logger.debug`, including the two that mean the reader
|
|
1075
|
+
* is watching a blank space: a push that threw, and a room with no subscribers.
|
|
1076
|
+
* Issue #2248 was opened after a live session where the body reached the browser
|
|
1077
|
+
* — or did not — and the server logs could not answer which, because debug is
|
|
1078
|
+
* off in the builds people run. An unobservable push is a feature that can only
|
|
1079
|
+
* be debugged by reproducing it.
|
|
1080
|
+
*
|
|
1081
|
+
* ## Why once
|
|
1082
|
+
*
|
|
1083
|
+
* The publisher runs on EVERY poll tick of a generating session. Logging each
|
|
1084
|
+
* tick at info would put a line per second per agent into the operator's log and
|
|
1085
|
+
* make the level useless, so this collapses a run of identical ticks into its
|
|
1086
|
+
* first: the outcome and the turn it happened on are the identity, and a repeat
|
|
1087
|
+
* of the pair says nothing the first line did not.
|
|
1088
|
+
*
|
|
1089
|
+
* The consequences of that identity, both deliberate:
|
|
1090
|
+
*
|
|
1091
|
+
* - **a new turn always logs**, because `turnKey` is part of the pair. That is
|
|
1092
|
+
* the acceptance criterion — one info line per turn — and the reason
|
|
1093
|
+
* `loggedTurnKey` exists at all rather than a bare boolean;
|
|
1094
|
+
* - **a CHANGE of outcome always logs**, so "the subscriber left" and "it
|
|
1095
|
+
* started failing" are both visible the tick they happen, without the
|
|
1096
|
+
* steady state that follows repeating them.
|
|
1097
|
+
*
|
|
1098
|
+
* `no-subscribers` and `failed` carry no turn key — neither knows one; the first
|
|
1099
|
+
* returns before the source is asked and the second is why there is no frame —
|
|
1100
|
+
* so for them the pair is `(outcome, null)` and the run collapses to one line
|
|
1101
|
+
* until something else happens.
|
|
1102
|
+
*/
|
|
1103
|
+
function logChatTurnProgressOutcome(target, outcome, turnKey, extra = {}) {
|
|
1104
|
+
const key = chatTurnProgressKey(target);
|
|
1105
|
+
const state = chatTurnProgressState.get(key) ?? newChatTurnProgressState();
|
|
1106
|
+
chatTurnProgressState.set(key, state);
|
|
1107
|
+
if (state.loggedOutcome === outcome && state.loggedTurnKey === turnKey)
|
|
1108
|
+
return;
|
|
1109
|
+
state.loggedOutcome = outcome;
|
|
1110
|
+
state.loggedTurnKey = turnKey;
|
|
1111
|
+
// Written out rather than interpolated: these strings are what an operator
|
|
1112
|
+
// greps the log for, and an interpolated name cannot be found in the source.
|
|
1113
|
+
const message = outcome === 'published'
|
|
1114
|
+
? 'chat-turn-progress-published'
|
|
1115
|
+
: outcome === 'no-subscribers'
|
|
1116
|
+
? 'chat-turn-progress-no-subscribers'
|
|
1117
|
+
: 'chat-turn-progress-failed';
|
|
1118
|
+
logger.info(message, {
|
|
1119
|
+
worktreeId: target.worktreeId,
|
|
1120
|
+
cliToolId: target.cliToolId,
|
|
1121
|
+
instanceId: target.instanceId ?? target.cliToolId,
|
|
1122
|
+
turnKey,
|
|
1123
|
+
...extra,
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1054
1126
|
/**
|
|
1055
1127
|
* Decide whether this instance has a new progress frame, and build it.
|
|
1056
1128
|
*
|
|
@@ -1085,12 +1157,7 @@ function resetChatTurnProgressState() {
|
|
|
1085
1157
|
*/
|
|
1086
1158
|
async function buildChatTurnProgress(target, source, now = Date.now()) {
|
|
1087
1159
|
const key = chatTurnProgressKey(target);
|
|
1088
|
-
const state = chatTurnProgressState.get(key) ??
|
|
1089
|
-
version: 0,
|
|
1090
|
-
askedAt: Number.NEGATIVE_INFINITY,
|
|
1091
|
-
turnKey: null,
|
|
1092
|
-
body: null,
|
|
1093
|
-
};
|
|
1160
|
+
const state = chatTurnProgressState.get(key) ?? newChatTurnProgressState();
|
|
1094
1161
|
if (now - state.askedAt < types_1.CHAT_TURN_PROGRESS_MIN_INTERVAL_MS)
|
|
1095
1162
|
return null;
|
|
1096
1163
|
state.askedAt = now;
|
|
@@ -1145,19 +1212,28 @@ async function buildChatTurnProgress(target, source, now = Date.now()) {
|
|
|
1145
1212
|
async function emitChatTurnProgress(target, source, now = Date.now()) {
|
|
1146
1213
|
try {
|
|
1147
1214
|
const { broadcast, hasRoomSubscribers } = await Promise.resolve().then(() => __importStar(require('../../lib/ws-server')));
|
|
1148
|
-
if (!hasRoomSubscribers(target.worktreeId))
|
|
1215
|
+
if (!hasRoomSubscribers(target.worktreeId)) {
|
|
1216
|
+
// Issue #2248. Reported, not silent: "the body never reached the browser"
|
|
1217
|
+
// and "nobody was listening" look identical from a screenshot, and this is
|
|
1218
|
+
// the only place that can tell them apart.
|
|
1219
|
+
logChatTurnProgressOutcome(target, 'no-subscribers', null);
|
|
1149
1220
|
return false;
|
|
1221
|
+
}
|
|
1150
1222
|
const event = await buildChatTurnProgress(target, source, now);
|
|
1223
|
+
// Not logged: null is the throttle, an unchanged body, or a turn with no
|
|
1224
|
+
// text yet — the quiet, correct majority of ticks.
|
|
1151
1225
|
if (!event)
|
|
1152
1226
|
return false;
|
|
1153
1227
|
broadcast(target.worktreeId, event);
|
|
1228
|
+
logChatTurnProgressOutcome(target, 'published', event.turnKey, {
|
|
1229
|
+
version: event.version,
|
|
1230
|
+
bodyLength: event.body.length,
|
|
1231
|
+
partial: event.partial,
|
|
1232
|
+
});
|
|
1154
1233
|
return true;
|
|
1155
1234
|
}
|
|
1156
1235
|
catch (error) {
|
|
1157
|
-
|
|
1158
|
-
worktreeId: target.worktreeId,
|
|
1159
|
-
cliToolId: target.cliToolId,
|
|
1160
|
-
instanceId: target.instanceId ?? target.cliToolId,
|
|
1236
|
+
logChatTurnProgressOutcome(target, 'failed', null, {
|
|
1161
1237
|
error: error instanceof Error ? error.message : String(error),
|
|
1162
1238
|
});
|
|
1163
1239
|
return false;
|
|
@@ -1177,11 +1253,26 @@ async function emitChatTurnProgress(target, source, now = Date.now()) {
|
|
|
1177
1253
|
* out of the module graph of the `/current-output` route and of `commandmate
|
|
1178
1254
|
* capture`, both of which reach this file for a payload and nothing else.
|
|
1179
1255
|
*
|
|
1256
|
+
* ## Which half the caller waits for (Issue #2248)
|
|
1257
|
+
*
|
|
1258
|
+
* The caller awaits the CHEAP half — the worktree row and "is anybody watching"
|
|
1259
|
+
* — and not the expensive one. That split is what `void` was protecting in the
|
|
1260
|
+
* first place: the 4 MiB transcript read, the JSONL parse, the render and the
|
|
1261
|
+
* broadcast still run detached, so no poll tick and no WebSocket snapshot waits
|
|
1262
|
+
* on them.
|
|
1263
|
+
*
|
|
1264
|
+
* What awaiting the prelude buys is the reason this Issue exists: the line that
|
|
1265
|
+
* says whether anybody received the frame is written while the tick it belongs
|
|
1266
|
+
* to is still the tick in progress. Left inside the detached half it landed
|
|
1267
|
+
* wherever the event loop happened to get to it, next to some unrelated
|
|
1268
|
+
* request's output, which is not a log an operator can read backwards.
|
|
1269
|
+
*
|
|
1180
1270
|
* Never throws: `emitChatTurnProgress` swallows, and so does this.
|
|
1181
1271
|
*/
|
|
1182
1272
|
async function publishChatTurnProgress(db, worktreeId, cliToolId, instanceId) {
|
|
1183
1273
|
if (cliToolId !== 'claude')
|
|
1184
1274
|
return;
|
|
1275
|
+
const target = { worktreeId, cliToolId, instanceId };
|
|
1185
1276
|
try {
|
|
1186
1277
|
// The slug the transcript directory is named after is a function of the
|
|
1187
1278
|
// worktree's path, so the row is what makes the file findable at all. Read
|
|
@@ -1192,15 +1283,26 @@ async function publishChatTurnProgress(db, worktreeId, cliToolId, instanceId) {
|
|
|
1192
1283
|
const worktreePath = getWorktreeById(db, worktreeId)?.path;
|
|
1193
1284
|
if (!worktreePath)
|
|
1194
1285
|
return;
|
|
1195
|
-
|
|
1286
|
+
// Issue #2248. Hoisted out of `emitChatTurnProgress` — which still makes the
|
|
1287
|
+
// same check for its other caller — so the answer, and the line that reports
|
|
1288
|
+
// it, are settled before this function returns. Costs one Map lookup on the
|
|
1289
|
+
// sessions nobody is watching, which is the bargain that was already being
|
|
1290
|
+
// struck one frame later.
|
|
1291
|
+
const { hasRoomSubscribers } = await Promise.resolve().then(() => __importStar(require('../../lib/ws-server')));
|
|
1292
|
+
if (!hasRoomSubscribers(worktreeId)) {
|
|
1293
|
+
logChatTurnProgressOutcome(target, 'no-subscribers', null);
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1296
|
+
// Detached on purpose: everything past this point is the transcript read.
|
|
1297
|
+
void emitChatTurnProgress(target, async () => {
|
|
1196
1298
|
const { readClaudeTurnProgress } = await Promise.resolve().then(() => __importStar(require('../../lib/hooks/sources/claude/history')));
|
|
1197
1299
|
return readClaudeTurnProgress({ worktreeId, cliToolId, instanceId: instanceId ?? cliToolId }, { worktreePath });
|
|
1198
1300
|
});
|
|
1199
1301
|
}
|
|
1200
1302
|
catch (error) {
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1303
|
+
// Issue #2248: the reader's half of the same failure — the worktree row or
|
|
1304
|
+
// one of the dynamic imports — on the same once-per-run gate as the push's.
|
|
1305
|
+
logChatTurnProgressOutcome(target, 'failed', null, {
|
|
1204
1306
|
error: error instanceof Error ? error.message : String(error),
|
|
1205
1307
|
});
|
|
1206
1308
|
}
|
package/package.json
CHANGED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=2827,exports.ids=[261,2827,7836],exports.modules={60:(a,b,c)=>{c.d(b,{QM:()=>h,V0:()=>e,ZX:()=>f,bE:()=>g});var d=c(85164);function e(a){let b=(0,d.x7)(a),c=(0,d.M4)(a,b);return{chromeStart:b,echoEnd:c,start:c+1,end:b>=0?b:a.length,headTruncated:c<0}}function f(a){let b=a.split("\n"),c=e(b.map(d.aJ));return c.start>=c.end?"":b.slice(c.start,c.end).join("\n")}function g(a){let b=a.split("\n"),c=e(b),f=c.start>=c.end?"":b.slice(c.start,c.end).join("\n");return d.$t.test(f)&&!d.kD.test(a)&&!d.Ty.test(a)}function h(a,b,c,d,e,f=!1){if(a=Math.max(0,a),"opencode"===d||"copilot"===d||f){let a=e(b);return a>=0?a+1:0}if("antigravity"===d){let c=e(b);return c>=0?c+1:Math.max(0,a)}if(a>=b||c){let a=e(40);return a>=0?a+1:0}if("codex"===d)return Math.max(0,a);if(a>=b-5){let a=e(50);return a>=0?a+1:Math.max(0,b-40)}return Math.max(0,a)}},8988:(a,b,c)=>{c.d(b,{R:()=>g});let d=/📄 Session log: (.+?\/([^\/\s]+\.jsonl))/,e=/Request ID: ([^\s\n]+)/,f=/Summary: (.+?)(?:\n─|$)/s;function g(a){let b={content:a},c=d.exec(a);c&&(b.logFileName=c[2],b.logFilePath=c[1]);let g=e.exec(a);g&&(b.requestId=g[1]);let h=f.exec(a);return h&&(b.summary=h[1].trim()),b}},13033:(a,b,c)=>{c.d(b,{IW:()=>h,IZ:()=>l,K0:()=>g,Uz:()=>m,l1:()=>f,o0:()=>i,q1:()=>n,tb:()=>k,vQ:()=>j});var d=c(85164);let e=globalThis.__tuiResponseAccumulator??(globalThis.__tuiResponseAccumulator=new Map);function f(a){return(0,d._A)((0,d.aJ)(a)).replace(/^\u2503\s?/,"").replace(/\s*\u2503$/,"").trim()}function g(a){let b=a.split("\n"),c=[];for(let a of b){let b=f(a);!(!b||d.sx.some(a=>a.test(b)))&&(d.Md.test(b)||c.push(b))}return c}function h(a){return a.replace(/[\u2500-\u257F]/g,"").replace(/\s{2,}/g," ").trim()}function i(a){let b=(0,d.aJ)(a).split("\n");if((0,d.gT)(b))return[];let c=(0,d.wv)(b),e=c>=0?b.slice(0,c):b,f=[],g=!1;for(let a of e){if(d.JN.test(a)){g=!1;continue}if(d.y.test(a))g=!0;else if(g){if(d.Fg.test(a))continue;g=!1}let b=h(a);b&&(d.J7.some(a=>a.test(b))||f.push(b))}return f}function j(a,b){if(0===a.length||0===b.length)return 0;let c=Math.min(a.length,b.length);for(let d=c;d>=1;d--){let c=a.slice(-d),e=b.slice(0,d),f=!0;for(let a=0;a<d;a++)if(c[a]!==e[a]){f=!1;break}if(f)return d}return 0}function k(a){e.set(a,{lines:[],lastFingerprint:[],pollCount:0})}function l(a,b,c="opencode"){let d=e.get(a);if(!d)return;let f="copilot"===c?i(b):g(b);if(0!==f.length){if(d.pollCount++,0===d.lines.length)d.lines=[...f];else{let a=j(d.lastFingerprint,f);if(a>0){let b=f.slice(a);d.lines.push(...b)}else d.lines.push(...f)}d.lastFingerprint=f.slice(-10)}}function m(a){let b=e.get(a);return b&&0!==b.lines.length?b.lines.join("\n"):""}function n(a){e.delete(a)}},18778:(a,b,c)=>{c.d(b,{T:()=>g});var d=c(56791),e=c(41364);let f=(0,c(72626).h)("conversation-logger");async function g(a,b,c,h="claude"){let i=(0,d.getLastUserMessage)(a,b);if(i)try{await (0,e.hM)(b,i.content,c,h)}catch(a){f.error("conversation:log-failed",{error:a instanceof Error?a.message:String(a)})}}},21684:(a,b,c)=>{c.d(b,{U:()=>h});var d=c(33873),e=c.n(d),f=c(87447),g=c(8004);function h(){let a=e().join(process.cwd(),"data","logs");return(0,g.T)((0,f._p)("CM_LOG_DIR"),a,"CM_LOG_DIR")}},41364:(a,b,c)=>{c.d(b,{Gv:()=>o,hM:()=>n});var d=c(79748),e=c.n(d),f=c(33873),g=c.n(f),h=c(1634),i=c(21684),j=c(72626),k=c(15194);function l(a="claude"){return g().join((0,i.U)(),a)}async function m(a="claude"){let b=l(a);try{await e().access(b)}catch{await e().mkdir(b,{recursive:!0})}}async function n(a,b,c,d="claude"){await m(d);let f=function(a,b="claude"){let c=(0,h.GP)(new Date,"yyyy-MM-dd"),d=`${a}-${c}.md`,e=l(b);return g().join(e,d)}(a,d),i=(0,h.GP)(new Date,"yyyy-MM-dd HH:mm:ss"),j="";try{j=await e().readFile(f,"utf-8")}catch{let b=(0,k.hR)(d)?k.ef[d]:d;j=`# ${b} Conversation Log: ${a}
|
|
2
|
-
|
|
3
|
-
Created: ${i}
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
`}j+=`## Conversation at ${i}
|
|
8
|
-
|
|
9
|
-
`,j+=`### User
|
|
10
|
-
|
|
11
|
-
`,j+=`${b}
|
|
12
|
-
|
|
13
|
-
`;let o=(0,k.hR)(d)?k.ef[d]:d;return j+=`### ${o}
|
|
14
|
-
|
|
15
|
-
`,j+=`${c}
|
|
16
|
-
|
|
17
|
-
`,j+=`---
|
|
18
|
-
|
|
19
|
-
`,await e().writeFile(f,j,"utf-8"),f}async function o(a,b="all"){let c="all"===b?[...k.XH]:[b],d=[];for(let b of c){await m(b);let c=l(b);try{let b=(await e().readdir(c)).filter(b=>b.startsWith(`${a}-`)&&b.endsWith(".md")).map(a=>g().join(c,a));d.push(...b)}catch{}}return d.sort().reverse()}(0,j.h)("log-manager")},45146:(a,b,c)=>{c.d(b,{Et:()=>x,KQ:()=>z,MN:()=>q,SI:()=>m,fq:()=>y,g8:()=>r,sR:()=>B});var d=c(84297),e=c(72626),f=c(13033),g=c(72457),h=c(71080),i=c(44321),j=c(86582),k=c(99508);let l=(0,e.h)("response-poller"),m=["Waiting for auth","⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],n=globalThis.__responsePollerCoordinator??(globalThis.__responsePollerCoordinator={activePollers:new Map,pollingStartTimes:new Map,owners:new Map,running:new Map,pendingRestart:new Map,ownerStorage:new d.AsyncLocalStorage,generationCounter:0}),o=n.activePollers,p=n.pollingStartTimes;function q(a,b,c){return`${a}:${c??b}`}function r(a,b,c){let d=q(a,b,c),e={worktreeId:a,cliToolId:b,instanceId:c},f=n.running.get(d);if(f){if(f.owner.superseded=!0,Date.now()-f.since<6e4)return void n.pendingRestart.set(d,e);l.warn("poller:restart-past-stalled-tick",{pollerKey:d,generation:f.owner.generation,runningForMs:Date.now()-f.since}),n.running.delete(d)}x(a,b,c),s(e)}function s(a){let b=q(a.worktreeId,a.cliToolId,a.instanceId);n.pollingStartTimes.set(b,Date.now()),("opencode"===a.cliToolId||"copilot"===a.cliToolId)&&(0,f.tb)(b),t(a.worktreeId,a.cliToolId,a.instanceId)}function t(a,b,c){let d=q(a,b,c);u({worktreeId:a,cliToolId:b,instanceId:c},function(a){let b=n.owners.get(a);b&&(b.superseded=!0);let c={pollerKey:a,generation:++n.generationCounter,superseded:!1,stopped:!1};return n.owners.set(a,c),c}(d))}function u(a,b){let c=setTimeout(()=>{v(a,b)},2e3);n.activePollers.set(b.pollerKey,c)}async function v(a,b){let c=b.pollerKey;if(!b.superseded&&!b.stopped){n.running.set(c,{owner:b,since:Date.now()});try{let d=n.pollingStartTimes.get(c);if(d&&Date.now()-d>18e5)return void w(c);try{await n.ownerStorage.run(b,()=>(0,j.zX)(a.worktreeId,a.cliToolId,a.instanceId))}catch(a){l.error("error:",{error:a instanceof Error?a.message:String(a)})}b.superseded||(0,k.broadcastTerminalSnapshot)(a.worktreeId,a.cliToolId,a.instanceId),b.superseded||b.stopped||u(a,b)}finally{n.running.get(c)?.owner===b&&n.running.delete(c);let a=n.pendingRestart.get(c);a&&(n.pendingRestart.delete(c),w(c),s(a))}}}function w(a){let b=n.ownerStorage.getStore();if(b&&b.pollerKey===a&&(b.superseded||b.stopped))return void l.info("poller:stale-stop-ignored",{pollerKey:a,generation:b.generation});let c=n.owners.get(a);c&&(c.stopped=!0,n.owners.delete(a)),n.pendingRestart.delete(a);let d=n.activePollers.get(a);d&&(clearTimeout(d),n.activePollers.delete(a),n.pollingStartTimes.delete(a)),(0,f.q1)(a),(0,g.iX)(a),(0,h.L1)(a)}function x(a,b,c){w(q(a,b,c))}function y(){for(let a of new Set([...Array.from(n.activePollers.keys()),...Array.from(n.owners.keys())]))w(a);n.pendingRestart.clear()}function z(){return Array.from(n.activePollers.keys())}function A(a){let b=a.indexOf(":");return b<=0||b===a.length-1?null:{worktreeId:a.slice(0,b),instanceId:a.slice(b+1)}}function B(a,b){let c=new Map;for(let{oldId:b,newId:d}of a)b&&d&&b!==d&&c.set(b,d);if(0===c.size)return[];let d=[],e=[];for(let a of Array.from(o.keys())){let f=A(a);if(!f)continue;let g=c.get(f.worktreeId);if(!g)continue;let h=b(f.worktreeId,f.instanceId);if(!h){e.push(a);continue}d.push({oldKey:a,newKey:q(g,h,f.instanceId),newWorktreeId:g,cliToolId:h,instanceId:f.instanceId})}let j=new Map;for(let a of d){let b=o.get(a.oldKey);b&&clearTimeout(b),o.delete(a.oldKey);let c=n.owners.get(a.oldKey);c&&(c.superseded=!0,c.stopped=!0,n.owners.delete(a.oldKey)),n.pendingRestart.delete(a.oldKey),j.set(a.newKey,{startedAt:p.get(a.oldKey)}),p.delete(a.oldKey),(0,g.i2)(a.oldKey,a.newKey),(0,h.Re)(a.oldKey,a.newKey);let d=A(a.oldKey);d&&(0,i.fL)(d.worktreeId,a.newWorktreeId,a.cliToolId,a.instanceId),(0,f.q1)(a.oldKey)}for(let a of e)w(a),l.warn("poller:migrate-abandoned",{pollerKey:a});for(let a of d){let b=j.get(a.newKey)?.startedAt;p.set(a.newKey,b??Date.now()),("opencode"===a.cliToolId||"copilot"===a.cliToolId)&&(0,f.tb)(a.newKey),t(a.newWorktreeId,a.cliToolId,a.instanceId)}return d}},50779:(a,b,c)=>{c.d(b,{GT:()=>m});var d=c(88807),e=c(43167),f=c(73753),g=c(72626),h=c(57836),i=c(4806),j=c(61191),k=c(27519);let l=(0,g.h)("push/resolution");async function m(a){let{worktreeId:b,agentName:c,at:g=Date.now()}=a,m=function(a,b=Date.now()){let c;if(!(0,k.lU)())return{send:!1,reason:"push-unconfigured"};if(!(0,i.r0)(a,b))return{send:!1,reason:"no-card"};if((0,h.Te)(a))return{send:!1,reason:"still-waiting"};try{c=(0,e.rC)((0,d.getDbInstance)(),"prompt")}catch{return{send:!1,reason:"single-device",deviceCount:0}}return c<2?{send:!1,reason:"single-device",deviceCount:c}:{send:!0,reason:"cross-device-clear",deviceCount:c}}(b,g),n={worktreeId:b,instanceId:c,reason:m.reason,...void 0!==m.deviceCount?{deviceCount:m.deviceCount}:{}};if("still-waiting"!==m.reason&&(0,i._P)(b),!m.send)return void("single-device"===m.reason?l.info("resolution-push-skipped",n):l.debug("resolution-push-skipped",n));try{await (0,j.notifyPushSubscribers)({worktreeId:b,worktreeName:function(a){try{return(0,f.getWorktreeById)((0,d.getDbInstance)(),a)?.name??a}catch{return a}}(b),kind:"prompt",agentName:c,resolved:!0},g),l.info("resolution-push-sent",n)}catch(a){l.warn("resolution-push-failed",{...n,error:a instanceof Error?a.message:String(a)})}}},57836:(a,b,c)=>{c.d(b,{Jp:()=>k,Te:()=>l,hd:()=>j,wN:()=>h});var d=c(24455);let e=(0,c(72626).h)("waiting-episode-state"),f=globalThis.__sessionWaitingEpisodes??(globalThis.__sessionWaitingEpisodes=new Map),g=globalThis.__sessionWaitingTransitionListeners??(globalThis.__sessionWaitingTransitionListeners=new Set);function h(a){return g.add(a),()=>{g.delete(a)}}function i(a){for(let b of g)try{b(a)}catch(b){e.error("waiting-transition-listener-failed",{worktreeId:a.worktreeId,cliToolId:a.cliToolId,instanceId:a.instanceId??a.cliToolId,waiting:a.waiting,error:b instanceof Error?b.message:String(b)})}}function j({worktreeId:a,cliToolId:b,instanceId:c,waiting:e,kind:g=null,structuredSince:h=null,now:j=Date.now()}){let k=(0,d.v7)(a,b,c),l=f.get(k);if(!e)return void 0===l||(f.delete(k),i({worktreeId:a,cliToolId:b,instanceId:c,waiting:!1,since:null,kind:null,at:j})),null;if(void 0!==l)return l.kind=g,l.since;let m=h??j;return f.set(k,{since:m,kind:g}),i({worktreeId:a,cliToolId:b,instanceId:c,waiting:!0,since:m,kind:g,at:j}),m}function k(a,b,c){return f.get((0,d.v7)(a,b,c))??null}function l(a){let b=`${a}${d.CS}`;for(let a of f.keys())if(a.startsWith(b))return!0;return!1}},71080:(a,b,c)=>{c.d(b,{L1:()=>g,Re:()=>h,j7:()=>f});var d=c(55511);let e=globalThis.__responseHashCache??(globalThis.__responseHashCache=new Map);function f(a,b){let c=(0,d.createHash)("sha256").update(b).digest("hex");return e.get(a)===c||(e.set(a,c),!1)}function g(a){e.delete(a)}function h(a,b){if(a===b)return;let c=e.get(a);e.delete(a),void 0!==c&&e.set(b,c)}},72457:(a,b,c)=>{c.d(b,{gv:()=>f,i2:()=>h,iX:()=>g,zm:()=>i});var d=c(55511);let e=globalThis.__promptHashCache??(globalThis.__promptHashCache=new Map);function f(a,b){let c=(0,d.createHash)("sha256").update(b).digest("hex");return e.get(a)===c||(e.set(a,c),!1)}function g(a){e.delete(a)}function h(a,b){if(a===b)return;let c=e.get(a);e.delete(a),void 0!==c&&e.set(b,c)}function i(a,b){return"copilot"!==b?a:a.replace(/^[❯>]\s/gm," ")}},73478:(a,b,c)=>{c.d(b,{I7:()=>u});var d=c(24455),e=c(88807),f=c(73753),g=c(72626),h=c(57836),i=c(80544),j=c(92010),k=c(61191),l=c(50779),m=c(27519);let n=(0,g.h)("push/waiting-notifier"),o=globalThis.__waitingPushPending??(globalThis.__waitingPushPending=new Map),p=globalThis.__waitingPushGraceTimers??(globalThis.__waitingPushGraceTimers=new Map);async function q(a,b,c){let d=a.instanceId??a.cliToolId;try{await (0,k.notifyPushSubscribers)({worktreeId:a.worktreeId,worktreeName:function(a){try{return(0,f.getWorktreeById)((0,e.getDbInstance)(),a)?.name??a}catch{return a}}(a.worktreeId),kind:"prompt",agentName:d,instanceId:d,waitingKind:a.kind,waitingSince:a.since,escalated:b},c)}catch(c){n.warn("waiting-push-failed",{worktreeId:a.worktreeId,instanceId:d,escalated:b,error:c instanceof Error?c.message:String(c)})}}function r(a){let b=p.get(a);void 0!==b&&(clearTimeout(b),p.delete(a))}function s(a,b){(0,j.R)({worktreeId:a.worktreeId,cliToolId:a.cliToolId,instanceId:a.instanceId,waitingSince:a.since})||q(a,!1,b)}function t(){if(o.size>0)return;let a=globalThis.__waitingPushEscalationTimer;void 0!==a&&(clearInterval(a),globalThis.__waitingPushEscalationTimer=void 0)}function u(){let a=globalThis.__waitingPushUnsubscribe;for(let b of(a&&(a(),globalThis.__waitingPushUnsubscribe=void 0),p.values()))clearTimeout(b);p.clear(),o.clear(),t();let b=(0,h.wN)(a=>{!function(a){var b;if(!(0,m.lU)())return;let c=(0,d.v7)(a.worktreeId,a.cliToolId,a.instanceId);if(!a.waiting||null===a.since){r(c),o.delete(c),t(),(0,l.GT)({worktreeId:a.worktreeId,agentName:a.instanceId??a.cliToolId,at:a.at});return}let e={worktreeId:a.worktreeId,cliToolId:a.cliToolId,instanceId:a.instanceId,since:a.since,kind:a.kind};if(o.set(c,e),!function(){if(void 0!==globalThis.__waitingPushEscalationTimer)return;let a=setInterval(()=>{!function(a=Date.now()){if(0===o.size)return t();let b=(0,i.rS)(),c=6e4*b.thresholdMinutes;for(let[d,e]of Array.from(o)){let f=(0,h.Jp)(e.worktreeId,e.cliToolId,e.instanceId);if(null===f||f.since!==e.since){o.delete(d);continue}b.enabled&&!(a-e.since<c)&&((0,j.R)({worktreeId:e.worktreeId,cliToolId:e.cliToolId,instanceId:e.instanceId,waitingSince:e.since,escalated:!0})||(o.delete(d),q({...e,kind:f.kind??e.kind},!0,a)))}t()}()},6e4);a.unref?.(),globalThis.__waitingPushEscalationTimer=a}(),null==(b=e.kind)||"unclassified"===b){r(c);let a=setTimeout(()=>{!function(a){p.delete(a);let b=o.get(a);if(void 0===b)return;let c=(0,h.Jp)(b.worktreeId,b.cliToolId,b.instanceId);if(null===c||c.since!==b.since){o.delete(a),t();return}let d={...b,kind:c.kind};o.set(a,d),s(d,Date.now())}(c)},8e3);a.unref?.(),p.set(c,a);return}s(e,a.at)}(a)});return globalThis.__waitingPushUnsubscribe=b,b}},80544:(a,b,c)=>{c.d(b,{Di:()=>h,O$:()=>g,d7:()=>k,rS:()=>j});var d=c(88807);let e=(0,c(72626).h)("push/escalation-settings"),f="push_escalation",g={enabled:!0,thresholdMinutes:10},h=[5,10,30,60];function i(a){if("object"!=typeof a||null===a)return{...g};let b="boolean"==typeof a.enabled?a.enabled:g.enabled,c=a.thresholdMinutes;return{enabled:b,thresholdMinutes:"number"==typeof c&&Number.isFinite(c)&&c>=1&&c<=1440?Math.round(c):g.thresholdMinutes}}function j(){try{let a=(0,d.getDbInstance)().prepare("SELECT value FROM app_settings WHERE key = ?").get(f);if(!a)return{...g};return i(JSON.parse(a.value))}catch(a){return e.warn("escalation-settings-read-failed",{error:a instanceof Error?a.message:String(a)}),{...g}}}function k(a){let b=i(a),c=Date.now();return(0,d.getDbInstance)().prepare(`
|
|
20
|
-
INSERT INTO app_settings (key, value, created_at, updated_at)
|
|
21
|
-
VALUES (?, ?, ?, ?)
|
|
22
|
-
ON CONFLICT(key) DO UPDATE SET
|
|
23
|
-
value = excluded.value,
|
|
24
|
-
updated_at = excluded.updated_at
|
|
25
|
-
`).run(f,JSON.stringify(b),c,c),b}},82450:(a,b,c)=>{c.d(b,{IS:()=>h,LH:()=>n,NN:()=>g,Sj:()=>p,aW:()=>o});var d=c(85164),e=c(13033),f=c(56263);function g(a){let b=(0,d.aJ)(a).split("\n"),c=(0,d.GT)(b),e=c>=0?b.slice(0,c):b,f=-1;for(let a=e.length-1;a>=0;a--)if(/^❯\s+\S/.test(e[a])){f=a;break}let g=f>=0?f+1:0,h=e.slice(g),i=[/CLAUDE_HOOKS_/,/\/bin\/claude/,/^claude\s*$/,/@.*\s+%\s*$/,/^[^⏺]*curl.*POST/,/^[^⏺]*Content-Type/,/^[^⏺]*export\s+CLAUDE_/,/^\s*$/,/^[╭╮╰╯│─\s]+$/,/^[│╭╮╰╯].*[│╭╮╰╯]$/,/Claude Code v[\d.]+/,/^Tips for getting started/,/^Welcome back/,/Run \/init to create/,/^Recent activity/,/^No recent activity/,/▐▛███▜▌|▝▜█████▛▘|▘▘ ▝▝/,/^\s*Opus \d+\.\d+\s*·\s*Claude Max/,/\.com's Organization/,/\?\s*for shortcuts\s*$/,/^─{10,}$/,/^❯\s*$/,d.fW],j=[];for(let a of h)!i.some(b=>b.test(a))&&a.trim()&&j.push(a);return j.join("\n").trim()}function h(a){let b=(0,d.aJ)(a).split("\n"),c=[],e=[/^maenokota@.*%/,/^zsh:/,/^feature-issue-\d+/,/^\s*$/],f=!1,g=[];for(let a of b){if(a.includes("✦")){f=!0;let b=a.indexOf("✦"),c=a.substring(b+1).trim();c&&g.push(c);continue}if(f){if(e.some(b=>b.test(a)))continue;g.push(a)}}if(g.length>0)return g.join("\n").trim();for(let a of b)e.some(b=>b.test(a))||c.push(a);return c.join("\n").trim()}let i=/^●\s+(?:Get |Read |Run |Search |Write |Edit |Delete |List |Create |Fetch |Explore |Execute |Install |Model changed to:)/,j=/^\$\s+[A-Z][A-Za-z]*(?:\s|$)/,k=/^\d+\s+lines\.\.\.$/,l=/^[◐◑◒◓]/,m=/^(?:git\s+--no-pager|git\s+(?:log|diff|show|status|branch|remote|fetch|pull|push|merge|rebase|checkout|reset|stash|tag|config|clone|init|add|commit|rm|mv|bisect|grep|ls-files|rev-parse|describe|shortlog|blame|reflog|cherry-pick|revert|submodule|worktree)\b|npm\s+|npx\s+|yarn\s+|pnpm\s+|cargo\s+|pip\s+|rustc\s+|cmake\s+|docker\s+|kubectl\s+|aws\s+|gcloud\s+|az\s+|terraform\s+|ansible\s+|curl\s+|wget\s+|ssh\s+|scp\s+|rsync\s+|grep\s+|sed\s+|awk\s+|mkdir\s+|rm\s+|cp\s+|mv\s+|chmod\s+|chown\s+)/;function n(a){let b=(0,d.aJ)(a).split("\n"),c=(0,d.wv)(b),f=c>=0?b.slice(0,c):b,g=-1;for(let a=f.length-1;a>=0;a--){let b=(0,e.IW)(f[a]);if(b&&/^❯\s+\S/.test(b)){g=a;break}}let h=g>=0?g+1:0;if(g>=0)for(;h<f.length&&d.Fg.test(f[h]);)h++;let n=f.slice(h),o=[],p=!1,q=!1;for(let a of n){let b=(0,e.IW)(a);if(!b){p=!1,q=!1;continue}if(d.J7.some(a=>a.test(b)))continue;if(j.test(b)){q=!0,p=!1;continue}if(i.test(b))continue;if(l.test(b)){p=!0,q=!1;continue}if(!(k.test(b)||m.test(b))){if(/^❯\s*/.test(b)){p=!1,q=!1;continue}if(!/^[│└]/.test(b)){if(/^●/.test(b)){p=!1,q=!1,o.push(b.replace(/^●\s*/,""));continue}p||q||o.push(b)}}}return o.join("\n").trim()}function o(a){let b=a.split("\n"),c=[];for(let a=0;a<b.length;a++){let f=(0,e.l1)(b[a]);f&&d.Md.test(f)&&c.push(a)}let f=0;c.length>=2&&(f=c[c.length-2]+1);let g=[];for(let a=f;a<b.length;a++){let c=(0,e.l1)(b[a]);!(!c||d.sx.some(a=>a.test(c)))&&(d.Md.test(c)||g.push(c))}return g.join("\n").trim()}function p(a,b=f.Rf,c=f.ky){if(!a||a.length<=b)return a;let d=c+"\n",e=b-d.length;if(e<=0)return c.slice(0,b);let g=a.length-e;if(g>0&&g<a.length){let b=a.charCodeAt(g);b>=56320&&b<=57343&&(g+=1)}return d+a.slice(g)}},86582:(a,b,c)=>{c.d(b,{zX:()=>aM,z$:()=>aL});var d=c(31766),e=c(88807),f=c(56791),g=c(79129),h=c(26895),i=c(18778),j=c(15194),k=c(8988),l=c(85164),m=c(72626),n=c(46423),o=c(93997),p=c(60),q=c(82450),r=c(56263),s=c(13033),t=c(72457),u=c(44321),v=c(71080),w=c(53163),x=c(79696),y=c(79748),z=c(21820),A=c(33873),B=c(24455);let C=(0,m.h)("lib/history/transcript-tail");async function D(a){let b;try{b=await (0,y.open)(a,"r");let{size:c}=await b.stat(),d=Math.max(0,c-4194304),e=c-d;if(e<=0)return"";let f=Buffer.alloc(e),{bytesRead:g}=await b.read(f,0,e,d),h=f.subarray(0,g).toString("utf8");if(0===d)return h;let i=h.indexOf("\n");return -1===i?"":h.slice(i+1)}catch(b){return C.warn("transcript-tail-read-failed",{path:a,error:b instanceof Error?b.message:String(b)}),null}finally{await b?.close().catch(()=>{})}}var E=c(18201),F=c(86594),G=c(57510),H=c(27128);let I=["sessions"],J=".jsonl",K="\n\n_(truncated)_";function L(a){return a.replace(/\s+/g," ").trim()}function M(a){return a.length<=200?a:`${a.slice(0,199)}…`}let N=new Set(["ContextCompaction"]),O={CommandExecution:"exec",FileChange:"edit",McpToolCall:"mcp",ImageView:"view",Extension:"extension"},P=(0,m.h)("lib/hooks/sources/codex/history"),Q=/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/,R=globalThis.__codexTranscriptSessions??=new Map,S=globalThis.__codexTranscriptPaths??=new Map;async function T(a){let b=(0,B.v7)(a.worktreeId,a.cliToolId,a.instanceId);try{let{getLastAgentEvent:d}=await Promise.resolve().then(c.bind(c,48083)),e=d(a.worktreeId,a.cliToolId,a.instanceId)?.sessionId;if("string"==typeof e&&e.length>0)return R.set(b,e),e}catch(b){P.debug("codex-transcript-session-lookup-failed",{worktreeId:a.worktreeId,instanceId:a.instanceId??a.cliToolId,error:b instanceof Error?b.message:String(b)})}return R.get(b)??null}function U(a){return(0,A.join)(a,...I)}async function V(a,b,c=4){return Q.test(b)?W(U(a),b,c):null}async function W(a,b,c){let d;if(c<=0)return null;try{d=await (0,y.readdir)(a,{withFileTypes:!0})}catch{return null}let e=[];for(let c of d){if(c.isFile()){var f;if(f=c.name,f.startsWith("rollout-")&&f.endsWith(`-${b}${J}`))return(0,A.join)(a,c.name);continue}c.isDirectory()&&e.push(c.name)}for(let d of(e.sort((a,b)=>a<b?1:a>b?-1:0),e)){let e=await W((0,A.join)(a,d),b,c-1);if(e)return e}return null}async function X(a,b={}){let c=a.instanceId??a.cliToolId;try{var d,e;let f=b.codexHome??function(a=process.env){let b=a.CODEX_HOME;return"string"==typeof b&&b.length>0?b:(0,A.join)((0,z.homedir)(),".codex")}(),g=await T(a);if(!g)return P.debug("codex-transcript-unavailable",{worktreeId:a.worktreeId,instanceId:c,reason:"no-session-pointer"}),!1;let h=await Y(f,g);if(!h)return P.debug("codex-transcript-unavailable",{worktreeId:a.worktreeId,instanceId:c,sessionId:g,reason:"no-file"}),!1;let i=await D(h);if(null===i)return!1;let j=function(a){let b=[],c=0;for(let d of a.split("\n")){let a;if(0===d.trim().length)continue;try{a=JSON.parse(d)}catch{c+=1;continue}let e=function(a){if(!(0,G.Qd)(a))return null;let b=(0,G.O2)(a,"type");if(!b)return null;let c=(0,G.Qd)(a.payload)?a.payload:null,d=c?(0,G.O2)(c,"type"):null,e=(0,G.O2)(a,"timestamp"),f=e?Date.parse(e):NaN;return{type:b,payloadType:d,turnId:c?(0,G.O2)(c,"turn_id"):null,sessionId:c?(0,G.O2)(c,"session_id")??(0,G.O2)(c,"thread_id"):null,timestampMs:Number.isFinite(f)?f:null,item:c&&"item_completed"===d?function(a){var b,c;if(!(0,G.Qd)(a))return null;let d=(0,G.O2)(a,"type");return d?{type:d,id:(0,G.O2)(a,"id"),text:(b=d,c=a,"UserMessage"===b||"AgentMessage"===b?function(a){if(!Array.isArray(a))return null;let b="";for(let c of a){if(!(0,G.Qd)(c))continue;let a=(0,G.O2)(c,"text");a&&(b+=a)}return b.length>0?b:null}(c.content):"Reasoning"===b?function(a){if(!Array.isArray(a))return null;let b=a.filter(a=>"string"==typeof a&&""!==a);return b.length>0?b.join("\n\n"):null}(c.summary_text):null),phase:(0,G.O2)(a,"phase"),detail:function(a,b){if("CommandExecution"===a){let a=function(a){if(!Array.isArray(a))return null;let b=[];for(let c of a){if(!(0,G.Qd)(c))continue;let a=(0,G.O2)(c,"cmd");a&&b.push(a)}return b.length>0?b.join(" ; "):null}(b.parsed_cmd);if(a)return M(L(a));let c=function(a){if(!Array.isArray(a))return null;let b=a.filter(a=>"string"==typeof a);return b.length>0?b.join(" "):null}(b.command);return c?M(L(c)):null}if("FileChange"===a){let a=b.changes;if(!(0,G.Qd)(a))return null;let c=Object.keys(a);return c.length>0?M(c.join(", ")):null}if("McpToolCall"===a){let a=(0,G.O2)(b,"server"),c=(0,G.O2)(b,"tool");return a||c?M([a,c].filter(Boolean).join(".")):null}if("ImageView"===a){let a=(0,G.O2)(b,"path");return a?M(a):null}if("Extension"===a){let a=(0,G.O2)(b,"query")??(0,G.O2)(b,"action");return a?M(L(a)):null}return null}(d,a)}:null}(c.item):null}}(a);e?b.push(e):c+=1}return{records:b,malformedLines:c}}(i),k=function(a,b){let c=new Map,d=0,e=0,f=null;for(let g of a){if("session_meta"===g.type&&g.sessionId&&(f=g.sessionId),"response_item"===g.type){d+=1;continue}let a=g.turnId;if(!a){e+=1;continue}let h=c.get(a);if(h||(h={sessionId:g.sessionId??f??b,turnId:a,startedAt:g.timestampMs??0,prompts:[],items:[],closed:!1,overflowed:!1},c.set(a,h)),"task_complete"===g.payloadType){h.closed=!0;continue}let i=g.item;if(i){if("UserMessage"===i.type){i.id&&i.text&&h.prompts.push({itemId:i.id,text:i.text,timestampMs:g.timestampMs??h.startedAt});continue}if(h.items.length>=2048){h.overflowed=!0;continue}h.items.push(i)}}return{turns:[...c.values()],duplicateStreamRecords:d,turnlessRecords:e}}(j.records,g),l=k.turns.at(-1);if(!l)return P.info("codex-transcript-no-turn",{worktreeId:a.worktreeId,instanceId:c,path:h,records:j.records.length,malformedLines:j.malformedLines,duplicateStreamRecords:k.duplicateStreamRecords}),!1;j.malformedLines>0&&P.info("codex-transcript-partial-read",{worktreeId:a.worktreeId,instanceId:c,path:h,malformedLines:j.malformedLines,turnlessRecords:k.turnlessRecords,duplicateStreamRecords:k.duplicateStreamRecords});let m=await $(a,l);return await _(a,l,function(a){let b=[],c=new Set,d=0,e=0;for(let f of a.items){if("AgentMessage"===f.type){let a=f.text?.trim()??"";if(0===a.length)continue;b.push({kind:"prose",text:a}),d+=1;continue}if("Reasoning"===f.type){let a=f.text?.trim()??"";if(0===a.length)continue;b.push({kind:"aside",text:function(a){let b=a.trim().split("\n").map(a=>a.length>0?`> ${a}`:">").join("\n");return`> **Thinking**
|
|
26
|
-
>
|
|
27
|
-
${b}`}(a)});continue}if(f.type in O){b.push({kind:"tool",text:function(a){let b=O[a.type]??a.type;return a.detail?`- \`${b}\` — ${a.detail}`:`- \`${b}\``}(f)}),e+=1;continue}N.has(f.type)||c.add(f.type)}let f=(0,H.t)(b).body;return f.length>2e5&&(f=f.slice(0,2e5-K.length)+K),{sessionId:a.sessionId,turnId:a.turnId,body:f,textBlocks:d,toolBlocks:e,unknownBlockTypes:[...c]}}(l),(d=l,e=m,null===e.timestampMs?d.startedAt:Math.max(d.startedAt,e.timestampMs+1)),h)}catch(b){return P.error("codex-transcript-capture-failed",{worktreeId:a.worktreeId,instanceId:c,error:b instanceof Error?b.message:String(b)}),!1}}async function Y(a,b){let c=`${a}\0${b}`,d=S.get(c);if(d&&await Z(d))return d;d&&S.delete(c);let e=await V(a,b);if(!e)return null;let f=function(a,b){if(!b.endsWith(J)||b.includes("\0"))return null;let c=(0,A.resolve)(U(a)),d=(0,A.resolve)(b);return d===c||d.startsWith(c+A.sep)?d:null}(a,e);return f?(S.set(c,f),f):null}async function Z(a){try{return(await (0,y.stat)(a)).isFile()}catch{return!1}}async function $(a,b){let c=a.instanceId??a.cliToolId,d={outcome:"skipped",messageId:null,timestampMs:null};for(let e of b.prompts){let f=await (0,E.Ce)(a,(0,F.Ac)(e.itemId),e.text,e.timestampMs);if("failed"===f.outcome){P.warn("codex-transcript-user-turn-failed",{worktreeId:a.worktreeId,instanceId:c,sessionId:b.sessionId,turnId:b.turnId,promptItemId:e.itemId});continue}d=f}return d}async function _(a,b,d,e,f){let g=a.instanceId??a.cliToolId;if(!b.closed)return P.info("codex-transcript-turn-open",{worktreeId:a.worktreeId,instanceId:g,sessionId:d.sessionId,turnId:d.turnId,items:b.items.length}),!1;if(0===d.body.length)return P.info("codex-transcript-turn-empty",{worktreeId:a.worktreeId,instanceId:g,sessionId:d.sessionId,turnId:d.turnId}),!1;d.unknownBlockTypes.length>0&&P.info("codex-transcript-unknown-items",{worktreeId:a.worktreeId,instanceId:g,sessionId:d.sessionId,turnId:d.turnId,itemTypes:d.unknownBlockTypes}),b.overflowed&&P.info("codex-transcript-turn-overflowed",{worktreeId:a.worktreeId,instanceId:g,sessionId:d.sessionId,turnId:d.turnId});let h=(0,F.ZS)(d.turnId),[{getDbInstance:i},{createMessage:j,findMessageByRequestId:k},{broadcastMessage:l}]=await Promise.all([Promise.resolve().then(c.bind(c,88807)),Promise.resolve().then(c.bind(c,56791)),Promise.resolve().then(c.bind(c,79129))]),m=i();if(k(m,a.worktreeId,h))return P.debug("codex-transcript-turn-already-saved",{worktreeId:a.worktreeId,instanceId:g,requestId:h}),!0;let n=j(m,{worktreeId:a.worktreeId,role:"assistant",content:d.body,messageType:"normal",timestamp:new Date(e>0?e:Date.now()),cliToolId:a.cliToolId,instanceId:g,requestId:h});return l("message",{worktreeId:a.worktreeId,message:n}),P.info("codex-transcript-turn-saved",{worktreeId:a.worktreeId,instanceId:g,sessionId:d.sessionId,requestId:h,path:f,bodyLength:d.body.length,textBlocks:d.textBlocks,toolBlocks:d.toolBlocks,prompts:b.prompts.length}),!0}let aa=[".system_generated","logs","transcript_full.jsonl"],ab="\n\n_(truncated)_",ac="MODEL",ad=new Set(["RUN_COMMAND","VIEW_FILE","LIST_DIRECTORY","GREP_SEARCH","SEARCH_WEB","CODE_ACTION","GENERATE_IMAGE","GENERIC"]),ae=new Set(["CHECKPOINT","CONVERSATION_HISTORY","SYSTEM_MESSAGE","EPHEMERAL_MESSAGE","ERROR_MESSAGE"]),af=(0,m.h)("lib/hooks/sources/antigravity/history"),ag=[".gemini","antigravity-cli"],ah=/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/,ai=globalThis.__antigravityTranscriptConversations??=new Map;async function aj(a){let b=(0,B.v7)(a.worktreeId,a.cliToolId,a.instanceId);try{let{getLastAgentEvent:d}=await Promise.resolve().then(c.bind(c,48083)),e=d(a.worktreeId,a.cliToolId,a.instanceId)?.sessionId;if("string"==typeof e&&e.length>0)return ai.set(b,e),e}catch(b){af.debug("antigravity-transcript-conversation-lookup-failed",{worktreeId:a.worktreeId,instanceId:a.instanceId??a.cliToolId,error:b instanceof Error?b.message:String(b)})}return ai.get(b)??null}function ak(a){return(0,A.join)(a,"brain")}async function al(a,b={}){let c=a.instanceId??a.cliToolId;try{var d,e;let f=b.antigravityHome??function(a=(0,z.homedir)()){return(0,A.join)(a,...ag)}(),g=await aj(a);if(!g)return af.debug("antigravity-transcript-unavailable",{worktreeId:a.worktreeId,instanceId:c,reason:"no-conversation-pointer"}),!1;let h=await am(f,g);if(!h)return af.debug("antigravity-transcript-unavailable",{worktreeId:a.worktreeId,instanceId:c,conversationId:g,reason:"no-file"}),!1;let i=await D(h);if(null===i)return!1;let j=function(a){let b=[],c=0;for(let d of a.split("\n")){let a;if(0===d.trim().length)continue;try{a=JSON.parse(d)}catch{c+=1;continue}let e=function(a){if(!(0,G.Qd)(a))return null;let b=a.step_index;if("number"!=typeof b||!Number.isInteger(b)||b<0)return null;let c=(0,G.O2)(a,"source"),d=(0,G.O2)(a,"type");if(!c||!d)return null;let e=(0,G.O2)(a,"created_at"),f=e?Date.parse(e):NaN,g=[];if(Array.isArray(a.tool_calls))for(let b of a.tool_calls){let a=function(a){var b;if(!(0,G.Qd)(a))return null;let c=(0,G.O2)(a,"name");if(!c)return null;let d=(0,G.Qd)(a.args)?a.args:null,e=d?(0,G.O2)(d,"toolAction")??(0,G.O2)(d,"toolSummary"):null;return{name:c,detail:e?(b=e.replace(/\s+/g," ").trim()).length<=200?b:`${b.slice(0,199)}…`:null}}(b);a&&g.push(a)}return{stepIndex:b,source:c,type:d,status:(0,G.O2)(a,"status"),timestampMs:Number.isFinite(f)?f:null,content:(0,G.O2)(a,"content"),thinking:(0,G.O2)(a,"thinking"),toolCalls:g}}(a);e?b.push(e):c+=1}return{records:b,malformedLines:c}}(i),k=function(a,b){let c=[],d=0;for(let f of a){var e;if(e=f,"USER_EXPLICIT"===e.source&&"USER_INPUT"===e.type){let a=f.content?function(a){let b=a.indexOf("<USER_REQUEST>");if(-1===b)return null;let c=b+14,d=a.indexOf("</USER_REQUEST>",c);if(-1===d)return null;let e=a.slice(c,d).trim();return e.length>0?e:null}(f.content):null,d=f.timestampMs??0;c.push({conversationId:b,stepIndex:f.stepIndex,startedAt:d,prompt:a?{stepIndex:f.stepIndex,text:a,timestampMs:f.timestampMs??d}:null,records:[],overflowed:!1});continue}let a=c.at(-1);if(!a){d+=1;continue}if(a.records.length>=2048){a.overflowed=!0;continue}a.records.push(f)}return{turns:c,preludeRecords:d}}(j.records,g),l=k.turns.at(-1);if(!l)return af.info("antigravity-transcript-no-turn",{worktreeId:a.worktreeId,instanceId:c,path:h,records:j.records.length,malformedLines:j.malformedLines,preludeRecords:k.preludeRecords}),!1;j.malformedLines>0&&af.info("antigravity-transcript-partial-read",{worktreeId:a.worktreeId,instanceId:c,path:h,malformedLines:j.malformedLines,preludeRecords:k.preludeRecords});let m=await ao(a,l);return await ap(a,l,function(a){let b=[],c=new Set,d=0,e=0;for(let f of a.records){if(f.source===ac&&"PLANNER_RESPONSE"===f.type){let a=f.thinking?.trim()??"";a.length>0&&b.push({kind:"aside",text:function(a){let b=a.trim().split("\n").map(a=>a.length>0?`> ${a}`:">").join("\n");return`> **Thinking**
|
|
28
|
-
>
|
|
29
|
-
${b}`}(a)});let c=f.content?.trim()??"";for(let a of(c.length>0&&(b.push({kind:"prose",text:c}),d+=1),f.toolCalls))b.push({kind:"tool",text:a.detail?`- \`${a.name}\` — ${a.detail}`:`- \`${a.name}\``}),e+=1;continue}if(f.source===ac){ad.has(f.type)||c.add(f.type);continue}ae.has(f.type)||c.add(f.type)}let f=(0,H.t)(b).body;return f.length>2e5&&(f=f.slice(0,2e5-ab.length)+ab),{conversationId:a.conversationId,stepIndex:a.stepIndex,body:f,textBlocks:d,toolBlocks:e,unknownRecordTypes:[...c]}}(l),(d=l,e=m,null===e.timestampMs?d.startedAt:Math.max(d.startedAt,e.timestampMs+1)),h)}catch(b){return af.error("antigravity-transcript-capture-failed",{worktreeId:a.worktreeId,instanceId:c,error:b instanceof Error?b.message:String(b)}),!1}}async function am(a,b){let c=ah.test(b)?(0,A.join)(ak(a),b,...aa):null;if(!c)return null;let d=function(a,b){if(!b.endsWith(".jsonl")||b.includes("\0"))return null;let c=(0,A.resolve)(ak(a)),d=(0,A.resolve)(b);return d===c||d.startsWith(c+A.sep)?d:null}(a,c);return d&&await an(d)?d:null}async function an(a){try{return(await (0,y.stat)(a)).isFile()}catch{return!1}}async function ao(a,b){let c={outcome:"skipped",messageId:null,timestampMs:null},d=b.prompt;if(!d)return c;let e=await (0,E.Ce)(a,(0,F.jN)(b.conversationId,d.stepIndex),d.text,d.timestampMs);return"failed"===e.outcome?(af.warn("antigravity-transcript-user-turn-failed",{worktreeId:a.worktreeId,instanceId:a.instanceId??a.cliToolId,conversationId:b.conversationId,stepIndex:d.stepIndex}),c):e}async function ap(a,b,d,e,f){let g=a.instanceId??a.cliToolId;if(0===d.body.length)return af.info("antigravity-transcript-turn-empty",{worktreeId:a.worktreeId,instanceId:g,conversationId:d.conversationId,stepIndex:d.stepIndex,records:b.records.length}),!1;d.unknownRecordTypes.length>0&&af.info("antigravity-transcript-unknown-records",{worktreeId:a.worktreeId,instanceId:g,conversationId:d.conversationId,stepIndex:d.stepIndex,recordTypes:d.unknownRecordTypes}),b.overflowed&&af.info("antigravity-transcript-turn-overflowed",{worktreeId:a.worktreeId,instanceId:g,conversationId:d.conversationId,stepIndex:d.stepIndex});let h=(0,F.O1)(d.conversationId,d.stepIndex),[{getDbInstance:i},{createMessage:j,findMessageByRequestId:k},{broadcastMessage:l}]=await Promise.all([Promise.resolve().then(c.bind(c,88807)),Promise.resolve().then(c.bind(c,56791)),Promise.resolve().then(c.bind(c,79129))]),m=i();if(k(m,a.worktreeId,h))return af.debug("antigravity-transcript-turn-already-saved",{worktreeId:a.worktreeId,instanceId:g,requestId:h}),!0;let n=j(m,{worktreeId:a.worktreeId,role:"assistant",content:d.body,messageType:"normal",timestamp:new Date(e>0?e:Date.now()),cliToolId:a.cliToolId,instanceId:g,requestId:h});return l("message",{worktreeId:a.worktreeId,message:n}),af.info("antigravity-transcript-turn-saved",{worktreeId:a.worktreeId,instanceId:g,conversationId:d.conversationId,requestId:h,path:f,bodyLength:d.body.length,textBlocks:d.textBlocks,toolBlocks:d.toolBlocks}),!0}var aq=c(70997),ar=c(2734),as=c(76835),at=c(97709);let au=(0,m.h)("lib/polling/structured-history-gate"),av={[aq.v]:(a,b)=>(0,x.K$)(a,b),[ar.c]:(a,b)=>X(a,b),[as.F]:(a,b)=>al(a,b)};function aw(a){try{return(0,at.VM)(a).capabilities.transcriptHistory??null}catch(b){return au.warn("structured-history-capability-unavailable",{cliToolId:a,error:b instanceof Error?b.message:String(b)}),null}}async function ax(a,b,c,d){if("pull"!==aw(b))return!1;let e=av[b];if(!e)return au.warn("structured-history-reader-missing",{worktreeId:a,cliToolId:b,instanceId:c??b}),!1;try{return await e({worktreeId:a,cliToolId:b,instanceId:c??b},d)}catch(d){return au.warn("structured-history-capture-unavailable",{worktreeId:a,cliToolId:b,instanceId:c??b,error:d instanceof Error?d.message:String(d)}),!1}}var ay=c(45146),az=c(91601),aA=c(92010),aB=c(81099),aC=c(63209),aD=c(73478),aE=c(57836),aF=c(52767);let aG=(0,m.h)("response-poller");function aH(a){return b=>{try{(0,g.broadcastMessage)("message_updated",{worktreeId:a,message:b})}catch(b){aG.warn("prompt-sweep-broadcast-failed",{worktreeId:a,error:b instanceof Error?b.message:String(b)})}}}function aI(a){return{response:"",isComplete:!1,lineCount:a}}function aJ(a,b,c,d,e,f,g,h=!1){let i=(0,p.QM)(b,c,d,e,f,h),j=a.slice(i);return{response:(0,l.aJ)(j.join("\n")),isComplete:!0,lineCount:c,promptDetection:g,bufferReset:d,captureWindowSaturated:h}}function aK(a,b){let c=(0,l.KO)(b);return(0,h.gF)((0,l._A)((0,l.aJ)(a)),c)}function aL(a,b,c,d=o.xE){let e=a.split("\n"),f=e.length;for(;f>0&&""===e[f-1].trim();)f--;let g=e.slice(0,f),h=g.length,i=(0,o.sl)(e.length,d),j="opencode"===c?g.map(l.aJ):null,k="claude"===c?(0,l.GT)(g):"copilot"===c?(0,l.wv)(g):j?(0,l.x7)(j):-1,m=k>=0?k:h,q=h>0&&b>25&&h+25<b,r=h>0&&b>50&&h<50,s=q||r;if(!s&&h<b-5)return null;let t=Math.max(0,h-20),u=g.slice(t),v=j?j.join("\n"):u.join("\n"),{promptPattern:w,separatorPattern:x,thinkingPattern:y,skipPatterns:z}=(0,l._X)(c),A=(a=60)=>{let b;if("codex"===c)b=/^›\s+(?!Implement|Find and fix|Type|Summarize)/;else if(j)return(0,p.V0)(j).echoEnd;else if("copilot"===c){for(let b=m-1;b>=Math.max(0,m-a);b--){if(!l.y.test((0,l.aJ)(g[b])))continue;let a=b;for(;a+1<m&&l.Fg.test((0,l.aJ)(g[a+1]));)a++;return a}return -1}else b=/^[>❯]\s+\S/;for(let c=m-1;c>=Math.max(0,m-a);c--){let a=(0,l.aJ)(g[c]);if(b.test(a))return c}return -1};if("claude"===c||"codex"===c||"copilot"===c){let a=aK(g.join("\n"),c);if(a.isPrompt)return aJ(g,b,h,s,c,A,a,i)}let B=(0,l.aJ)(v),C=w.test(B),D=x.test(B),E="codex"===c?(0,l.DR)(g,20):y.test(B),F="copilot"===c?(0,l.Wn)(g.slice(Math.max(0,h-8)).map(l.aJ)):null,G="copilot"===c?"idle"===F:("codex"===c||"gemini"===c||"vibe-local"===c||"antigravity"===c)&&C&&!E,H="claude"===c&&C&&D&&!E,I="opencode"===c&&(0,p.bE)(B);if(G||H||I){let a=[],d=(0,p.QM)(b,h,s,c,A,i),e=h;for(let b=d;b<m;b++){let d=g[b],f=(0,l.aJ)(d);if("codex"===c&&/^›\s+/.test(f)||"gemini"===c&&/^(%|\$|.*@.*[%$#])\s*$/.test(f)||"antigravity"===c&&/^>\s*$/.test(f)||"opencode"===c&&k<0&&(l.sy.test(f)||l.uA.test(f))){e=b;break}z.some(a=>a.test(f))||a.push(d)}let f=a.join("\n").trim(),o=f.split("\n").slice(-n.$).join("\n");if("copilot"!==c&&y.test(o))return aI(h);if("claude"===c){let a=(0,l.aJ)(f),b=/[╭╮╰╯│]/.test(a)||/░{3,}/.test(a)||/▓{3,}/.test(a),c=/Claude Code|claude\/|v\d+\.\d+/.test(a),d=/Tip:|for shortcuts|\?\s*for help/.test(a),e=/^\s*\/Users\/.*$/m.test(a)&&a.split("\n").length<30,g=a.match(/^[>❯]\s+(\S.*)$/m);if(g){let b=a.indexOf(g[0]);if(0===a.substring(b+g[0].length).trim().split("\n").filter(a=>{let b=a.trim();return b&&!z.some(a=>a.test(b))&&!/^─+$/.test(b)}).length)return aI(h)}else if((b||c||d||e)&&f.length<2e3)return aI(h)}if("copilot"===c){let a=(0,l.aJ)(f);if(!a.split("\n").some(a=>l.y.test(a))&&l.E0.some(b=>b.test(a)))return aI(h)}if("gemini"===c&&((f.match(/[░███]/g)||[]).length>.3*f.length||ay.SI.some(a=>f.includes(a))||!f.includes("✦")&&f.length<10))return aI(h);if("opencode"===c){let a=(0,l.aJ)(f);if((a.length<50||!l.Md.test(B))&&0===a.split("\n").filter(a=>{let b=a.trim();return b&&!l.sx.some(a=>a.test(b))}).length)return aI(h)}return{response:f,isComplete:!0,lineCount:e,bufferReset:s,captureWindowSaturated:i,turnHeadTruncated:j?(0,p.V0)(j).headTruncated:void 0}}if("opencode"!==c){let a=aK(g.join("\n"),c);if(a.isPrompt)return aJ(g,b,h,s,c,A,a,i)}let J=[],K=s||i||b>=h-5,L=K?A(80):-1,M=K?L>=0?L+1:Math.max(0,h-80):Math.max(0,b);for(let a=M;a<Math.min(h,m);a++){let b=g[a],c=(0,l.aJ)(b);z.some(a=>a.test(c))||J.push(b)}let N=J.join("\n").trim();return N?{response:N,isComplete:!1,lineCount:h}:aI(h)}async function aM(a,b,c){let h=(0,e.getDbInstance)(),m=c??b;try{let e=(0,f.getWorktreeById)(h,a);if(!e)return aG.error("worktree-worktreeid-not"),(0,ay.Et)(a,b,c),!1;if(!await (0,d.K1)(a,b,c))return aG.info("session-not-running"),(0,ay.Et)(a,b,c),!1;let x=(0,f.getSessionState)(h,a,m),y=x?.lastCapturedLine||0,z=await (0,d.Wh)(a,b,o.xE,c),A=z.split("\n").slice(-100).join("\n"),B=(0,aC.bT)(A);if((0,aB.notifyUpstreamFaultPush)({worktreeId:a,cliToolId:b,instanceId:c,faultId:B?.fault.id??null,matchedText:B?.matchedText}).catch(()=>{}),"opencode"===b||"copilot"===b){let d=(0,ay.MN)(a,b,c),e="opencode"===b?(0,p.ZX)(z):z;(0,s.IZ)(d,e,b)}let C=aL(z,y,b,o.xE);if(!C||!C.isComplete){let{thinkingPattern:c}=(0,l._X)(b),d=(0,l.aJ)(z).split("\n").slice(-n.$).join("\n");return c.test(d)&&(0,f.markPendingPromptsAsAnswered)(h,a,b,m,aH(a))>0&&aG.info("marked-answeredcount-pending"),!1}let D="opencode"===b||"copilot"===b,E=!(0,j.VA)(b)&&!C.captureWindowSaturated;if(E&&!C.bufferReset&&C.lineCount===y&&!x?.inProgressMessageId)return!1;if(E&&!C.bufferReset&&C.lineCount<=y)return aG.info("already-saved-up-to-line-lastcapturedlin"),!1;let F=C.promptDetection??aK(C.response,b);if(F.isPrompt){let d=F.rawContent||F.cleanContent,i=(0,ay.MN)(a,b,c),j=(0,t.zm)(d,b);if((0,t.gv)(i,j))return(0,u.LN)(a,b,c),aG.info("duplicate-prompt-skipped",{worktreeId:a,cliToolId:b}),!1;let k=d;"copilot"===b&&(k=(0,q.LH)(d),k=(0,q.Sj)(k,r.Rf,r.ky)),(0,f.clearInProgressMessageId)(h,a,b,m);let l=(0,f.createMessage)(h,{worktreeId:a,role:"assistant",content:k,messageType:"prompt",promptData:F.promptData,timestamp:new Date,cliToolId:b,instanceId:m});(0,f.updateSessionState)(h,a,b,C.lineCount,m),(0,g.broadcastMessage)("message",{worktreeId:a,message:l}),(0,aF.r)(h,a,b,m,"prompt_detected",{promptType:F.promptData?.type});let n=Date.now(),o=(0,aE.Jp)(a,b,c)?.since??n;return(0,aA.R)({worktreeId:a,cliToolId:b,instanceId:c,waitingSince:o})||(0,az.J$)({worktreeId:a,worktreeName:e.name,kind:"prompt",agentName:m,instanceId:m,waitingKind:"prompt",waitingSince:o,excerpt:F.promptData?.question??k}).catch(()=>{}),(0,aE.hd)({worktreeId:a,cliToolId:b,instanceId:c,waiting:!0,kind:"prompt",now:n}),D||(0,ay.Et)(a,b,c),!0}if(!C.response||""===C.response.trim())return(0,f.updateSessionState)(h,a,b,C.lineCount,m),!1;let G="claude"===b?(0,k.R)(C.response):void 0,H=C.response;if("gemini"===b)H=(0,q.IS)(C.response);else if("claude"===b)H=(0,q.NN)(C.response);else if("copilot"===b){let d=(0,ay.MN)(a,b,c),e=(0,s.Uz)(d)||C.response;H=(0,q.LH)(e),H=(0,q.Sj)(H,r.Rf,r.ky),(0,s.q1)(d)}else if("opencode"===b){let d=(0,ay.MN)(a,b,c),e=(0,s.Uz)(d),f=C.turnHeadTruncated&&e?e:C.response;H=(0,q.aW)(f),(0,s.q1)(d)}if(!H||""===H.trim()||"[No content]"===H)return(0,f.updateSessionState)(h,a,b,C.lineCount,m),(0,f.clearInProgressMessageId)(h,a,b,m),!1;if(!E){let d=(0,ay.MN)(a,b,c);if((0,v.j7)(d,H))return aG.info("duplicate-response-skipped",{worktreeId:a,cliToolId:b,instanceId:m}),(0,f.updateSessionState)(h,a,b,C.lineCount,m),!1}let I=function(a,b,c){if("push"!==aw(b))return!1;try{return(0,w.f4)({worktreeId:a,cliToolId:b,instanceId:c??b})}catch(d){return au.warn("structured-history-gate-unavailable",{worktreeId:a,cliToolId:b,instanceId:c??b,error:d instanceof Error?d.message:String(d)}),!1}}(a,b,c)||await ax(a,b,c,{worktreePath:e.path,transcriptPathHint:G?.logFilePath??null});H&&!I&&await (0,i.T)(h,a,H,b),(0,f.markPendingPromptsAsAnswered)(h,a,b,m,aH(a))>0&&aG.info("marked-answeredcount-pending");let J=(0,f.getSessionState)(h,a,m);if(E&&J&&C.lineCount<=J.lastCapturedLine)return aG.info("race-condition-detected-skipping-save-re"),!1;if(I)aG.info("structured-history-scrape-suppressed",{worktreeId:a,cliToolId:b,instanceId:m,scrapedLength:H.length});else{let c=(0,f.createMessage)(h,{worktreeId:a,role:"assistant",content:H,messageType:"normal",timestamp:new Date,cliToolId:b,instanceId:m,summary:G?.summary,logFileName:G?.logFileName,requestId:G?.requestId});(0,g.broadcastMessage)("message",{worktreeId:a,message:c})}return(0,aE.hd)({worktreeId:a,cliToolId:b,instanceId:c,waiting:!1}),(0,az.J$)({worktreeId:a,worktreeName:e.name,kind:"completion",agentName:m,excerpt:H}).catch(()=>{}),(0,f.updateSessionState)(h,a,b,C.lineCount,m),D&&(0,ay.Et)(a,b,c),!0}catch(a){return aG.error("response:check-failed",{error:a instanceof Error?a.message:String(a)}),!1}}(0,aD.I7)()},91601:(a,b,c)=>{c.d(b,{Di:()=>f.Di,HR:()=>d.HR,J$:()=>e.notifyPushSubscribers,O$:()=>f.O$,d7:()=>f.d7,rS:()=>f.rS});var d=c(27519);c(8532);var e=c(61191);c(3915),c(92010),c(81099),c(77703),c(73478);var f=c(80544);c(50779),c(4806)},92010:(a,b,c)=>{c.d(b,{R:()=>h});var d=c(24455),e=c(72626),f=c(52277);let g=(0,e.h)("push/prompt-gate");function h(a){let b=function(a){let{worktreeId:b,cliToolId:c,instanceId:e,waitingSince:g}=a,h=(0,d.aq)(b,c,e);if(null===h||!h.enabled)return{suppress:!1,reason:"auto-yes-inactive",stopReason:h?.stopReason};let i=(0,f.gb)(b,c,e);return null!==i&&i.at>=g?{suppress:!1,reason:"policy-withheld",suppressedBy:i.reason}:!0===a.escalated?{suppress:!1,reason:"escalation-reminder"}:{suppress:!0,reason:"auto-yes-answering"}}(a),c={worktreeId:a.worktreeId,cliToolId:a.cliToolId,instanceId:a.instanceId??a.cliToolId,waitingSince:a.waitingSince,escalated:!0===a.escalated,reason:b.reason,...void 0!==b.stopReason?{stopReason:b.stopReason}:{},...void 0!==b.suppressedBy?{suppressedBy:b.suppressedBy}:{}};return b.suppress?g.info("prompt-push-suppressed",c):g.debug("prompt-push-allowed",c),b.suppress}},99508:(a,b,c)=>{c.r(b),c.d(b,{INTERACTION_SNAPSHOT_RETRY_DELAYS_MS:()=>l,__resetTerminalBroadcastState:()=>s,broadcastSessionStatus:()=>r,broadcastTerminalSnapshot:()=>m,broadcastTerminalSnapshotAfterInteraction:()=>q});var d=c(79129),e=c(88807),f=c(1058),g=c(72626),h=c(83468),i=c(93997);let j=(0,g.h)("terminal-broadcast"),k=globalThis.__terminalSnapshotVersions??(globalThis.__terminalSnapshotVersions=new Map),l=[100,250,500,750];async function m(a,b,c){if((0,d.hasRoomSubscribers)(a))try{let d=(0,e.getDbInstance)(),g=await (0,f.$v)(d,a,b,c);p(a,b,g,c)}catch(b){j.error("terminal-snapshot:failed",{worktreeId:a,error:b instanceof Error?b.message:String(b)})}}function n(a){return JSON.stringify([a.fullOutput??"",a.isRunning,a.sessionStatus,a.thinking??!1,a.isPromptWaiting??!1,a.isSelectionListActive??!1,a.isPagerActive??!1,a.isUnclassifiedActive??!1])}async function o(a,b,c){let d=h.CLIToolManager.getInstance().getTool(b);return(0,i.gm)(d.getSessionName(a,c)),(0,f.$v)((0,e.getDbInstance)(),a,b,c)}function p(a,b,c,e){let f=e??b,g=`${a}:${b}:${f}`;(0,d.broadcast)(a,{type:"terminal_snapshot",worktreeId:a,cliToolId:b,instanceId:f,output:c.fullOutput??"",isRunning:c.isRunning,sessionStatus:c.sessionStatus,thinking:c.thinking??!1,isPromptWaiting:c.isPromptWaiting??!1,promptData:c.promptData??null,isSelectionListActive:c.isSelectionListActive??!1,isPagerActive:c.isPagerActive??!1,isUnclassifiedActive:c.isUnclassifiedActive??!1,version:function(a){let b=(k.get(a)??0)+1;return k.set(a,b),b}(g)})}async function q(a,b,c,e=l){if((0,d.hasRoomSubscribers)(a))try{let d=await o(a,b,c),f=n(d);for(let g of(p(a,b,d,c),e)){await new Promise(a=>setTimeout(a,g));let d=await o(a,b,c);if(n(d)!==f)return void p(a,b,d,c)}}catch(d){j.error("terminal-snapshot:interaction-refresh-failed",{worktreeId:a,cliToolId:b,instanceId:c,error:d instanceof Error?d.message:String(d)})}}function r(a,b,c){(0,d.broadcast)(a,{type:"session_status_changed",worktreeId:a,isRunning:b,cliTool:c?.cliTool??null,instance:c?.instance??null})}function s(){k.clear()}}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=6781,exports.ids=[6781],exports.modules={16781:(a,b,c)=>{c.r(b),c.d(b,{AGENT_EVENT_TYPES:()=>m.b0,MAX_CWD_LENGTH:()=>o,applyAgentStopEvent:()=>t,isAgentEventType:()=>m.o0,resolveWorktreeByCwd:()=>r,validateHookCwd:()=>p});var d=c(29021),e=c(33873),f=c(56791),g=c(48524),h=c(66007),i=c(52767),j=c(23707),k=c(48083),l=c(72626),m=c(62887);let n=(0,l.h)("lib/hooks/agent-event-service"),o=4096;function p(a){if("string"!=typeof a||""===a.trim())return{ok:!1,reason:"empty"};if(a.length>o)return{ok:!1,reason:"too_long"};let b=a;try{b=decodeURIComponent(a)}catch{b=a}return a.includes("\0")||b.includes("\0")?{ok:!1,reason:"nul_byte"}:(0,e.isAbsolute)(a)?q(a)||q(b)?{ok:!1,reason:"traversal"}:{ok:!0,cwd:a}:{ok:!1,reason:"not_absolute"}}function q(a){return a.split("\\"===e.sep?/[\\/]/:"/").some(a=>".."===a)}function r(a,b){let c=s(b);if(null===c)return null;let d=null,e=-1;for(let b of(0,f.getWorktrees)(a)){let a=s(b.path);null!==a&&(0,h.Uc)(c,a)&&a.length>e&&(d=b,e=a.length)}return d}function s(a){try{return(0,d.realpathSync)(a)}catch{return null}}async function t(a,b,c,d){let e;(0,k.S9)(b.id,c,d);try{e=(0,g.MH)(a,b.id,c,d)}catch(a){return n.warn("agent-stop-task-lookup-failed",{worktreeId:b.id,error:a instanceof Error?a.message:String(a)}),{taskId:null,taskEventApplied:!1,verificationRunId:null}}if(!e)return{taskId:null,taskEventApplied:!1,verificationRunId:null};let f=!1;try{let b=(0,i.g)(a,e.id,"agent_idle",{source:"hook"});f=null!==b&&null!==b.toStatus}catch(a){n.warn("agent-stop-event-failed",{taskId:e.id,error:a instanceof Error?a.message:String(a)})}if(!e.contract.success.autoVerifyOnStop)return{taskId:e.id,taskEventApplied:f,verificationRunId:null};let h=null;try{let{runId:a}=await (0,j.AT)({worktreeId:b.id,worktreePath:b.path,instanceId:d,taskId:e.id,trigger:"task"});h=a}catch(a){a instanceof j.Wb||n.error("agent-stop-auto-verify-failed",{taskId:e.id,error:a instanceof Error?a.message:String(a)})}return{taskId:e.id,taskEventApplied:f,verificationRunId:h}}}};
|