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
|
@@ -22,6 +22,8 @@ const auto_yes_resolver_1 = require("./auto-yes-resolver");
|
|
|
22
22
|
const auto_yes_policy_1 = require("./auto-yes-policy");
|
|
23
23
|
const logger_1 = require("../../lib/logger");
|
|
24
24
|
const global_state_1 = require("../global-state");
|
|
25
|
+
const prompt_screen_key_1 = require("../detection/prompt-screen-key");
|
|
26
|
+
const auto_yes_poller_state_1 = require("./auto-yes-poller-state");
|
|
25
27
|
const auto_yes_suppression_reason_1 = require("./auto-yes-suppression-reason");
|
|
26
28
|
const auto_yes_suppression_state_1 = require("./auto-yes-suppression-state");
|
|
27
29
|
const logger = (0, logger_1.createLogger)('auto-yes-poller');
|
|
@@ -70,12 +72,20 @@ const WITHHELD_NO_RECEIPT_LOG_INTERVAL_MS = 60_000;
|
|
|
70
72
|
* ungated reading this function already took, and the reason it recorded.
|
|
71
73
|
*
|
|
72
74
|
* @param compositeKey - The instance's key, for the once-a-minute limit
|
|
75
|
+
* Issue #3880: a person's send that may have left keys on the pane holds the
|
|
76
|
+
* dialog (`partial-answer`), but no tick inside the window published it — the
|
|
77
|
+
* manual hold kept them off it — so there is no record to re-stamp. Given that
|
|
78
|
+
* hold's screen, a dialog still up at it is withheld as `partial-answer` here,
|
|
79
|
+
* before the contract and the receipt (as on the tick, step 2.5).
|
|
80
|
+
*
|
|
73
81
|
* @param readWithoutGate - The same frame read without `receiptScope`
|
|
82
|
+
* @param personHoldScreenKey - The screen of a person's hold the tick had
|
|
83
|
+
* (`PartialAutoYesAnswer.byPerson`), else null
|
|
74
84
|
* @returns The prompt the ungated reading saw, with the reason this call
|
|
75
85
|
* recorded or kept for it (null when none: a dialog the gate accepted and is
|
|
76
86
|
* waiting to be answered); null when no dialog was read past the gate
|
|
77
87
|
*/
|
|
78
|
-
function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, readWithoutGate) {
|
|
88
|
+
function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, readWithoutGate, personHoldScreenKey = null) {
|
|
79
89
|
// Issue #3767: the gate's own verdict for this tick's candidate. Null means it
|
|
80
90
|
// never saw one (no dialog), `ok` that it let the frame through.
|
|
81
91
|
let verdict = (0, antigravity_receipt_episodes_1.getAntigravityReceiptVerdict)(worktreeId, instanceId);
|
|
@@ -91,6 +101,14 @@ function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, rea
|
|
|
91
101
|
verdict ??= (0, antigravity_receipt_episodes_1.judgeAntigravityPermissionReceipt)(worktreeId, instanceId, now);
|
|
92
102
|
if (verdict.ok)
|
|
93
103
|
return null;
|
|
104
|
+
if (personHoldScreenKey !== null && (0, auto_yes_poller_state_1.partialAnswerCovers)(personHoldScreenKey, (0, prompt_screen_key_1.promptScreenKey)(promptData))) {
|
|
105
|
+
(0, auto_yes_suppression_state_1.recordPolicySuppression)(worktreeId, 'antigravity', instanceId, {
|
|
106
|
+
reason: auto_yes_suppression_reason_1.PARTIAL_ANSWER_SUPPRESSION_REASON,
|
|
107
|
+
mode: null,
|
|
108
|
+
promptType: promptData.type,
|
|
109
|
+
});
|
|
110
|
+
return { promptData, reason: auto_yes_suppression_reason_1.PARTIAL_ANSWER_SUPPRESSION_REASON, keptPersonHold: true };
|
|
111
|
+
}
|
|
94
112
|
// Issue #3724: a contract that withholds the answer makes the server reply
|
|
95
113
|
// `ask`, so the dialog stays up past the receipt window. The cause is then the
|
|
96
114
|
// contract, not a hooks.json that points elsewhere. Judged exactly as the tick
|
|
@@ -102,7 +120,7 @@ function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, rea
|
|
|
102
120
|
// dropping the `policy-lookup-failed` record the tick made.
|
|
103
121
|
const { policy, taskId } = (0, auto_yes_policy_1.getSessionAutoYesPolicyLookupEntry)(worktreeId, 'antigravity', instanceId);
|
|
104
122
|
const mode = (0, auto_yes_resolver_1.policyLookupMode)(policy);
|
|
105
|
-
const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(ungated.promptData, policy);
|
|
123
|
+
const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(ungated.promptData, policy, 'antigravity');
|
|
106
124
|
// Issue #3767: `answered` is the dialog the gate already let through on this
|
|
107
125
|
// receipt, still up past the window. Unless the contract withheld it, that is
|
|
108
126
|
// not a missing receipt: neither recorded nor logged, nor counted for the limit.
|
|
@@ -149,9 +167,7 @@ function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, rea
|
|
|
149
167
|
reason: resolution.suppressedBy,
|
|
150
168
|
mode,
|
|
151
169
|
taskId,
|
|
152
|
-
hint: resolution.suppressedBy
|
|
153
|
-
? '契約の照会に失敗したので答えていない。サーバーログの policy-lookup-failed を確認'
|
|
154
|
-
: '契約の autoYes が答えを止めている。契約の autoYes を確認',
|
|
170
|
+
hint: withheldHint(resolution.suppressedBy),
|
|
155
171
|
});
|
|
156
172
|
return seen(contractReason ?? null);
|
|
157
173
|
}
|
|
@@ -172,6 +188,24 @@ function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, rea
|
|
|
172
188
|
});
|
|
173
189
|
return seen(auto_yes_suppression_reason_1.NO_HOOK_RECEIPT_SUPPRESSION_REASON);
|
|
174
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* The hint of `antigravity-autoyes-withheld-by-policy` for `reason`. Issue
|
|
193
|
+
* #3822: the base rules' withholding (`allow-once-unidentified`) is not the
|
|
194
|
+
* contract's, so the line does not send the operator to the contract for it.
|
|
195
|
+
*/
|
|
196
|
+
function withheldHint(reason) {
|
|
197
|
+
if (reason === auto_yes_suppression_reason_1.POLICY_LOOKUP_FAILED_SUPPRESSION_REASON) {
|
|
198
|
+
return '契約の照会に失敗したので答えていない。サーバーログの policy-lookup-failed を確認';
|
|
199
|
+
}
|
|
200
|
+
// Issue #3863: the other base-rule withholding, over a question's recommended option.
|
|
201
|
+
if (reason === auto_yes_suppression_reason_1.RECOMMENDED_OPTION_UNIDENTIFIED_SUPPRESSION_REASON) {
|
|
202
|
+
return '質問の推奨の選択肢を 1 つに特定できないので答えていない(基本の判定。契約の判定ではない)。画面で答える';
|
|
203
|
+
}
|
|
204
|
+
if ((0, auto_yes_suppression_reason_1.isBaseRuleSuppressionReason)(reason)) {
|
|
205
|
+
return '今回だけ許可の選択肢を 1 つに特定できないので答えていない(基本の判定。契約の判定ではない)。画面で答える';
|
|
206
|
+
}
|
|
207
|
+
return '契約の autoYes が答えを止めている。契約の autoYes を確認';
|
|
208
|
+
}
|
|
175
209
|
/**
|
|
176
210
|
* Whether a withheld line for `compositeKey` is due at `now` under the
|
|
177
211
|
* once-a-minute limit; when it is, entries past the interval are pruned and
|
|
@@ -218,6 +252,9 @@ function refreshEpisodeSuppression(worktreeId, instanceId, verdict, resolution)
|
|
|
218
252
|
// up (same episode, accepted on the same receipt). Not `getPartialAnswer`:
|
|
219
253
|
// the tick forgets it as soon as the gated reading stops seeing the prompt,
|
|
220
254
|
// which past the window is every tick.
|
|
255
|
+
// Issue #3798: re-stamped under the waiting episode it was recorded for
|
|
256
|
+
// (`episodeId` is carried over), not whichever is open now — the keys went
|
|
257
|
+
// to that wait's dialog.
|
|
221
258
|
const { at: _recordedAt, ...suppression } = own;
|
|
222
259
|
(0, auto_yes_suppression_state_1.recordPolicySuppression)(worktreeId, 'antigravity', instanceId, suppression);
|
|
223
260
|
return true;
|
|
@@ -6,15 +6,24 @@
|
|
|
6
6
|
* `AutoYesPollerState`. Must not import auto-yes-poller.ts (cycle).
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.partialAnswerScreenKey = exports.UNIDENTIFIED_SCREEN_KEY = void 0;
|
|
10
|
+
exports.getAutoYesLastAnswer = getAutoYesLastAnswer;
|
|
9
11
|
exports.promptFrameKey = promptFrameKey;
|
|
10
12
|
exports.warnOncePerFrame = warnOncePerFrame;
|
|
11
|
-
exports.
|
|
13
|
+
exports.partialAnswerCovers = partialAnswerCovers;
|
|
12
14
|
exports.ledgerScreenKey = ledgerScreenKey;
|
|
15
|
+
exports.approvalTargetWithoutCursor = approvalTargetWithoutCursor;
|
|
13
16
|
exports.getPartialAnswer = getPartialAnswer;
|
|
14
17
|
exports.forgetPartialAnswer = forgetPartialAnswer;
|
|
18
|
+
exports.personSendsInFlight = personSendsInFlight;
|
|
15
19
|
exports.forgetPartialAnswersByWorktree = forgetPartialAnswersByWorktree;
|
|
20
|
+
exports.releasePartialAnswerToHuman = releasePartialAnswerToHuman;
|
|
21
|
+
exports.identifyPartialAnswerScreen = identifyPartialAnswerScreen;
|
|
22
|
+
exports.keepPartialAnswerByPerson = keepPartialAnswerByPerson;
|
|
23
|
+
exports.nextSendOrder = nextSendOrder;
|
|
16
24
|
exports.clearPartialAnswers = clearPartialAnswers;
|
|
17
25
|
exports.beginSendAttempt = beginSendAttempt;
|
|
26
|
+
exports.beginManualSendAttempt = beginManualSendAttempt;
|
|
18
27
|
exports.settleSendAttempt = settleSendAttempt;
|
|
19
28
|
exports.hasMovedSendInFlight = hasMovedSendInFlight;
|
|
20
29
|
exports.movePartialAnswers = movePartialAnswers;
|
|
@@ -24,7 +33,17 @@ const auto_yes_state_1 = require("../auto-yes-state");
|
|
|
24
33
|
const global_state_1 = require("../global-state");
|
|
25
34
|
const auto_yes_enter_fallback_state_1 = require("./auto-yes-enter-fallback-state");
|
|
26
35
|
const appearance_1 = require("../prompt-observation/appearance");
|
|
36
|
+
const prompt_screen_key_1 = require("../detection/prompt-screen-key");
|
|
27
37
|
const logger = (0, logger_1.createLogger)('auto-yes-poller');
|
|
38
|
+
/**
|
|
39
|
+
* The Auto-Yes poller's last answer for one instance (Issue #3798), for the
|
|
40
|
+
* other observers of the same waiting episode (the response poller). Read off
|
|
41
|
+
* `globalThis` (`__autoYesPollerStates`) as the push gate reads the poller's
|
|
42
|
+
* answer time, so a reader need not import the poller.
|
|
43
|
+
*/
|
|
44
|
+
function getAutoYesLastAnswer(compositeKey) {
|
|
45
|
+
return globalThis.__autoYesPollerStates?.get(compositeKey)?.lastAnswer ?? null;
|
|
46
|
+
}
|
|
28
47
|
/**
|
|
29
48
|
* Issue #2995: what makes two ticks "the same prompt" for `warnOncePerFrame`.
|
|
30
49
|
*
|
|
@@ -65,41 +84,21 @@ function warnOncePerFrame(pollerState, frameKey, event, fields) {
|
|
|
65
84
|
logger.warn(event, fields);
|
|
66
85
|
}
|
|
67
86
|
/**
|
|
68
|
-
*
|
|
69
|
-
* the
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*/
|
|
75
|
-
function partialAnswerScreenKey(promptData) {
|
|
76
|
-
const options = promptData.type === 'multiple_choice'
|
|
77
|
-
? promptData.options.map((o) => `${o.number}.${o.label}`).join('\n')
|
|
78
|
-
: promptData.options.join('\n');
|
|
79
|
-
return [(0, prompt_key_1.generatePromptKey)(promptData), options, withoutCursorMarks(promptData)].join('\u0000');
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* `approvalTarget` with the cursor taken out: the generic parser copies the
|
|
83
|
-
* option panel into it, `❯` row included, so a moved cursor would otherwise
|
|
84
|
-
* read as another prompt.
|
|
85
|
-
*
|
|
86
|
-
* [Issue #3817] Only the rows the block reader adopted as the options are
|
|
87
|
-
* aligned (`approvalTargetWithOptionRowsAligned`, the reading #3812 gives the
|
|
88
|
-
* strict respond), so two commands whose bodies differ by an indent or a `>`
|
|
89
|
-
* are two screens. A label the block reader read may run longer than the
|
|
90
|
-
* prompt's — it folds wrapped rows and the footer in — so it only has to start
|
|
91
|
-
* with it. A yes/no prompt has no cursor and is read as it is. A list whose
|
|
92
|
-
* rows cannot be told that way keeps the old reading below: two bodies then
|
|
93
|
-
* read as one screen, which holds the prompt for a human rather than typing
|
|
94
|
-
* the answer twice.
|
|
87
|
+
* The screen key of a person's send made with no prompt read off the screen
|
|
88
|
+
* (Issue #3880: the capture before it failed). A hold at it covers whatever
|
|
89
|
+
* confirmation the next tick reads, and takes that confirmation's key there
|
|
90
|
+
* ({@link identifyPartialAnswerScreen}); from then on it is released like any
|
|
91
|
+
* other — the screen changing, the session relaunched, a person's answer going
|
|
92
|
+
* through — and before then by a frame with no prompt on it.
|
|
95
93
|
*/
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const aligned = (0, appearance_1.approvalTargetWithOptionRowsAligned)(target, promptData.options.map((o) => o.label), (read, named) => read.startsWith(named));
|
|
101
|
-
return aligned ?? withoutLeadingMarks(target);
|
|
94
|
+
exports.UNIDENTIFIED_SCREEN_KEY = '\u0000unidentified-screen';
|
|
95
|
+
/** Whether a hold (or a send) at `heldScreenKey` covers the confirmation at `screenKey`. */
|
|
96
|
+
function partialAnswerCovers(heldScreenKey, screenKey) {
|
|
97
|
+
return heldScreenKey === screenKey || heldScreenKey === exports.UNIDENTIFIED_SCREEN_KEY;
|
|
102
98
|
}
|
|
99
|
+
/** Issue #3798: moved to `detection/prompt-screen-key`, where the waiting episodes read it too. */
|
|
100
|
+
var prompt_screen_key_2 = require("../detection/prompt-screen-key");
|
|
101
|
+
Object.defineProperty(exports, "partialAnswerScreenKey", { enumerable: true, get: function () { return prompt_screen_key_2.promptScreenKey; } });
|
|
103
102
|
/**
|
|
104
103
|
* Which confirmation the ledger counts a prompt as (Issue #3820): the
|
|
105
104
|
* {@link partialAnswerScreenKey} reading where the option rows can be told,
|
|
@@ -115,14 +114,32 @@ function withoutCursorMarks(promptData) {
|
|
|
115
114
|
*/
|
|
116
115
|
function ledgerScreenKey(promptData) {
|
|
117
116
|
if (promptData.type !== 'multiple_choice')
|
|
118
|
-
return
|
|
117
|
+
return (0, prompt_screen_key_1.promptScreenKey)(promptData);
|
|
119
118
|
const target = promptData.approvalTarget ?? '';
|
|
120
119
|
const aligned = (0, appearance_1.approvalTargetWithOptionRowsAligned)(target, promptData.options.map((o) => o.label), (read, named) => read.startsWith(named));
|
|
121
120
|
if (aligned !== null)
|
|
122
|
-
return
|
|
121
|
+
return (0, prompt_screen_key_1.promptScreenKey)(promptData);
|
|
123
122
|
const options = promptData.options.map((o) => `${o.number}.${o.label}`).join('\n');
|
|
124
123
|
return [(0, prompt_key_1.generatePromptKey)(promptData), options, withOptionRowGuttersAligned(target, promptData.options)].join('\u0000');
|
|
125
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* `approvalTarget` with only the cursor taken out of its option rows, or null
|
|
127
|
+
* when the prompt has none (Issue #3821, the identity of the confirmation an
|
|
128
|
+
* Auto-Yes decision is about). The reading {@link ledgerScreenKey} keeps: the
|
|
129
|
+
* rows the block reader adopted as the options are aligned
|
|
130
|
+
* (`approvalTargetWithOptionRowsAligned`), else only the rows that ARE the
|
|
131
|
+
* prompt's options lose their gutter; the body — its indent, a `>`, a blank
|
|
132
|
+
* row — stays byte for byte, so two commands that differ there are two
|
|
133
|
+
* confirmations (#3817), and a moved cursor is the same one.
|
|
134
|
+
*/
|
|
135
|
+
function approvalTargetWithoutCursor(promptData) {
|
|
136
|
+
const target = promptData.approvalTarget;
|
|
137
|
+
if (typeof target !== 'string')
|
|
138
|
+
return null;
|
|
139
|
+
if (promptData.type !== 'multiple_choice')
|
|
140
|
+
return target;
|
|
141
|
+
return ((0, appearance_1.approvalTargetWithOptionRowsAligned)(target, promptData.options.map((o) => o.label), (read, named) => read.startsWith(named)) ?? withOptionRowGuttersAligned(target, promptData.options));
|
|
142
|
+
}
|
|
126
143
|
/** A row's leading cursor marks and indentation. */
|
|
127
144
|
const LEADING_MARKS_PATTERN = /^[\s\u276F\u203A>\u25B6\u25BA\u25CF\u25CB\u25C9\u2192]+/u;
|
|
128
145
|
/** A row's option number and the text after its separator (`1.`, `1)` or `1`, then spaces). */
|
|
@@ -145,13 +162,6 @@ function withOptionRowGuttersAligned(text, options) {
|
|
|
145
162
|
})
|
|
146
163
|
.join('\n');
|
|
147
164
|
}
|
|
148
|
-
/** Every row's leading marks and indentation taken out (the reading before #3817). */
|
|
149
|
-
function withoutLeadingMarks(text) {
|
|
150
|
-
return text
|
|
151
|
-
.split('\n')
|
|
152
|
-
.map((line) => line.replace(/^[\s\u276F\u203A>\u25B6\u25BA\u25CF\u25CB\u25C9\u2192]+/u, ''))
|
|
153
|
-
.join('\n');
|
|
154
|
-
}
|
|
155
165
|
/** compositeKey -> the answer stopped part-way. globalThis for hot reload (#153). */
|
|
156
166
|
const partialAnswers = (0, global_state_1.getOrInitGlobal)('__autoYesPartialAnswers', () => new Map());
|
|
157
167
|
/**
|
|
@@ -168,6 +178,7 @@ function getPartialAnswer(compositeKey, epoch) {
|
|
|
168
178
|
}
|
|
169
179
|
return partial;
|
|
170
180
|
}
|
|
181
|
+
const NO_ATTEMPTS = new Set();
|
|
171
182
|
/**
|
|
172
183
|
* Forget it: the prompt left the screen, another prompt came up, or the session ended.
|
|
173
184
|
*
|
|
@@ -179,6 +190,8 @@ function getPartialAnswer(compositeKey, epoch) {
|
|
|
179
190
|
* and records as before. Expiring is the mark: it drops the attempt from the
|
|
180
191
|
* registry, so no per-key "forgotten up to seq" state has to outlive it.
|
|
181
192
|
*
|
|
193
|
+
* @param spare - Issue #3880: sends that are not expired (a person's, at agy's
|
|
194
|
+
* dialog the ungated reading still shows)
|
|
182
195
|
* @param screenKey - Given when the memory is dropped because ANOTHER prompt is
|
|
183
196
|
* on screen (re-instruction 3): only the sends at the forgotten memory's
|
|
184
197
|
* screen are expired. A send at the screen now shown (Y, carried here by a
|
|
@@ -186,16 +199,27 @@ function getPartialAnswer(compositeKey, epoch) {
|
|
|
186
199
|
* stop is still remembered when it comes back. Omitted (the prompt left the
|
|
187
200
|
* screen), every send under the key is expired.
|
|
188
201
|
*/
|
|
189
|
-
function forgetPartialAnswer(compositeKey, screenKey) {
|
|
202
|
+
function forgetPartialAnswer(compositeKey, screenKey, spare = NO_ATTEMPTS) {
|
|
190
203
|
partialAnswers.delete(compositeKey);
|
|
191
204
|
for (const attempt of [...sendAttempts]) {
|
|
192
205
|
if (attempt.recordKey !== compositeKey)
|
|
193
206
|
continue;
|
|
194
207
|
if (screenKey !== undefined && attempt.screenKey !== screenKey)
|
|
195
208
|
continue;
|
|
209
|
+
if (spare.has(attempt))
|
|
210
|
+
continue;
|
|
196
211
|
expireSendAttempt(attempt);
|
|
197
212
|
}
|
|
198
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* A person's sends still in flight under this key, to this session epoch
|
|
216
|
+
* (Issue #3880): agy's gated reading seeing no prompt does not say the screen
|
|
217
|
+
* they type at is gone, so the tick checks the ungated reading before it
|
|
218
|
+
* expires them ({@link forgetPartialAnswer}'s `spare`).
|
|
219
|
+
*/
|
|
220
|
+
function personSendsInFlight(compositeKey, epoch) {
|
|
221
|
+
return [...sendAttempts].filter((attempt) => attempt.byPerson === true && attempt.recordKey === compositeKey && attempt.recordEpoch === epoch);
|
|
222
|
+
}
|
|
199
223
|
/**
|
|
200
224
|
* {@link forgetPartialAnswer} for every instance of a worktree, and the sends
|
|
201
225
|
* still in flight there are expired (Issue #3713): a slow tick that comes back
|
|
@@ -213,6 +237,53 @@ function forgetPartialAnswersByWorktree(worktreeId) {
|
|
|
213
237
|
expireSendAttempt(attempt);
|
|
214
238
|
}
|
|
215
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* A person's answer went through, or was refused before any key (Issue #3880):
|
|
242
|
+
* the answer Auto-Yes held at that confirmation is theirs now, so the hold is
|
|
243
|
+
* dropped — only one recorded before the person's answer began (`before`, its
|
|
244
|
+
* {@link nextSendOrder}). A hold recorded since, by a send begun after theirs
|
|
245
|
+
* (another person's from another screen, a tick's), is about what that send
|
|
246
|
+
* did and stays. Only the record: a send still in flight records what it did
|
|
247
|
+
* when it comes back. Not called when a person's own send may have left keys
|
|
248
|
+
* on the pane, nor at the START of their answer.
|
|
249
|
+
*/
|
|
250
|
+
function releasePartialAnswerToHuman(compositeKey, before) {
|
|
251
|
+
const recorded = partialAnswers.get(compositeKey);
|
|
252
|
+
if (recorded !== undefined && recorded.seq < before)
|
|
253
|
+
partialAnswers.delete(compositeKey);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* The hold's screen, now that a tick read the confirmation on screen (Issue
|
|
257
|
+
* #3880): a hold at {@link UNIDENTIFIED_SCREEN_KEY} takes `screenKey`.
|
|
258
|
+
*/
|
|
259
|
+
function identifyPartialAnswerScreen(compositeKey, screenKey) {
|
|
260
|
+
const recorded = partialAnswers.get(compositeKey);
|
|
261
|
+
if (recorded?.screenKey === exports.UNIDENTIFIED_SCREEN_KEY)
|
|
262
|
+
partialAnswers.set(compositeKey, { ...recorded, screenKey });
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Put back a person's hold the tick dropped because its gated reading saw no
|
|
266
|
+
* prompt, while agy's dialog it is about is still up past the receipt window
|
|
267
|
+
* (Issue #3880). Only into the same session, and over nothing newer.
|
|
268
|
+
*/
|
|
269
|
+
function keepPartialAnswerByPerson(compositeKey, partial, screenKey) {
|
|
270
|
+
if ((0, auto_yes_enter_fallback_state_1.getEnterFallbackSessionEpoch)(compositeKey) !== partial.epoch)
|
|
271
|
+
return;
|
|
272
|
+
const recorded = partialAnswers.get(compositeKey);
|
|
273
|
+
if (recorded !== undefined && recorded.seq > partial.seq)
|
|
274
|
+
return;
|
|
275
|
+
partialAnswers.set(compositeKey, { ...partial, screenKey });
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* A place in the order sends are registered in (Issue #3880): a person's
|
|
279
|
+
* answer takes one as it begins, so the hold it releases when it ends is only
|
|
280
|
+
* one recorded by a send registered before it began. What its own send
|
|
281
|
+
* records is ordered by that send's registration instead
|
|
282
|
+
* ({@link beginManualSendAttempt}).
|
|
283
|
+
*/
|
|
284
|
+
function nextSendOrder() {
|
|
285
|
+
return ++sendAttemptSeq.last;
|
|
286
|
+
}
|
|
216
287
|
/** Forget every one, and expire every send in flight: server shutdown, and a test seam. */
|
|
217
288
|
function clearPartialAnswers() {
|
|
218
289
|
partialAnswers.clear();
|
|
@@ -240,12 +311,38 @@ function beginSendAttempt(compositeKey, screenKey, epoch, ledger = null) {
|
|
|
240
311
|
sendAttempts.add(attempt);
|
|
241
312
|
return attempt;
|
|
242
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* Register a person's send about to start (Issue #3880): the screen it types
|
|
316
|
+
* at and the session epoch it goes to, fixed now, and its place among the
|
|
317
|
+
* sends taken now too, as Auto-Yes's own is — not when the answer began: an
|
|
318
|
+
* answer that waited before its first key (the re-verification of the screen)
|
|
319
|
+
* may send after one begun later, and then its keys are the newer ones.
|
|
320
|
+
* Settled with {@link settleSendAttempt} like Auto-Yes's own, so it records a
|
|
321
|
+
* hold only for the session the keys went to, never over a hold of a send
|
|
322
|
+
* registered after it, and not at all once the screen it typed at was seen gone.
|
|
323
|
+
*/
|
|
324
|
+
function beginManualSendAttempt(compositeKey, screenKey) {
|
|
325
|
+
const attempt = {
|
|
326
|
+
seq: ++sendAttemptSeq.last,
|
|
327
|
+
screenKey,
|
|
328
|
+
recordKey: compositeKey,
|
|
329
|
+
recordEpoch: (0, auto_yes_enter_fallback_state_1.getEnterFallbackSessionEpoch)(compositeKey),
|
|
330
|
+
moved: false,
|
|
331
|
+
state: 'pending',
|
|
332
|
+
byPerson: true,
|
|
333
|
+
ledger: null,
|
|
334
|
+
};
|
|
335
|
+
sendAttempts.add(attempt);
|
|
336
|
+
return attempt;
|
|
337
|
+
}
|
|
243
338
|
/**
|
|
244
339
|
* The send came back. `keysSent` — it was stopped with keys already on the
|
|
245
|
-
* pane
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
340
|
+
* pane, or (Issue #3880) a tmux call of it ended without an exit status and
|
|
341
|
+
* its keys may be there — records the partial answer under the attempt's key
|
|
342
|
+
* as it is now, when that key's session is still the one the keys went to;
|
|
343
|
+
* otherwise (sent in full, stopped before any key, or failed with nothing
|
|
344
|
+
* sent) only the attempt itself is removed. A second call, or a call on an
|
|
345
|
+
* expired attempt, does nothing.
|
|
249
346
|
*/
|
|
250
347
|
function settleSendAttempt(attempt, keysSent, at = Date.now()) {
|
|
251
348
|
if (attempt.state !== 'pending')
|
|
@@ -267,6 +364,7 @@ function settleSendAttempt(attempt, keysSent, at = Date.now()) {
|
|
|
267
364
|
epoch: attempt.recordEpoch,
|
|
268
365
|
at,
|
|
269
366
|
seq: attempt.seq,
|
|
367
|
+
...(attempt.byPerson ? { byPerson: true } : {}),
|
|
270
368
|
});
|
|
271
369
|
}
|
|
272
370
|
function expireSendAttempt(attempt) {
|
|
@@ -286,7 +384,7 @@ function hasMovedSendInFlight(compositeKey, epoch, screenKey) {
|
|
|
286
384
|
if (attempt.moved &&
|
|
287
385
|
attempt.recordKey === compositeKey &&
|
|
288
386
|
attempt.recordEpoch === epoch &&
|
|
289
|
-
attempt.screenKey
|
|
387
|
+
partialAnswerCovers(attempt.screenKey, screenKey)) {
|
|
290
388
|
return true;
|
|
291
389
|
}
|
|
292
390
|
}
|
|
@@ -12,11 +12,18 @@
|
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.withheldForEarlierSend = withheldForEarlierSend;
|
|
15
|
+
exports.answerModeOfTick = answerModeOfTick;
|
|
16
|
+
exports.questionAnsweringOf = questionAnsweringOf;
|
|
17
|
+
exports.withheldAsQuestion = withheldAsQuestion;
|
|
18
|
+
exports.withheldAtSend = withheldAtSend;
|
|
15
19
|
exports.resolveAnswerUnderPolicy = resolveAnswerUnderPolicy;
|
|
16
20
|
exports.skippedForUnownedSession = skippedForUnownedSession;
|
|
17
21
|
const auto_yes_resolver_1 = require("./auto-yes-resolver");
|
|
18
22
|
const auto_yes_policy_1 = require("./auto-yes-policy");
|
|
19
23
|
const auto_yes_suppression_reason_1 = require("./auto-yes-suppression-reason");
|
|
24
|
+
const auto_yes_state_1 = require("../auto-yes-state");
|
|
25
|
+
const auto_yes_dialog_gate_1 = require("./auto-yes-dialog-gate");
|
|
26
|
+
const auto_yes_answer_mode_1 = require("../../types/auto-yes-answer-mode");
|
|
20
27
|
const auto_yes_poller_state_1 = require("./auto-yes-poller-state");
|
|
21
28
|
const auto_yes_prompt_suppression_1 = require("./auto-yes-prompt-suppression");
|
|
22
29
|
const auto_yes_confirmation_ledger_1 = require("./auto-yes-confirmation-ledger");
|
|
@@ -30,7 +37,10 @@ function withheldForEarlierSend(judged, screenKey, epoch) {
|
|
|
30
37
|
const { worktreeId, cliToolId, instanceId, compositeKey, pollerState, promptData, frameKey } = judged;
|
|
31
38
|
const partial = (0, auto_yes_poller_state_1.getPartialAnswer)(compositeKey, epoch);
|
|
32
39
|
if (partial !== null) {
|
|
33
|
-
if (partial.screenKey
|
|
40
|
+
if ((0, auto_yes_poller_state_1.partialAnswerCovers)(partial.screenKey, screenKey)) {
|
|
41
|
+
// Issue #3880: a person's send made with no prompt read (the capture
|
|
42
|
+
// failed) holds the first confirmation read after it, as that one.
|
|
43
|
+
(0, auto_yes_poller_state_1.identifyPartialAnswerScreen)(compositeKey, screenKey);
|
|
34
44
|
(0, auto_yes_prompt_suppression_1.suppressAndWarnOnce)(judged, {
|
|
35
45
|
reason: auto_yes_suppression_reason_1.PARTIAL_ANSWER_SUPPRESSION_REASON,
|
|
36
46
|
mode: null,
|
|
@@ -54,6 +64,165 @@ function withheldForEarlierSend(judged, screenKey, epoch) {
|
|
|
54
64
|
}
|
|
55
65
|
return false;
|
|
56
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* The answer mode a tick acts under (Issue #3863): the grant the tick read
|
|
69
|
+
* (its generation's, #3706), or — for a direct caller with no generation —
|
|
70
|
+
* the instance's grant as it stands, if it is on. Neither: the default,
|
|
71
|
+
* `recommended`. A grant that cannot be read is `careful`, the mode that
|
|
72
|
+
* answers less.
|
|
73
|
+
*/
|
|
74
|
+
function answerModeOfTick(worktreeId, cliToolId, instanceId, grant) {
|
|
75
|
+
if (grant !== undefined)
|
|
76
|
+
return (0, auto_yes_state_1.autoYesAnswerModeOf)(grant);
|
|
77
|
+
try {
|
|
78
|
+
const state = (0, auto_yes_state_1.getAutoYesState)(worktreeId, cliToolId, instanceId);
|
|
79
|
+
return state?.enabled ? (0, auto_yes_state_1.autoYesAnswerModeOf)(state) : auto_yes_answer_mode_1.DEFAULT_AUTO_YES_ANSWER_MODE;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return 'careful';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Issue #3863: what the resolver needs to answer the prompt as a question
|
|
87
|
+
* under `answerMode`, or undefined when it is not answered as one — not a
|
|
88
|
+
* question reader's picker, or the mode is `careful` (which never answers it).
|
|
89
|
+
*/
|
|
90
|
+
function questionAnsweringOf(judged, answerMode) {
|
|
91
|
+
// Issue #3881 (review N3): the shared table, which the observation reads too.
|
|
92
|
+
const kind = (0, auto_yes_dialog_gate_1.classifyAutoYesQuestion)(judged.promptData, judged.dialogGate, judged.cliToolId);
|
|
93
|
+
if ((0, auto_yes_dialog_gate_1.autoYesQuestionTreatment)(kind, answerMode) !== 'recommended-choice')
|
|
94
|
+
return undefined;
|
|
95
|
+
return { optionRecommendations: judged.optionRecommendations };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Step 3.7 of `detectAndRespondToPrompt` (Issue #3822): a question to the
|
|
99
|
+
* operator is left to the human when Auto-Yes's answer mode says so.
|
|
100
|
+
*
|
|
101
|
+
* Issue #3863: which questions, by {@link classifyAutoYesQuestion}:
|
|
102
|
+
*
|
|
103
|
+
* - a question reader's picker (Claude's AskUserQuestion, Command Code's
|
|
104
|
+
* question screen) — left to a human under the `careful` answer mode; under
|
|
105
|
+
* `recommended` it goes on to step 4, which answers it with its recommended
|
|
106
|
+
* option (`auto-yes-question-choice`). Judged without the dialog gate, so a
|
|
107
|
+
* `legacy` tool and the `CM_AUTOYES_DIALOG_GATE` kill switch change nothing
|
|
108
|
+
* here;
|
|
109
|
+
* - OpenCode V2's question form — left to a human under either mode;
|
|
110
|
+
* - Issue #3881: a copilot / codex numbered list nothing marks as a question
|
|
111
|
+
* or as a permission (`'unidentified'`) — left to a human under `careful`;
|
|
112
|
+
* under `recommended` it goes on to step 4 and is answered as before.
|
|
113
|
+
*
|
|
114
|
+
* Not a contract verdict, so `allowPromptTypes` cannot bring it back: an
|
|
115
|
+
* `allow-listed` contract naming `multiple_choice` delegates permission
|
|
116
|
+
* dialogs, not the operator's questions.
|
|
117
|
+
*
|
|
118
|
+
* Recorded as `question-left-to-human` — a question in general, not the
|
|
119
|
+
* `Submit` / `Cancel` confirm page that follows one (`question-confirm-page`,
|
|
120
|
+
* #3748, recorded at step 3.3 before this step is reached).
|
|
121
|
+
*
|
|
122
|
+
* @returns true when the prompt is withheld (the caller returns `no_answer`)
|
|
123
|
+
*/
|
|
124
|
+
function withheldAsQuestion(judged) {
|
|
125
|
+
const { promptData, dialogGate, cliToolId } = judged;
|
|
126
|
+
const kind = (0, auto_yes_dialog_gate_1.classifyAutoYesQuestion)(promptData, dialogGate, cliToolId);
|
|
127
|
+
if (kind === null)
|
|
128
|
+
return false;
|
|
129
|
+
const answerMode = judged.answerMode ?? auto_yes_answer_mode_1.DEFAULT_AUTO_YES_ANSWER_MODE;
|
|
130
|
+
if ((0, auto_yes_dialog_gate_1.autoYesQuestionTreatment)(kind, answerMode) !== 'left-to-human')
|
|
131
|
+
return false;
|
|
132
|
+
withholdQuestion(judged, answerMode, false, kind);
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
/** Record a question left to a human (`question-left-to-human`), warning once per frame. */
|
|
136
|
+
function withholdQuestion(judged, answerMode, atSend, kind) {
|
|
137
|
+
const { promptData, frameKey, dialogGate } = judged;
|
|
138
|
+
(0, auto_yes_prompt_suppression_1.suppressAndWarnOnce)(judged, { reason: auto_yes_suppression_reason_1.QUESTION_LEFT_TO_HUMAN_SUPPRESSION_REASON, mode: null, promptType: promptData.type }, `${frameKey}\u0000question`, 'poller:auto-yes-skipped-question', {
|
|
139
|
+
reason: auto_yes_suppression_reason_1.QUESTION_LEFT_TO_HUMAN_SUPPRESSION_REASON,
|
|
140
|
+
promptType: promptData.type,
|
|
141
|
+
dialogKind: dialogGate?.dialog?.kind ?? null,
|
|
142
|
+
// Issue #3881: `unidentified` — not known to be a question, nor not one.
|
|
143
|
+
questionKind: kind,
|
|
144
|
+
question: (0, auto_yes_prompt_suppression_1.truncateForLog)(promptData.question),
|
|
145
|
+
answerMode,
|
|
146
|
+
...(atSend ? { atSend: true } : {}),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The last look before a key (Issue #3822): is the answer still Auto-Yes's to
|
|
151
|
+
* send? Asked after the last wait before the send (the ownership check), so
|
|
152
|
+
* nothing it reads can change before the first key goes out.
|
|
153
|
+
*
|
|
154
|
+
* - With a `generation` (a poller tick), Auto-Yes must still be on and inside
|
|
155
|
+
* its window. `getAutoYesState` disables an expired grant on read, the
|
|
156
|
+
* boundary the hook and the next tick see. Without one (direct callers,
|
|
157
|
+
* tests) the grant is not checked, as the tick checks nothing then (#3706).
|
|
158
|
+
* - The contract is read again past the policy cache, so a switched contract,
|
|
159
|
+
* an `off`, or a deny pattern added since the tick's lookup withholds the
|
|
160
|
+
* key. A read that fails is "contract unknown" (`policy-lookup-failed`), as
|
|
161
|
+
* in step 4, and so is a grant that cannot be read.
|
|
162
|
+
* - Issue #3863: the answer mode is read off that grant again. A question the
|
|
163
|
+
* `careful` mode leaves to a human gets no key, whatever the tick began
|
|
164
|
+
* under; the question's answer is resolved again under the mode as it is.
|
|
165
|
+
* (A mode change replaces the grant, so a tick that began under the old one
|
|
166
|
+
* has usually stopped at its last generation check already.)
|
|
167
|
+
*
|
|
168
|
+
* The `PermissionRequest` hook is not asked this: its `allow` IS the answer,
|
|
169
|
+
* decided against the grant and the contract when the hook is answered, and
|
|
170
|
+
* nothing is typed afterwards for a later look to stop.
|
|
171
|
+
*
|
|
172
|
+
* @param checkGrant - Whether the grant is checked (a tick with a generation)
|
|
173
|
+
* @returns true when the key is withheld (the caller returns `no_answer`)
|
|
174
|
+
*/
|
|
175
|
+
function withheldAtSend(judged, checkGrant) {
|
|
176
|
+
const { worktreeId, cliToolId, instanceId, pollerState, promptData, frameKey } = judged;
|
|
177
|
+
let answerMode = judged.answerMode ?? auto_yes_answer_mode_1.DEFAULT_AUTO_YES_ANSWER_MODE;
|
|
178
|
+
if (checkGrant) {
|
|
179
|
+
let grant;
|
|
180
|
+
try {
|
|
181
|
+
grant = (0, auto_yes_state_1.getAutoYesState)(worktreeId, cliToolId, instanceId);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return withholdAsUnknown(judged);
|
|
185
|
+
}
|
|
186
|
+
if (!grant?.enabled) {
|
|
187
|
+
// Auto-Yes is off: nothing is recorded as withheld (the poller stops on
|
|
188
|
+
// its next tick and the state says why), only that the key was not sent.
|
|
189
|
+
(0, auto_yes_poller_state_1.warnOncePerFrame)(pollerState, `${frameKey}\u0000at-send-disabled`, 'poller:auto-yes-withheld-at-send', {
|
|
190
|
+
worktreeId,
|
|
191
|
+
cliToolId,
|
|
192
|
+
instanceId,
|
|
193
|
+
reason: grant?.stopReason === 'expired' ? 'expired' : 'auto-yes-disabled',
|
|
194
|
+
promptType: promptData.type,
|
|
195
|
+
});
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
answerMode = (0, auto_yes_state_1.autoYesAnswerModeOf)(grant);
|
|
199
|
+
const questionKind = (0, auto_yes_dialog_gate_1.classifyAutoYesQuestion)(promptData, judged.dialogGate, cliToolId);
|
|
200
|
+
if (answerMode === 'careful' && questionKind !== null
|
|
201
|
+
&& (0, auto_yes_dialog_gate_1.autoYesQuestionTreatment)(questionKind, answerMode) === 'left-to-human') {
|
|
202
|
+
withholdQuestion(judged, answerMode, true, questionKind);
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const policy = (0, auto_yes_policy_1.getSessionAutoYesPolicy)(worktreeId, cliToolId, instanceId, { fresh: true });
|
|
207
|
+
const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(promptData, policy, cliToolId, questionAnsweringOf(judged, answerMode));
|
|
208
|
+
if (resolution.suppressedBy) {
|
|
209
|
+
const mode = (0, auto_yes_resolver_1.policyLookupMode)(policy);
|
|
210
|
+
(0, auto_yes_prompt_suppression_1.suppressAndWarnOnce)(judged, { reason: resolution.suppressedBy, mode, promptType: promptData.type, pattern: resolution.pattern }, `${frameKey}\u0000${resolution.suppressedBy}\u0000${mode ?? ''}\u0000${resolution.pattern ?? ''}`, 'poller:auto-yes-suppressed-by-policy', {
|
|
211
|
+
reason: resolution.suppressedBy,
|
|
212
|
+
mode,
|
|
213
|
+
pattern: resolution.pattern,
|
|
214
|
+
promptType: promptData.type,
|
|
215
|
+
atSend: true,
|
|
216
|
+
});
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
function withholdAsUnknown(judged) {
|
|
222
|
+
const { promptData, frameKey } = judged;
|
|
223
|
+
(0, auto_yes_prompt_suppression_1.suppressAndWarnOnce)(judged, { reason: auto_yes_suppression_reason_1.POLICY_LOOKUP_FAILED_SUPPRESSION_REASON, mode: null, promptType: promptData.type }, `${frameKey}\u0000${auto_yes_suppression_reason_1.POLICY_LOOKUP_FAILED_SUPPRESSION_REASON}\u0000at-send`, 'poller:auto-yes-suppressed-by-policy', { reason: auto_yes_suppression_reason_1.POLICY_LOOKUP_FAILED_SUPPRESSION_REASON, mode: null, promptType: promptData.type, atSend: true });
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
57
226
|
/**
|
|
58
227
|
* Step 4 of `detectAndRespondToPrompt`: the auto answer under the execution
|
|
59
228
|
* contract's policy, recording the suppression when the policy withholds it.
|
|
@@ -64,7 +233,8 @@ function resolveAnswerUnderPolicy(judged) {
|
|
|
64
233
|
const { worktreeId, cliToolId, instanceId, promptData, frameKey } = judged;
|
|
65
234
|
// Issue #3822: a failed lookup reaches the resolver as unknown and withholds.
|
|
66
235
|
const policy = (0, auto_yes_policy_1.getSessionAutoYesPolicy)(worktreeId, cliToolId, instanceId);
|
|
67
|
-
|
|
236
|
+
// Issue #3863: a question the `recommended` mode answers takes its recommended option.
|
|
237
|
+
const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(promptData, policy, cliToolId, questionAnsweringOf(judged, judged.answerMode ?? auto_yes_answer_mode_1.DEFAULT_AUTO_YES_ANSWER_MODE));
|
|
68
238
|
if (resolution.suppressedBy) {
|
|
69
239
|
const mode = (0, auto_yes_resolver_1.policyLookupMode)(policy);
|
|
70
240
|
// Issue #1684: the log line alone leaves a CLI-driven pipeline blind to
|
|
@@ -247,8 +247,8 @@ function suppressIfNotOursToAnswer(prompt, frame) {
|
|
|
247
247
|
//
|
|
248
248
|
// Issue #3748: Claude's confirmation page (`Ready to submit your answers?` /
|
|
249
249
|
// `❯ 1. Submit answers` / `2. Cancel`) is the same page and is declined the
|
|
250
|
-
// same way. Judged by `isAutoYesDeclinedConfirmPage
|
|
251
|
-
//
|
|
250
|
+
// same way. Judged by `isAutoYesDeclinedConfirmPage` (the browser's fallback,
|
|
251
|
+
// `useAutoYes`, read the same page by its options until #3821 retired it), and recorded with a reason of its own,
|
|
252
252
|
// `question-confirm-page`, which `cmate wait` names as such (it reused
|
|
253
253
|
// `unclassified-frame`, whose wording says no detector recognised the frame).
|
|
254
254
|
if ((0, auto_yes_confirm_page_1.isAutoYesDeclinedConfirmPage)(cliToolId, frame)) {
|