commandmate 0.47.2 → 0.49.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 +180 -180
- package/.next/app-path-routes-manifest.json +30 -30
- 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.js.nft.json +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page.js +1 -1
- package/.next/server/app/skills/[skillId]/page.js.nft.json +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.js +2 -2
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +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.js.nft.json +1 -1
- 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 +30 -30
- 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/2069.js +1 -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/4243.js +1 -1
- 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 +8 -8
- 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 +5 -5
- 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/1128-914c559913546bbc.js +1 -0
- package/.next/static/chunks/{2407-a6533805a86d05bd.js → 2407-ab92ae9837c39dce.js} +1 -1
- package/.next/static/chunks/{2863-6a07ec82fb52f4dd.js → 2863-7173dc305dffc4f6.js} +1 -1
- package/.next/static/chunks/6288-6fadbba6e84393b2.js +1 -0
- package/.next/static/chunks/7665-e9ef6e0a85b9fa49.js +1 -0
- package/.next/static/chunks/8407-35bbfc84793d7004.js +1 -0
- package/.next/static/chunks/9079-987939d231704218.js +1 -0
- package/.next/static/chunks/app/{layout-538d8d2746ad1588.js → layout-aa8e66164a4367af.js} +1 -1
- package/.next/static/chunks/app/sessions/page-cfd645305e25fd33.js +1 -0
- package/.next/static/chunks/app/skills/[skillId]/{page-52ba58712faf3378.js → page-cb6e74fd9a6a571d.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/files/[...path]/page-704086656fb45699.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-a8d7886703ffc7b4.js +1 -0
- package/.next/static/css/{743f79ff19ab91e9.css → db8959555c3d9c96.css} +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 +76 -8
- package/dist/cli/commands/capture.d.ts.map +1 -1
- package/dist/cli/commands/capture.js +5 -0
- 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 +19 -6
- package/dist/cli/commands/verify.d.ts.map +1 -1
- package/dist/cli/commands/verify.js +8 -1
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +101 -13
- package/dist/cli/config/duration-constants.d.ts +16 -13
- package/dist/cli/config/duration-constants.d.ts.map +1 -1
- package/dist/cli/config/duration-constants.js +21 -21
- 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 +29 -1
- package/dist/cli/types/api-responses.d.ts +145 -3
- 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/cli/utils/verify-runner.d.ts +24 -1
- package/dist/cli/utils/verify-runner.d.ts.map +1 -1
- package/dist/cli/utils/verify-runner.js +54 -1
- package/dist/config/auto-yes-duration.d.ts +56 -0
- package/dist/config/auto-yes-duration.d.ts.map +1 -0
- package/dist/config/auto-yes-duration.js +76 -0
- 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/config/auto-yes-config.js +14 -19
- package/dist/server/src/config/auto-yes-duration.js +76 -0
- 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 +59 -4
- package/dist/server/src/lib/cli-tools/submit-verified-sender.js +235 -19
- 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/composer-text.js +215 -11
- 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-chrome.js +193 -0
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +402 -539
- 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/upstream-faults.js +19 -2
- 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/hooks/structured-decision-response.js +1 -1
- 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 +124 -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 +145 -58
- 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/composer-clear.js +56 -4
- package/dist/server/src/lib/session/current-output-builder.js +66 -12
- package/dist/server/src/lib/session/send-attempt-state.js +24 -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-ops.js +152 -0
- package/dist/server/src/lib/session/waiting-episode-state-store.js +202 -0
- package/dist/server/src/lib/session/waiting-episode-state-types.js +6 -0
- package/dist/server/src/lib/session/waiting-episode-state.js +68 -91
- 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 +79 -9
- package/dist/server/src/lib/verification/gate-runner.js +172 -16
- 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 +47 -13
- package/package.json +1 -1
- package/public/sw.js +76 -4
- package/release-notes/0.48.0.json +57 -0
- package/release-notes/0.49.0.json +45 -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/server/chunks/6722.js +0 -1
- package/.next/static/chunks/5371-a549a0d2c2044d41.js +0 -1
- package/.next/static/chunks/602-1c1488959215e140.js +0 -1
- package/.next/static/chunks/6288-09feba367cc2c65e.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]/files/[...path]/page-9cf1ecc59e36a004.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-46aced20b2b1c010.js +0 -1
- /package/.next/static/{etorRtpxbQqqOzdUeXdw2 → 3_JtAZaKMJEDFIIfkHv4n}/_buildManifest.js +0 -0
- /package/.next/static/{etorRtpxbQqqOzdUeXdw2 → 3_JtAZaKMJEDFIIfkHv4n}/_ssgManifest.js +0 -0
|
@@ -78,6 +78,7 @@ const ansi_1 = require("../../ansi");
|
|
|
78
78
|
const prompt_detect_multiple_choice_1 = require("../../prompt-detect-multiple-choice");
|
|
79
79
|
const selection_shape_1 = require("../../selection-shape");
|
|
80
80
|
const dialog_block_1 = require("../dialog-block");
|
|
81
|
+
const option_recommendation_1 = require("../../option-recommendation");
|
|
81
82
|
const truncate_raw_content_1 = require("../../truncate-raw-content");
|
|
82
83
|
/**
|
|
83
84
|
* How many rows of dialog this reader will parse.
|
|
@@ -354,6 +355,8 @@ function readCommandCodeQuestionDialog(frame) {
|
|
|
354
355
|
region,
|
|
355
356
|
prompt: {
|
|
356
357
|
...built,
|
|
358
|
+
// Issue #3863: beside the payload, never in it — see `PromptDetectionResult`.
|
|
359
|
+
optionRecommendations: readCommandCodeOptionRecommendations(lines, regionRows.slice(block.firstRow), labels.length),
|
|
357
360
|
promptData: {
|
|
358
361
|
...promptData,
|
|
359
362
|
// Only ever added, never set to `false`: see the `checked` note above.
|
|
@@ -373,6 +376,70 @@ function readCommandCodeQuestionDialog(frame) {
|
|
|
373
376
|
},
|
|
374
377
|
};
|
|
375
378
|
}
|
|
379
|
+
/** The option row's own prefix — indent, gutter, cursor and number — up to where its label starts. */
|
|
380
|
+
const OPTION_ROW_PREFIX_PATTERN = /^[^\S\n]*[│┃]?[^\S\n]*[❯›●>]?[^\S\n]*\d{1,2}[.)][^\S\n]+/;
|
|
381
|
+
/**
|
|
382
|
+
* What each option's title says about being recommended (Issue #3863,
|
|
383
|
+
* `option-recommendation`), read off the option rows again — the block reader
|
|
384
|
+
* joins everything under an option into its label, and this screen says
|
|
385
|
+
* which rows are the title.
|
|
386
|
+
*
|
|
387
|
+
* Measured on the reported capture (#2521, 1.53.0): an option's description
|
|
388
|
+
* starts on its own row at the option's LABEL column (`❯ 1. ` → five spaces),
|
|
389
|
+
* and only what the pane wraps lands further left (column 0 or 1). So under an
|
|
390
|
+
* option row:
|
|
391
|
+
*
|
|
392
|
+
* - a row at or right of the label column starts the description, and
|
|
393
|
+
* everything after it is description;
|
|
394
|
+
* - a row left of it, before any description, is the title wrapping — unless
|
|
395
|
+
* the row above could not have wrapped into it (its first word would have
|
|
396
|
+
* fit there, `cannotBeWrapOf`), in which case it is a description drawn
|
|
397
|
+
* further left (the synthetic indent 0 / 1 / 2 shapes #2522 reads), and the
|
|
398
|
+
* rest is description too;
|
|
399
|
+
* - `Submit` / `Next` and the hint bar under the last option are nobody's.
|
|
400
|
+
*
|
|
401
|
+
* Every option `'unknown'` when the walk does not find the same options the
|
|
402
|
+
* reading did.
|
|
403
|
+
*
|
|
404
|
+
* @param frameRows - Every row of the capture, for the pane's width
|
|
405
|
+
* @param optionRows - The region's rows from option 1's row on
|
|
406
|
+
* @param optionCount - How many options the reading found
|
|
407
|
+
*/
|
|
408
|
+
function readCommandCodeOptionRecommendations(frameRows, optionRows, optionCount) {
|
|
409
|
+
const paneColumns = (0, option_recommendation_1.lowerBoundPaneColumns)(frameRows);
|
|
410
|
+
const titles = [];
|
|
411
|
+
let labelColumn = 0;
|
|
412
|
+
let lastTitleRow = '';
|
|
413
|
+
let inDescription = false;
|
|
414
|
+
for (const row of optionRows) {
|
|
415
|
+
if (row.trim() === '')
|
|
416
|
+
continue;
|
|
417
|
+
const parsed = (0, dialog_block_1.parseNumberedOptionRow)(row);
|
|
418
|
+
if (parsed !== null && parsed.number === titles.length + 1) {
|
|
419
|
+
titles.push([parsed.label]);
|
|
420
|
+
labelColumn = OPTION_ROW_PREFIX_PATTERN.exec(row)?.[0].length ?? 0;
|
|
421
|
+
lastTitleRow = row;
|
|
422
|
+
inDescription = false;
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
if (titles.length === 0)
|
|
426
|
+
break;
|
|
427
|
+
if (COMMAND_CODE_CONFIRM_ROW_PATTERN.test(row) || COMMAND_CODE_QUESTION_HINT_BAR_PATTERN.test(row))
|
|
428
|
+
continue;
|
|
429
|
+
if (inDescription)
|
|
430
|
+
continue;
|
|
431
|
+
const indent = row.length - row.trimStart().length;
|
|
432
|
+
if (indent >= labelColumn || (0, option_recommendation_1.cannotBeWrapOf)(lastTitleRow, row, paneColumns)) {
|
|
433
|
+
inDescription = true;
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
titles[titles.length - 1].push(row.trim());
|
|
437
|
+
lastTitleRow = row;
|
|
438
|
+
}
|
|
439
|
+
if (titles.length !== optionCount)
|
|
440
|
+
return Array.from({ length: optionCount }, () => 'unknown');
|
|
441
|
+
return titles.map((rows) => (0, option_recommendation_1.isRecommendedTitle)(rows.join(' ')));
|
|
442
|
+
}
|
|
376
443
|
/**
|
|
377
444
|
* The same reading as a `PromptDetectionResult | null`, for the call sites whose
|
|
378
445
|
* only question is "is there an answerable prompt here?".
|
|
@@ -30,7 +30,9 @@
|
|
|
30
30
|
* glyph or an SGR attribute, so both spellings parse to the same block.
|
|
31
31
|
*/
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
+
exports.parseNumberedOptionRow = parseNumberedOptionRow;
|
|
33
34
|
exports.findNumberedOptionBlock = findNumberedOptionBlock;
|
|
35
|
+
const option_recommendation_1 = require("../option-recommendation");
|
|
34
36
|
/**
|
|
35
37
|
* One numbered option row.
|
|
36
38
|
*
|
|
@@ -58,6 +60,16 @@ const OPTION_ROW_PATTERN = /^[^\S\n]*[│┃]?[^\S\n]*([❯›●>])?[^\S\n]*(\d
|
|
|
58
60
|
const DEFAULT_FOOTER_SCAN_ROWS = 8;
|
|
59
61
|
/** How many rows one option block may span, wrapped continuations included. */
|
|
60
62
|
const MAX_BLOCK_ROWS = 60;
|
|
63
|
+
/**
|
|
64
|
+
* Read one row as a numbered option row (`❯ 1. label`), or null.
|
|
65
|
+
*
|
|
66
|
+
* Exported for a tool module that walks the block's rows again to tell an
|
|
67
|
+
* option's title from its description (Issue #3863), so it reads an option
|
|
68
|
+
* row exactly as this reader does.
|
|
69
|
+
*/
|
|
70
|
+
function parseNumberedOptionRow(row) {
|
|
71
|
+
return parseOptionRow(row);
|
|
72
|
+
}
|
|
61
73
|
function parseOptionRow(row) {
|
|
62
74
|
const match = OPTION_ROW_PATTERN.exec(row);
|
|
63
75
|
if (!match)
|
|
@@ -117,6 +129,8 @@ function findNumberedOptionBlock(lines, endExclusive, footerScanRows = DEFAULT_F
|
|
|
117
129
|
const lastRow = cursor;
|
|
118
130
|
// 2. Walk up the run, collecting each option and any wrapped rows above it.
|
|
119
131
|
const collected = [bottom];
|
|
132
|
+
// Issue #3863: whether rows were folded into each collected option's label.
|
|
133
|
+
const folded = [false];
|
|
120
134
|
let expected = bottom.number - 1;
|
|
121
135
|
let row = cursor - 1;
|
|
122
136
|
let spanned = 1;
|
|
@@ -135,6 +149,7 @@ function findNumberedOptionBlock(lines, endExclusive, footerScanRows = DEFAULT_F
|
|
|
135
149
|
const parsed = parseOptionRow(text);
|
|
136
150
|
if (parsed && parsed.number === expected) {
|
|
137
151
|
collected.unshift({ ...parsed, label: [parsed.label, ...pending].join(' ').trim() });
|
|
152
|
+
folded.unshift(pending.length > 0);
|
|
138
153
|
pending = [];
|
|
139
154
|
expected--;
|
|
140
155
|
row--;
|
|
@@ -155,5 +170,6 @@ function findNumberedOptionBlock(lines, endExclusive, footerScanRows = DEFAULT_F
|
|
|
155
170
|
firstRow: row + 1,
|
|
156
171
|
lastRow,
|
|
157
172
|
footer: footerRows.join('\n'),
|
|
173
|
+
optionRecommendations: collected.map((option, index) => folded[index] ? 'unknown' : (0, option_recommendation_1.isRecommendedTitle)(option.label)),
|
|
158
174
|
};
|
|
159
175
|
}
|
|
@@ -54,6 +54,22 @@ exports.UPSTREAM_FAULTS = [
|
|
|
54
54
|
pattern: /\bmaximum context length is \d+ tokens\b/i,
|
|
55
55
|
selfRetrying: false,
|
|
56
56
|
},
|
|
57
|
+
{
|
|
58
|
+
// codex ends the turn with `Selected model is at capacity` and does not
|
|
59
|
+
// answer (Issue #3936); the same model will not, so the cue is to switch
|
|
60
|
+
// instance or model. Anchored on the sentence, not on "at capacity": the
|
|
61
|
+
// 529 line above says "The API is at capacity" and is `overloaded`.
|
|
62
|
+
//
|
|
63
|
+
// And on codex's own error row, not on the sentence alone: `■ ` at column
|
|
64
|
+
// 0, the shape codex 0.160.0 draws its errors in (measured on
|
|
65
|
+
// `■ Conversation interrupted`). A reply that names or quotes the error —
|
|
66
|
+
// this Issue, its review — is indented (`• ` / ` `), and an input echo
|
|
67
|
+
// starts with `› `; matching those would fail a healthy turn with exit 11.
|
|
68
|
+
// The capacity row itself is unmeasured (the fixture is synthetic).
|
|
69
|
+
id: 'model-capacity',
|
|
70
|
+
pattern: /^■ Selected model is at capacity\b/im,
|
|
71
|
+
selfRetrying: false,
|
|
72
|
+
},
|
|
57
73
|
{ id: 'limit-reached', pattern: /\blimit reached\b/i, selfRetrying: false },
|
|
58
74
|
{ id: 'api-error', pattern: /\bAPI Error(?::|\s+\d{3})/i, selfRetrying: false },
|
|
59
75
|
];
|
|
@@ -90,8 +106,9 @@ function matchUpstreamFault(frame) {
|
|
|
90
106
|
const clean = (0, ansi_1.stripAnsi)(frame);
|
|
91
107
|
for (const fault of exports.UPSTREAM_FAULTS) {
|
|
92
108
|
const match = fault.pattern.exec(clean);
|
|
93
|
-
// The patterns are
|
|
94
|
-
//
|
|
109
|
+
// The patterns are stateless (no /g; only `model-capacity` is anchored, to a
|
|
110
|
+
// line start with /m), so `exec` cannot carry a lastIndex between calls —
|
|
111
|
+
// but reading `index` requires exec regardless.
|
|
95
112
|
if (!match)
|
|
96
113
|
continue;
|
|
97
114
|
const lineStart = clean.lastIndexOf('\n', match.index) + 1;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* One reading of a frame for the waiting episodes (Issue #3798, design §2.2 /
|
|
4
|
+
* 規則 1 / I9).
|
|
5
|
+
*
|
|
6
|
+
* Three observers read a frame and tell the episode store about it: the status
|
|
7
|
+
* probe (`worktree-status-helper`), the response poller and the Auto-Yes poller.
|
|
8
|
+
* They used to read it three ways — the Auto-Yes poller through the agy receipt
|
|
9
|
+
* window, which turns a real confirmation outside the window into "no prompt" —
|
|
10
|
+
* and a wait one of them saw as a person's screen another saw as nothing. Here
|
|
11
|
+
* is the one reading they share: whether the frame waits, what kind of wait it
|
|
12
|
+
* is, and whether only a person can end it (`humanHeld`), from the detector's
|
|
13
|
+
* verdict WITHOUT the receipt scope.
|
|
14
|
+
*
|
|
15
|
+
* `humanHeld` (規則 1) is all of: the detector says `waiting`, the same
|
|
16
|
+
* verdict's prompt reading says there is no prompt, and the agent reported no
|
|
17
|
+
* structured wait. So a copilot `ask_user` with four or more options (a prompt
|
|
18
|
+
* the detector reads, `isPrompt: true`) and an opencode permission strip the
|
|
19
|
+
* agent reported a decision for (a structured wait) are not a person's screen;
|
|
20
|
+
* a survey, a picker or a trust screen is.
|
|
21
|
+
*
|
|
22
|
+
* Detection layer: reads the detector and the waiting taxonomy, and nothing in
|
|
23
|
+
* `polling/` or the session stores.
|
|
24
|
+
*
|
|
25
|
+
* @module lib/detection/waiting-screen-reading
|
|
26
|
+
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.waitingReadingFromVerdict = waitingReadingFromVerdict;
|
|
29
|
+
exports.promptWaitingReading = promptWaitingReading;
|
|
30
|
+
exports.readWaitingScreen = readWaitingScreen;
|
|
31
|
+
const status_detector_1 = require("./status-detector");
|
|
32
|
+
const status_reason_1 = require("./status-reason");
|
|
33
|
+
const waiting_kind_1 = require("../../lib/session/waiting-kind");
|
|
34
|
+
/**
|
|
35
|
+
* The reasons that mean "no rule could read this frame" — the set
|
|
36
|
+
* `session/status-evidence`'s `isUnclassifiedFrame` names. Restated rather than
|
|
37
|
+
* imported because that module sits above this layer (it reads the agent's
|
|
38
|
+
* event store).
|
|
39
|
+
*/
|
|
40
|
+
const UNCLASSIFIED_REASONS = new Set([
|
|
41
|
+
status_reason_1.STATUS_REASON.NO_RECENT_OUTPUT,
|
|
42
|
+
status_reason_1.STATUS_REASON.UNKNOWN_FRAME,
|
|
43
|
+
status_reason_1.STATUS_REASON.DEFAULT,
|
|
44
|
+
]);
|
|
45
|
+
/**
|
|
46
|
+
* A reading from a verdict the caller has already made, with the caller's own
|
|
47
|
+
* composed answer to "is it waiting" (the status probe folds the structured
|
|
48
|
+
* layer and a launch in progress into it). `humanHeld` is decided here and
|
|
49
|
+
* nowhere else.
|
|
50
|
+
*/
|
|
51
|
+
function waitingReadingFromVerdict(input) {
|
|
52
|
+
if (!input.waiting)
|
|
53
|
+
return { kind: 'not-waiting' };
|
|
54
|
+
const { verdict } = input;
|
|
55
|
+
return {
|
|
56
|
+
kind: 'waiting',
|
|
57
|
+
waitingKind: input.waitingKind,
|
|
58
|
+
humanHeld: verdict.status === 'waiting' && verdict.promptDetection.isPrompt === false && !input.structuredWaiting,
|
|
59
|
+
promptData: verdict.promptDetection.promptData ?? null,
|
|
60
|
+
structuredSince: input.structuredSince,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The reading of a prompt an observer has already read off the frame (the
|
|
65
|
+
* response poller's saved prompt). A prompt is never a person's screen.
|
|
66
|
+
*/
|
|
67
|
+
function promptWaitingReading(promptData) {
|
|
68
|
+
return { kind: 'waiting', waitingKind: 'prompt', humanHeld: false, promptData, structuredSince: null };
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Read one captured frame (design §2.2). The detector is asked without the
|
|
72
|
+
* receipt scope (I9); the structured wait, and whether the app answers it over
|
|
73
|
+
* the agent's API, are the caller's to look up — the status probe's reading of
|
|
74
|
+
* the same frame gives the same kind only when both are passed.
|
|
75
|
+
*
|
|
76
|
+
* `verdict` is the detector's answer on this same frame when the caller has
|
|
77
|
+
* already asked for it (to look the structured wait up with), so the frame is
|
|
78
|
+
* not judged twice.
|
|
79
|
+
*/
|
|
80
|
+
function readWaitingScreen(input) {
|
|
81
|
+
const verdict = input.verdict ?? (0, status_detector_1.detectSessionStatus)(input.output, input.cliToolId, input.lastOutputTimestamp);
|
|
82
|
+
if (verdict.status === 'running' && UNCLASSIFIED_REASONS.has(verdict.reason))
|
|
83
|
+
return { kind: 'unknown' };
|
|
84
|
+
const waiting = verdict.status === 'waiting' || verdict.hasActivePrompt || input.structuredWaiting;
|
|
85
|
+
return waitingReadingFromVerdict({
|
|
86
|
+
verdict,
|
|
87
|
+
waiting,
|
|
88
|
+
waitingKind: (0, waiting_kind_1.deriveWaitingKind)({
|
|
89
|
+
waiting,
|
|
90
|
+
hasActivePrompt: verdict.hasActivePrompt,
|
|
91
|
+
scraperStatus: verdict.status,
|
|
92
|
+
scraperReason: verdict.reason,
|
|
93
|
+
apiAnswerable: input.apiAnswerable === true,
|
|
94
|
+
}),
|
|
95
|
+
structuredWaiting: input.structuredWaiting,
|
|
96
|
+
structuredSince: input.structuredSince,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
@@ -119,6 +119,13 @@ function readContractPolicy(session) {
|
|
|
119
119
|
* | policy suppresses (mode off, deny pattern, type) | no-decision + suppression |
|
|
120
120
|
* | otherwise | allow |
|
|
121
121
|
*
|
|
122
|
+
* Issue #3822: the screen path reads the grant and the contract once more right
|
|
123
|
+
* before its first key (`withheldAtSend`). This path has no such moment: the
|
|
124
|
+
* `allow` returned here IS the answer — Claude runs the call without drawing a
|
|
125
|
+
* dialog and nothing is typed afterwards — so the grant and the contract it is
|
|
126
|
+
* judged against are read now, when the hook is answered, and the contract
|
|
127
|
+
* through the same cache-backed lookup (a failed read withholds, #3830).
|
|
128
|
+
*
|
|
122
129
|
* @param session - Worktree / tool / instance the request came from
|
|
123
130
|
* @param payload - Parsed payload, or null when it could not be parsed
|
|
124
131
|
* @param deps - Substitutions for the database-backed lookups; see
|
|
@@ -465,5 +465,5 @@ async function answerStructuredDecision({ worktreeId, cliToolId, instanceId, ans
|
|
|
465
465
|
reply: option.reply,
|
|
466
466
|
delivered,
|
|
467
467
|
});
|
|
468
|
-
return { kind: 'answered', decisionId: decision.id, option, delivered };
|
|
468
|
+
return { kind: 'answered', decisionId: decision.id, option, delivered, receipt: delivery };
|
|
469
469
|
}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* answers. On Kewton/Musunest#283 that was the worker's own proposal, which the
|
|
8
8
|
* worker then implemented as though a human had approved it. So neither the
|
|
9
9
|
* server's poller (`suppressIfNotOursToAnswer`, step 3.3) nor the browser's
|
|
10
|
-
* fallback (`useAutoYes`, which
|
|
11
|
-
* a key to them.
|
|
10
|
+
* fallback (`useAutoYes`, which answered only while no server poller ran, and
|
|
11
|
+
* since Issue #3821 answers nothing) sends a key to them.
|
|
12
12
|
*
|
|
13
13
|
* Server-only: `normalizeFrame` and the tools' detectors reach `logger` → `env`
|
|
14
14
|
* → `fs`. The browser judges by the prompt's options instead
|
|
@@ -72,6 +72,9 @@ const WITHHOLD_REASONS = {
|
|
|
72
72
|
'partial-answer': true,
|
|
73
73
|
'startup-trust-unhandled': true,
|
|
74
74
|
'question-confirm-page': true,
|
|
75
|
+
'question-left-to-human': true,
|
|
76
|
+
'allow-once-unidentified': true,
|
|
77
|
+
'recommended-option-unidentified': true,
|
|
75
78
|
'no-hook-receipt': true,
|
|
76
79
|
'send-failed': true,
|
|
77
80
|
'send-no-keys': true,
|
|
@@ -243,6 +243,8 @@ function runHour(state, at) {
|
|
|
243
243
|
presence: entry.presence,
|
|
244
244
|
answerability: interval === null ? 'answerable' : 'withheld',
|
|
245
245
|
withheldMsTotal: entry.withheldMsClosed + intervalMs,
|
|
246
|
+
// Issue #3863: the mode of the open interval, else of the last decision.
|
|
247
|
+
...answerModeField(interval?.answerMode ?? entry.answerMode),
|
|
246
248
|
...(interval !== null
|
|
247
249
|
? { intervalId: interval.id, reason: interval.reason, intervalStartedAtMs: interval.startedAt, intervalMs }
|
|
248
250
|
: {}),
|
|
@@ -252,11 +254,20 @@ function runHour(state, at) {
|
|
|
252
254
|
// =============================================================================
|
|
253
255
|
// Intervals and closing
|
|
254
256
|
// =============================================================================
|
|
255
|
-
|
|
257
|
+
/** Issue #3863: `{ answerMode }` when there is one, else nothing (the line keeps its old shape). */
|
|
258
|
+
function answerModeField(answerMode) {
|
|
259
|
+
return answerMode === undefined ? {} : { answerMode };
|
|
260
|
+
}
|
|
261
|
+
function withhold(state, entry, reason, now, answerMode = entry.answerMode) {
|
|
256
262
|
const interval = entry.interval;
|
|
257
263
|
if (interval === null) {
|
|
258
264
|
entry.intervals += 1;
|
|
259
|
-
const opened = {
|
|
265
|
+
const opened = {
|
|
266
|
+
id: `${entry.id}#${entry.intervals}`,
|
|
267
|
+
startedAt: now,
|
|
268
|
+
reason,
|
|
269
|
+
...answerModeField(answerMode),
|
|
270
|
+
};
|
|
260
271
|
entry.interval = opened;
|
|
261
272
|
(0, auto_yes_ledger_records_1.emit)(state, auto_yes_confirmation_ledger_types_1.AUTO_YES_LEDGER_EVENTS.withholdStarted, {
|
|
262
273
|
atMs: now,
|
|
@@ -266,6 +277,7 @@ function withhold(state, entry, reason, now) {
|
|
|
266
277
|
source: entry.source,
|
|
267
278
|
reason,
|
|
268
279
|
startedAtMs: now,
|
|
280
|
+
...answerModeField(answerMode),
|
|
269
281
|
});
|
|
270
282
|
return;
|
|
271
283
|
}
|
|
@@ -300,6 +312,7 @@ function endInterval(state, entry, end, now) {
|
|
|
300
312
|
withheldMs,
|
|
301
313
|
end,
|
|
302
314
|
lastReason: interval.reason,
|
|
315
|
+
...answerModeField(interval.answerMode),
|
|
303
316
|
});
|
|
304
317
|
}
|
|
305
318
|
function closeEntry(state, entry, now, how) {
|
|
@@ -356,6 +369,10 @@ function closeEntry(state, entry, now, how) {
|
|
|
356
369
|
// The screen path cannot tell Auto-Yes's keys from a human's; only a
|
|
357
370
|
// delivered reply that released it is known to be Auto-Yes's (design §2.6).
|
|
358
371
|
resolvedBy: how.kind === 'reply' ? 'auto' : how.kind === 'gone' ? (how.resolvedBy ?? 'unknown') : 'unknown',
|
|
372
|
+
// Issue #3863: the mode the last decision about it was made under, and
|
|
373
|
+
// the mode of the send that answered it (which a later decision does not move).
|
|
374
|
+
...answerModeField(entry.answerMode),
|
|
375
|
+
...(entry.answeredAnswerMode !== undefined ? { answeredAnswerMode: entry.answeredAnswerMode } : {}),
|
|
359
376
|
openMs: Math.max(0, now - entry.openedAt),
|
|
360
377
|
withheldMsTotal: entry.withheldMsClosed,
|
|
361
378
|
unobservableMs: entry.unobservableMs,
|
|
@@ -552,6 +569,8 @@ function withholdLedgerConfirmation(scope, reason) {
|
|
|
552
569
|
if (entry === undefined || entry.presence !== 'present')
|
|
553
570
|
return;
|
|
554
571
|
entry.decision = 'withhold';
|
|
572
|
+
if (scope.answerMode !== undefined)
|
|
573
|
+
entry.answerMode = scope.answerMode;
|
|
555
574
|
withhold(state, entry, reason, now);
|
|
556
575
|
});
|
|
557
576
|
}
|
|
@@ -566,6 +585,8 @@ function beginLedgerAttempt(scope, basis, options = {}) {
|
|
|
566
585
|
const entry = (0, auto_yes_ledger_records_1.currentEntry)(state, (0, auto_yes_ledger_records_1.keyOf)(scope));
|
|
567
586
|
if (entry === undefined)
|
|
568
587
|
return null;
|
|
588
|
+
if (scope.answerMode !== undefined)
|
|
589
|
+
entry.answerMode = scope.answerMode;
|
|
569
590
|
return beginAttempt(state, entry, basis, options.receiptAccepted === true);
|
|
570
591
|
});
|
|
571
592
|
}
|
|
@@ -579,7 +600,13 @@ function beginAttempt(state, entry, basis, receiptAccepted) {
|
|
|
579
600
|
if (oldest !== undefined)
|
|
580
601
|
state.pending.delete(oldest);
|
|
581
602
|
}
|
|
582
|
-
state.pending.set(handle.attemptId, {
|
|
603
|
+
state.pending.set(handle.attemptId, {
|
|
604
|
+
confirmationId: entry.id,
|
|
605
|
+
cliToolId: entry.cliToolId,
|
|
606
|
+
basis,
|
|
607
|
+
receiptAccepted,
|
|
608
|
+
...answerModeField(entry.answerMode),
|
|
609
|
+
});
|
|
583
610
|
return handle;
|
|
584
611
|
}
|
|
585
612
|
const WITHHOLD_REASON_OF_RESULT = {
|
|
@@ -616,11 +643,15 @@ function settleAttempt(state, handle, result, expired, now, options = {}) {
|
|
|
616
643
|
late: entry === undefined,
|
|
617
644
|
expired,
|
|
618
645
|
...(pending.receiptAccepted ? { receiptAccepted: true } : {}),
|
|
646
|
+
...answerModeField(pending.answerMode),
|
|
619
647
|
});
|
|
620
648
|
if (entry === undefined)
|
|
621
649
|
return;
|
|
622
650
|
if (result === 'ok') {
|
|
623
651
|
entry.attempts.ok += 1;
|
|
652
|
+
// Issue #3863: the first send that answered it says which mode answered it.
|
|
653
|
+
if (!entry.answered && pending.answerMode !== undefined)
|
|
654
|
+
entry.answeredAnswerMode = pending.answerMode;
|
|
624
655
|
entry.answered = true;
|
|
625
656
|
endInterval(state, entry, 'answered', now);
|
|
626
657
|
return;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Auto-Yes's decision about the confirmation on screen (Issue #3821).
|
|
4
|
+
*
|
|
5
|
+
* Written by the poller's tick (`detectAndRespondToPrompt`), which is where the
|
|
6
|
+
* decision is actually made, and read by `buildCurrentOutput`, which publishes
|
|
7
|
+
* it as `autoYesDecision` next to the prompt. The answer surfaces show their
|
|
8
|
+
* panel under Auto-Yes for every decision but `answering`.
|
|
9
|
+
*
|
|
10
|
+
* ## What a record is tied to
|
|
11
|
+
*
|
|
12
|
+
* A record is published only while everything it was made under still holds:
|
|
13
|
+
*
|
|
14
|
+
* - the GRANT — the same `AutoYesState` object (`getAutoYesState` stores a new
|
|
15
|
+
* one on every enable and on expiry, as the tick's own generation check
|
|
16
|
+
* reads it, #3706), so turning Auto-Yes off and on again or letting it expire
|
|
17
|
+
* drops the old decision even with the same screen up;
|
|
18
|
+
* - the SESSION epoch (`getEnterFallbackSessionEpoch`): a relaunch drops it;
|
|
19
|
+
* - the CONFIRMATION ({@link matchesConfirmation}): the question and the
|
|
20
|
+
* options ({@link enterFallbackScreenKey}), AND what is being approved — the
|
|
21
|
+
* whole `approvalTarget` as read, with only the cursor on its option rows
|
|
22
|
+
* taken out ({@link approvalTargetRows}, the body's indent, `>` and blank
|
|
23
|
+
* rows kept, as #3817 reads it) — AND, for agy, the hook call the receipt
|
|
24
|
+
* was accepted for. Two approvals that differ only in their target (agy's
|
|
25
|
+
* file creation names the file only there, two commands that differ by an
|
|
26
|
+
* indent) are two confirmations. Two readings of one screen that differ in
|
|
27
|
+
* how many rows they kept (one cut from the top) are not matched either:
|
|
28
|
+
* the rows a cut leaves need not name what is approved (a diff row, not the
|
|
29
|
+
* file), and the hook call known now may be an earlier one's (review 3), so
|
|
30
|
+
* they read `none` — the panel opens, nothing is sent. The published
|
|
31
|
+
* `confirmation` ({@link autoYesConfirmationKey}) is this same identity: a
|
|
32
|
+
* record matches exactly when the keys are equal;
|
|
33
|
+
* - a TICK not long ago ({@link AUTO_YES_DECISION_STALE_MS}): a live poller
|
|
34
|
+
* re-decides every tick, so a record nobody refreshed says nothing now.
|
|
35
|
+
*
|
|
36
|
+
* Anything else — no record, another confirmation, an old grant — is `none`,
|
|
37
|
+
* never `answering`. A human's answer through `/prompt-response` drops the
|
|
38
|
+
* record (`./auto-yes-manual-answer`).
|
|
39
|
+
*
|
|
40
|
+
* Two confirmations identical in every part above, in a row, with no frame
|
|
41
|
+
* without a prompt between them, read as one here: nothing on the screen tells
|
|
42
|
+
* them apart. The tick re-decides on its next pass either way.
|
|
43
|
+
*
|
|
44
|
+
* Not the confirmation ledger (#3820): the ledger measures, never decides, and
|
|
45
|
+
* a failure in it changes nothing. This record is what the tick decided.
|
|
46
|
+
*
|
|
47
|
+
* In-memory and on `globalThis` for the reason `auto-yes-suppression-state`
|
|
48
|
+
* gives: the poller writes it and the `current-output` route reads it, and
|
|
49
|
+
* under `next dev` the two are bundled apart.
|
|
50
|
+
*
|
|
51
|
+
* @module lib/polling/auto-yes-decision-state
|
|
52
|
+
*/
|
|
53
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
+
exports.AUTO_YES_DECISION_STALE_MS = void 0;
|
|
55
|
+
exports.approvalTargetRows = approvalTargetRows;
|
|
56
|
+
exports.autoYesConfirmationKey = autoYesConfirmationKey;
|
|
57
|
+
exports.matchesConfirmation = matchesConfirmation;
|
|
58
|
+
exports.recordAutoYesDecision = recordAutoYesDecision;
|
|
59
|
+
exports.reaffirmAutoYesAnswering = reaffirmAutoYesAnswering;
|
|
60
|
+
exports.getAutoYesDecisionRecord = getAutoYesDecisionRecord;
|
|
61
|
+
exports.forgetAutoYesDecision = forgetAutoYesDecision;
|
|
62
|
+
exports.forgetAutoYesDecisionsByWorktree = forgetAutoYesDecisionsByWorktree;
|
|
63
|
+
exports.clearAutoYesDecisions = clearAutoYesDecisions;
|
|
64
|
+
exports.publishAutoYesDecision = publishAutoYesDecision;
|
|
65
|
+
const auto_yes_state_1 = require("../../lib/auto-yes-state");
|
|
66
|
+
const auto_yes_decision_1 = require("../../types/auto-yes-decision");
|
|
67
|
+
const global_state_1 = require("../global-state");
|
|
68
|
+
const auto_yes_enter_fallback_state_1 = require("./auto-yes-enter-fallback-state");
|
|
69
|
+
const auto_yes_poller_state_1 = require("./auto-yes-poller-state");
|
|
70
|
+
const crypto_1 = require("crypto");
|
|
71
|
+
/**
|
|
72
|
+
* How long a record stays current without a tick refreshing it. The poller
|
|
73
|
+
* ticks every couple of seconds and refreshes the record on each tick that
|
|
74
|
+
* sees the screen; one past this is from a poller that is not ticking.
|
|
75
|
+
*/
|
|
76
|
+
exports.AUTO_YES_DECISION_STALE_MS = 30_000;
|
|
77
|
+
const decisions = (0, global_state_1.getOrInitGlobal)('__autoYesDecisions', () => new Map());
|
|
78
|
+
/**
|
|
79
|
+
* The rows of `approvalTarget` with only the cursor taken out of its option
|
|
80
|
+
* rows (`approvalTargetWithoutCursor`), or null when the prompt has none. The
|
|
81
|
+
* body stays as read: an indent, a `>` or a blank row is part of what is
|
|
82
|
+
* approved (#3817).
|
|
83
|
+
*/
|
|
84
|
+
function approvalTargetRows(promptData) {
|
|
85
|
+
const target = (0, auto_yes_poller_state_1.approvalTargetWithoutCursor)(promptData);
|
|
86
|
+
return target === null ? null : target.split('\n');
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Which confirmation a reading is of: question and options
|
|
90
|
+
* ({@link enterFallbackScreenKey}), the approval target row for row
|
|
91
|
+
* ({@link approvalTargetRows}) and the agy call, hashed. The one identity both
|
|
92
|
+
* the record ({@link matchesConfirmation}) and the wire (`confirmation`, read
|
|
93
|
+
* by `laterAutoYesDecision`) use: same key, same confirmation; another key,
|
|
94
|
+
* another confirmation — or the same one read with other rows, which is not
|
|
95
|
+
* claimed to be the same.
|
|
96
|
+
*/
|
|
97
|
+
function autoYesConfirmationKey(identity) {
|
|
98
|
+
return (0, crypto_1.createHash)('sha256')
|
|
99
|
+
.update(JSON.stringify([
|
|
100
|
+
(0, auto_yes_enter_fallback_state_1.enterFallbackScreenKey)(identity.promptData),
|
|
101
|
+
approvalTargetRows(identity.promptData),
|
|
102
|
+
identity.callId ?? null,
|
|
103
|
+
]))
|
|
104
|
+
.digest('hex')
|
|
105
|
+
.slice(0, 32);
|
|
106
|
+
}
|
|
107
|
+
/** Is `record` about the confirmation `identity` describes? The same {@link autoYesConfirmationKey}. */
|
|
108
|
+
function matchesConfirmation(record, identity) {
|
|
109
|
+
return record.confirmation === autoYesConfirmationKey(identity);
|
|
110
|
+
}
|
|
111
|
+
/** Record what the tick decided for the prompt on screen. */
|
|
112
|
+
function recordAutoYesDecision(compositeKey, decision, at = Date.now()) {
|
|
113
|
+
decisions.set(compositeKey, {
|
|
114
|
+
state: decision.state,
|
|
115
|
+
reason: decision.state === 'withheld' ? decision.reason : null,
|
|
116
|
+
confirmation: autoYesConfirmationKey(decision),
|
|
117
|
+
grant: decision.grant,
|
|
118
|
+
epoch: decision.epoch,
|
|
119
|
+
at,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Issue #3821 (review 2): the duplicate guard (#306) says "answered less than
|
|
124
|
+
* `DUPLICATE_RETRY_EXPIRY_MS` ago", comparing only the type and the question.
|
|
125
|
+
* That is not evidence the confirmation on screen is the one answered, so the
|
|
126
|
+
* `answering` record is only kept — its time moved on — when it is the one
|
|
127
|
+
* this tick's send made: about this very confirmation, under the same grant
|
|
128
|
+
* and session. Otherwise the record is dropped (`none`).
|
|
129
|
+
*
|
|
130
|
+
* @returns Whether `answering` still stands
|
|
131
|
+
*/
|
|
132
|
+
function reaffirmAutoYesAnswering(compositeKey, tick, at = Date.now()) {
|
|
133
|
+
const record = decisions.get(compositeKey);
|
|
134
|
+
if (record === undefined ||
|
|
135
|
+
record.state !== 'answering' ||
|
|
136
|
+
record.grant !== tick.grant ||
|
|
137
|
+
record.epoch !== tick.epoch ||
|
|
138
|
+
!matchesConfirmation(record, tick)) {
|
|
139
|
+
decisions.delete(compositeKey);
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
decisions.set(compositeKey, { ...record, at });
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
/** The record as kept, or null. Test seam and diagnostics. */
|
|
146
|
+
function getAutoYesDecisionRecord(compositeKey) {
|
|
147
|
+
return decisions.get(compositeKey) ?? null;
|
|
148
|
+
}
|
|
149
|
+
/** Drop one instance's record: no prompt on screen, a human answered, the poller stopped. */
|
|
150
|
+
function forgetAutoYesDecision(compositeKey) {
|
|
151
|
+
decisions.delete(compositeKey);
|
|
152
|
+
}
|
|
153
|
+
/** {@link forgetAutoYesDecision} for every instance of a worktree. */
|
|
154
|
+
function forgetAutoYesDecisionsByWorktree(worktreeId) {
|
|
155
|
+
for (const key of (0, auto_yes_state_1.filterCompositeKeysByWorktree)([...decisions.keys()], worktreeId)) {
|
|
156
|
+
decisions.delete(key);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/** Drop every record: server shutdown, and a test seam. */
|
|
160
|
+
function clearAutoYesDecisions() {
|
|
161
|
+
decisions.clear();
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* The decision published for the payload's prompt.
|
|
165
|
+
*
|
|
166
|
+
* - no screen prompt, or Auto-Yes off: `none`;
|
|
167
|
+
* - Auto-Yes on with no poller for the instance: `withheld`
|
|
168
|
+
* (`server-poller-inactive`) — nothing answers the screen, whatever an
|
|
169
|
+
* earlier record said;
|
|
170
|
+
* - a record made under this grant and session, about this confirmation
|
|
171
|
+
* ({@link matchesConfirmation}), refreshed recently: that record;
|
|
172
|
+
* - otherwise `none`.
|
|
173
|
+
*
|
|
174
|
+
* Each names the payload's prompt in `confirmation` ({@link autoYesConfirmationKey}; null with no prompt).
|
|
175
|
+
*/
|
|
176
|
+
function publishAutoYesDecision(input) {
|
|
177
|
+
const now = input.now ?? Date.now();
|
|
178
|
+
const { compositeKey, grant, promptData } = input;
|
|
179
|
+
const confirmation = promptData == null ? null : autoYesConfirmationKey({ promptData, callId: input.callId });
|
|
180
|
+
const none = { state: 'none', reason: null, observedAt: now, confirmation };
|
|
181
|
+
if (promptData == null || !grant?.enabled)
|
|
182
|
+
return none;
|
|
183
|
+
if (!input.pollerActive) {
|
|
184
|
+
return { state: 'withheld', reason: auto_yes_decision_1.SERVER_POLLER_INACTIVE_DECISION_REASON, observedAt: now, confirmation };
|
|
185
|
+
}
|
|
186
|
+
const record = decisions.get(compositeKey);
|
|
187
|
+
if (record === undefined ||
|
|
188
|
+
record.grant !== grant ||
|
|
189
|
+
record.epoch !== (0, auto_yes_enter_fallback_state_1.getEnterFallbackSessionEpoch)(compositeKey) ||
|
|
190
|
+
record.confirmation !== confirmation ||
|
|
191
|
+
now - record.at > exports.AUTO_YES_DECISION_STALE_MS) {
|
|
192
|
+
return none;
|
|
193
|
+
}
|
|
194
|
+
return { state: record.state, reason: record.reason, observedAt: now, confirmation };
|
|
195
|
+
}
|