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
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The observation half of `waiting-episode-binding` (Issue #3798): the
|
|
4
|
+
* observers' starts, the dating of a captured frame, and the plan of tables
|
|
5
|
+
* O-1 / O-2. Split out of `waiting-episode-binding` (Issue #3892), which
|
|
6
|
+
* re-exports all of it and carries the plan out (`commitWaitingObservation`).
|
|
7
|
+
*
|
|
8
|
+
* @module lib/session/waiting-episode-binding-observation
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.startWaitingObservation = startWaitingObservation;
|
|
12
|
+
exports.startWorktreeWaitingObservations = startWorktreeWaitingObservations;
|
|
13
|
+
exports.captureFrameTime = captureFrameTime;
|
|
14
|
+
exports.captureObservedFrame = captureObservedFrame;
|
|
15
|
+
exports.planWaitingObservation = planWaitingObservation;
|
|
16
|
+
const async_hooks_1 = require("async_hooks");
|
|
17
|
+
const auto_yes_state_1 = require("../../lib/auto-yes-state");
|
|
18
|
+
const prompt_screen_key_1 = require("../../lib/detection/prompt-screen-key");
|
|
19
|
+
const agent_event_turn_1 = require("../../lib/session/agent-event-turn");
|
|
20
|
+
const waiting_episode_binding_resolve_1 = require("../../lib/session/waiting-episode-binding-resolve");
|
|
21
|
+
const waiting_episode_state_1 = require("../../lib/session/waiting-episode-state");
|
|
22
|
+
const waiting_episode_verdict_1 = require("../../lib/session/waiting-episode-verdict");
|
|
23
|
+
const global_state_1 = require("../global-state");
|
|
24
|
+
/** Where `cli-session` reports a frame's source to the observer it runs for (Issue #3798). */
|
|
25
|
+
function frameMetaSink() {
|
|
26
|
+
return (0, global_state_1.getOrInitGlobal)('__captureFrameMetaSink', () => new async_hooks_1.AsyncLocalStorage());
|
|
27
|
+
}
|
|
28
|
+
/** Fix the observer's start (design §2.5). Read-only. */
|
|
29
|
+
function startWaitingObservation(worktreeId, cliToolId, instanceId) {
|
|
30
|
+
return {
|
|
31
|
+
generation: (0, waiting_episode_binding_resolve_1.generationOf)({ worktreeId, cliToolId, instanceId }),
|
|
32
|
+
version: (0, waiting_episode_state_1.getEpisodeVersion)(worktreeId, cliToolId, instanceId),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Fix the start of every instance of a worktree at once (design §2.5): the
|
|
37
|
+
* status routes call it before `listSessions()`, so a session that started —
|
|
38
|
+
* and opened a wait — after the list was taken is not closed as gone by a
|
|
39
|
+
* probe that did not see it. Instances that have no version or generation yet
|
|
40
|
+
* are fixed at 0 / none.
|
|
41
|
+
*/
|
|
42
|
+
function startWorktreeWaitingObservations(worktreeId) {
|
|
43
|
+
const prefix = `${worktreeId}${auto_yes_state_1.COMPOSITE_KEY_SEPARATOR}`;
|
|
44
|
+
const versions = (0, waiting_episode_state_1.snapshotEpisodeVersions)(worktreeId);
|
|
45
|
+
const generations = new Map();
|
|
46
|
+
for (const [key, at] of agent_event_turn_1.generationStartedAt) {
|
|
47
|
+
if (key.startsWith(prefix))
|
|
48
|
+
generations.set(key, at);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
startFor(cliToolId, instanceId) {
|
|
52
|
+
const key = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
53
|
+
return { generation: (0, agent_event_turn_1.toGenerationRef)(generations.get(key) ?? null), version: versions.get(key) ?? 0 };
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* When the frame a scraper just read was fetched (design §2.2
|
|
59
|
+
* `frameCapturedAt`), from `meta` — what the capture reported for that one
|
|
60
|
+
* frame ({@link captureObservedFrame}). A frame served from the cache, or
|
|
61
|
+
* joined to a fetch already in flight, is as old as that fetch, and is never
|
|
62
|
+
* one this observer fetched itself — even when that fetch started in the very
|
|
63
|
+
* millisecond the observer asked. Only a frame the capture fetched itself,
|
|
64
|
+
* starting at or after `requestedAt` (the moment the observer asked, after its
|
|
65
|
+
* start), counts as fetched after the start. A frame nothing was reported for
|
|
66
|
+
* (a capture module a test replaced) is dated 0, before any close (design
|
|
67
|
+
* §2.6): it opens no wait I6 would hold back, and closes no `screen`.
|
|
68
|
+
*/
|
|
69
|
+
function captureFrameTime(meta, requestedAt) {
|
|
70
|
+
if (meta === null)
|
|
71
|
+
return { frameCapturedAt: 0, frameFetchedAfterStart: false };
|
|
72
|
+
return {
|
|
73
|
+
frameCapturedAt: Math.min(meta.fetchStartedAt, requestedAt),
|
|
74
|
+
frameFetchedAfterStart: meta.source === 'fetched' && meta.fetchStartedAt >= requestedAt,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Run one capture for an observer and date the frame it returns (Issue #3798):
|
|
79
|
+
* `cli-session` reports where THIS call's frame came from through an async
|
|
80
|
+
* context set up here, so another capture of the same session running at the
|
|
81
|
+
* same time — a different number of lines, a different text — cannot stand in
|
|
82
|
+
* for it.
|
|
83
|
+
*/
|
|
84
|
+
async function captureObservedFrame(capture) {
|
|
85
|
+
const reported = { meta: null };
|
|
86
|
+
const requestedAt = Date.now();
|
|
87
|
+
const frame = await frameMetaSink().run((meta) => {
|
|
88
|
+
reported.meta = meta;
|
|
89
|
+
}, capture);
|
|
90
|
+
return { frame, frameTime: captureFrameTime(reported.meta, requestedAt) };
|
|
91
|
+
}
|
|
92
|
+
function screenBinding(generation, originTurnId) {
|
|
93
|
+
return { kind: 'screen', generation, originTurnId };
|
|
94
|
+
}
|
|
95
|
+
function sameBinding(a, b) {
|
|
96
|
+
if (a.kind !== b.kind)
|
|
97
|
+
return false;
|
|
98
|
+
switch (a.kind) {
|
|
99
|
+
case 'turn':
|
|
100
|
+
return a.turnId === b.turnId;
|
|
101
|
+
case 'dialog-only':
|
|
102
|
+
return a.recordTurnId === b.recordTurnId;
|
|
103
|
+
default:
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** Whether the Auto-Yes poller answered this episode and the screen now shows another confirmation (R1-7, PR 3). */
|
|
108
|
+
function answeredThenAnother(obs, episode, k) {
|
|
109
|
+
return (obs.freshPrompt === true &&
|
|
110
|
+
obs.lastAnswer != null &&
|
|
111
|
+
obs.lastAnswer.episodeId === episode.episodeId &&
|
|
112
|
+
k !== null &&
|
|
113
|
+
k !== obs.lastAnswer.screenKey);
|
|
114
|
+
}
|
|
115
|
+
/** Table O-1: a `waiting` reading on the instance's episode (or none). */
|
|
116
|
+
function verdictForWaiting(obs, episode, humanHeld, c, k, current) {
|
|
117
|
+
if (episode === null)
|
|
118
|
+
return { action: 'opened', binding: c };
|
|
119
|
+
const binding = episode.binding;
|
|
120
|
+
// The row below the table: a binding of another generation is replaced (P3-2).
|
|
121
|
+
if (!(0, waiting_episode_verdict_1.sameGeneration)(binding.generation, current))
|
|
122
|
+
return { action: 'replaced', binding: c };
|
|
123
|
+
if (humanHeld) {
|
|
124
|
+
if (binding.kind === 'screen')
|
|
125
|
+
return { action: 'kept' };
|
|
126
|
+
return { action: 'rebound', binding: screenBinding(current, binding.kind === 'turn' ? binding.turnId : null) };
|
|
127
|
+
}
|
|
128
|
+
switch (binding.kind) {
|
|
129
|
+
case 'turn': {
|
|
130
|
+
const stillOpen = c.kind === 'turn' && c.turnId === binding.turnId;
|
|
131
|
+
if (stillOpen)
|
|
132
|
+
return answeredThenAnother(obs, episode, k) ? { action: 'replaced', binding: c } : { action: 'kept' };
|
|
133
|
+
if (c.kind === 'turn')
|
|
134
|
+
return { action: 'replaced', binding: c };
|
|
135
|
+
// T has ended (stop, screen evidence, the 30-minute stale bound — R2-3):
|
|
136
|
+
// only another confirmation replaces it.
|
|
137
|
+
return obs.freshPrompt === true && k !== null && k !== episode.promptScreenKey
|
|
138
|
+
? { action: 'replaced', binding: c }
|
|
139
|
+
: { action: 'kept' };
|
|
140
|
+
}
|
|
141
|
+
case 'dialog-only':
|
|
142
|
+
if (c.kind === 'turn')
|
|
143
|
+
return { action: 'rebound', binding: c };
|
|
144
|
+
if (c.kind === 'dialog-only' && c.recordTurnId !== binding.recordTurnId)
|
|
145
|
+
return { action: 'replaced', binding: c };
|
|
146
|
+
return { action: 'kept' };
|
|
147
|
+
case 'unattributed':
|
|
148
|
+
if (c.kind === 'unattributed') {
|
|
149
|
+
return answeredThenAnother(obs, episode, k) ? { action: 'replaced', binding: c } : { action: 'kept' };
|
|
150
|
+
}
|
|
151
|
+
if (c.kind === 'dialog-only')
|
|
152
|
+
return { action: 'rebound', binding: c };
|
|
153
|
+
// c = turn(N): the wait turned out to be N's when it shows the same confirmation (R2-4).
|
|
154
|
+
return k !== null && k === episode.promptScreenKey
|
|
155
|
+
? { action: 'rebound', binding: c }
|
|
156
|
+
: { action: 'replaced', binding: c };
|
|
157
|
+
case 'screen':
|
|
158
|
+
return c.kind === 'turn' && c.turnId === binding.originTurnId
|
|
159
|
+
? { action: 'rebound', binding: c }
|
|
160
|
+
: { action: 'replaced', binding: c };
|
|
161
|
+
default:
|
|
162
|
+
binding;
|
|
163
|
+
return { action: 'kept' };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/** Table O-2: the closing side. Null when the reading closes nothing. */
|
|
167
|
+
function closeReasonFor(obs, episode) {
|
|
168
|
+
const { reading } = obs;
|
|
169
|
+
if (reading.kind === 'gone')
|
|
170
|
+
return 'session-gone';
|
|
171
|
+
if (reading.kind !== 'not-waiting')
|
|
172
|
+
return null;
|
|
173
|
+
switch (obs.observer) {
|
|
174
|
+
case 'status-probe':
|
|
175
|
+
return 'screen-cleared';
|
|
176
|
+
case 'response-checker':
|
|
177
|
+
return 'response-recorded';
|
|
178
|
+
case 'auto-yes-poller':
|
|
179
|
+
// A screen only after a frame fetched since it became one (R3-1, P3-1);
|
|
180
|
+
// any other wait only when the poller answered it (PR 3, 規則 3).
|
|
181
|
+
if (episode.binding.kind === 'screen') {
|
|
182
|
+
return obs.frameCapturedAt > Math.max(episode.openedAt, episode.boundAt) ? 'screen-cleared' : null;
|
|
183
|
+
}
|
|
184
|
+
return obs.lastAnswer != null && obs.lastAnswer.episodeId === episode.episodeId ? 'poller-answered' : null;
|
|
185
|
+
default:
|
|
186
|
+
obs.observer;
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** Why the old episode of a replacement ended. */
|
|
191
|
+
function replacedBecause(old, next, current) {
|
|
192
|
+
if (!(0, waiting_episode_verdict_1.sameGeneration)(old.generation, current))
|
|
193
|
+
return 'generation';
|
|
194
|
+
return next.kind === 'turn' || next.kind === 'dialog-only' ? 'turn-superseded' : 'screen-cleared';
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Decide what one observation does to the instance's episode (design §2.4
|
|
198
|
+
* 規則 3・4・5, tables O-1 / O-2 and preconditions 1–3). Reads the store and
|
|
199
|
+
* the turn model; writes nothing.
|
|
200
|
+
*/
|
|
201
|
+
function planWaitingObservation(obs) {
|
|
202
|
+
const at = obs.now ?? Date.now();
|
|
203
|
+
const parts = { worktreeId: obs.worktreeId, cliToolId: obs.cliToolId, instanceId: obs.instanceId };
|
|
204
|
+
const episode = (0, waiting_episode_state_1.getWaitingEpisodeRecord)(obs.worktreeId, obs.cliToolId, obs.instanceId);
|
|
205
|
+
const current = (0, waiting_episode_binding_resolve_1.generationOf)(parts);
|
|
206
|
+
const base = {
|
|
207
|
+
observation: obs,
|
|
208
|
+
action: 'ignored',
|
|
209
|
+
episodeId: episode?.episodeId ?? null,
|
|
210
|
+
since: obs.reading.kind === 'waiting' ? episode?.since ?? null : null,
|
|
211
|
+
next: null,
|
|
212
|
+
binding: null,
|
|
213
|
+
closeReason: null,
|
|
214
|
+
ignoredBecause: null,
|
|
215
|
+
at,
|
|
216
|
+
};
|
|
217
|
+
const ignored = (because) => ({
|
|
218
|
+
...base,
|
|
219
|
+
action: 'ignored',
|
|
220
|
+
ignoredBecause: because,
|
|
221
|
+
});
|
|
222
|
+
// Precondition 1: the observer started in another generation.
|
|
223
|
+
if (!(0, waiting_episode_verdict_1.sameGeneration)(obs.start.generation, current))
|
|
224
|
+
return ignored('generation');
|
|
225
|
+
const versionMoved = obs.start.version !== (0, waiting_episode_state_1.getEpisodeVersion)(obs.worktreeId, obs.cliToolId, obs.instanceId) && obs.freshPrompt !== true;
|
|
226
|
+
const { reading } = obs;
|
|
227
|
+
if (reading.kind !== 'waiting') {
|
|
228
|
+
// Table O-2.
|
|
229
|
+
if (episode === null)
|
|
230
|
+
return ignored('nothing-open');
|
|
231
|
+
if (reading.kind === 'unknown')
|
|
232
|
+
return ignored('unknown-frame');
|
|
233
|
+
const reason = closeReasonFor(obs, episode);
|
|
234
|
+
if (reason === null)
|
|
235
|
+
return ignored('not-this-observer');
|
|
236
|
+
if (versionMoved)
|
|
237
|
+
return ignored('version');
|
|
238
|
+
return { ...base, action: 'closed', closeReason: reason, since: null };
|
|
239
|
+
}
|
|
240
|
+
// Table O-1.
|
|
241
|
+
const k = reading.promptData !== null ? (0, prompt_screen_key_1.promptScreenKey)(reading.promptData) : null;
|
|
242
|
+
// 規則 1: a person's screen is `screen` whatever the turn model says, with
|
|
243
|
+
// the open turn as its origin.
|
|
244
|
+
const resolved = (0, waiting_episode_binding_resolve_1.resolveEpisodeBinding)(parts, at);
|
|
245
|
+
const c = reading.humanHeld
|
|
246
|
+
? screenBinding(current, resolved.kind === 'turn' ? resolved.turnId : null)
|
|
247
|
+
: resolved;
|
|
248
|
+
const verdict = verdictForWaiting(obs, episode, reading.humanHeld, c, k, current);
|
|
249
|
+
if (verdict.action === 'kept')
|
|
250
|
+
return { ...base, action: 'kept' };
|
|
251
|
+
// Precondition 2 (I5 (b) / (d)) and 3 (I6).
|
|
252
|
+
if (versionMoved)
|
|
253
|
+
return ignored('version');
|
|
254
|
+
const lastClosed = (0, waiting_episode_state_1.getLastClosedEpisode)(obs.worktreeId, obs.cliToolId, obs.instanceId);
|
|
255
|
+
const closedBeforeOwnFetch = obs.frameFetchedAfterStart === true &&
|
|
256
|
+
obs.start.version === (0, waiting_episode_state_1.getEpisodeVersion)(obs.worktreeId, obs.cliToolId, obs.instanceId);
|
|
257
|
+
if (lastClosed !== null &&
|
|
258
|
+
!closedBeforeOwnFetch &&
|
|
259
|
+
obs.frameCapturedAt <= lastClosed.at &&
|
|
260
|
+
(k === null || k === lastClosed.promptScreenKey)) {
|
|
261
|
+
return ignored('stale-frame');
|
|
262
|
+
}
|
|
263
|
+
if (verdict.action === 'rebound') {
|
|
264
|
+
if (episode !== null && sameBinding(episode.binding, verdict.binding))
|
|
265
|
+
return { ...base, action: 'kept' };
|
|
266
|
+
return { ...base, action: 'rebound', binding: verdict.binding };
|
|
267
|
+
}
|
|
268
|
+
const binding = verdict.binding;
|
|
269
|
+
const structuredSince = reading.structuredSince;
|
|
270
|
+
const since = verdict.action === 'opened' || episode === null
|
|
271
|
+
? structuredSince ?? at
|
|
272
|
+
: structuredSince !== null && structuredSince > episode.since
|
|
273
|
+
? structuredSince
|
|
274
|
+
: at;
|
|
275
|
+
const next = {
|
|
276
|
+
since,
|
|
277
|
+
kind: reading.waitingKind,
|
|
278
|
+
binding,
|
|
279
|
+
openedBy: obs.observer,
|
|
280
|
+
promptScreenKey: k,
|
|
281
|
+
};
|
|
282
|
+
return {
|
|
283
|
+
...base,
|
|
284
|
+
action: verdict.action,
|
|
285
|
+
since,
|
|
286
|
+
next,
|
|
287
|
+
closeReason: verdict.action === 'replaced' && episode !== null ? replacedBecause(episode.binding, binding, current) : null,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* What a new waiting episode is bound to, read from the turn model (Issue #3798).
|
|
4
|
+
* Split out of `waiting-episode-binding` (Issue #3892), which re-exports it.
|
|
5
|
+
*
|
|
6
|
+
* @module lib/session/waiting-episode-binding-resolve
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.generationOf = generationOf;
|
|
10
|
+
exports.resolveEpisodeBinding = resolveEpisodeBinding;
|
|
11
|
+
const auto_yes_state_1 = require("../../lib/auto-yes-state");
|
|
12
|
+
const agent_event_turn_1 = require("../../lib/session/agent-event-turn");
|
|
13
|
+
function generationOf(parts) {
|
|
14
|
+
return (0, agent_event_turn_1.toGenerationRef)((0, agent_event_turn_1.currentGeneration)((0, auto_yes_state_1.buildCompositeKey)(parts.worktreeId, parts.cliToolId, parts.instanceId)));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* What an episode opening now is bound to (design §2.4 規則 1).
|
|
18
|
+
*
|
|
19
|
+
* Read from the fenced, aged turn record — the same reading `getAgentTurn`
|
|
20
|
+
* gives every other reader — with the live decisions counted without retiring
|
|
21
|
+
* the expired ones, so deciding a binding writes nothing a transition would
|
|
22
|
+
* later read differently.
|
|
23
|
+
*/
|
|
24
|
+
function resolveEpisodeBinding(parts, at) {
|
|
25
|
+
const generation = generationOf(parts);
|
|
26
|
+
const turn = (0, agent_event_turn_1.getAgentTurn)(parts.worktreeId, parts.cliToolId, parts.instanceId, at);
|
|
27
|
+
if (turn === null)
|
|
28
|
+
return { kind: 'unattributed', generation, lastClosedTurnId: null };
|
|
29
|
+
if (turn.closedAt === null && turn.openedAt !== null) {
|
|
30
|
+
return { kind: 'turn', generation, turnId: turn.turnId };
|
|
31
|
+
}
|
|
32
|
+
if (turn.closedAt === null && (0, agent_event_turn_1.liveDecisionCount)(turn, at) > 0) {
|
|
33
|
+
return { kind: 'dialog-only', generation, recordTurnId: turn.turnId, sessionId: turn.sessionId };
|
|
34
|
+
}
|
|
35
|
+
// A closed turn, or a record holding no live decision (an `idle_prompt`
|
|
36
|
+
// display record, or a forecast whose 20 s ran out).
|
|
37
|
+
return { kind: 'unattributed', generation, lastClosedTurnId: turn.turnId };
|
|
38
|
+
}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Which turn a waiting episode belongs to, and what the turn transitions do to
|
|
4
|
+
* it (Issue #3798).
|
|
5
|
+
*
|
|
6
|
+
* The episode store (`waiting-episode-state`) knows when a wait began and what
|
|
7
|
+
* it is bound to; the turn model (`agent-event-turn`) knows how each delivery
|
|
8
|
+
* moved the instance's turn. This module joins the two:
|
|
9
|
+
*
|
|
10
|
+
* - {@link resolveEpisodeBinding} decides what a new episode is bound to, from
|
|
11
|
+
* the turn model as it stands (design §2.4 規則 1). It is registered with the
|
|
12
|
+
* store, so an episode `observeWaitingEdge` opens is bound like any other.
|
|
13
|
+
* - {@link applyTurnOutcomesToEpisode} is the T table (design §2.4): what a
|
|
14
|
+
* transition's outcome does to the open episode. It runs in the synchronous
|
|
15
|
+
* step that recorded the delivery (`recordAgentEvent`'s end,
|
|
16
|
+
* `beginAgentEventGeneration`, the two `report*Pending`, the duplicate-window
|
|
17
|
+
* restore) and never after an `await`, so a closer that resumes later
|
|
18
|
+
* cannot reach a wait that opened meanwhile (design §2.5).
|
|
19
|
+
* - {@link captureLegacyStopTarget} / {@link settleLegacyStop} are the one
|
|
20
|
+
* closer that cannot be synchronous: `/api/hooks/claude-done` names no
|
|
21
|
+
* session and awaits a capture and a log before it is done (design 規則 6).
|
|
22
|
+
* - {@link planWaitingObservation} / {@link commitWaitingObservation} are the
|
|
23
|
+
* tables O-1 and O-2 (design §2.4 規則 3・4・5): what one observer's reading
|
|
24
|
+
* of a frame does to the open episode. The three observers — the status
|
|
25
|
+
* probe, the response poller and the Auto-Yes poller — fix an
|
|
26
|
+
* {@link ObservationStart} before their first `await` and are refused when
|
|
27
|
+
* the episode moved meanwhile (I5 (b)), or when the frame was fetched
|
|
28
|
+
* before the close of the very confirmation it shows (I6).
|
|
29
|
+
*
|
|
30
|
+
* The store is a leaf and does not import this module; this module registers
|
|
31
|
+
* itself with the store and with the turn model through `globalThis` when it is
|
|
32
|
+
* loaded. `agent-event-state` imports it, and so does every module that calls
|
|
33
|
+
* the observation functions — the resolver is registered by the import that
|
|
34
|
+
* uses it, not by a transitive one (design R2-10, PR 1a review P3-2).
|
|
35
|
+
*
|
|
36
|
+
* Design: `docs/design/issue-3798-waiting-episode.md`.
|
|
37
|
+
*
|
|
38
|
+
* @module lib/session/waiting-episode-binding
|
|
39
|
+
*/
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.startWorktreeWaitingObservations = exports.startWaitingObservation = exports.planWaitingObservation = exports.captureObservedFrame = exports.captureFrameTime = exports.resolveEpisodeBinding = exports.verdictForOutcome = void 0;
|
|
42
|
+
exports.applyTurnOutcomesToEpisode = applyTurnOutcomesToEpisode;
|
|
43
|
+
exports.commitWaitingObservation = commitWaitingObservation;
|
|
44
|
+
exports.observeWaiting = observeWaiting;
|
|
45
|
+
exports.captureLegacyStopTarget = captureLegacyStopTarget;
|
|
46
|
+
exports.settleLegacyStop = settleLegacyStop;
|
|
47
|
+
exports.clearWaitingEpisodeBindingState = clearWaitingEpisodeBindingState;
|
|
48
|
+
const auto_yes_state_1 = require("../../lib/auto-yes-state");
|
|
49
|
+
const logger_1 = require("../../lib/logger");
|
|
50
|
+
const agent_event_turn_1 = require("../../lib/session/agent-event-turn");
|
|
51
|
+
const waiting_episode_binding_observation_1 = require("../../lib/session/waiting-episode-binding-observation");
|
|
52
|
+
const waiting_episode_binding_resolve_1 = require("../../lib/session/waiting-episode-binding-resolve");
|
|
53
|
+
Object.defineProperty(exports, "resolveEpisodeBinding", { enumerable: true, get: function () { return waiting_episode_binding_resolve_1.resolveEpisodeBinding; } });
|
|
54
|
+
const waiting_episode_state_1 = require("../../lib/session/waiting-episode-state");
|
|
55
|
+
const waiting_episode_verdict_1 = require("../../lib/session/waiting-episode-verdict");
|
|
56
|
+
Object.defineProperty(exports, "verdictForOutcome", { enumerable: true, get: function () { return waiting_episode_verdict_1.verdictForOutcome; } });
|
|
57
|
+
const global_state_1 = require("../global-state");
|
|
58
|
+
const logger = (0, logger_1.createLogger)('waiting-episode-binding');
|
|
59
|
+
/**
|
|
60
|
+
* compositeKey -> the generation in which a structured `stop` was last
|
|
61
|
+
* applied. While it names the current generation, the agent's own hook speaks
|
|
62
|
+
* for the end of its turns and `claude-done` does not close (規則 6).
|
|
63
|
+
*/
|
|
64
|
+
const hookStopGeneration = (0, global_state_1.getOrInitGlobal)('__waitingHookStopGeneration', () => new Map());
|
|
65
|
+
/** Mark that the agent's own hook reported a stop in this generation (規則 6). */
|
|
66
|
+
function noteHookStop(key, outcome) {
|
|
67
|
+
if (outcome.kind === 'stopped' || outcome.kind === 'stop-without-turn') {
|
|
68
|
+
hookStopGeneration.set(key, outcome.generation);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function applyVerdict(parts, episode, outcome, verdict, at) {
|
|
72
|
+
const base = { outcome: outcome.kind, episodeId: episode.episodeId };
|
|
73
|
+
if (verdict.action === 'close') {
|
|
74
|
+
const closed = (0, waiting_episode_state_1.closeEpisode)(parts, episode.episodeId, verdict.reason, at);
|
|
75
|
+
if (closed) {
|
|
76
|
+
logger.info('waiting-episode-closed-by-turn', {
|
|
77
|
+
worktreeId: parts.worktreeId,
|
|
78
|
+
cliToolId: parts.cliToolId,
|
|
79
|
+
instanceId: parts.instanceId ?? parts.cliToolId,
|
|
80
|
+
episodeId: episode.episodeId,
|
|
81
|
+
outcome: outcome.kind,
|
|
82
|
+
reason: verdict.reason,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return { ...base, action: closed ? 'closed' : 'none', ...(closed ? { reason: verdict.reason } : {}) };
|
|
86
|
+
}
|
|
87
|
+
if (verdict.action === 'rebind') {
|
|
88
|
+
const rebound = (0, waiting_episode_state_1.rebindEpisode)(parts, episode.episodeId, verdict.binding, at);
|
|
89
|
+
if (rebound) {
|
|
90
|
+
logger.debug('waiting-episode-rebound', {
|
|
91
|
+
worktreeId: parts.worktreeId,
|
|
92
|
+
instanceId: parts.instanceId ?? parts.cliToolId,
|
|
93
|
+
episodeId: episode.episodeId,
|
|
94
|
+
outcome: outcome.kind,
|
|
95
|
+
binding: verdict.binding.kind,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return { ...base, action: rebound ? 'rebound' : 'none' };
|
|
99
|
+
}
|
|
100
|
+
if (verdict.action === 'unmatched') {
|
|
101
|
+
logger.warn('waiting-episode-unmatched', {
|
|
102
|
+
worktreeId: parts.worktreeId,
|
|
103
|
+
instanceId: parts.instanceId ?? parts.cliToolId,
|
|
104
|
+
episodeId: episode.episodeId,
|
|
105
|
+
outcome: outcome.kind,
|
|
106
|
+
binding: episode.binding.kind,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return { ...base, action: 'none' };
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Apply a delivery's transition outcomes to the instance's open episode
|
|
113
|
+
* (Issue #3798, design §2.4 T table), in order.
|
|
114
|
+
*
|
|
115
|
+
* Called in the synchronous step that produced the outcomes. Never throws: the
|
|
116
|
+
* turn has been recorded already, and a failure here must not cost the hook
|
|
117
|
+
* its answer (design §2.6). An episode it leaves open is still closed by the
|
|
118
|
+
* screen observers.
|
|
119
|
+
*
|
|
120
|
+
* @param at - Epoch ms of the change; defaults to now
|
|
121
|
+
*/
|
|
122
|
+
function applyTurnOutcomesToEpisode(parts, outcomes, at = Date.now()) {
|
|
123
|
+
const effects = [];
|
|
124
|
+
try {
|
|
125
|
+
const key = (0, auto_yes_state_1.buildCompositeKey)(parts.worktreeId, parts.cliToolId, parts.instanceId);
|
|
126
|
+
for (const outcome of outcomes) {
|
|
127
|
+
noteHookStop(key, outcome);
|
|
128
|
+
const episode = (0, waiting_episode_state_1.getWaitingEpisodeRecord)(parts.worktreeId, parts.cliToolId, parts.instanceId);
|
|
129
|
+
if (episode === null) {
|
|
130
|
+
effects.push({ outcome: outcome.kind, action: 'none', episodeId: null });
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const verdict = (0, waiting_episode_verdict_1.verdictForOutcome)(outcome, episode.binding, (0, waiting_episode_binding_resolve_1.generationOf)(parts));
|
|
134
|
+
effects.push(applyVerdict(parts, episode, outcome, verdict, at));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
logger.warn('waiting-episode-turn-sync-failed', {
|
|
139
|
+
worktreeId: parts.worktreeId,
|
|
140
|
+
instanceId: parts.instanceId ?? parts.cliToolId,
|
|
141
|
+
error: error instanceof Error ? error.message : String(error),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
return effects;
|
|
145
|
+
}
|
|
146
|
+
var waiting_episode_binding_observation_2 = require("../../lib/session/waiting-episode-binding-observation");
|
|
147
|
+
Object.defineProperty(exports, "captureFrameTime", { enumerable: true, get: function () { return waiting_episode_binding_observation_2.captureFrameTime; } });
|
|
148
|
+
Object.defineProperty(exports, "captureObservedFrame", { enumerable: true, get: function () { return waiting_episode_binding_observation_2.captureObservedFrame; } });
|
|
149
|
+
Object.defineProperty(exports, "planWaitingObservation", { enumerable: true, get: function () { return waiting_episode_binding_observation_2.planWaitingObservation; } });
|
|
150
|
+
Object.defineProperty(exports, "startWaitingObservation", { enumerable: true, get: function () { return waiting_episode_binding_observation_2.startWaitingObservation; } });
|
|
151
|
+
Object.defineProperty(exports, "startWorktreeWaitingObservations", { enumerable: true, get: function () { return waiting_episode_binding_observation_2.startWorktreeWaitingObservations; } });
|
|
152
|
+
/**
|
|
153
|
+
* Carry out a plan (design I5 (b)). Each write names the episode the plan was
|
|
154
|
+
* made about, so a plan committed late changes nothing that moved since.
|
|
155
|
+
*
|
|
156
|
+
* @returns What was done — `ignored` also when the episode moved after the plan
|
|
157
|
+
*/
|
|
158
|
+
function commitWaitingObservation(plan) {
|
|
159
|
+
const obs = plan.observation;
|
|
160
|
+
const parts = { worktreeId: obs.worktreeId, cliToolId: obs.cliToolId, instanceId: obs.instanceId };
|
|
161
|
+
try {
|
|
162
|
+
switch (plan.action) {
|
|
163
|
+
case 'kept':
|
|
164
|
+
if (plan.episodeId === null || obs.reading.kind !== 'waiting')
|
|
165
|
+
return 'ignored';
|
|
166
|
+
return (0, waiting_episode_state_1.updateEpisodeKind)(parts, plan.episodeId, obs.reading.waitingKind) ? 'kept' : 'ignored';
|
|
167
|
+
case 'opened':
|
|
168
|
+
if (plan.next === null || (0, waiting_episode_state_1.getWaitingEpisodeRecord)(obs.worktreeId, obs.cliToolId, obs.instanceId) !== null) {
|
|
169
|
+
return 'ignored';
|
|
170
|
+
}
|
|
171
|
+
(0, waiting_episode_state_1.openEpisode)(parts, plan.next, plan.at);
|
|
172
|
+
return 'opened';
|
|
173
|
+
case 'replaced':
|
|
174
|
+
if (plan.next === null || plan.episodeId === null || plan.closeReason === null)
|
|
175
|
+
return 'ignored';
|
|
176
|
+
return (0, waiting_episode_state_1.replaceEpisode)(parts, plan.episodeId, plan.next, plan.closeReason, plan.at) !== null
|
|
177
|
+
? 'replaced'
|
|
178
|
+
: 'ignored';
|
|
179
|
+
case 'rebound':
|
|
180
|
+
if (plan.binding === null || plan.episodeId === null)
|
|
181
|
+
return 'ignored';
|
|
182
|
+
return (0, waiting_episode_state_1.rebindEpisode)(parts, plan.episodeId, plan.binding, plan.at) ? 'rebound' : 'ignored';
|
|
183
|
+
case 'closed':
|
|
184
|
+
if (plan.episodeId === null || plan.closeReason === null)
|
|
185
|
+
return 'ignored';
|
|
186
|
+
return (0, waiting_episode_state_1.closeEpisode)(parts, plan.episodeId, plan.closeReason, plan.at) ? 'closed' : 'ignored';
|
|
187
|
+
case 'ignored':
|
|
188
|
+
if (plan.ignoredBecause === 'version' || plan.ignoredBecause === 'stale-frame' || plan.ignoredBecause === 'generation') {
|
|
189
|
+
logger.debug('waiting-observation-ignored', {
|
|
190
|
+
worktreeId: obs.worktreeId,
|
|
191
|
+
instanceId: obs.instanceId ?? obs.cliToolId,
|
|
192
|
+
observer: obs.observer,
|
|
193
|
+
reading: obs.reading.kind,
|
|
194
|
+
because: plan.ignoredBecause,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return 'ignored';
|
|
198
|
+
default:
|
|
199
|
+
plan.action;
|
|
200
|
+
return 'ignored';
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
logger.warn('waiting-observation-failed', {
|
|
205
|
+
worktreeId: obs.worktreeId,
|
|
206
|
+
instanceId: obs.instanceId ?? obs.cliToolId,
|
|
207
|
+
observer: obs.observer,
|
|
208
|
+
error: error instanceof Error ? error.message : String(error),
|
|
209
|
+
});
|
|
210
|
+
return 'ignored';
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/** {@link planWaitingObservation} and {@link commitWaitingObservation} in one step; the plan with what was done. */
|
|
214
|
+
function observeWaiting(obs) {
|
|
215
|
+
const plan = (0, waiting_episode_binding_observation_1.planWaitingObservation)(obs);
|
|
216
|
+
const action = commitWaitingObservation(plan);
|
|
217
|
+
return action === plan.action ? plan : { ...plan, action };
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Fix the episode a legacy (`claude-done`) stop is about, before its first
|
|
221
|
+
* capture `await` (design 規則 6). The body read before it cannot be helped: the
|
|
222
|
+
* worktree id is in the body — a known limit (design §8).
|
|
223
|
+
*/
|
|
224
|
+
function captureLegacyStopTarget(worktreeId, cliToolId, instanceId) {
|
|
225
|
+
const parts = { worktreeId, cliToolId, instanceId };
|
|
226
|
+
return {
|
|
227
|
+
generation: (0, waiting_episode_binding_resolve_1.generationOf)(parts),
|
|
228
|
+
episodeId: (0, waiting_episode_state_1.getWaitingEpisodeRecord)(worktreeId, cliToolId, instanceId)?.episodeId ?? null,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Close the episode a legacy stop was fixed on, if it is still the open one
|
|
233
|
+
* (design 規則 6). Nothing when the hook reported a stop in this generation
|
|
234
|
+
* (the hook speaks for the end of turns; closing again is the double close the
|
|
235
|
+
* rule forbids), when another episode opened meanwhile, or for a screen only a
|
|
236
|
+
* person drives.
|
|
237
|
+
*
|
|
238
|
+
* @param at - Epoch ms; defaults to now
|
|
239
|
+
*/
|
|
240
|
+
function settleLegacyStop(worktreeId, cliToolId, instanceId, target, at = Date.now()) {
|
|
241
|
+
try {
|
|
242
|
+
const parts = { worktreeId, cliToolId, instanceId };
|
|
243
|
+
const key = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
244
|
+
const episode = (0, waiting_episode_state_1.getWaitingEpisodeRecord)(worktreeId, cliToolId, instanceId);
|
|
245
|
+
if (episode === null)
|
|
246
|
+
return 'nothing-open';
|
|
247
|
+
const current = (0, waiting_episode_binding_resolve_1.generationOf)(parts);
|
|
248
|
+
if (target.episodeId === null ||
|
|
249
|
+
episode.episodeId !== target.episodeId ||
|
|
250
|
+
!(0, waiting_episode_verdict_1.sameGeneration)(target.generation, current)) {
|
|
251
|
+
return 'target-gone';
|
|
252
|
+
}
|
|
253
|
+
const hookStop = hookStopGeneration.get(key);
|
|
254
|
+
if (hookStop !== undefined && (0, waiting_episode_verdict_1.sameGeneration)(hookStop, current))
|
|
255
|
+
return 'hook-authority';
|
|
256
|
+
if (episode.binding.kind === 'screen')
|
|
257
|
+
return 'screen';
|
|
258
|
+
return (0, waiting_episode_state_1.closeEpisode)(parts, episode.episodeId, 'legacy-stop', at) ? 'closed' : 'target-gone';
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
logger.warn('waiting-episode-legacy-stop-failed', {
|
|
262
|
+
worktreeId,
|
|
263
|
+
instanceId: instanceId ?? cliToolId,
|
|
264
|
+
error: error instanceof Error ? error.message : String(error),
|
|
265
|
+
});
|
|
266
|
+
return 'nothing-open';
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/** Forget the hook-stop marks. Test seam, called by `clearAgentStopEvents`. */
|
|
270
|
+
function clearWaitingEpisodeBindingState() {
|
|
271
|
+
hookStopGeneration.clear();
|
|
272
|
+
}
|
|
273
|
+
(0, waiting_episode_state_1.registerEpisodeBindingResolver)(waiting_episode_binding_resolve_1.resolveEpisodeBinding);
|
|
274
|
+
(0, agent_event_turn_1.registerTurnOutcomeSink)((parts, outcomes) => {
|
|
275
|
+
applyTurnOutcomesToEpisode(parts, outcomes);
|
|
276
|
+
});
|