commandmate 0.47.2 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +215 -215
- package/.next/app-path-routes-manifest.json +41 -41
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +9 -9
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/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/release-notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route.js +3 -3
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/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 +2 -2
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route.js +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/route.js +1 -1
- package/.next/server/app/api/relays/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route_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/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js.nft.json +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]/prompt-response/strict/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +3 -3
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -103
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/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.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 +41 -41
- package/.next/server/chunks/1191.js +11 -4
- package/.next/server/chunks/1501.js +1 -1
- package/.next/server/chunks/1601.js +2 -2
- package/.next/server/chunks/1656.js +2 -2
- package/.next/server/chunks/1945.js +3 -3
- package/.next/server/chunks/1990.js +103 -0
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/2422.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/2534.js +1 -1
- package/.next/server/chunks/255.js +1 -1
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3505.js +2 -2
- package/.next/server/chunks/4248.js +1 -1
- package/.next/server/chunks/4280.js +1 -0
- package/.next/server/chunks/5209.js +1 -1
- package/.next/server/chunks/6119.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/6486.js +9 -8
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/720.js +103 -0
- package/.next/server/chunks/7604.js +2 -0
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8581.js +7 -7
- package/.next/server/chunks/8728.js +3 -3
- package/.next/server/chunks/8791.js +1 -1
- package/.next/server/chunks/8807.js +19 -18
- package/.next/server/chunks/8918.js +2 -104
- package/.next/server/chunks/936.js +1 -1
- package/.next/server/chunks/9390.js +1 -1
- package/.next/server/chunks/9540.js +1 -1
- package/.next/server/chunks/9627.js +3 -3
- package/.next/server/chunks/9731.js +2 -2
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/2099-c3e0ab70a1b95dd3.js +1 -0
- package/.next/static/chunks/{2407-a6533805a86d05bd.js → 2407-26139a8a2f1adbe8.js} +1 -1
- package/.next/static/chunks/{2619-04bc32f026a0d946.js → 2619-a305ad4810f1393a.js} +1 -1
- package/.next/static/chunks/{2863-6a07ec82fb52f4dd.js → 2863-f0121af1cbbedb3b.js} +1 -1
- package/.next/static/chunks/{8165-263172c17ae8e8c3.js → 8165-c68b3dc844210e6a.js} +1 -1
- package/.next/static/chunks/8407-35bbfc84793d7004.js +1 -0
- package/.next/static/chunks/9079-406b84d3cc891a87.js +1 -0
- package/.next/static/chunks/app/{layout-538d8d2746ad1588.js → layout-46b4cbf07520d9b6.js} +1 -1
- package/.next/static/chunks/app/sessions/page-fb241bed579c67aa.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-cbc7749a33450cc5.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/terminal/{page-373ea37b16d930c7.js → page-c601f3b3ece6557e.js} +1 -1
- package/.next/trace +13 -13
- package/dist/cli/commands/auto-yes.d.ts +24 -0
- package/dist/cli/commands/auto-yes.d.ts.map +1 -1
- package/dist/cli/commands/auto-yes.js +73 -3
- package/dist/cli/commands/instances.d.ts.map +1 -1
- package/dist/cli/commands/instances.js +10 -1
- package/dist/cli/commands/prompt.d.ts.map +1 -1
- package/dist/cli/commands/prompt.js +5 -3
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +15 -0
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +101 -13
- package/dist/cli/docs/agent-operations.d.ts +2 -2
- package/dist/cli/docs/agent-operations.d.ts.map +1 -1
- package/dist/cli/docs/agent-operations.js +27 -0
- package/dist/cli/types/api-responses.d.ts +116 -2
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/types/index.d.ts +4 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/utils/resource-resolvers.d.ts +0 -18
- package/dist/cli/utils/resource-resolvers.d.ts.map +1 -1
- package/dist/cli/utils/resource-resolvers.js +1 -51
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts +54 -2
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts.map +1 -1
- package/dist/lib/polling/auto-yes-suppression-reason.js +33 -2
- package/dist/lib/prompt-observation/types.d.ts +13 -0
- package/dist/lib/prompt-observation/types.d.ts.map +1 -1
- package/dist/server/locales/en/worktree.json +2 -1
- package/dist/server/locales/ja/worktree.json +2 -1
- package/dist/server/src/lib/auto-yes-poller-answer-target.js +38 -0
- package/dist/server/src/lib/auto-yes-poller-keys.js +35 -0
- package/dist/server/src/lib/auto-yes-poller-session-presence.js +26 -0
- package/dist/server/src/lib/auto-yes-poller-tick.js +233 -0
- package/dist/server/src/lib/auto-yes-poller.js +337 -376
- package/dist/server/src/lib/auto-yes-state.js +50 -2
- package/dist/server/src/lib/cli-tools/submit-verified-sender.js +107 -14
- package/dist/server/src/lib/db/chat-db.js +5 -1
- package/dist/server/src/lib/db/verification-db.js +23 -2
- package/dist/server/src/lib/detection/option-recommendation.js +120 -0
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice-approval-context.js +290 -0
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +396 -350
- package/dist/server/src/lib/detection/prompt-detector.js +92 -21
- package/dist/server/src/lib/detection/prompt-screen-key.js +60 -0
- package/dist/server/src/lib/detection/tools/antigravity/dialog.js +158 -35
- package/dist/server/src/lib/detection/tools/claude/detect.js +111 -10
- package/dist/server/src/lib/detection/tools/command-code/dialog.js +67 -0
- package/dist/server/src/lib/detection/tools/dialog-block.js +16 -0
- package/dist/server/src/lib/detection/waiting-screen-reading.js +98 -0
- package/dist/server/src/lib/hooks/permission-decision-service.js +7 -0
- package/dist/server/src/lib/polling/auto-yes-confirm-page.js +2 -2
- package/dist/server/src/lib/polling/auto-yes-confirmation-ledger-types.js +3 -0
- package/dist/server/src/lib/polling/auto-yes-confirmation-ledger.js +34 -3
- package/dist/server/src/lib/polling/auto-yes-decision-state.js +195 -0
- package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +139 -10
- package/dist/server/src/lib/polling/auto-yes-enter-fallback.js +14 -0
- package/dist/server/src/lib/polling/auto-yes-manual-answer.js +122 -0
- package/dist/server/src/lib/polling/auto-yes-option-effect.js +157 -0
- package/dist/server/src/lib/polling/auto-yes-policy.js +11 -5
- package/dist/server/src/lib/polling/auto-yes-poller-capture.js +15 -2
- package/dist/server/src/lib/polling/auto-yes-poller-generation.js +42 -1
- package/dist/server/src/lib/polling/auto-yes-poller-receipt-log.js +42 -5
- package/dist/server/src/lib/polling/auto-yes-poller-state.js +147 -49
- package/dist/server/src/lib/polling/auto-yes-poller-steps.js +172 -2
- package/dist/server/src/lib/polling/auto-yes-prompt-suppression.js +2 -2
- package/dist/server/src/lib/polling/auto-yes-question-choice.js +57 -0
- package/dist/server/src/lib/polling/auto-yes-resolver.js +96 -21
- package/dist/server/src/lib/polling/auto-yes-suppression-reason.js +33 -2
- package/dist/server/src/lib/polling/auto-yes-suppression-state.js +25 -1
- package/dist/server/src/lib/polling/prompt-screen-reading.js +232 -0
- package/dist/server/src/lib/polling/response-checker-dialog-gate.js +39 -0
- package/dist/server/src/lib/polling/response-checker.js +133 -43
- package/dist/server/src/lib/prompt-answer-sender.js +104 -10
- package/dist/server/src/lib/push/notification-dedup.js +15 -2
- package/dist/server/src/lib/push/prompt-card-state.js +140 -19
- package/dist/server/src/lib/push/prompt-push-gate.js +158 -12
- package/dist/server/src/lib/push/push-sender.js +23 -3
- package/dist/server/src/lib/push/resolution-push-notifier.js +14 -0
- package/dist/server/src/lib/push/waiting-push-notifier.js +139 -17
- package/dist/server/src/lib/realtime/terminal-broadcast.js +16 -0
- package/dist/server/src/lib/session/agent-event-state.js +25 -5
- package/dist/server/src/lib/session/agent-event-turn.js +140 -46
- package/dist/server/src/lib/session/cli-session.js +21 -2
- package/dist/server/src/lib/session/current-output-builder.js +64 -11
- package/dist/server/src/lib/session/send-attempt-state.js +23 -7
- package/dist/server/src/lib/session/waiting-episode-binding-observation.js +289 -0
- package/dist/server/src/lib/session/waiting-episode-binding-resolve.js +38 -0
- package/dist/server/src/lib/session/waiting-episode-binding.js +276 -0
- package/dist/server/src/lib/session/waiting-episode-state.js +307 -17
- package/dist/server/src/lib/session/waiting-episode-verdict.js +174 -0
- package/dist/server/src/lib/tmux/tmux-capture-cache.js +76 -11
- package/dist/server/src/lib/tmux/tmux.js +54 -9
- package/dist/server/src/lib/verification/gate-runner.js +162 -13
- package/dist/server/src/lib/verification/machine-lock.js +5 -0
- package/dist/server/src/lib/ws-server.js +18 -3
- package/dist/server/src/types/auto-yes-answer-mode.js +38 -0
- package/dist/server/src/types/auto-yes-decision.js +61 -0
- package/dist/server/src/types/auto-yes.js +6 -0
- package/dist/server/src/types/prompt-reading.js +32 -0
- package/dist/types/auto-yes-answer-mode.d.ts +35 -0
- package/dist/types/auto-yes-answer-mode.d.ts.map +1 -0
- package/dist/types/auto-yes-answer-mode.js +38 -0
- package/docs/en/user-guide/webapp-guide.md +33 -4
- package/package.json +1 -1
- package/public/sw.js +76 -4
- package/release-notes/0.48.0.json +57 -0
- package/.next/server/chunks/1559.js +0 -2
- package/.next/server/chunks/2460.js +0 -1
- package/.next/server/chunks/5595.js +0 -1
- package/.next/server/chunks/610.js +0 -1
- package/.next/static/chunks/602-1c1488959215e140.js +0 -1
- package/.next/static/chunks/8407-155f84e5ba05f1d5.js +0 -1
- package/.next/static/chunks/9079-24f9fa549ed298f1.js +0 -1
- package/.next/static/chunks/app/sessions/page-e02f1adb1d1c1ccc.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-46aced20b2b1c010.js +0 -1
- /package/.next/static/{etorRtpxbQqqOzdUeXdw2 → PTlAswXLq8PAe2vUJ8dVP}/_buildManifest.js +0 -0
- /package/.next/static/{etorRtpxbQqqOzdUeXdw2 → PTlAswXLq8PAe2vUJ8dVP}/_ssgManifest.js +0 -0
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.reopenedTurns = exports.agentTurns = exports.generationStartedAt = void 0;
|
|
13
|
+
exports.registerTurnOutcomeSink = registerTurnOutcomeSink;
|
|
14
|
+
exports.toGenerationRef = toGenerationRef;
|
|
15
|
+
exports.liveDecisionCount = liveDecisionCount;
|
|
13
16
|
exports.currentGeneration = currentGeneration;
|
|
14
17
|
exports.effectiveTurn = effectiveTurn;
|
|
15
18
|
exports.livePendingDecisions = livePendingDecisions;
|
|
@@ -71,6 +74,38 @@ exports.reopenedTurns = (0, global_state_1.getOrInitGlobal)('__agentEventReopene
|
|
|
71
74
|
* boundary rather than a cosmetic clash.
|
|
72
75
|
*/
|
|
73
76
|
const turnSequence = (0, global_state_1.getOrInitGlobal)('__agentEventTurnSeq', () => ({ value: 0 }));
|
|
77
|
+
/**
|
|
78
|
+
* Install the sink for outcomes this module produces outside a
|
|
79
|
+
* `recordAgentEvent` call. Registered by `waiting-episode-binding`, through
|
|
80
|
+
* `globalThis`, so this module imports nothing that imports it back.
|
|
81
|
+
*/
|
|
82
|
+
function registerTurnOutcomeSink(sink) {
|
|
83
|
+
globalThis.__agentEventTurnOutcomeSink = sink;
|
|
84
|
+
}
|
|
85
|
+
/** A generation as the waiting episode names it. */
|
|
86
|
+
function toGenerationRef(generation) {
|
|
87
|
+
return generation === null ? { kind: 'none' } : { kind: 'opened', at: generation };
|
|
88
|
+
}
|
|
89
|
+
/** Live decisions held by a record, counted without retiring the expired ones. */
|
|
90
|
+
function liveDecisionCount(turn, now) {
|
|
91
|
+
return turn.pendingDecisions.filter((decision) => (0, provisional_turn_1.isDecisionLive)(decision, now)).length;
|
|
92
|
+
}
|
|
93
|
+
/** Describe the instance's record before a transition rewrites it. */
|
|
94
|
+
function describePrevious(turn, eventSessionId, at) {
|
|
95
|
+
if (turn === null)
|
|
96
|
+
return { kind: 'none' };
|
|
97
|
+
if (turn.closedAt !== null)
|
|
98
|
+
return { kind: 'closed', turnId: turn.turnId, closedBy: turn.closedBy ?? 'stop' };
|
|
99
|
+
if (turn.openedAt === null) {
|
|
100
|
+
const decisions = liveDecisionCount(turn, at);
|
|
101
|
+
return decisions > 0
|
|
102
|
+
? { kind: 'dialog-only', turnId: turn.turnId, decisions, sessionId: turn.sessionId }
|
|
103
|
+
: { kind: 'display-only', turnId: turn.turnId };
|
|
104
|
+
}
|
|
105
|
+
return (0, provisional_turn_1.closesTurn)(turn, eventSessionId)
|
|
106
|
+
? { kind: 'open-same-session', turnId: turn.turnId }
|
|
107
|
+
: { kind: 'open-other-session', turnId: turn.turnId };
|
|
108
|
+
}
|
|
74
109
|
// =============================================================================
|
|
75
110
|
// Turn model (Issue #1930)
|
|
76
111
|
// =============================================================================
|
|
@@ -283,10 +318,18 @@ function observeScraperCompletionEvidence(worktreeId, cliToolId, instanceId, com
|
|
|
283
318
|
* were raised by a process that no longer exists, and answering one would
|
|
284
319
|
* deliver a verdict into a slot nobody is holding.
|
|
285
320
|
*/
|
|
286
|
-
function fenceTurnForNewGeneration(key, at) {
|
|
321
|
+
function fenceTurnForNewGeneration(key, at, source = 'session-start') {
|
|
287
322
|
const turn = exports.agentTurns.get(key);
|
|
323
|
+
// Issue #3798: reported whether or not a turn existed — the waiting episode
|
|
324
|
+
// is fenced by its own generation, not by the turn's.
|
|
325
|
+
const outcome = {
|
|
326
|
+
kind: 'generation-fenced',
|
|
327
|
+
source,
|
|
328
|
+
generation: toGenerationRef(currentGeneration(key)),
|
|
329
|
+
fencedTurnId: turn?.turnId ?? null,
|
|
330
|
+
};
|
|
288
331
|
if (!turn)
|
|
289
|
-
return;
|
|
332
|
+
return outcome;
|
|
290
333
|
evictDecisions(key, turn);
|
|
291
334
|
// A turn that had ALREADY ended is left where it is, which means the fence in
|
|
292
335
|
// `fencedTurn` hides it from here on. That asymmetry is deliberate: the
|
|
@@ -295,7 +338,7 @@ function fenceTurnForNewGeneration(key, at) {
|
|
|
295
338
|
// nobody has typed into yet. Before #1930 the same protection came from
|
|
296
339
|
// comparing the event's timestamp against the generation.
|
|
297
340
|
if (turn.closedAt !== null)
|
|
298
|
-
return;
|
|
341
|
+
return outcome;
|
|
299
342
|
// An OPEN turn is closed and carried across, so `capture --json` can say
|
|
300
343
|
// `closedBy: 'generation'` rather than going quiet. `getStructuredSessionState`
|
|
301
344
|
// reads that reason as "nothing is known", so it publishes no verdict either
|
|
@@ -304,6 +347,7 @@ function fenceTurnForNewGeneration(key, at) {
|
|
|
304
347
|
turn.closedAt = at;
|
|
305
348
|
turn.closedBy = 'generation';
|
|
306
349
|
turn.generationAt = at;
|
|
350
|
+
return outcome;
|
|
307
351
|
}
|
|
308
352
|
/**
|
|
309
353
|
* The turn transition: what one delivery does to {@link TurnRecord}
|
|
@@ -406,23 +450,32 @@ function applyTurnTransition(key, record) {
|
|
|
406
450
|
// An event stamped before the current generation was produced by a process
|
|
407
451
|
// that has been replaced. Refusing it here is what makes re-recording a stale
|
|
408
452
|
// `user_prompt_submit` at its original timestamp a no-op.
|
|
409
|
-
if (generation !== null && record.at < generation)
|
|
410
|
-
|
|
453
|
+
if (generation !== null && record.at < generation) {
|
|
454
|
+
if (record.event === 'stop')
|
|
455
|
+
return { kind: 'stop-rejected', reason: 'before-generation' };
|
|
456
|
+
if (record.event === 'session_end')
|
|
457
|
+
return { kind: 'session-end-rejected', reason: 'before-generation' };
|
|
458
|
+
return { kind: 'none' };
|
|
459
|
+
}
|
|
411
460
|
switch (record.event) {
|
|
412
|
-
case 'user_prompt_submit':
|
|
461
|
+
case 'user_prompt_submit': {
|
|
413
462
|
// Issue #3330: a queued notice the agent attached to its running turn
|
|
414
463
|
// continues that turn; any other prompt is a new one.
|
|
415
|
-
openTurn(key, record, generation, {
|
|
464
|
+
const outcome = openTurn(key, record, 'user_prompt_submit', generation, {
|
|
465
|
+
continueOpen: record.joinsOpenTurn === true,
|
|
466
|
+
});
|
|
416
467
|
releaseAllDecisions(key);
|
|
417
|
-
return;
|
|
418
|
-
|
|
419
|
-
|
|
468
|
+
return outcome;
|
|
469
|
+
}
|
|
470
|
+
case 'post_tool_use': {
|
|
471
|
+
const outcome = openTurn(key, record, 'post_tool_use', generation, { continueOpen: true });
|
|
420
472
|
// The tool call the dialog was gating has finished, so somebody answered
|
|
421
473
|
// it (Issue #1726). This is the release #1725 could not have: it had no
|
|
422
474
|
// event meaning "the human answered", only `Stop` meaning "the turn
|
|
423
475
|
// ended", which can be minutes later.
|
|
424
476
|
releaseAllDecisions(key);
|
|
425
|
-
return;
|
|
477
|
+
return outcome;
|
|
478
|
+
}
|
|
426
479
|
case 'pre_tool_use':
|
|
427
480
|
// Deliberately leaves the dialog alone (Issue #1726). It is the
|
|
428
481
|
// `AskUserQuestion` invocation, and a picker being *about to be drawn* is
|
|
@@ -432,28 +485,26 @@ function applyTurnTransition(key, record) {
|
|
|
432
485
|
// start of a turn when the agent's own `Stop` is the last thing that
|
|
433
486
|
// ended one. See the `after its stop` row above.
|
|
434
487
|
if (record.promptOpensTurns === true && endedByOwnStop(key))
|
|
435
|
-
return;
|
|
436
|
-
openTurn(key, record, generation, { continueOpen: true });
|
|
437
|
-
return;
|
|
488
|
+
return { kind: 'none' };
|
|
489
|
+
return openTurn(key, record, 'pre_tool_use', generation, { continueOpen: true });
|
|
438
490
|
case 'stop':
|
|
439
|
-
applyStopToTurn(key, record, generation);
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
applySessionEndToTurn(key, record);
|
|
491
|
+
return applyStopToTurn(key, record, generation);
|
|
492
|
+
case 'session_end': {
|
|
493
|
+
const outcome = applySessionEndToTurn(key, record);
|
|
443
494
|
releaseAllDecisions(key);
|
|
444
|
-
return;
|
|
495
|
+
return outcome;
|
|
496
|
+
}
|
|
445
497
|
case 'session_start':
|
|
446
498
|
// The generation was opened by `recordAgentEvent` before this ran, and
|
|
447
499
|
// `fenceTurnForNewGeneration` closed the turn with it. Nothing further:
|
|
448
500
|
// the frame carries no verdict, so it is not the displayed event either.
|
|
449
|
-
return;
|
|
501
|
+
return { kind: 'none' };
|
|
450
502
|
case 'notification':
|
|
451
|
-
applyNotificationToTurn(key, record, generation);
|
|
452
|
-
return;
|
|
503
|
+
return applyNotificationToTurn(key, record, generation);
|
|
453
504
|
default:
|
|
454
505
|
// exhaustive check: a new AgentEventType must decide its transition here
|
|
455
506
|
record.event;
|
|
456
|
-
return;
|
|
507
|
+
return { kind: 'none' };
|
|
457
508
|
}
|
|
458
509
|
}
|
|
459
510
|
/**
|
|
@@ -494,8 +545,10 @@ function displayOf(record) {
|
|
|
494
545
|
* this event's turn. False for `user_prompt_submit`, which IS a new turn —
|
|
495
546
|
* unless the source marked it as joining the running one (Issue #3330).
|
|
496
547
|
*/
|
|
497
|
-
function openTurn(key, record, generation, { continueOpen }) {
|
|
548
|
+
function openTurn(key, record, event, generation, { continueOpen }) {
|
|
498
549
|
const turn = fencedTurn(key);
|
|
550
|
+
// Issue #3798: read before anything below rewrites the record.
|
|
551
|
+
const previous = describePrevious(turn, record.sessionId, record.at);
|
|
499
552
|
const openHere = turn !== null &&
|
|
500
553
|
turn.closedAt === null &&
|
|
501
554
|
turn.openedAt !== null &&
|
|
@@ -506,7 +559,7 @@ function openTurn(key, record, generation, { continueOpen }) {
|
|
|
506
559
|
// partway through. Learning it is what lets a later `stop` be matched.
|
|
507
560
|
turn.sessionId ??= record.sessionId;
|
|
508
561
|
turn.scraperCompletionPolls = 0;
|
|
509
|
-
return;
|
|
562
|
+
return { kind: 'continued', turnId: turn.turnId };
|
|
510
563
|
}
|
|
511
564
|
// A dialog-only record (openedAt null) is not a turn; its decisions belong to
|
|
512
565
|
// the turn that is opening now, because that is when they were raised.
|
|
@@ -532,6 +585,7 @@ function openTurn(key, record, generation, { continueOpen }) {
|
|
|
532
585
|
exports.reopenedTurns.set(key, { turnId: opened.turnId, replaced: turn });
|
|
533
586
|
(0, agent_event_dedup_1.trimOldestEntries)(exports.reopenedTurns, agent_event_dedup_1.MAX_RECENT_EVENT_KEYS);
|
|
534
587
|
}
|
|
588
|
+
return { kind: 'opened', turnId: opened.turnId, event, generation: toGenerationRef(generation), previous };
|
|
535
589
|
}
|
|
536
590
|
/**
|
|
537
591
|
* Give a dropped copy's queued-notice mark its effect (Issue #3330).
|
|
@@ -590,6 +644,11 @@ function joinOpenTurnFromDuplicate(worktreeId, cliToolId, instanceId, record) {
|
|
|
590
644
|
scraperCompletionPolls: 0,
|
|
591
645
|
});
|
|
592
646
|
exports.reopenedTurns.delete(key);
|
|
647
|
+
// Issue #3798: a wait that opened under the discarded turn belongs to the
|
|
648
|
+
// turn put back. Told through the sink — this runs outside `recordAgentEvent`.
|
|
649
|
+
globalThis.__agentEventTurnOutcomeSink?.({ worktreeId, cliToolId, instanceId }, [
|
|
650
|
+
{ kind: 'restored', restoredTurnId: replaced.turnId, discardedTurnId: current.turnId },
|
|
651
|
+
]);
|
|
593
652
|
return true;
|
|
594
653
|
}
|
|
595
654
|
/**
|
|
@@ -604,15 +663,27 @@ function applyStopToTurn(key, record, generation) {
|
|
|
604
663
|
const turn = fencedTurn(key);
|
|
605
664
|
if (turn !== null && turn.closedAt === null && turn.openedAt !== null) {
|
|
606
665
|
if (!(0, provisional_turn_1.closesTurn)(turn, record.sessionId))
|
|
607
|
-
return;
|
|
666
|
+
return { kind: 'stop-rejected', reason: 'other-session' };
|
|
608
667
|
turn.closedAt = record.at;
|
|
609
668
|
turn.closedBy = 'stop';
|
|
610
669
|
turn.displayEvent = displayOf(record);
|
|
611
670
|
releaseAllDecisions(key);
|
|
612
|
-
return;
|
|
671
|
+
return { kind: 'stopped', turnId: turn.turnId, generation: toGenerationRef(generation) };
|
|
672
|
+
}
|
|
673
|
+
const previous = describePrevious(turn, record.sessionId, record.at);
|
|
674
|
+
// Issue #3798: a dialog raised by one agent session is not ended by another
|
|
675
|
+
// session's stop. Both ids are needed to tell — a record or a stop with no id
|
|
676
|
+
// is read as the same session, as `closesTurn` reads it. opencode publishes
|
|
677
|
+
// `session.idle` for every session its server holds (#1758 §5.6).
|
|
678
|
+
if (previous.kind === 'dialog-only' &&
|
|
679
|
+
previous.sessionId !== null &&
|
|
680
|
+
record.sessionId !== null &&
|
|
681
|
+
previous.sessionId !== record.sessionId) {
|
|
682
|
+
return { kind: 'stop-rejected', reason: 'other-session' };
|
|
613
683
|
}
|
|
684
|
+
const recordTurnId = nextTurnId(record.at);
|
|
614
685
|
exports.agentTurns.set(key, {
|
|
615
|
-
turnId:
|
|
686
|
+
turnId: recordTurnId,
|
|
616
687
|
sessionId: record.sessionId,
|
|
617
688
|
openedAt: null,
|
|
618
689
|
closedAt: record.at,
|
|
@@ -623,6 +694,7 @@ function applyStopToTurn(key, record, generation) {
|
|
|
623
694
|
scraperCompletionPolls: 0,
|
|
624
695
|
});
|
|
625
696
|
boundTurnMap();
|
|
697
|
+
return { kind: 'stop-without-turn', recordTurnId, generation: toGenerationRef(generation), previous };
|
|
626
698
|
}
|
|
627
699
|
/**
|
|
628
700
|
* `session_end`: the agent session this instance was talking to is gone.
|
|
@@ -643,11 +715,12 @@ function applyStopToTurn(key, record, generation) {
|
|
|
643
715
|
function applySessionEndToTurn(key, record) {
|
|
644
716
|
const turn = fencedTurn(key);
|
|
645
717
|
if (turn === null)
|
|
646
|
-
return;
|
|
718
|
+
return { kind: 'session-end-rejected', reason: 'no-turn' };
|
|
647
719
|
if (!(0, provisional_turn_1.closesTurn)(turn, record.sessionId))
|
|
648
|
-
return;
|
|
720
|
+
return { kind: 'session-end-rejected', reason: 'other-session' };
|
|
649
721
|
turn.closedAt = record.at;
|
|
650
722
|
turn.closedBy = 'session_end';
|
|
723
|
+
return { kind: 'session-ended', turnId: turn.turnId };
|
|
651
724
|
}
|
|
652
725
|
/**
|
|
653
726
|
* The notification rows of the transition table.
|
|
@@ -663,10 +736,9 @@ function applyNotificationToTurn(key, record, generation) {
|
|
|
663
736
|
// reached the agent. There is no dialog and there never was one for a
|
|
664
737
|
// human to answer — opening a record for it published `waiting` for the
|
|
665
738
|
// whole of the tool call that followed (measured at eight seconds).
|
|
666
|
-
releaseSettledDecision(key, record);
|
|
667
|
-
return;
|
|
739
|
+
return releaseSettledDecision(key, record);
|
|
668
740
|
}
|
|
669
|
-
openDecision(key, generation, {
|
|
741
|
+
const opened = openDecision(key, generation, {
|
|
670
742
|
source: 'notification',
|
|
671
743
|
at: record.at,
|
|
672
744
|
message: record.message ?? null,
|
|
@@ -679,16 +751,17 @@ function applyNotificationToTurn(key, record, generation) {
|
|
|
679
751
|
patterns: record.decisionPatterns ?? null,
|
|
680
752
|
decisionId: record.decisionId ?? null,
|
|
681
753
|
bootstrapDisplay: displayOf(record),
|
|
754
|
+
sessionId: record.sessionId,
|
|
682
755
|
});
|
|
683
|
-
return;
|
|
756
|
+
return { kind: 'decision-opened', ...opened };
|
|
684
757
|
}
|
|
685
758
|
if (record.detail === agent_event_types_1.PERMISSION_REPLIED_DETAIL) {
|
|
686
759
|
// Issue #1898. The agent's own statement that the dialog is gone — whoever
|
|
687
760
|
// answered it. Not a word this build reads a status from, so it decides
|
|
688
761
|
// nothing; all it does is retire the record.
|
|
689
762
|
if (record.promptSettled === true)
|
|
690
|
-
releaseSettledDecision(key, record);
|
|
691
|
-
return;
|
|
763
|
+
return releaseSettledDecision(key, record);
|
|
764
|
+
return { kind: 'none' };
|
|
692
765
|
}
|
|
693
766
|
if (record.detail === 'idle_prompt') {
|
|
694
767
|
// The agent reporting it is sitting at the composer waiting for input is the
|
|
@@ -697,10 +770,10 @@ function applyNotificationToTurn(key, record, generation) {
|
|
|
697
770
|
const turn = fencedTurn(key);
|
|
698
771
|
if (turn !== null && turn.closedAt === null) {
|
|
699
772
|
turn.displayEvent = displayOf(record);
|
|
700
|
-
return;
|
|
773
|
+
return { kind: 'none' };
|
|
701
774
|
}
|
|
702
775
|
if (turn !== null)
|
|
703
|
-
return;
|
|
776
|
+
return { kind: 'none' };
|
|
704
777
|
// Nothing to attach it to — the first thing this instance ever said, or the
|
|
705
778
|
// first since a generation. It still carries a verdict (`ready`), and #1723
|
|
706
779
|
// publishes it, so a display-only record is opened to hold it. `openedAt`
|
|
@@ -718,10 +791,11 @@ function applyNotificationToTurn(key, record, generation) {
|
|
|
718
791
|
scraperCompletionPolls: 0,
|
|
719
792
|
});
|
|
720
793
|
boundTurnMap();
|
|
721
|
-
return;
|
|
794
|
+
return { kind: 'none' };
|
|
722
795
|
}
|
|
723
796
|
// An unrecognised notification type is not evidence of anything, and guessing
|
|
724
797
|
// would be worse than the scraper.
|
|
798
|
+
return { kind: 'none' };
|
|
725
799
|
}
|
|
726
800
|
/**
|
|
727
801
|
* Open, or refresh, a dialog record on this instance's turn.
|
|
@@ -736,7 +810,7 @@ function openDecision(key, generation, input) {
|
|
|
736
810
|
if (turn === null) {
|
|
737
811
|
turn = {
|
|
738
812
|
turnId: nextTurnId(input.at),
|
|
739
|
-
sessionId: null,
|
|
813
|
+
sessionId: input.sessionId ?? null,
|
|
740
814
|
openedAt: null,
|
|
741
815
|
closedAt: null,
|
|
742
816
|
closedBy: null,
|
|
@@ -754,7 +828,7 @@ function openDecision(key, generation, input) {
|
|
|
754
828
|
// late. Re-open a dialog-only record rather than resurrecting the turn.
|
|
755
829
|
turn = {
|
|
756
830
|
turnId: nextTurnId(input.at),
|
|
757
|
-
sessionId: null,
|
|
831
|
+
sessionId: input.sessionId ?? null,
|
|
758
832
|
openedAt: null,
|
|
759
833
|
closedAt: null,
|
|
760
834
|
closedBy: null,
|
|
@@ -766,6 +840,15 @@ function openDecision(key, generation, input) {
|
|
|
766
840
|
exports.agentTurns.set(key, turn);
|
|
767
841
|
boundTurnMap();
|
|
768
842
|
}
|
|
843
|
+
else if (turn.openedAt === null && turn.sessionId === null) {
|
|
844
|
+
// A dialog-only record bootstrapped by a forecast with no session learns
|
|
845
|
+
// the session from the report that confirms it.
|
|
846
|
+
turn.sessionId = input.sessionId ?? null;
|
|
847
|
+
}
|
|
848
|
+
const opened = {
|
|
849
|
+
recordTurnId: turn.turnId,
|
|
850
|
+
recordKind: turn.openedAt !== null ? 'turn' : 'dialog-only',
|
|
851
|
+
};
|
|
769
852
|
// Issue #1930 / S1: an id that fails validation is DISCARDED, not truncated —
|
|
770
853
|
// a truncated id compares equal to a different id sharing its prefix, and the
|
|
771
854
|
// reply to one approval would then retire another's record.
|
|
@@ -807,14 +890,14 @@ function openDecision(key, generation, input) {
|
|
|
807
890
|
existing.source = 'notification';
|
|
808
891
|
existing.confirmedAt ??= input.at;
|
|
809
892
|
}
|
|
810
|
-
return;
|
|
893
|
+
return opened;
|
|
811
894
|
}
|
|
812
895
|
if (turn.pendingDecisions.length >= provisional_turn_1.MAX_PENDING_DECISIONS_PER_TURN) {
|
|
813
896
|
// S14(d). Counted rather than dropped in silence: an agent raising more
|
|
814
897
|
// approvals than this in one turn is a fact an operator has to be able to
|
|
815
898
|
// see, and the oldest is the one a human has been looking at.
|
|
816
899
|
(0, agent_event_dedup_1.dropsFor)(key).decisionOverflow += 1;
|
|
817
|
-
return;
|
|
900
|
+
return opened;
|
|
818
901
|
}
|
|
819
902
|
turn.pendingDecisions.push({
|
|
820
903
|
decisionId,
|
|
@@ -827,6 +910,7 @@ function openDecision(key, generation, input) {
|
|
|
827
910
|
scraperCorroborated: false,
|
|
828
911
|
recorded: false,
|
|
829
912
|
});
|
|
913
|
+
return opened;
|
|
830
914
|
}
|
|
831
915
|
/** Retire every dialog this instance was holding. */
|
|
832
916
|
function releaseAllDecisions(key) {
|
|
@@ -846,15 +930,25 @@ function releaseAllDecisions(key) {
|
|
|
846
930
|
function releaseSettledDecision(key, record) {
|
|
847
931
|
const turn = fencedTurn(key);
|
|
848
932
|
if (turn === null || turn.pendingDecisions.length === 0)
|
|
849
|
-
return;
|
|
933
|
+
return { kind: 'none' };
|
|
934
|
+
const before = turn.pendingDecisions.length;
|
|
850
935
|
const settledId = record.decisionId === null || record.decisionId === undefined
|
|
851
936
|
? null
|
|
852
937
|
: (0, provisional_turn_1.acceptExternalId)(record.decisionId);
|
|
853
938
|
if (settledId === null) {
|
|
854
939
|
turn.pendingDecisions = [];
|
|
855
|
-
return;
|
|
856
940
|
}
|
|
857
|
-
|
|
941
|
+
else {
|
|
942
|
+
turn.pendingDecisions = turn.pendingDecisions.filter((decision) => decision.decisionId !== null && decision.decisionId !== settledId);
|
|
943
|
+
}
|
|
944
|
+
// Issue #3798: an explicit answer — the one release that ends a wait.
|
|
945
|
+
return {
|
|
946
|
+
kind: 'decision-answered',
|
|
947
|
+
recordTurnId: turn.turnId,
|
|
948
|
+
recordKind: turn.openedAt !== null ? 'turn' : 'dialog-only',
|
|
949
|
+
before,
|
|
950
|
+
remaining: turn.pendingDecisions.length,
|
|
951
|
+
};
|
|
858
952
|
}
|
|
859
953
|
/** Keep the turn map bounded the way every other map in this module is. */
|
|
860
954
|
function boundTurnMap() {
|
|
@@ -35,6 +35,14 @@ const session_status_options_1 = require("../../lib/tmux/session-status-options"
|
|
|
35
35
|
const tmux_1 = require("../../lib/tmux/tmux");
|
|
36
36
|
const tmux_session_surface_1 = require("./tmux-session-surface");
|
|
37
37
|
const logger = (0, logger_1.createLogger)('cli-session');
|
|
38
|
+
/** Tell the observer this capture runs for, if any, where its frame came from (Issue #3798). */
|
|
39
|
+
function reportFrameMeta(meta) {
|
|
40
|
+
globalThis.__captureFrameMetaSink?.getStore()?.(meta);
|
|
41
|
+
}
|
|
42
|
+
/** Tell the observer this capture runs for, if any, whether its window cut the pane's top (Issue #3881 N4). */
|
|
43
|
+
function reportHeadCut(headCut) {
|
|
44
|
+
globalThis.__captureHeadCutSink?.getStore()?.(headCut);
|
|
45
|
+
}
|
|
38
46
|
function getDefaultTransport() {
|
|
39
47
|
return (0, polling_tmux_transport_1.getPollingTmuxTransport)();
|
|
40
48
|
}
|
|
@@ -95,7 +103,11 @@ async function captureSessionOutput(worktreeId, cliToolId, lines = 1000, instanc
|
|
|
95
103
|
throw new Error(`${cliTool.name} session ${sessionName} does not exist`);
|
|
96
104
|
}
|
|
97
105
|
return await transport.captureSnapshot(sessionName, { startLine: -tmux_capture_cache_1.CACHE_MAX_CAPTURE_LINES });
|
|
98
|
-
}
|
|
106
|
+
},
|
|
107
|
+
// Issue #3798: this call's own frame, to the observer it runs for
|
|
108
|
+
reportFrameMeta,
|
|
109
|
+
// Issue #3881 (third review N4): and whether the window cut its top
|
|
110
|
+
reportHeadCut);
|
|
99
111
|
log.debug('captureSessionOutput:success', {
|
|
100
112
|
actualLines: output.split('\n').length,
|
|
101
113
|
lastFewLines: output.split('\n').slice(-3).join(' | '),
|
|
@@ -132,18 +144,25 @@ async function captureSessionOutputFresh(worktreeId, cliToolId, lines = 5000, in
|
|
|
132
144
|
const transport = getDefaultTransport();
|
|
133
145
|
// Issue #3734: snapshot the generation before the capture starts
|
|
134
146
|
const generation = (0, tmux_capture_cache_1.getCaptureGeneration)(sessionName);
|
|
147
|
+
// Issue #3798: and the time, so the cache says when this frame was fetched,
|
|
148
|
+
// not when a slow capture came back
|
|
149
|
+
const fetchStartedAt = Date.now();
|
|
135
150
|
try {
|
|
136
151
|
const output = await transport.captureSnapshot(sessionName, { startLine: -lines });
|
|
137
152
|
// Write back to cache if non-empty [SEC4-007]. Skip it when the session was
|
|
138
153
|
// invalidated while waiting: the output may predate a send (Issue #3734).
|
|
139
154
|
if (output.length > 0) {
|
|
140
155
|
if ((0, tmux_capture_cache_1.isCaptureGenerationCurrent)(sessionName, generation)) {
|
|
141
|
-
(0, tmux_capture_cache_1.setCachedCapture)(sessionName, output, lines);
|
|
156
|
+
(0, tmux_capture_cache_1.setCachedCapture)(sessionName, output, lines, fetchStartedAt);
|
|
142
157
|
}
|
|
143
158
|
}
|
|
144
159
|
else {
|
|
145
160
|
(0, tmux_capture_cache_1.invalidateCache)(sessionName);
|
|
146
161
|
}
|
|
162
|
+
reportFrameMeta({ fetchStartedAt, source: 'fetched' });
|
|
163
|
+
const headCutSink = globalThis.__captureHeadCutSink?.getStore();
|
|
164
|
+
if (headCutSink)
|
|
165
|
+
headCutSink((0, tmux_capture_cache_1.sliceCutsHead)(output, lines));
|
|
147
166
|
return (0, tmux_capture_cache_1.sliceOutput)(output, lines);
|
|
148
167
|
}
|
|
149
168
|
catch (error) {
|
|
@@ -33,7 +33,11 @@ const cli_session_1 = require("../../lib/session/cli-session");
|
|
|
33
33
|
const status_detector_1 = require("../../lib/detection/status-detector");
|
|
34
34
|
const auto_yes_manager_1 = require("../../lib/polling/auto-yes-manager");
|
|
35
35
|
const auto_yes_suppression_state_1 = require("../../lib/polling/auto-yes-suppression-state");
|
|
36
|
-
const
|
|
36
|
+
const auto_yes_poller_state_1 = require("../../lib/polling/auto-yes-poller-state");
|
|
37
|
+
const waiting_episode_state_1 = require("../../lib/session/waiting-episode-state");
|
|
38
|
+
const auto_yes_state_1 = require("../../lib/auto-yes-state");
|
|
39
|
+
const auto_yes_decision_state_1 = require("../../lib/polling/auto-yes-decision-state");
|
|
40
|
+
const antigravity_receipt_episodes_1 = require("../../lib/polling/antigravity-receipt-episodes");
|
|
37
41
|
const prompt_dedup_state_1 = require("../../lib/polling/prompt-dedup-state");
|
|
38
42
|
const status_capture_config_1 = require("../../config/status-capture-config");
|
|
39
43
|
const tmux_capture_cache_1 = require("../../lib/tmux/tmux-capture-cache");
|
|
@@ -45,6 +49,7 @@ const status_evidence_1 = require("../../lib/session/status-evidence");
|
|
|
45
49
|
const ask_user_question_prompt_1 = require("../../lib/session/ask-user-question-prompt");
|
|
46
50
|
const prompt_view_1 = require("../../lib/session/prompt-view");
|
|
47
51
|
const auto_yes_dialog_gate_1 = require("../../lib/polling/auto-yes-dialog-gate");
|
|
52
|
+
const prompt_screen_reading_1 = require("../../lib/polling/prompt-screen-reading");
|
|
48
53
|
const layer_disagreement_1 = require("../../lib/session/layer-disagreement");
|
|
49
54
|
const structured_prompt_1 = require("../../lib/session/structured-prompt");
|
|
50
55
|
const chat_turn_progress_1 = require("./chat-turn-progress");
|
|
@@ -226,7 +231,7 @@ function readAgentEvents(worktreeId, cliToolId, instanceId, resolvedInstanceId)
|
|
|
226
231
|
* every value below is derived from the arguments, and nothing is assigned
|
|
227
232
|
* outside this function.
|
|
228
233
|
*/
|
|
229
|
-
function composePromptData({ worktreeId, cliToolId, output, statusResult, startingSince, promptWaiting, askUserQuestion, eventSource, }) {
|
|
234
|
+
function composePromptData({ worktreeId, cliToolId, output, captureWindowLines, statusResult, startingSince, promptWaiting, askUserQuestion, eventSource, }) {
|
|
230
235
|
const scraperPromptWaiting = statusResult.hasActivePrompt;
|
|
231
236
|
// Issue #1726: the agent's own account of what it asked. It contributes only
|
|
232
237
|
// where some other layer has already established that a dialog is on screen —
|
|
@@ -238,7 +243,14 @@ function composePromptData({ worktreeId, cliToolId, output, statusResult, starti
|
|
|
238
243
|
// takes it there today (the decision entries publish the same episode's
|
|
239
244
|
// choices) — and this line now re-uses it, so the two surfaces cannot describe
|
|
240
245
|
// different instants.
|
|
241
|
-
|
|
246
|
+
//
|
|
247
|
+
// Issue #3881 (second review N3): with the capture's top as the Auto-Yes
|
|
248
|
+
// poller reads it — an approval target whose upward scan reached a top that
|
|
249
|
+
// may be cut carries `approvalTargetCompleteness: 'top-unknown'`, so the
|
|
250
|
+
// contract re-evaluation of `observe=1` (`prompt-observation/observe.ts`)
|
|
251
|
+
// and `wait` read the same completeness the poller acted on, from the same
|
|
252
|
+
// `captureTopOf` on this payload's own capture window.
|
|
253
|
+
const scraperPromptData = (0, prompt_screen_reading_1.withCaptureTopCompleteness)(statusResult.promptDetection, (0, prompt_screen_reading_1.captureTopOf)(output, captureWindowLines, cliToolId)).promptData;
|
|
242
254
|
const correctedPromptData = scraperPromptData && askUserQuestion
|
|
243
255
|
? (0, ask_user_question_prompt_1.applyAskUserQuestion)(scraperPromptData, askUserQuestion.spec)
|
|
244
256
|
: null;
|
|
@@ -468,12 +480,26 @@ function logDetectionDivergence(worktreeId, cliToolId, resolvedInstanceId, statu
|
|
|
468
480
|
});
|
|
469
481
|
}
|
|
470
482
|
}
|
|
483
|
+
/**
|
|
484
|
+
* Issue #3821: the agy hook call the receipt on screen was accepted for, for
|
|
485
|
+
* the decision to be matched against; null when unknown. Read only, never throws.
|
|
486
|
+
*/
|
|
487
|
+
function acceptedAgyCallId(worktreeId, instanceId) {
|
|
488
|
+
try {
|
|
489
|
+
return (0, antigravity_receipt_episodes_1.getAntigravityAcceptedReceiptCallId)(worktreeId, instanceId);
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
return null;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
471
495
|
/**
|
|
472
496
|
* The payload of a running session (Issue #3272). Split out of
|
|
473
497
|
* {@link buildPayload} as it stood there, so the keys keep their order and the
|
|
474
498
|
* reads inside it keep theirs.
|
|
475
499
|
*/
|
|
476
|
-
function buildRunningPayload({ worktreeId, cliToolId, instanceId, sessionName, published, merged, newContent, output, realtimeSnippet, totalLines, lastCapturedLine, isPromptWaiting, promptData, promptAnswerable, autoYesState, lastEnterFallback, isSelectionListActive, isPagerActive, isDismissablePanelActive, startingSince, lastKnown, lastServerResponseTimestamp, compositeKey, stopEventAt, structuredEvents, model, effort, upstreamFaultMatch, paneObstruction, composer, }) {
|
|
500
|
+
function buildRunningPayload({ worktreeId, cliToolId, instanceId, sessionName, published, merged, newContent, output, realtimeSnippet, totalLines, lastCapturedLine, isPromptWaiting, promptData, promptAnswerable, autoYesState, lastEnterFallback, autoYesDecision, isSelectionListActive, isPagerActive, isDismissablePanelActive, startingSince, lastKnown, lastServerResponseTimestamp, compositeKey, stopEventAt, structuredEvents, model, effort, upstreamFaultMatch, paneObstruction, composer, }) {
|
|
501
|
+
const lastSuppression = (0, auto_yes_suppression_state_1.getLastPolicySuppression)(worktreeId, cliToolId, instanceId);
|
|
502
|
+
const waitingEpisodeId = (0, waiting_episode_state_1.getWaitingEpisodeRecord)(worktreeId, cliToolId, instanceId)?.episodeId ?? null;
|
|
477
503
|
return {
|
|
478
504
|
isRunning: true,
|
|
479
505
|
sessionName,
|
|
@@ -496,14 +522,29 @@ function buildRunningPayload({ worktreeId, cliToolId, instanceId, sessionName, p
|
|
|
496
522
|
enabled: autoYesState?.enabled ?? false,
|
|
497
523
|
expiresAt: autoYesState?.enabled ? autoYesState.expiresAt : null,
|
|
498
524
|
stopReason: autoYesState?.stopReason,
|
|
499
|
-
lastSuppression
|
|
525
|
+
lastSuppression,
|
|
526
|
+
// Issue #3798: read in the same step as the record above, which names the
|
|
527
|
+
// wait it was written for — `cmate wait` holds the two against each other.
|
|
528
|
+
waitingEpisodeId,
|
|
500
529
|
// Issue #1694: undefined (so the key is absent from the JSON) unless a
|
|
501
530
|
// stop pattern actually fired — the state clears it on every other path.
|
|
502
531
|
stopMatchedText: autoYesState?.stopMatchedText,
|
|
503
532
|
// Issue #3397: appended last, after the published fields above. Null when
|
|
504
|
-
// Auto-Yes never sent its Enter to an unreadable choice screen here
|
|
533
|
+
// Auto-Yes never sent its Enter to an unreadable choice screen here —
|
|
534
|
+
// always, since Issue #3821 retired the Enter.
|
|
505
535
|
lastEnterFallback,
|
|
536
|
+
// Issue #3798: appended last. Whether the poller answered the open wait
|
|
537
|
+
// after the record above was written — the push gate's own reading, so
|
|
538
|
+
// `cmate wait` does not take that record for this wait's reason.
|
|
539
|
+
lastSuppressionAnswered: lastSuppression !== null &&
|
|
540
|
+
(0, auto_yes_suppression_state_1.suppressionPredatesAnswer)(lastSuppression, waitingEpisodeId, (0, auto_yes_poller_state_1.getAutoYesLastAnswer)(compositeKey)),
|
|
506
541
|
},
|
|
542
|
+
// Issue #3821: next to `autoYes`, and about `promptData` above — whether
|
|
543
|
+
// Auto-Yes is answering it, has left it to a human, or neither.
|
|
544
|
+
autoYesDecision,
|
|
545
|
+
// Issue #3863: how a question on this screen is treated while Auto-Yes is
|
|
546
|
+
// on; the key is absent while it is off.
|
|
547
|
+
...(autoYesState?.enabled ? { autoYesAnswerMode: (0, auto_yes_state_1.autoYesAnswerModeOf)(autoYesState) } : {}),
|
|
507
548
|
isSelectionListActive,
|
|
508
549
|
isPagerActive,
|
|
509
550
|
isDismissablePanelActive,
|
|
@@ -664,7 +705,8 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
664
705
|
// The effective window is the smaller of what this path asks for and what the
|
|
665
706
|
// capture layer will ever fetch — captureSessionOutput() reads at most
|
|
666
707
|
// CACHE_MAX_CAPTURE_LINES regardless of the request.
|
|
667
|
-
const
|
|
708
|
+
const captureWindowLines = Math.min(status_capture_config_1.STATUS_CAPTURE_LINES, tmux_capture_cache_1.CACHE_MAX_CAPTURE_LINES);
|
|
709
|
+
const captureWindowSaturated = (0, tmux_capture_cache_1.isCaptureWindowSaturated)(totalLines, captureWindowLines);
|
|
668
710
|
// Issue #1910: saturation of the capture WINDOW is only one of the two ways
|
|
669
711
|
// the cursor dies, and it is the one that never fires for the alternate-screen
|
|
670
712
|
// tools — their pane is 1000 rows (claude / copilot) or 200 (opencode), so a
|
|
@@ -761,6 +803,7 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
761
803
|
worktreeId,
|
|
762
804
|
cliToolId,
|
|
763
805
|
output,
|
|
806
|
+
captureWindowLines,
|
|
764
807
|
statusResult,
|
|
765
808
|
startingSince,
|
|
766
809
|
promptWaiting,
|
|
@@ -922,10 +965,20 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
922
965
|
promptData,
|
|
923
966
|
promptAnswerable,
|
|
924
967
|
autoYesState,
|
|
925
|
-
// Issue #
|
|
926
|
-
|
|
927
|
-
//
|
|
928
|
-
|
|
968
|
+
// Issue #3821: the Enter is retired; the key is kept, and is null.
|
|
969
|
+
lastEnterFallback: null,
|
|
970
|
+
// Issue #3821: judged against the screen-read prompt only — the one
|
|
971
|
+
// `promptAnswerable` is published for, and the only kind the poller
|
|
972
|
+
// answers. A structured (hook / degraded) prompt is never that screen, and
|
|
973
|
+
// reads `none`.
|
|
974
|
+
autoYesDecision: (0, auto_yes_decision_state_1.publishAutoYesDecision)({
|
|
975
|
+
compositeKey,
|
|
976
|
+
grant: autoYesState,
|
|
977
|
+
promptData: promptData !== null && promptAnswerable !== undefined ? statusResult.promptDetection.promptData : null,
|
|
978
|
+
// agy: the decision is tied to the hook call its receipt was accepted for.
|
|
979
|
+
callId: cliToolId === 'antigravity' ? acceptedAgyCallId(worktreeId, instanceId) : null,
|
|
980
|
+
pollerActive: (0, auto_yes_manager_1.isPollerActive)(compositeKey),
|
|
981
|
+
}),
|
|
929
982
|
isSelectionListActive,
|
|
930
983
|
isPagerActive,
|
|
931
984
|
isDismissablePanelActive,
|
|
@@ -82,6 +82,12 @@ function getLastSendAttempt(instance) {
|
|
|
82
82
|
function clearSendAttempts() {
|
|
83
83
|
records.clear();
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* The wordings of a failed tmux call that can carry the message body: `tmux.ts`
|
|
87
|
+
* wraps the child_process error (`Command failed: tmux …argv…`) as
|
|
88
|
+
* `Failed to send keys to tmux session: …` and the like (Issue #3880).
|
|
89
|
+
*/
|
|
90
|
+
const TMUX_TRANSPORT_FAILURE = /Command failed: tmux |Failed to send (?:special )?keys? to tmux session|Failed to send special key:|Failed to paste message into tmux session/;
|
|
85
91
|
/**
|
|
86
92
|
* Where a failed `ICLITool.sendMessage` stopped, read from its error.
|
|
87
93
|
*
|
|
@@ -103,13 +109,10 @@ function classifySendFailure(error) {
|
|
|
103
109
|
return { state: 'not-sent', reason: 'plan-review' };
|
|
104
110
|
}
|
|
105
111
|
const message = error instanceof Error ? error.message : String(error);
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
//
|
|
110
|
-
if (/still holds unsent text after \d+ clear passes/.test(message)) {
|
|
111
|
-
return { state: 'not-sent', reason: 'composer-not-empty' };
|
|
112
|
-
}
|
|
112
|
+
// Issue #3880: the "after the body was typed" wordings are matched FIRST. A
|
|
113
|
+
// body-not-landed error quotes what the composer shows — the user's own text —
|
|
114
|
+
// and a body that says `prompt not ready` must not turn "may have been typed"
|
|
115
|
+
// into "was not typed". Indeterminate wins whenever its wording is present.
|
|
113
116
|
// #2464 / #3366: typed, never submitted, taken back out best-effort.
|
|
114
117
|
if (/Enter was not pressed, so nothing was submitted/.test(message)) {
|
|
115
118
|
return { state: 'indeterminate', reason: 'body-not-landed' };
|
|
@@ -122,6 +125,19 @@ function classifySendFailure(error) {
|
|
|
122
125
|
if (/submit could not be confirmed/i.test(message)) {
|
|
123
126
|
return { state: 'indeterminate', reason: 'submit-unconfirmed' };
|
|
124
127
|
}
|
|
128
|
+
// Issue #3880 (N2): a failed tmux call quotes its argv — and the argv of a
|
|
129
|
+
// literal send IS the body (`Command failed: tmux send-keys -t =s: -l -- <body>`).
|
|
130
|
+
// Whether any of the body reached the pane is unknown, and the body's own words
|
|
131
|
+
// (`Explain prompt not ready.`) must not be read as a readiness refusal below.
|
|
132
|
+
if (TMUX_TRANSPORT_FAILURE.test(message))
|
|
133
|
+
return { state: 'indeterminate', reason: 'send-error' };
|
|
134
|
+
// The readiness waits of every tool throw before typing anything.
|
|
135
|
+
if (/prompt not ready/i.test(message))
|
|
136
|
+
return { state: 'not-sent', reason: 'prompt-not-ready' };
|
|
137
|
+
// #1880: refused before the body, after only the clear keys (C-e / C-u).
|
|
138
|
+
if (/still holds unsent text after \d+ clear passes/.test(message)) {
|
|
139
|
+
return { state: 'not-sent', reason: 'composer-not-empty' };
|
|
140
|
+
}
|
|
125
141
|
return { state: 'indeterminate', reason: 'send-error' };
|
|
126
142
|
}
|
|
127
143
|
/** The whitespace-free form two renderings of one text share. */
|