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
|
@@ -12,11 +12,23 @@
|
|
|
12
12
|
*
|
|
13
13
|
* So the edge is detected exactly once, here, by {@link observeWaitingEdge}, and
|
|
14
14
|
* everything else either reads {@link getWaitingEpisode} or subscribes with
|
|
15
|
-
* {@link onWaitingTransition}.
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* {@link onWaitingTransition}. The observers are `worktree-status-helper`, on
|
|
16
|
+
* the list API's per-instance probe — it passes the *composed* verdict (scraper
|
|
17
|
+
* OR structured), so a wait that only the agent's own events can see opens an
|
|
18
|
+
* episode exactly like one the screen scraper read — and `response-checker`
|
|
19
|
+
* (#1790), which opens the episode for a prompt it saved and closes it when it
|
|
20
|
+
* records a reply.
|
|
21
|
+
*
|
|
22
|
+
* Issue #3798 added the agent's own turn transitions as closers: a `stop` that
|
|
23
|
+
* ended the turn an episode belongs to closes it in the same synchronous step
|
|
24
|
+
* that records the stop (`waiting-episode-binding`), so a tool whose reply
|
|
25
|
+
* arrives on a hook closes its wait with no browser open. That needs each
|
|
26
|
+
* episode to carry an identity and the turn it belongs to; see "identity and
|
|
27
|
+
* attribution" below. The screen observers — the status probe, the response
|
|
28
|
+
* poller and now the Auto-Yes poller — go through the same module's
|
|
29
|
+
* observation tables (`observeWaiting`), which refuse a reading made against an
|
|
30
|
+
* episode that has moved since the observer started; {@link observeWaitingEdge}
|
|
31
|
+
* stays for the callers and suites written against #1786.
|
|
20
32
|
*
|
|
21
33
|
* ## Where #1788 / #1790 plug in
|
|
22
34
|
*
|
|
@@ -40,6 +52,17 @@
|
|
|
40
52
|
*/
|
|
41
53
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
54
|
exports.onWaitingTransition = onWaitingTransition;
|
|
55
|
+
exports.onWaitingEpisodeTransition = onWaitingEpisodeTransition;
|
|
56
|
+
exports.openEpisode = openEpisode;
|
|
57
|
+
exports.closeEpisode = closeEpisode;
|
|
58
|
+
exports.replaceEpisode = replaceEpisode;
|
|
59
|
+
exports.rebindEpisode = rebindEpisode;
|
|
60
|
+
exports.updateEpisodeKind = updateEpisodeKind;
|
|
61
|
+
exports.getWaitingEpisodeRecord = getWaitingEpisodeRecord;
|
|
62
|
+
exports.getEpisodeVersion = getEpisodeVersion;
|
|
63
|
+
exports.snapshotEpisodeVersions = snapshotEpisodeVersions;
|
|
64
|
+
exports.getLastClosedEpisode = getLastClosedEpisode;
|
|
65
|
+
exports.registerEpisodeBindingResolver = registerEpisodeBindingResolver;
|
|
43
66
|
exports.observeWaitingEdge = observeWaitingEdge;
|
|
44
67
|
exports.getWaitingEpisode = getWaitingEpisode;
|
|
45
68
|
exports.hasOpenWaitingEpisode = hasOpenWaitingEpisode;
|
|
@@ -53,6 +76,30 @@ const logger = (0, logger_1.createLogger)('waiting-episode-state');
|
|
|
53
76
|
const episodes = (0, global_state_1.getOrInitGlobal)('__sessionWaitingEpisodes', () => new Map());
|
|
54
77
|
/** Subscribers to the edge. See the module docblock. */
|
|
55
78
|
const listeners = (0, global_state_1.getOrInitGlobal)('__sessionWaitingTransitionListeners', () => new Set());
|
|
79
|
+
const metas = (0, global_state_1.getOrInitGlobal)('__sessionWaitingEpisodeMeta', () => new WeakMap());
|
|
80
|
+
const versions = (0, global_state_1.getOrInitGlobal)('__sessionWaitingEpisodeVersions', () => new Map());
|
|
81
|
+
const lastClosed = (0, global_state_1.getOrInitGlobal)('__sessionWaitingEpisodeLastClosed', () => new Map());
|
|
82
|
+
const episodeSeq = (0, global_state_1.getOrInitGlobal)('__sessionWaitingEpisodeSeq', () => ({
|
|
83
|
+
value: 0,
|
|
84
|
+
nonce: Math.random().toString(36).slice(2, 10),
|
|
85
|
+
}));
|
|
86
|
+
const episodeListeners = (0, global_state_1.getOrInitGlobal)('__sessionWaitingEpisodeListeners', () => new Set());
|
|
87
|
+
/** The binding used when no resolver is registered: nothing is known. */
|
|
88
|
+
const UNKNOWN_BINDING = {
|
|
89
|
+
kind: 'unattributed',
|
|
90
|
+
generation: { kind: 'none' },
|
|
91
|
+
lastClosedTurnId: null,
|
|
92
|
+
};
|
|
93
|
+
function nextEpisodeId() {
|
|
94
|
+
episodeSeq.value += 1;
|
|
95
|
+
return `wep-${episodeSeq.nonce}-${episodeSeq.value}`;
|
|
96
|
+
}
|
|
97
|
+
function keyOf(parts) {
|
|
98
|
+
return (0, auto_yes_state_1.buildCompositeKey)(parts.worktreeId, parts.cliToolId, parts.instanceId);
|
|
99
|
+
}
|
|
100
|
+
function bumpVersion(key) {
|
|
101
|
+
versions.set(key, (versions.get(key) ?? 0) + 1);
|
|
102
|
+
}
|
|
56
103
|
/**
|
|
57
104
|
* Subscribe to waiting edges.
|
|
58
105
|
*
|
|
@@ -64,23 +111,257 @@ function onWaitingTransition(listener) {
|
|
|
64
111
|
listeners.delete(listener);
|
|
65
112
|
};
|
|
66
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Subscribe to waiting edges with the episode's identity (Issue #3798).
|
|
116
|
+
*
|
|
117
|
+
* The same crossings `onWaitingTransition` delivers, in the same order, with
|
|
118
|
+
* the cause, the episode ids and the close reason added.
|
|
119
|
+
*/
|
|
120
|
+
function onWaitingEpisodeTransition(listener) {
|
|
121
|
+
episodeListeners.add(listener);
|
|
122
|
+
return () => {
|
|
123
|
+
episodeListeners.delete(listener);
|
|
124
|
+
};
|
|
125
|
+
}
|
|
67
126
|
/** Notify subscribers, containing anything they throw. */
|
|
68
127
|
function emit(transition) {
|
|
128
|
+
const { cause: _cause, episodeId: _id, previousEpisodeId: _prev, closeReason: _reason, ...plain } = transition;
|
|
69
129
|
for (const listener of listeners) {
|
|
130
|
+
try {
|
|
131
|
+
listener(plain);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
logListenerFailure(transition, error);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
for (const listener of episodeListeners) {
|
|
70
138
|
try {
|
|
71
139
|
listener(transition);
|
|
72
140
|
}
|
|
73
141
|
catch (error) {
|
|
74
|
-
|
|
75
|
-
worktreeId: transition.worktreeId,
|
|
76
|
-
cliToolId: transition.cliToolId,
|
|
77
|
-
instanceId: transition.instanceId ?? transition.cliToolId,
|
|
78
|
-
waiting: transition.waiting,
|
|
79
|
-
error: error instanceof Error ? error.message : String(error),
|
|
80
|
-
});
|
|
142
|
+
logListenerFailure(transition, error);
|
|
81
143
|
}
|
|
82
144
|
}
|
|
83
145
|
}
|
|
146
|
+
function logListenerFailure(transition, error) {
|
|
147
|
+
logger.error('waiting-transition-listener-failed', {
|
|
148
|
+
worktreeId: transition.worktreeId,
|
|
149
|
+
cliToolId: transition.cliToolId,
|
|
150
|
+
instanceId: transition.instanceId ?? transition.cliToolId,
|
|
151
|
+
waiting: transition.waiting,
|
|
152
|
+
error: error instanceof Error ? error.message : String(error),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Open an episode (Issue #3798). Low-level: the caller has decided there is
|
|
157
|
+
* none open and what it is bound to. Emits the opening edge.
|
|
158
|
+
*/
|
|
159
|
+
function openEpisode(parts, next, at) {
|
|
160
|
+
const key = keyOf(parts);
|
|
161
|
+
const view = { since: next.since, kind: next.kind };
|
|
162
|
+
const meta = {
|
|
163
|
+
episodeId: nextEpisodeId(),
|
|
164
|
+
openedAt: at,
|
|
165
|
+
boundAt: at,
|
|
166
|
+
binding: next.binding,
|
|
167
|
+
openedBy: next.openedBy,
|
|
168
|
+
promptScreenKey: next.promptScreenKey ?? null,
|
|
169
|
+
};
|
|
170
|
+
episodes.set(key, view);
|
|
171
|
+
metas.set(view, meta);
|
|
172
|
+
bumpVersion(key);
|
|
173
|
+
emit({
|
|
174
|
+
worktreeId: parts.worktreeId,
|
|
175
|
+
cliToolId: parts.cliToolId,
|
|
176
|
+
instanceId: parts.instanceId,
|
|
177
|
+
waiting: true,
|
|
178
|
+
since: view.since,
|
|
179
|
+
kind: view.kind,
|
|
180
|
+
at,
|
|
181
|
+
cause: 'opened',
|
|
182
|
+
episodeId: meta.episodeId,
|
|
183
|
+
previousEpisodeId: null,
|
|
184
|
+
closeReason: null,
|
|
185
|
+
});
|
|
186
|
+
return { ...view, ...meta };
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Close the open episode when it is still `expectedId` (Issue #3798). A closer
|
|
190
|
+
* that names the episode it decided about cannot close a later one.
|
|
191
|
+
*
|
|
192
|
+
* @returns Whether an episode was closed
|
|
193
|
+
*/
|
|
194
|
+
function closeEpisode(parts, expectedId, reason, at) {
|
|
195
|
+
const key = keyOf(parts);
|
|
196
|
+
const view = episodes.get(key);
|
|
197
|
+
if (view === undefined)
|
|
198
|
+
return false;
|
|
199
|
+
const meta = metaOf(view);
|
|
200
|
+
if (meta.episodeId !== expectedId)
|
|
201
|
+
return false;
|
|
202
|
+
episodes.delete(key);
|
|
203
|
+
lastClosed.set(key, { at, promptScreenKey: meta.promptScreenKey });
|
|
204
|
+
bumpVersion(key);
|
|
205
|
+
emit({
|
|
206
|
+
worktreeId: parts.worktreeId,
|
|
207
|
+
cliToolId: parts.cliToolId,
|
|
208
|
+
instanceId: parts.instanceId,
|
|
209
|
+
waiting: false,
|
|
210
|
+
since: null,
|
|
211
|
+
kind: null,
|
|
212
|
+
at,
|
|
213
|
+
cause: 'closed',
|
|
214
|
+
episodeId: null,
|
|
215
|
+
previousEpisodeId: meta.episodeId,
|
|
216
|
+
closeReason: reason,
|
|
217
|
+
});
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Put a new episode in place of `expectedId` as one operation (Issue #3798):
|
|
222
|
+
* listeners hear a single opening edge for the new wait and no closing one
|
|
223
|
+
* in between, so nothing reports "nobody is waiting" mid-swap.
|
|
224
|
+
*
|
|
225
|
+
* @returns The new episode, or null when `expectedId` is no longer open
|
|
226
|
+
*/
|
|
227
|
+
function replaceEpisode(parts, expectedId, next, reason, at) {
|
|
228
|
+
const key = keyOf(parts);
|
|
229
|
+
const old = episodes.get(key);
|
|
230
|
+
if (old === undefined)
|
|
231
|
+
return null;
|
|
232
|
+
const oldMeta = metaOf(old);
|
|
233
|
+
if (oldMeta.episodeId !== expectedId)
|
|
234
|
+
return null;
|
|
235
|
+
lastClosed.set(key, { at, promptScreenKey: oldMeta.promptScreenKey });
|
|
236
|
+
const view = { since: next.since, kind: next.kind };
|
|
237
|
+
const meta = {
|
|
238
|
+
episodeId: nextEpisodeId(),
|
|
239
|
+
openedAt: at,
|
|
240
|
+
boundAt: at,
|
|
241
|
+
binding: next.binding,
|
|
242
|
+
openedBy: next.openedBy,
|
|
243
|
+
promptScreenKey: next.promptScreenKey ?? null,
|
|
244
|
+
};
|
|
245
|
+
episodes.set(key, view);
|
|
246
|
+
metas.set(view, meta);
|
|
247
|
+
bumpVersion(key);
|
|
248
|
+
emit({
|
|
249
|
+
worktreeId: parts.worktreeId,
|
|
250
|
+
cliToolId: parts.cliToolId,
|
|
251
|
+
instanceId: parts.instanceId,
|
|
252
|
+
waiting: true,
|
|
253
|
+
since: view.since,
|
|
254
|
+
kind: view.kind,
|
|
255
|
+
at,
|
|
256
|
+
cause: 'replaced',
|
|
257
|
+
episodeId: meta.episodeId,
|
|
258
|
+
previousEpisodeId: oldMeta.episodeId,
|
|
259
|
+
closeReason: reason,
|
|
260
|
+
});
|
|
261
|
+
return { ...view, ...meta };
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Change what the open episode `expectedId` is bound to (Issue #3798). Not an
|
|
265
|
+
* edge: the wait goes on, so nothing is emitted and `since` stays.
|
|
266
|
+
*
|
|
267
|
+
* @returns Whether the episode was rebound
|
|
268
|
+
*/
|
|
269
|
+
function rebindEpisode(parts, expectedId, binding, at) {
|
|
270
|
+
const key = keyOf(parts);
|
|
271
|
+
const view = episodes.get(key);
|
|
272
|
+
if (view === undefined)
|
|
273
|
+
return false;
|
|
274
|
+
const meta = metaOf(view);
|
|
275
|
+
if (meta.episodeId !== expectedId)
|
|
276
|
+
return false;
|
|
277
|
+
meta.binding = binding;
|
|
278
|
+
meta.boundAt = at;
|
|
279
|
+
bumpVersion(key);
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Refresh the kind of the open episode `expectedId` (Issue #3798, I10). The
|
|
284
|
+
* wait goes on: no edge, and the version does not move.
|
|
285
|
+
*
|
|
286
|
+
* @returns Whether the episode was still open
|
|
287
|
+
*/
|
|
288
|
+
function updateEpisodeKind(parts, expectedId, kind) {
|
|
289
|
+
const view = episodes.get(keyOf(parts));
|
|
290
|
+
if (view === undefined || metaOf(view).episodeId !== expectedId)
|
|
291
|
+
return false;
|
|
292
|
+
view.kind = kind;
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* The meta of an episode in the map. An episode put there without one (a test
|
|
297
|
+
* that wrote the map directly) is given an unattributed identity on first read.
|
|
298
|
+
*/
|
|
299
|
+
function metaOf(view) {
|
|
300
|
+
let meta = metas.get(view);
|
|
301
|
+
if (meta === undefined) {
|
|
302
|
+
meta = {
|
|
303
|
+
episodeId: nextEpisodeId(),
|
|
304
|
+
openedAt: view.since,
|
|
305
|
+
boundAt: view.since,
|
|
306
|
+
binding: UNKNOWN_BINDING,
|
|
307
|
+
openedBy: 'legacy-edge',
|
|
308
|
+
promptScreenKey: null,
|
|
309
|
+
};
|
|
310
|
+
metas.set(view, meta);
|
|
311
|
+
}
|
|
312
|
+
return meta;
|
|
313
|
+
}
|
|
314
|
+
/** The open episode with its identity and binding, or null (Issue #3798). */
|
|
315
|
+
function getWaitingEpisodeRecord(worktreeId, cliToolId, instanceId) {
|
|
316
|
+
const view = episodes.get((0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId));
|
|
317
|
+
if (view === undefined)
|
|
318
|
+
return null;
|
|
319
|
+
const meta = metaOf(view);
|
|
320
|
+
return { since: view.since, kind: view.kind, ...meta, binding: meta.binding };
|
|
321
|
+
}
|
|
322
|
+
/** The instance's episode version: it moves on every open, close, replacement and rebind. */
|
|
323
|
+
function getEpisodeVersion(worktreeId, cliToolId, instanceId) {
|
|
324
|
+
return versions.get((0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId)) ?? 0;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Every instance version of one worktree, as of now (Issue #3798): the status
|
|
328
|
+
* probe fixes them before it lists the tmux sessions. An instance missing from
|
|
329
|
+
* the map is at version 0.
|
|
330
|
+
*/
|
|
331
|
+
function snapshotEpisodeVersions(worktreeId) {
|
|
332
|
+
const prefix = `${worktreeId}${auto_yes_state_1.COMPOSITE_KEY_SEPARATOR}`;
|
|
333
|
+
const snapshot = new Map();
|
|
334
|
+
for (const [key, version] of versions) {
|
|
335
|
+
if (key.startsWith(prefix))
|
|
336
|
+
snapshot.set(key, version);
|
|
337
|
+
}
|
|
338
|
+
return snapshot;
|
|
339
|
+
}
|
|
340
|
+
/** The last episode that ended for this instance, or null. */
|
|
341
|
+
function getLastClosedEpisode(worktreeId, cliToolId, instanceId) {
|
|
342
|
+
return lastClosed.get((0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId)) ?? null;
|
|
343
|
+
}
|
|
344
|
+
/** Install the binding resolver `observeWaitingEdge` uses. The last one wins. */
|
|
345
|
+
function registerEpisodeBindingResolver(resolver) {
|
|
346
|
+
globalThis.__sessionWaitingEpisodeBindingResolver = resolver;
|
|
347
|
+
}
|
|
348
|
+
function resolveBinding(parts, at) {
|
|
349
|
+
const resolver = globalThis.__sessionWaitingEpisodeBindingResolver;
|
|
350
|
+
if (resolver === undefined)
|
|
351
|
+
return UNKNOWN_BINDING;
|
|
352
|
+
try {
|
|
353
|
+
return resolver(parts, at);
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
logger.warn('waiting-episode-binding-resolve-failed', {
|
|
357
|
+
worktreeId: parts.worktreeId,
|
|
358
|
+
cliToolId: parts.cliToolId,
|
|
359
|
+
instanceId: parts.instanceId ?? parts.cliToolId,
|
|
360
|
+
error: error instanceof Error ? error.message : String(error),
|
|
361
|
+
});
|
|
362
|
+
return UNKNOWN_BINDING;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
84
365
|
/**
|
|
85
366
|
* Record this poll's waiting verdict and answer when the current wait began.
|
|
86
367
|
*
|
|
@@ -89,16 +370,23 @@ function emit(transition) {
|
|
|
89
370
|
* `since` and emit nothing, so a listener hears one event per wait rather than
|
|
90
371
|
* one per poll.
|
|
91
372
|
*
|
|
373
|
+
* Issue #3798: an episode opened here is bound by the registered resolver
|
|
374
|
+
* (`waiting-episode-binding`), so the turn transitions can end it. The
|
|
375
|
+
* production observers no longer call it: they go through
|
|
376
|
+
* `waiting-episode-binding`'s `observeWaiting`, which also checks that the
|
|
377
|
+
* episode has not moved since they started and that the frame does not
|
|
378
|
+
* predate the close of what it shows.
|
|
379
|
+
*
|
|
92
380
|
* @returns The episode's `since` while waiting, or null when it is not.
|
|
93
381
|
*/
|
|
94
382
|
function observeWaitingEdge({ worktreeId, cliToolId, instanceId, waiting, kind = null, structuredSince = null, now = Date.now(), }) {
|
|
95
|
-
const
|
|
383
|
+
const parts = { worktreeId, cliToolId, instanceId };
|
|
384
|
+
const key = keyOf(parts);
|
|
96
385
|
const existing = episodes.get(key);
|
|
97
386
|
if (!waiting) {
|
|
98
387
|
if (existing === undefined)
|
|
99
388
|
return null;
|
|
100
|
-
|
|
101
|
-
emit({ worktreeId, cliToolId, instanceId, waiting: false, since: null, kind: null, at: now });
|
|
389
|
+
closeEpisode(parts, metaOf(existing).episodeId, 'screen-cleared', now);
|
|
102
390
|
return null;
|
|
103
391
|
}
|
|
104
392
|
if (existing !== undefined) {
|
|
@@ -109,8 +397,7 @@ function observeWaitingEdge({ worktreeId, cliToolId, instanceId, waiting, kind =
|
|
|
109
397
|
return existing.since;
|
|
110
398
|
}
|
|
111
399
|
const since = structuredSince ?? now;
|
|
112
|
-
|
|
113
|
-
emit({ worktreeId, cliToolId, instanceId, waiting: true, since, kind, at: now });
|
|
400
|
+
openEpisode(parts, { since, kind, binding: resolveBinding(parts, now), openedBy: 'legacy-edge' }, now);
|
|
114
401
|
return since;
|
|
115
402
|
}
|
|
116
403
|
/**
|
|
@@ -152,8 +439,11 @@ function hasOpenWaitingEpisode(worktreeId) {
|
|
|
152
439
|
*/
|
|
153
440
|
function clearWaitingEpisodes() {
|
|
154
441
|
episodes.clear();
|
|
442
|
+
versions.clear();
|
|
443
|
+
lastClosed.clear();
|
|
155
444
|
}
|
|
156
445
|
/** Drop every subscriber. Test seam, paired with {@link clearWaitingEpisodes}. */
|
|
157
446
|
function clearWaitingTransitionListeners() {
|
|
158
447
|
listeners.clear();
|
|
448
|
+
episodeListeners.clear();
|
|
159
449
|
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The T table (Issue #3798, design §2.4): what one turn transition's outcome
|
|
4
|
+
* does to the open waiting episode. Pure — it reads the outcome, the episode's
|
|
5
|
+
* binding and the current generation, and writes nothing. Applying the verdict
|
|
6
|
+
* is `waiting-episode-binding`'s job (Issue #3864 split it out of there).
|
|
7
|
+
*
|
|
8
|
+
* Design: `docs/design/issue-3798-waiting-episode.md`.
|
|
9
|
+
*
|
|
10
|
+
* @module lib/session/waiting-episode-verdict
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.sameGeneration = sameGeneration;
|
|
14
|
+
exports.verdictForOutcome = verdictForOutcome;
|
|
15
|
+
function sameGeneration(a, b) {
|
|
16
|
+
if (a.kind === 'none' || b.kind === 'none')
|
|
17
|
+
return a.kind === b.kind;
|
|
18
|
+
return a.at === b.at;
|
|
19
|
+
}
|
|
20
|
+
const NONE = { action: 'none' };
|
|
21
|
+
const close = (reason) => ({ action: 'close', reason });
|
|
22
|
+
/** The previous record's turn id, for the D and F columns. Null for `none`. */
|
|
23
|
+
function previousTurnId(previous) {
|
|
24
|
+
return previous.kind === 'none' ? null : previous.turnId;
|
|
25
|
+
}
|
|
26
|
+
/** T1–T5: a turn opened. */
|
|
27
|
+
function verdictForOpened(outcome, binding) {
|
|
28
|
+
const { previous, turnId: n, event } = outcome;
|
|
29
|
+
const asTurnN = { kind: 'turn', generation: outcome.generation, turnId: n };
|
|
30
|
+
if (binding.kind === 'screen')
|
|
31
|
+
return NONE;
|
|
32
|
+
if (binding.kind === 'turn' && binding.turnId === n)
|
|
33
|
+
return { action: 'unmatched' }; // ※1
|
|
34
|
+
const p = previousTurnId(previous);
|
|
35
|
+
const tookOverRecord = previous.kind === 'dialog-only' || previous.kind === 'display-only';
|
|
36
|
+
// D: the record this turn took over (R3-4). Only T2 / T3 / T4 have one (※5).
|
|
37
|
+
const isD = binding.kind === 'dialog-only' && binding.recordTurnId === p;
|
|
38
|
+
// T5 (R1-9): a turn replaced while it was open ends every wait but a screen's.
|
|
39
|
+
if (previous.kind === 'open-same-session' || previous.kind === 'open-other-session') {
|
|
40
|
+
return isD ? { action: 'unmatched' } : close('turn-superseded');
|
|
41
|
+
}
|
|
42
|
+
// T4 (R2-4): a prompt ends them too; the turn model drops every decision here.
|
|
43
|
+
if (event === 'user_prompt_submit')
|
|
44
|
+
return close('turn-superseded');
|
|
45
|
+
if (binding.kind === 'turn')
|
|
46
|
+
return close('turn-superseded');
|
|
47
|
+
if (binding.kind === 'dialog-only') {
|
|
48
|
+
if (!isD)
|
|
49
|
+
return close('turn-superseded');
|
|
50
|
+
return tookOverRecord ? { action: 'rebind', binding: asTurnN } : { action: 'unmatched' }; // T1: ※5
|
|
51
|
+
}
|
|
52
|
+
// unattributed — F: nothing opened between the wait and this turn (R2-4).
|
|
53
|
+
return binding.lastClosedTurnId === p ? { action: 'rebind', binding: asTurnN } : close('turn-superseded');
|
|
54
|
+
}
|
|
55
|
+
/** T9–T11: a stop with no turn open. */
|
|
56
|
+
function verdictForStopWithoutTurn(outcome, binding) {
|
|
57
|
+
const { previous } = outcome;
|
|
58
|
+
const p = previousTurnId(previous);
|
|
59
|
+
switch (previous.kind) {
|
|
60
|
+
case 'closed':
|
|
61
|
+
// T9: B (R1-2) and F (R2-1).
|
|
62
|
+
if (binding.kind === 'turn' && binding.turnId === p)
|
|
63
|
+
return close('turn-stop');
|
|
64
|
+
if (binding.kind === 'unattributed' && binding.lastClosedTurnId === p)
|
|
65
|
+
return close('turn-stop');
|
|
66
|
+
if (binding.kind === 'dialog-only' && binding.recordTurnId === p)
|
|
67
|
+
return { action: 'unmatched' }; // ※5
|
|
68
|
+
return NONE;
|
|
69
|
+
case 'dialog-only':
|
|
70
|
+
// T10: D, F and G.
|
|
71
|
+
if (binding.kind === 'dialog-only' && binding.recordTurnId === p)
|
|
72
|
+
return close('turn-stop');
|
|
73
|
+
if (binding.kind === 'unattributed')
|
|
74
|
+
return close('turn-stop');
|
|
75
|
+
return NONE;
|
|
76
|
+
case 'display-only':
|
|
77
|
+
case 'none':
|
|
78
|
+
// T11: D (R3-4) and F.
|
|
79
|
+
if (binding.kind === 'dialog-only' && binding.recordTurnId === p)
|
|
80
|
+
return close('turn-stop');
|
|
81
|
+
if (binding.kind === 'unattributed' && binding.lastClosedTurnId === p)
|
|
82
|
+
return close('turn-stop');
|
|
83
|
+
return NONE;
|
|
84
|
+
default:
|
|
85
|
+
// An open turn is `stopped` / `stop-rejected`, never this outcome.
|
|
86
|
+
return { action: 'unmatched' };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** T19 / T20 and the rest of the generation fence. */
|
|
90
|
+
function verdictForGenerationFenced(outcome, binding) {
|
|
91
|
+
// T19 / T20 (R2-8): a session start in the same process keeps a screen.
|
|
92
|
+
if (outcome.source === 'session-start' && binding.kind === 'screen') {
|
|
93
|
+
return sameGeneration(binding.generation, outcome.generation)
|
|
94
|
+
? NONE
|
|
95
|
+
: { action: 'rebind', binding: { ...binding, generation: outcome.generation } };
|
|
96
|
+
}
|
|
97
|
+
return sameGeneration(binding.generation, outcome.generation) ? NONE : close('generation');
|
|
98
|
+
}
|
|
99
|
+
/** T7. */
|
|
100
|
+
function verdictForRestored(outcome, binding) {
|
|
101
|
+
// T7: a wait opened under the discarded turn belongs to the one put back.
|
|
102
|
+
return binding.kind === 'turn' && binding.turnId === outcome.discardedTurnId
|
|
103
|
+
? { action: 'rebind', binding: { ...binding, turnId: outcome.restoredTurnId } }
|
|
104
|
+
: NONE;
|
|
105
|
+
}
|
|
106
|
+
/** T8. */
|
|
107
|
+
function verdictForStopped(outcome, binding) {
|
|
108
|
+
// T8.
|
|
109
|
+
return binding.kind === 'turn' && binding.turnId === outcome.turnId ? close('turn-stop') : NONE;
|
|
110
|
+
}
|
|
111
|
+
/** T13. */
|
|
112
|
+
function verdictForSessionEnded(outcome, binding) {
|
|
113
|
+
// T13.
|
|
114
|
+
return binding.kind === 'turn' && binding.turnId === outcome.turnId ? close('turn-session-end') : NONE;
|
|
115
|
+
}
|
|
116
|
+
/** T15 / T16. */
|
|
117
|
+
function verdictForDecisionOpened(outcome, binding, current) {
|
|
118
|
+
// T15 / T16 (R3-6): a dialog the hook reported for a wait the screen showed first.
|
|
119
|
+
return outcome.recordKind === 'dialog-only' && binding.kind === 'unattributed'
|
|
120
|
+
? {
|
|
121
|
+
action: 'rebind',
|
|
122
|
+
binding: { kind: 'dialog-only', generation: current, recordTurnId: outcome.recordTurnId, sessionId: null },
|
|
123
|
+
}
|
|
124
|
+
: NONE;
|
|
125
|
+
}
|
|
126
|
+
/** T17 / T18. */
|
|
127
|
+
function verdictForDecisionAnswered(outcome, binding) {
|
|
128
|
+
// T17 / T18 (R3-3): an explicit answer that left nothing pending.
|
|
129
|
+
if (outcome.before === 0 || outcome.remaining > 0)
|
|
130
|
+
return NONE;
|
|
131
|
+
const bound = (binding.kind === 'turn' && binding.turnId === outcome.recordTurnId) ||
|
|
132
|
+
(binding.kind === 'dialog-only' && binding.recordTurnId === outcome.recordTurnId);
|
|
133
|
+
return bound ? close('decision-settled') : NONE;
|
|
134
|
+
}
|
|
135
|
+
/** Rows that close a binding of another generation (the I column). */
|
|
136
|
+
const CLOSES_OTHER_GENERATION = new Set([
|
|
137
|
+
'opened',
|
|
138
|
+
'stopped',
|
|
139
|
+
'stop-without-turn',
|
|
140
|
+
'session-ended',
|
|
141
|
+
]);
|
|
142
|
+
/** The T table (design §2.4): one outcome on the open episode. */
|
|
143
|
+
function verdictForOutcome(outcome, binding, current) {
|
|
144
|
+
if (outcome.kind === 'generation-fenced')
|
|
145
|
+
return verdictForGenerationFenced(outcome, binding);
|
|
146
|
+
if (!sameGeneration(binding.generation, current)) {
|
|
147
|
+
return CLOSES_OTHER_GENERATION.has(outcome.kind) ? close('generation') : NONE;
|
|
148
|
+
}
|
|
149
|
+
switch (outcome.kind) {
|
|
150
|
+
case 'opened':
|
|
151
|
+
return verdictForOpened(outcome, binding);
|
|
152
|
+
case 'restored':
|
|
153
|
+
return verdictForRestored(outcome, binding);
|
|
154
|
+
case 'stopped':
|
|
155
|
+
return verdictForStopped(outcome, binding);
|
|
156
|
+
case 'stop-without-turn':
|
|
157
|
+
return verdictForStopWithoutTurn(outcome, binding);
|
|
158
|
+
case 'session-ended':
|
|
159
|
+
return verdictForSessionEnded(outcome, binding);
|
|
160
|
+
case 'decision-opened':
|
|
161
|
+
return verdictForDecisionOpened(outcome, binding, current);
|
|
162
|
+
case 'decision-answered':
|
|
163
|
+
return verdictForDecisionAnswered(outcome, binding);
|
|
164
|
+
case 'continued':
|
|
165
|
+
case 'stop-rejected':
|
|
166
|
+
case 'session-end-rejected':
|
|
167
|
+
case 'none':
|
|
168
|
+
// T6, T12, T14, T21.
|
|
169
|
+
return NONE;
|
|
170
|
+
default:
|
|
171
|
+
outcome;
|
|
172
|
+
return NONE;
|
|
173
|
+
}
|
|
174
|
+
}
|