commandmate 0.47.0 → 0.47.2
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 +501 -501
- package/.next/app-path-routes-manifest.json +36 -36
- package/.next/build-manifest.json +8 -8
- package/.next/diagnostics/framework.json +1 -1
- package/.next/next-minimal-server.js.nft.json +1 -1
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +15 -15
- package/.next/react-loadable-manifest.json +1 -1
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_not-found/page.js +2 -2
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/update/route.js +2 -2
- package/.next/server/app/api/agents/update/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/versions/route.js +1 -1
- package/.next/server/app/api/agents/versions/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/app/release-notes/route.js.nft.json +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 +5 -5
- package/.next/server/app/api/app/update/route.js.nft.json +1 -1
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.js +1 -1
- package/.next/server/app/api/app/update-check/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/auth/login/route.js.nft.json +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route.js +1 -1
- package/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route.js +1 -1
- package/.next/server/app/api/auth/status/route.js.nft.json +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.js.nft.json +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route.js +1 -1
- package/.next/server/app/api/daily-summary/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/daily-summary/status/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/external-apps/route.js.nft.json +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route.js +1 -1
- package/.next/server/app/api/fs/browse/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route.js.nft.json +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.js +2 -2
- package/.next/server/app/api/metrics/vibe/route.js.nft.json +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route.js +1 -1
- package/.next/server/app/api/ollama/models/route.js.nft.json +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.js.nft.json +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route.js +1 -1
- package/.next/server/app/api/push/subscriptions/route.js.nft.json +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.js.nft.json +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.js +2 -2
- package/.next/server/app/api/remote/pair/route.js.nft.json +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/repositories/excluded/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route.js +1 -1
- package/.next/server/app/api/skills/installations/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route.js +2 -2
- package/.next/server/app/api/skills/operations/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route.js +1 -1
- package/.next/server/app/api/skills/reindex/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route.js +1 -1
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route.js +1 -1
- package/.next/server/app/api/slash-commands/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route.js.nft.json +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route.js +1 -1
- package/.next/server/app/api/templates/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route.js +1 -1
- package/.next/server/app/api/templates/route.js.nft.json +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/verification/runs/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route.js.nft.json +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.js +7 -7
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js.nft.json +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.js +2 -2
- package/.next/server/app/api/worktrees/[id]/env/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js.nft.json +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.js +3 -3
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route.js.nft.json +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.js +3 -3
- package/.next/server/app/api/worktrees/[id]/marp-render/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route.js.nft.json +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.js +2 -2
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js.nft.json +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.js +3 -3
- package/.next/server/app/api/worktrees/[id]/schedules/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +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 +5 -5
- 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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js.nft.json +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.js +2 -2
- package/.next/server/app/api/worktrees/[id]/tasks/route.js.nft.json +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 +2 -2
- 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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +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.js +2 -2
- package/.next/server/app/api/worktrees/[id]/verify/config/route.js.nft.json +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.js.nft.json +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.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route.js.nft.json +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/apple-icon.png/route.js +1 -1
- package/.next/server/app/apple-icon.png/route.js.nft.json +1 -1
- package/.next/server/app/apple-icon.png.meta +1 -1
- package/.next/server/app/icon.png/route.js +1 -1
- package/.next/server/app/icon.png/route.js.nft.json +1 -1
- package/.next/server/app/icon.png.meta +1 -1
- package/.next/server/app/icon1.png/route.js +1 -1
- package/.next/server/app/icon1.png/route.js.nft.json +1 -1
- package/.next/server/app/icon1.png.meta +1 -1
- package/.next/server/app/icon2.png/route.js +1 -1
- package/.next/server/app/icon2.png/route.js.nft.json +1 -1
- package/.next/server/app/icon2.png.meta +1 -1
- package/.next/server/app/login/page.js +2 -2
- package/.next/server/app/login/page.js.nft.json +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route.js +2 -2
- package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest.meta +1 -1
- package/.next/server/app/more/page.js +2 -2
- package/.next/server/app/more/page.js.nft.json +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page.js +2 -2
- package/.next/server/app/offline/page.js.nft.json +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page.js +2 -2
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route.js +1 -1
- package/.next/server/app/proxy/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page.js +2 -2
- package/.next/server/app/repositories/page.js.nft.json +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page.js +2 -2
- package/.next/server/app/review/page.js.nft.json +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +2 -2
- 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 +2 -2
- 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.js +2 -2
- package/.next/server/app/skills/installed/page.js.nft.json +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page.js +2 -2
- package/.next/server/app/skills/page.js.nft.json +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 +4 -4
- 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.js +3 -3
- package/.next/server/app/worktrees/[id]/terminal/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +36 -36
- package/.next/server/chunks/{5048.js → 1185.js} +1 -1
- package/.next/server/chunks/1656.js +19 -0
- package/.next/server/chunks/2460.js +1 -1
- package/.next/server/chunks/255.js +1 -0
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3505.js +7 -0
- package/.next/server/chunks/3897.js +22 -0
- package/.next/server/chunks/4072.js +5 -5
- package/.next/server/chunks/463.js +1 -0
- package/.next/server/chunks/5209.js +1 -1
- package/.next/server/chunks/5595.js +1 -1
- package/.next/server/chunks/5611.js +1 -1
- package/.next/server/chunks/610.js +1 -0
- package/.next/server/chunks/6119.js +1 -0
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6345.js +1 -1
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/6784.js +1 -0
- package/.next/server/chunks/8581.js +1 -1
- package/.next/server/chunks/8728.js +2 -2
- package/.next/server/chunks/8918.js +1 -1
- package/.next/server/chunks/9130.js +1 -1
- 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 +1 -1
- package/.next/server/chunks/9731.js +3 -3
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages/_document.js.nft.json +1 -1
- package/.next/server/pages/_error.js +3 -3
- package/.next/server/pages/_error.js.nft.json +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/server/src/middleware.js.map +1 -1
- package/.next/static/chunks/{1111.5ab4f0ffb0d944e5.js → 1111.1b653d4a9816a0a7.js} +8 -8
- package/.next/static/chunks/{1255-7e5873f06b25e129.js → 1255-a85690d352f4f8fd.js} +1 -1
- package/.next/static/chunks/{2407-b2f524f99f7fc353.js → 2407-a6533805a86d05bd.js} +1 -1
- package/.next/static/chunks/9465-b59bb255b376c813.js +1 -0
- package/.next/static/chunks/app/{layout-419eaf7de340f4ab.js → layout-538d8d2746ad1588.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/page-46aced20b2b1c010.js +1 -0
- package/.next/static/chunks/main-37ca13e38030fe8b.js +1 -0
- package/.next/static/chunks/{webpack-468b7b33030234b3.js → webpack-838df0273b03af19.js} +1 -1
- package/.next/trace +13 -13
- package/dist/cli/commands/prompt.d.ts.map +1 -1
- package/dist/cli/commands/prompt.js +23 -11
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +7 -1
- package/dist/cli/types/api-responses.d.ts +15 -2
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts +11 -0
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts.map +1 -1
- package/dist/lib/polling/auto-yes-suppression-reason.js +4 -1
- package/dist/server/src/lib/auto-yes-poller.js +269 -554
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +88 -6
- package/dist/server/src/lib/detection/prompt-detector.js +1 -1
- package/dist/server/src/lib/detection/tools/antigravity/dialog.js +1 -1
- package/dist/server/src/lib/hooks/permission-adjudication.js +26 -0
- package/dist/server/src/lib/hooks/permission-decision-service.js +42 -4
- package/dist/server/src/lib/hooks/permission-request-payload.js +20 -0
- package/dist/server/src/lib/hooks/sources/antigravity/source.js +21 -0
- package/dist/server/src/lib/hooks/sources/claude/source.js +3 -0
- package/dist/server/src/lib/hooks/sources/codex/source.js +2 -0
- package/dist/server/src/lib/hooks/sources/command-code/source.js +2 -0
- package/dist/server/src/lib/hooks/sources/copilot/source.js +2 -0
- package/dist/server/src/lib/hooks/sources/gemini/source.js +2 -0
- package/dist/server/src/lib/hooks/sources/legacy-relay.js +2 -0
- package/dist/server/src/lib/hooks/sources/opencode/ingest.js +6 -0
- package/dist/server/src/lib/hooks/sources/opencode/source.js +2 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/ingest.js +6 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/source.js +2 -0
- package/dist/server/src/lib/hooks/sources/pending-decisions.js +14 -2
- package/dist/server/src/lib/polling/antigravity-permission-receipts.js +14 -3
- package/dist/server/src/lib/polling/antigravity-receipt-episodes.js +21 -1
- package/dist/server/src/lib/polling/auto-yes-confirmation-ledger-types.js +114 -0
- package/dist/server/src/lib/polling/auto-yes-confirmation-ledger.js +1060 -0
- package/dist/server/src/lib/polling/auto-yes-ledger-records.js +143 -0
- package/dist/server/src/lib/polling/auto-yes-policy.js +36 -7
- package/dist/server/src/lib/polling/auto-yes-poller-capture.js +50 -0
- package/dist/server/src/lib/polling/auto-yes-poller-enter-fallback.js +37 -0
- package/dist/server/src/lib/polling/auto-yes-poller-generation.js +151 -0
- package/dist/server/src/lib/polling/auto-yes-poller-receipt-log.js +287 -0
- package/dist/server/src/lib/polling/auto-yes-poller-state.js +75 -6
- package/dist/server/src/lib/polling/auto-yes-poller-steps.js +109 -0
- package/dist/server/src/lib/polling/auto-yes-prompt-suppression.js +11 -0
- package/dist/server/src/lib/polling/auto-yes-resolver.js +21 -1
- package/dist/server/src/lib/polling/auto-yes-suppression-reason.js +4 -1
- package/dist/server/src/lib/polling/response-checker-blank-response.js +30 -0
- package/dist/server/src/lib/polling/response-checker.js +5 -10
- package/dist/server/src/lib/prompt-observation/appearance.js +165 -0
- package/package.json +2 -2
- package/release-notes/0.47.1.json +20 -0
- package/release-notes/0.47.2.json +20 -0
- package/scripts/hooks/cmate-agent-event.sh +22 -0
- package/.next/server/chunks/1331.js +0 -22
- package/.next/server/chunks/1836.js +0 -1
- package/.next/server/chunks/1944.js +0 -1
- package/.next/server/chunks/2328.js +0 -1
- package/.next/server/chunks/5292.js +0 -7
- package/.next/server/chunks/7166.js +0 -19
- package/.next/server/chunks/9051.js +0 -1
- package/.next/server/chunks/9199.js +0 -1
- package/.next/static/chunks/9465-e5a351baa941f31b.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-45294052ee3032f1.js +0 -1
- package/.next/static/chunks/main-ac91ed6e71380841.js +0 -1
- /package/.next/static/{b5BiQC9F6r_XFPdA9cuSj → etorRtpxbQqqOzdUeXdw2}/_buildManifest.js +0 -0
- /package/.next/static/{b5BiQC9F6r_XFPdA9cuSj → etorRtpxbQqqOzdUeXdw2}/_ssgManifest.js +0 -0
|
@@ -45,16 +45,10 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
45
45
|
};
|
|
46
46
|
})();
|
|
47
47
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
-
exports.AUTO_YES_ENTER_FALLBACK_ANSWER = void 0;
|
|
49
|
-
exports.getActivePollerCount = getActivePollerCount;
|
|
48
|
+
exports.capturePollerFrame = exports.captureAndCleanOutput = exports.AUTO_YES_ENTER_FALLBACK_ANSWER = exports.noHookReceiptHint = exports.isPollerActive = exports.getLastServerResponseTimestamp = exports.getActivePollerCount = void 0;
|
|
50
49
|
exports.clearAllPollerStates = clearAllPollerStates;
|
|
51
|
-
exports.getLastServerResponseTimestamp = getLastServerResponseTimestamp;
|
|
52
|
-
exports.isPollerActive = isPollerActive;
|
|
53
50
|
exports.validatePollingContext = validatePollingContext;
|
|
54
|
-
exports.capturePollerFrame = capturePollerFrame;
|
|
55
|
-
exports.captureAndCleanOutput = captureAndCleanOutput;
|
|
56
51
|
exports.processStopConditionDelta = processStopConditionDelta;
|
|
57
|
-
exports.noHookReceiptHint = noHookReceiptHint;
|
|
58
52
|
exports.detectAndRespondToPrompt = detectAndRespondToPrompt;
|
|
59
53
|
exports.startAutoYesPolling = startAutoYesPolling;
|
|
60
54
|
exports.stopAutoYesPolling = stopAutoYesPolling;
|
|
@@ -65,11 +59,11 @@ exports.isAnyPollerActiveForWorktree = isAnyPollerActiveForWorktree;
|
|
|
65
59
|
const cli_session_1 = require("./session/cli-session");
|
|
66
60
|
const response_checker_1 = require("./polling/response-checker");
|
|
67
61
|
const antigravity_receipt_episodes_1 = require("./polling/antigravity-receipt-episodes");
|
|
68
|
-
const antigravity_permission_receipts_1 = require("./polling/antigravity-permission-receipts");
|
|
69
62
|
const auto_yes_resolver_1 = require("./polling/auto-yes-resolver");
|
|
70
63
|
const auto_yes_policy_1 = require("./polling/auto-yes-policy");
|
|
71
64
|
const detect_1 = require("./detection/tools/codex/detect");
|
|
72
65
|
const frame_1 = require("./detection/tools/frame");
|
|
66
|
+
const dialog_1 = require("./detection/tools/antigravity/dialog");
|
|
73
67
|
const auto_yes_dialog_gate_1 = require("./polling/auto-yes-dialog-gate");
|
|
74
68
|
const auto_yes_enter_fallback_1 = require("./polling/auto-yes-enter-fallback");
|
|
75
69
|
const task_transition_service_1 = require("./tasks/task-transition-service");
|
|
@@ -92,42 +86,26 @@ const logger = (0, logger_1.createLogger)('auto-yes-poller');
|
|
|
92
86
|
const path_validator_1 = require("./security/path-validator");
|
|
93
87
|
const auto_yes_state_1 = require("./auto-yes-state");
|
|
94
88
|
const global_state_1 = require("./global-state");
|
|
95
|
-
const auto_yes_suppression_reason_1 = require("./polling/auto-yes-suppression-reason");
|
|
96
|
-
const auto_yes_suppression_state_1 = require("./polling/auto-yes-suppression-state");
|
|
97
89
|
const auto_yes_poller_state_1 = require("./polling/auto-yes-poller-state");
|
|
98
90
|
const auto_yes_prompt_suppression_1 = require("./polling/auto-yes-prompt-suppression");
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
* Get poller state by composite key.
|
|
118
|
-
*
|
|
119
|
-
* @param compositeKey - Composite key (worktreeId:cliToolId)
|
|
120
|
-
* @returns Poller state or undefined
|
|
121
|
-
*/
|
|
122
|
-
function getPollerState(compositeKey) {
|
|
123
|
-
return autoYesPollerStates.get(compositeKey);
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Get the number of active pollers.
|
|
127
|
-
*/
|
|
128
|
-
function getActivePollerCount() {
|
|
129
|
-
return autoYesPollerStates.size;
|
|
130
|
-
}
|
|
91
|
+
const auto_yes_poller_generation_1 = require("./polling/auto-yes-poller-generation");
|
|
92
|
+
const auto_yes_poller_receipt_log_1 = require("./polling/auto-yes-poller-receipt-log");
|
|
93
|
+
const auto_yes_poller_enter_fallback_1 = require("./polling/auto-yes-poller-enter-fallback");
|
|
94
|
+
const auto_yes_poller_capture_1 = require("./polling/auto-yes-poller-capture");
|
|
95
|
+
const auto_yes_confirmation_ledger_1 = require("./polling/auto-yes-confirmation-ledger");
|
|
96
|
+
const auto_yes_poller_steps_1 = require("./polling/auto-yes-poller-steps");
|
|
97
|
+
// Issue #3783: split out; re-exported so existing importers are unchanged.
|
|
98
|
+
var auto_yes_poller_generation_2 = require("./polling/auto-yes-poller-generation");
|
|
99
|
+
Object.defineProperty(exports, "getActivePollerCount", { enumerable: true, get: function () { return auto_yes_poller_generation_2.getActivePollerCount; } });
|
|
100
|
+
Object.defineProperty(exports, "getLastServerResponseTimestamp", { enumerable: true, get: function () { return auto_yes_poller_generation_2.getLastServerResponseTimestamp; } });
|
|
101
|
+
Object.defineProperty(exports, "isPollerActive", { enumerable: true, get: function () { return auto_yes_poller_generation_2.isPollerActive; } });
|
|
102
|
+
var auto_yes_poller_receipt_log_2 = require("./polling/auto-yes-poller-receipt-log");
|
|
103
|
+
Object.defineProperty(exports, "noHookReceiptHint", { enumerable: true, get: function () { return auto_yes_poller_receipt_log_2.noHookReceiptHint; } });
|
|
104
|
+
var auto_yes_poller_enter_fallback_2 = require("./polling/auto-yes-poller-enter-fallback");
|
|
105
|
+
Object.defineProperty(exports, "AUTO_YES_ENTER_FALLBACK_ANSWER", { enumerable: true, get: function () { return auto_yes_poller_enter_fallback_2.AUTO_YES_ENTER_FALLBACK_ANSWER; } });
|
|
106
|
+
var auto_yes_poller_capture_2 = require("./polling/auto-yes-poller-capture");
|
|
107
|
+
Object.defineProperty(exports, "captureAndCleanOutput", { enumerable: true, get: function () { return auto_yes_poller_capture_2.captureAndCleanOutput; } });
|
|
108
|
+
Object.defineProperty(exports, "capturePollerFrame", { enumerable: true, get: function () { return auto_yes_poller_capture_2.capturePollerFrame; } });
|
|
131
109
|
/**
|
|
132
110
|
* Clear all poller states.
|
|
133
111
|
* Stops all active pollers before clearing state.
|
|
@@ -136,58 +114,8 @@ function getActivePollerCount() {
|
|
|
136
114
|
function clearAllPollerStates() {
|
|
137
115
|
// Issue #3730: a test seam, not a shutdown — logged as such.
|
|
138
116
|
(0, auto_yes_poller_stop_reason_1.withPollerStopReason)('reset', () => stopAllAutoYesPolling());
|
|
139
|
-
autoYesPollerStates.clear();
|
|
140
|
-
withheldNoReceiptLoggedAt.clear();
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Get the last server response timestamp for a composite key.
|
|
144
|
-
*
|
|
145
|
-
* Issue #525: Changed from (worktreeId) to (compositeKey).
|
|
146
|
-
*
|
|
147
|
-
* @param compositeKey - Composite key (worktreeId:cliToolId)
|
|
148
|
-
* @returns Timestamp (Date.now()) of the last server response, or null if none
|
|
149
|
-
*/
|
|
150
|
-
function getLastServerResponseTimestamp(compositeKey) {
|
|
151
|
-
const pollerState = getPollerState(compositeKey);
|
|
152
|
-
return pollerState?.lastServerResponseTimestamp ?? null;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Check if a server-side auto-yes poller is active for a composite key.
|
|
156
|
-
*
|
|
157
|
-
* Issue #525: Changed from (worktreeId) to (compositeKey).
|
|
158
|
-
*
|
|
159
|
-
* @param compositeKey - Composite key (worktreeId:cliToolId)
|
|
160
|
-
* @returns true if a poller is actively running
|
|
161
|
-
*/
|
|
162
|
-
function isPollerActive(compositeKey) {
|
|
163
|
-
return autoYesPollerStates.has(compositeKey);
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Update the last server response timestamp.
|
|
167
|
-
*
|
|
168
|
-
* @param compositeKey - Composite key
|
|
169
|
-
* @param timestamp - Timestamp value (Date.now())
|
|
170
|
-
*/
|
|
171
|
-
function updateLastServerResponseTimestamp(compositeKey, timestamp, owner) {
|
|
172
|
-
const pollerState = ownedPollerState(compositeKey, owner);
|
|
173
|
-
if (pollerState) {
|
|
174
|
-
pollerState.lastServerResponseTimestamp = timestamp;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Reset error count for a poller and restore the default polling interval.
|
|
179
|
-
* Called after every poll that ran to the end without an error (Issue #3329)
|
|
180
|
-
* and after an answer is sent.
|
|
181
|
-
*
|
|
182
|
-
* @param compositeKey - Composite key
|
|
183
|
-
* @param owner - The tick's own poller state (Issue #3706); see {@link ownedPollerState}
|
|
184
|
-
*/
|
|
185
|
-
function resetErrorCount(compositeKey, owner) {
|
|
186
|
-
const pollerState = ownedPollerState(compositeKey, owner);
|
|
187
|
-
if (pollerState) {
|
|
188
|
-
pollerState.consecutiveErrors = 0;
|
|
189
|
-
pollerState.currentInterval = auto_yes_state_1.POLLING_INTERVAL_MS;
|
|
190
|
-
}
|
|
117
|
+
auto_yes_poller_generation_1.autoYesPollerStates.clear();
|
|
118
|
+
auto_yes_poller_receipt_log_1.withheldNoReceiptLoggedAt.clear();
|
|
191
119
|
}
|
|
192
120
|
/**
|
|
193
121
|
* Increment error count and apply backoff if the threshold is exceeded.
|
|
@@ -197,7 +125,7 @@ function resetErrorCount(compositeKey, owner) {
|
|
|
197
125
|
* @param owner - The tick's own poller state (Issue #3706); see {@link ownedPollerState}
|
|
198
126
|
*/
|
|
199
127
|
function incrementErrorCount(compositeKey, owner) {
|
|
200
|
-
const pollerState = ownedPollerState(compositeKey, owner);
|
|
128
|
+
const pollerState = (0, auto_yes_poller_generation_1.ownedPollerState)(compositeKey, owner);
|
|
201
129
|
if (pollerState) {
|
|
202
130
|
pollerState.consecutiveErrors++;
|
|
203
131
|
pollerState.currentInterval = (0, auto_yes_state_1.calculateBackoffInterval)(pollerState.consecutiveErrors);
|
|
@@ -221,46 +149,6 @@ function incrementErrorCount(compositeKey, owner) {
|
|
|
221
149
|
}
|
|
222
150
|
}
|
|
223
151
|
}
|
|
224
|
-
/**
|
|
225
|
-
* The poller state under `compositeKey`, but only when it is `owner` — the
|
|
226
|
-
* tick's own (Issue #3706). Without `owner` (callers outside a tick, and tests
|
|
227
|
-
* driving `detectAndRespondToPrompt` with a hand-built state) it is the plain
|
|
228
|
-
* by-key read this always was.
|
|
229
|
-
*/
|
|
230
|
-
function ownedPollerState(compositeKey, owner) {
|
|
231
|
-
const pollerState = getPollerState(compositeKey);
|
|
232
|
-
if (owner !== undefined && pollerState !== owner)
|
|
233
|
-
return undefined;
|
|
234
|
-
return pollerState;
|
|
235
|
-
}
|
|
236
|
-
/** Is the tick's poller still the one under its key (not stopped, not replaced)? */
|
|
237
|
-
function isPollerCurrent(generation) {
|
|
238
|
-
return getPollerState(generation.compositeKey) === generation.pollerState;
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* May the tick still act: its poller, its grant (the same enable, not expired)
|
|
242
|
-
* and its session (no relaunch since) are all still the ones it started under.
|
|
243
|
-
* Checked after capture, after each wait before a key, and inside the send.
|
|
244
|
-
*/
|
|
245
|
-
function isTickCurrent(generation) {
|
|
246
|
-
if (!isPollerCurrent(generation))
|
|
247
|
-
return false;
|
|
248
|
-
// `getAutoYesState` returns the stored object until it expires, when it
|
|
249
|
-
// stores (and returns) a disabled one — so an expiry fails identity too.
|
|
250
|
-
const grant = (0, auto_yes_state_1.getAutoYesState)(generation.worktreeId, generation.cliToolId, generation.instanceId);
|
|
251
|
-
if (grant !== generation.grant || !grant.enabled)
|
|
252
|
-
return false;
|
|
253
|
-
return isSameSession(generation);
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Is the session the tick answered still the one it started on (Issue #3706)?
|
|
257
|
-
* What the follow-ups of an answer already sent — the response poller restart,
|
|
258
|
-
* the terminal push — are judged by: a disable after the keys landed does not
|
|
259
|
-
* un-send them, a relaunch does make them about another process.
|
|
260
|
-
*/
|
|
261
|
-
function isSameSession(generation) {
|
|
262
|
-
return (0, auto_yes_enter_fallback_1.getEnterFallbackSessionEpoch)(generation.compositeKey) === generation.sessionEpoch;
|
|
263
|
-
}
|
|
264
152
|
/**
|
|
265
153
|
* End a tick that found its generation gone (Issue #3706). It changes nothing;
|
|
266
154
|
* it re-arms its timer only when its own poller is still the current one — a
|
|
@@ -272,25 +160,11 @@ function endStaleTick(generation) {
|
|
|
272
160
|
worktreeId: generation.worktreeId,
|
|
273
161
|
cliToolId: generation.cliToolId,
|
|
274
162
|
instanceId: generation.instanceId,
|
|
275
|
-
pollerCurrent: isPollerCurrent(generation),
|
|
163
|
+
pollerCurrent: (0, auto_yes_poller_generation_1.isPollerCurrent)(generation),
|
|
276
164
|
});
|
|
277
|
-
if (isPollerCurrent(generation))
|
|
165
|
+
if ((0, auto_yes_poller_generation_1.isPollerCurrent)(generation))
|
|
278
166
|
scheduleNextPoll(generation);
|
|
279
167
|
}
|
|
280
|
-
/**
|
|
281
|
-
* Check if the given prompt has already been answered recently.
|
|
282
|
-
*
|
|
283
|
-
* @param pollerState - Current poller state
|
|
284
|
-
* @param promptKey - Composite key of the current prompt
|
|
285
|
-
* @returns true if the prompt key matches and is within the retry expiry window
|
|
286
|
-
*/
|
|
287
|
-
function isDuplicatePrompt(pollerState, promptKey) {
|
|
288
|
-
if (pollerState.lastAnsweredPromptKey !== promptKey)
|
|
289
|
-
return false;
|
|
290
|
-
if (pollerState.lastAnsweredAt === null)
|
|
291
|
-
return false;
|
|
292
|
-
return (Date.now() - pollerState.lastAnsweredAt) < auto_yes_state_1.DUPLICATE_RETRY_EXPIRY_MS;
|
|
293
|
-
}
|
|
294
168
|
// =============================================================================
|
|
295
169
|
// Extracted Functions for pollAutoYes (Issue #323: SRP decomposition)
|
|
296
170
|
// =============================================================================
|
|
@@ -327,38 +201,6 @@ function validatePollingContext(compositeKey, pollerState) {
|
|
|
327
201
|
}
|
|
328
202
|
return 'valid';
|
|
329
203
|
}
|
|
330
|
-
/**
|
|
331
|
-
* Capture tmux session output once, keeping both spellings (Issue #2522).
|
|
332
|
-
*
|
|
333
|
-
* @internal Exported for testing purposes only.
|
|
334
|
-
* @param worktreeId - Worktree identifier
|
|
335
|
-
* @param cliToolId - CLI tool type being polled
|
|
336
|
-
* @param captureLines - Optional number of lines to capture
|
|
337
|
-
* @param instanceId - Optional agent instance ID (Issue #896; defaults to primary session)
|
|
338
|
-
* @returns The tick's raw capture and its cleaned form
|
|
339
|
-
*/
|
|
340
|
-
async function capturePollerFrame(worktreeId, cliToolId, captureLines, instanceId) {
|
|
341
|
-
const lines = captureLines ?? auto_yes_config_1.FULL_CAPTURE_LINES;
|
|
342
|
-
const output = await (0, cli_session_1.captureSessionOutput)(worktreeId, cliToolId, lines, instanceId);
|
|
343
|
-
return { raw: output, clean: (0, cli_patterns_1.stripBoxDrawing)((0, cli_patterns_1.stripAnsi)(output)) };
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Capture tmux session output and strip ANSI escape codes.
|
|
347
|
-
*
|
|
348
|
-
* Kept as the cleaned half of {@link capturePollerFrame} so the many callers and
|
|
349
|
-
* tests that only ever wanted that string are untouched; `pollAutoYes` takes the
|
|
350
|
-
* pair. `stripBoxDrawing` still runs exactly once per capture either way.
|
|
351
|
-
*
|
|
352
|
-
* @internal Exported for testing purposes only.
|
|
353
|
-
* @param worktreeId - Worktree identifier
|
|
354
|
-
* @param cliToolId - CLI tool type being polled
|
|
355
|
-
* @param captureLines - Optional number of lines to capture
|
|
356
|
-
* @param instanceId - Optional agent instance ID (Issue #896; defaults to primary session)
|
|
357
|
-
* @returns Cleaned output string (ANSI stripped)
|
|
358
|
-
*/
|
|
359
|
-
async function captureAndCleanOutput(worktreeId, cliToolId, captureLines, instanceId) {
|
|
360
|
-
return (await capturePollerFrame(worktreeId, cliToolId, captureLines, instanceId)).clean;
|
|
361
|
-
}
|
|
362
204
|
/**
|
|
363
205
|
* Process stop condition check using delta-based approach.
|
|
364
206
|
*
|
|
@@ -386,228 +228,6 @@ function processStopConditionDelta(compositeKey, pollerState, cleanOutput) {
|
|
|
386
228
|
}
|
|
387
229
|
return false;
|
|
388
230
|
}
|
|
389
|
-
/**
|
|
390
|
-
* Say, once a minute, that Auto-Yes left an agy dialog alone for want of a hook
|
|
391
|
-
* receipt (Issue #2857).
|
|
392
|
-
*
|
|
393
|
-
* `detectPromptOnCleanFrame` hands a frame the receipt gate (#2849) withholds
|
|
394
|
-
* back as an ordinary `isPrompt: false`, so the poller cannot tell "no dialog on
|
|
395
|
-
* the pane" from "a dialog agy never asked us about" by looking at the result.
|
|
396
|
-
* The gate is the ONLY thing `receiptScope` changes, so the same frame read
|
|
397
|
-
* without it answering a prompt is exactly the withheld case. That second
|
|
398
|
-
* reading is taken only after the cheap tests: no receipt for this instance in
|
|
399
|
-
* the window (with one, the gate let the frame through and a no-prompt result is
|
|
400
|
-
* a real one) and no line for it in the last minute.
|
|
401
|
-
*
|
|
402
|
-
* Why it is worth a line: a machine whose `~/.gemini/config/hooks.json` points at
|
|
403
|
-
* another server (#2622) never sends us the question, and every real dialog then
|
|
404
|
-
* waits for a human with no sign of why. The line names the file to look at.
|
|
405
|
-
*
|
|
406
|
-
* A stale receipt does not always mean that, though (Issue #3724): a dialog the
|
|
407
|
-
* contract's autoYes withheld got its receipt, the server answered `ask`, and
|
|
408
|
-
* the dialog outlived the window. When `resolveAutoAnswerWithPolicy` on the
|
|
409
|
-
* ungated reading suppresses the answer by contract (the base rules would have
|
|
410
|
-
* answered it), the line is `antigravity-autoyes-withheld-by-policy` instead,
|
|
411
|
-
* naming the reason, the mode and the task. Both share the limit.
|
|
412
|
-
* The response-checker's own `antigravity-dialog-no-recent-receipt` stays at
|
|
413
|
-
* debug — it prints on every tick the same pane is read again.
|
|
414
|
-
*
|
|
415
|
-
* @param compositeKey - The instance's key, for the once-a-minute limit
|
|
416
|
-
* @param readWithoutGate - The same frame read without `receiptScope`
|
|
417
|
-
*/
|
|
418
|
-
function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, readWithoutGate) {
|
|
419
|
-
// Issue #3767: the gate's own verdict for this tick's candidate. Null means it
|
|
420
|
-
// never saw one (no dialog), `ok` that it let the frame through.
|
|
421
|
-
let verdict = (0, antigravity_receipt_episodes_1.getAntigravityReceiptVerdict)(worktreeId, instanceId);
|
|
422
|
-
if (verdict?.ok)
|
|
423
|
-
return;
|
|
424
|
-
const now = Date.now();
|
|
425
|
-
const ungated = readWithoutGate();
|
|
426
|
-
if (!ungated.isPrompt || !ungated.promptData)
|
|
427
|
-
return;
|
|
428
|
-
// The gate was not consulted (the gated reading declined the frame on screen
|
|
429
|
-
// grounds alone) yet the frame reads as a prompt: judge it here.
|
|
430
|
-
verdict ??= (0, antigravity_receipt_episodes_1.judgeAntigravityPermissionReceipt)(worktreeId, instanceId, now);
|
|
431
|
-
if (verdict.ok)
|
|
432
|
-
return;
|
|
433
|
-
// Issue #3724: a contract that withholds the answer makes the server reply
|
|
434
|
-
// `ask`, so the dialog stays up past the receipt window. The cause is then the
|
|
435
|
-
// contract, not a hooks.json that points elsewhere. Judged exactly as the tick
|
|
436
|
-
// judges a prompt it can read — the base rules first, then the contract — so
|
|
437
|
-
// a prompt the base rules never answer (a checkbox, a typed option) is not
|
|
438
|
-
// blamed on the contract. Policy and task id come from one lookup.
|
|
439
|
-
const { policy, taskId } = (0, auto_yes_policy_1.getSessionAutoYesPolicyEntry)(worktreeId, 'antigravity', instanceId);
|
|
440
|
-
const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(ungated.promptData, policy);
|
|
441
|
-
// Issue #3767: `answered` is the dialog the gate already let through on this
|
|
442
|
-
// receipt, still up past the window. Unless the contract withheld it, that is
|
|
443
|
-
// not a missing receipt: neither recorded nor logged, nor counted for the limit.
|
|
444
|
-
// Issue #3789: `answered` is also a dialog accepted but never sent to (the
|
|
445
|
-
// tick recorded its own reason, if any, and that record is kept). One the
|
|
446
|
-
// poller DID send keys to and still up past the grace is `outlived`, which is
|
|
447
|
-
// recorded and logged like the others, so the stop is not a silent one.
|
|
448
|
-
// Issue #3796: the reason the poller recorded for this dialog (partial-answer,
|
|
449
|
-
// the contract, …) while it could still read it inside the window was not
|
|
450
|
-
// re-stamped once the window closed — the gated reading stopped seeing the
|
|
451
|
-
// prompt — so `cmate wait` dropped it as stale a minute later with the dialog
|
|
452
|
-
// still up. Re-stamped here on every tick the dialog stays — only while it
|
|
453
|
-
// still holds under this tick's evaluation — and kept over a `no-hook-receipt`
|
|
454
|
-
// for it: it is the more exact reason.
|
|
455
|
-
const keptPartialAnswer = refreshEpisodeSuppression(worktreeId, instanceId, verdict, resolution);
|
|
456
|
-
// Issue #3796 review D: a contract that withholds the prompt now is published
|
|
457
|
-
// whatever was recorded before — none at all (the window closed before the
|
|
458
|
-
// tick could read it, or an ended contract's record was dropped and a new one
|
|
459
|
-
// withholds it again) or another reason. Without it `cmate wait` read no
|
|
460
|
-
// reason and held the prompt as one Auto-Yes was answering. Only a partial
|
|
461
|
-
// answer still on screen comes first, as it does on the tick (step 2.5).
|
|
462
|
-
if (resolution.suppressedBy && !keptPartialAnswer) {
|
|
463
|
-
(0, auto_yes_suppression_state_1.recordPolicySuppression)(worktreeId, 'antigravity', instanceId, {
|
|
464
|
-
reason: resolution.suppressedBy,
|
|
465
|
-
mode: policy?.mode ?? null,
|
|
466
|
-
promptType: ungated.promptData.type,
|
|
467
|
-
...(resolution.pattern !== undefined ? { pattern: resolution.pattern } : {}),
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
if (!resolution.suppressedBy && (verdict.cause === 'answered' || keptPartialAnswer))
|
|
471
|
-
return;
|
|
472
|
-
const lastLoggedAt = withheldNoReceiptLoggedAt.get(compositeKey);
|
|
473
|
-
const logDue = lastLoggedAt === undefined || now - lastLoggedAt >= WITHHELD_NO_RECEIPT_LOG_INTERVAL_MS;
|
|
474
|
-
if (logDue) {
|
|
475
|
-
for (const [key, loggedAt] of withheldNoReceiptLoggedAt) {
|
|
476
|
-
if (now - loggedAt >= WITHHELD_NO_RECEIPT_LOG_INTERVAL_MS)
|
|
477
|
-
withheldNoReceiptLoggedAt.delete(key);
|
|
478
|
-
}
|
|
479
|
-
withheldNoReceiptLoggedAt.set(compositeKey, now);
|
|
480
|
-
}
|
|
481
|
-
if (resolution.suppressedBy) {
|
|
482
|
-
if (!logDue)
|
|
483
|
-
return;
|
|
484
|
-
logger.info('antigravity-autoyes-withheld-by-policy', {
|
|
485
|
-
worktreeId,
|
|
486
|
-
instanceId: instanceId ?? 'antigravity',
|
|
487
|
-
reason: resolution.suppressedBy,
|
|
488
|
-
mode: policy?.mode ?? null,
|
|
489
|
-
taskId,
|
|
490
|
-
hint: '契約の autoYes が答えを止めている。契約の autoYes を確認',
|
|
491
|
-
});
|
|
492
|
-
return;
|
|
493
|
-
}
|
|
494
|
-
// Issue #3767: recorded on every tick (the record's `at` follows the prompt
|
|
495
|
-
// while it stays up), logged once a minute.
|
|
496
|
-
(0, auto_yes_suppression_state_1.recordPolicySuppression)(worktreeId, 'antigravity', instanceId, {
|
|
497
|
-
reason: auto_yes_suppression_reason_1.NO_HOOK_RECEIPT_SUPPRESSION_REASON,
|
|
498
|
-
mode: null,
|
|
499
|
-
promptType: ungated.promptData.type,
|
|
500
|
-
});
|
|
501
|
-
if (!logDue)
|
|
502
|
-
return;
|
|
503
|
-
logger.info('antigravity-autoyes-withheld-no-hook-receipt', {
|
|
504
|
-
worktreeId,
|
|
505
|
-
instanceId: instanceId ?? 'antigravity',
|
|
506
|
-
windowMs: antigravity_permission_receipts_1.ANTIGRAVITY_PERMISSION_RECEIPT_WINDOW_MS,
|
|
507
|
-
hint: noHookReceiptHint(verdict, now),
|
|
508
|
-
});
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* Issue #3796: keep the suppression the poller recorded during this dialog's
|
|
512
|
-
* episode current while the dialog it accepted (`answered` / `outlived`) is
|
|
513
|
-
* still up. Only a record made since the dialog was first read, and never the
|
|
514
|
-
* receipt gate's own `no-hook-receipt` (the caller records that itself). A
|
|
515
|
-
* record is kept only while its reason still holds NOW:
|
|
516
|
-
*
|
|
517
|
-
* - `partial-answer` remembers an event: it holds for as long as the dialog
|
|
518
|
-
* the keys went to stays up (this episode), and is re-stamped here;
|
|
519
|
-
* - a contract reason is the contract's verdict on the prompt, re-evaluated on
|
|
520
|
-
* every tick (`resolution`): no verdict (the contract ended, or now answers
|
|
521
|
-
* it) drops the record — the dialog is then `answered` / `outlived` like any
|
|
522
|
-
* other. A verdict is recorded by the caller (review D), whatever was here;
|
|
523
|
-
* - any other reason is left as it was recorded.
|
|
524
|
-
*
|
|
525
|
-
* @returns true when a `partial-answer` that still holds was re-stamped
|
|
526
|
-
*/
|
|
527
|
-
function refreshEpisodeSuppression(worktreeId, instanceId, verdict, resolution) {
|
|
528
|
-
if (verdict.cause !== 'answered' && verdict.cause !== 'outlived')
|
|
529
|
-
return false;
|
|
530
|
-
const own = (0, auto_yes_suppression_state_1.getLastPolicySuppression)(worktreeId, 'antigravity', instanceId);
|
|
531
|
-
if (own === null || own.reason === auto_yes_suppression_reason_1.NO_HOOK_RECEIPT_SUPPRESSION_REASON || !(own.at >= verdict.firstSeenAt)) {
|
|
532
|
-
return false;
|
|
533
|
-
}
|
|
534
|
-
if (own.reason === auto_yes_suppression_reason_1.PARTIAL_ANSWER_SUPPRESSION_REASON) {
|
|
535
|
-
// The memory is the episode's: the dialog the keys went to is still the one
|
|
536
|
-
// up (same episode, accepted on the same receipt). Not `getPartialAnswer`:
|
|
537
|
-
// the tick forgets it as soon as the gated reading stops seeing the prompt,
|
|
538
|
-
// which past the window is every tick.
|
|
539
|
-
const { at: _recordedAt, ...suppression } = own;
|
|
540
|
-
(0, auto_yes_suppression_state_1.recordPolicySuppression)(worktreeId, 'antigravity', instanceId, suppression);
|
|
541
|
-
return true;
|
|
542
|
-
}
|
|
543
|
-
if (auto_yes_suppression_reason_1.CONTRACT_SUPPRESSION_REASONS.has(own.reason) && !resolution.suppressedBy) {
|
|
544
|
-
(0, auto_yes_suppression_state_1.forgetPolicySuppression)(worktreeId, 'antigravity', instanceId);
|
|
545
|
-
}
|
|
546
|
-
return false;
|
|
547
|
-
}
|
|
548
|
-
/**
|
|
549
|
-
* Issue #3789: keys for an agy dialog the receipt gate accepted reached tmux.
|
|
550
|
-
* Only here does the gate start the grace after which a dialog still up is
|
|
551
|
-
* reported as `outlived`; the tick's `no_answer` exits (another server's session,
|
|
552
|
-
* a partial answer, the base rules or the contract not answering) never get
|
|
553
|
-
* here, so their own records are not overwritten by `no-hook-receipt`.
|
|
554
|
-
*
|
|
555
|
-
* Issue #3796: `interrupted` — the send began and was cut short (stopped
|
|
556
|
-
* part-way, or failed). Its keys may be on the pane and the receipt is spent,
|
|
557
|
-
* so the grace starts here too; without it the dialog stayed `answered`, and
|
|
558
|
-
* silent, for as long as it stayed up.
|
|
559
|
-
*/
|
|
560
|
-
function noteAnswerSent(cliToolId, worktreeId, instanceId, interrupted = false, forReceiptAt) {
|
|
561
|
-
if (cliToolId !== 'antigravity')
|
|
562
|
-
return;
|
|
563
|
-
(0, antigravity_receipt_episodes_1.markAntigravityAnswerSent)(worktreeId, instanceId, Date.now(), {
|
|
564
|
-
interrupted,
|
|
565
|
-
...(forReceiptAt !== undefined ? { forReceiptAt } : {}),
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
/**
|
|
569
|
-
* Issue #3796 review: the agy episode a send is about to go to, read before
|
|
570
|
-
* its first await; null for other tools. Given back to {@link noteAnswerSent}
|
|
571
|
-
* however the send came back — whole, failed or cut short (review E) — so that
|
|
572
|
-
* only that episode is marked — the same
|
|
573
|
-
* idea as the Enter record's generation check in `tryEnterFallback`.
|
|
574
|
-
*/
|
|
575
|
-
function receiptEpisodeOfSend(cliToolId, worktreeId, instanceId) {
|
|
576
|
-
return cliToolId === 'antigravity' ? (0, antigravity_receipt_episodes_1.getAntigravityAcceptedReceiptAt)(worktreeId, instanceId) : null;
|
|
577
|
-
}
|
|
578
|
-
/**
|
|
579
|
-
* The hint for `antigravity-autoyes-withheld-no-hook-receipt` (Issue #3767):
|
|
580
|
-
* which of the withheld cases it was decides where to look.
|
|
581
|
-
*/
|
|
582
|
-
function noHookReceiptHint(verdict, now = Date.now()) {
|
|
583
|
-
const seconds = verdict.ageMs === null ? null : Math.round(verdict.ageMs / 1000);
|
|
584
|
-
// `lapsed` says how long ago, so from now: the line repeats once a minute.
|
|
585
|
-
const secondsAgo = verdict.lastReceiptAt === null ? null : Math.round((now - verdict.lastReceiptAt) / 1000);
|
|
586
|
-
switch (verdict.cause) {
|
|
587
|
-
case 'never':
|
|
588
|
-
return 'hook の受信が一度も無いため Auto-Yes は答えなかった。~/.gemini/config/hooks.json の向き先(#2622)を確認';
|
|
589
|
-
case 'late':
|
|
590
|
-
return `最後の受信から ${seconds} 秒後に確認が出た(窓 ${antigravity_permission_receipts_1.ANTIGRAVITY_PERMISSION_RECEIPT_WINDOW_MS / 1000} 秒の外)ため答えなかった。人が答える(auto-yes --disable → prompt --json → respond --expect-screen)。続くなら ~/.gemini/config/hooks.json の向き先(#2622)も確認`;
|
|
591
|
-
case 'lapsed':
|
|
592
|
-
return `最後の受信は ${secondsAgo} 秒前で途絶えている(hook が届かなくなった)。hooks.json の向き先(#2622)と agy の再起動を確認`;
|
|
593
|
-
case 'predates':
|
|
594
|
-
return '確認は最後の受信より前から画面に出ていた(引用か別の確認)ため答えなかった。人が答える';
|
|
595
|
-
case 'used':
|
|
596
|
-
return '最後の受信は直前の確認に使い済み。この確認に対する受信は無いため答えなかった。人が答える';
|
|
597
|
-
case 'outlived':
|
|
598
|
-
if (verdict.answerInterrupted === true) {
|
|
599
|
-
return `Auto-Yes が最後の受信の確認へ答えを送る途中で送信が止まり(キーの一部が入力に残っている可能性がある)、${antigravity_receipt_episodes_1.ANTIGRAVITY_ANSWERED_DIALOG_GRACE_MS / 1000} 秒を過ぎても確認が画面に残っている。未使用の受信が無いため、もう一度は答えない。人が答える(auto-yes --disable → prompt --json → respond --expect-screen)`;
|
|
600
|
-
}
|
|
601
|
-
return `Auto-Yes が最後の受信の確認へキーを送ってから ${antigravity_receipt_episodes_1.ANTIGRAVITY_ANSWERED_DIALOG_GRACE_MS / 1000} 秒を過ぎても、確認が画面に残っている。キーで確認が閉じなかったか、新しい受信の無い別の確認と入れ替わった(画面からは区別できない)。未使用の受信が無いため、もう一度は答えない。人が答える(auto-yes --disable → prompt --json → respond --expect-screen)`;
|
|
602
|
-
default:
|
|
603
|
-
return 'hook の受信記録が直近に無いため Auto-Yes は答えなかった。~/.gemini/config/hooks.json の向き先(#2622)を確認';
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
/**
|
|
607
|
-
* The audit row's `answer` for the Enter (Issue #3397): not a digit, so the
|
|
608
|
-
* History reads as "Auto-Yes pressed Enter" rather than as a chosen option.
|
|
609
|
-
*/
|
|
610
|
-
exports.AUTO_YES_ENTER_FALLBACK_ANSWER = '[Enter]';
|
|
611
231
|
/**
|
|
612
232
|
* Issue #3397: is the fresh capture still the screen the Enter was decided for?
|
|
613
233
|
* Re-reads it the way one tick does — prompt reading, the same `promptFrameKey`,
|
|
@@ -683,19 +303,20 @@ async function tryEnterFallback(prompt, promptDetection, dialogGate, rawOutput,
|
|
|
683
303
|
});
|
|
684
304
|
return false;
|
|
685
305
|
}
|
|
686
|
-
// 3. The contract policy, as step 4 reads it.
|
|
306
|
+
// 3. The contract policy, as step 4 reads it (Issue #3822: a failed lookup withholds).
|
|
687
307
|
const policy = (0, auto_yes_policy_1.getSessionAutoYesPolicy)(worktreeId, cliToolId, instanceId);
|
|
688
308
|
const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(promptData, policy);
|
|
689
309
|
if (resolution.suppressedBy) {
|
|
690
310
|
pollerState.enterFallbackCandidateKey = null;
|
|
311
|
+
const mode = (0, auto_yes_resolver_1.policyLookupMode)(policy);
|
|
691
312
|
(0, auto_yes_prompt_suppression_1.suppressAndWarnOnce)(prompt, {
|
|
692
313
|
reason: resolution.suppressedBy,
|
|
693
|
-
mode
|
|
314
|
+
mode,
|
|
694
315
|
promptType: promptData.type,
|
|
695
316
|
pattern: resolution.pattern,
|
|
696
|
-
}, `${frameKey}\u0000${resolution.suppressedBy}\u0000${
|
|
317
|
+
}, `${frameKey}\u0000${resolution.suppressedBy}\u0000${mode ?? ''}\u0000${resolution.pattern ?? ''}`, 'poller:auto-yes-suppressed-by-policy', {
|
|
697
318
|
reason: resolution.suppressedBy,
|
|
698
|
-
mode
|
|
319
|
+
mode,
|
|
699
320
|
pattern: resolution.pattern,
|
|
700
321
|
promptType: promptData.type,
|
|
701
322
|
enterFallback: true,
|
|
@@ -730,9 +351,11 @@ async function tryEnterFallback(prompt, promptDetection, dialogGate, rawOutput,
|
|
|
730
351
|
// 5. Never another server's session (Issue #2865).
|
|
731
352
|
const sessionName = manager_1.CLIToolManager.getInstance().getTool(cliToolId).getSessionName(worktreeId, instanceId);
|
|
732
353
|
const ownership = await (0, worktree_session_ownership_1.checkWorktreeSessionOwnership)(worktreeId, sessionName);
|
|
733
|
-
if (generation !== undefined && !isTickCurrent(generation))
|
|
354
|
+
if (generation !== undefined && !(0, auto_yes_poller_generation_1.isTickCurrent)(generation))
|
|
734
355
|
return false;
|
|
735
356
|
if (ownership === null || ownership.verdict === 'foreign') {
|
|
357
|
+
// Issue #3820: the ledger's own reason, as `skippedForUnownedSession` records it.
|
|
358
|
+
(0, auto_yes_confirmation_ledger_1.withholdLedgerConfirmation)(prompt, 'foreign-session');
|
|
736
359
|
(0, auto_yes_poller_state_1.warnOncePerFrame)(pollerState, `${frameKey}\u0000${sessionName}\u0000${ownership ? 'foreign' : 'worktree_not_found'}`, 'poller:auto-yes-skipped-foreign-session', {
|
|
737
360
|
worktreeId,
|
|
738
361
|
cliToolId,
|
|
@@ -751,7 +374,7 @@ async function tryEnterFallback(prompt, promptDetection, dialogGate, rawOutput,
|
|
|
751
374
|
// has the box back. Everything that decided the Enter is judged again on the
|
|
752
375
|
// fresh frame; any difference sends nothing, and the next tick starts over.
|
|
753
376
|
const fresh = await (0, cli_session_1.captureSessionOutputFresh)(worktreeId, cliToolId, (rawOutput ?? '').split('\n').length, instanceId);
|
|
754
|
-
if (generation !== undefined && !isTickCurrent(generation))
|
|
377
|
+
if (generation !== undefined && !(0, auto_yes_poller_generation_1.isTickCurrent)(generation))
|
|
755
378
|
return false;
|
|
756
379
|
if (!isStillEnterFallbackScreen(prompt, fresh)) {
|
|
757
380
|
pollerState.enterFallbackCandidateKey = null;
|
|
@@ -763,25 +386,29 @@ async function tryEnterFallback(prompt, promptDetection, dialogGate, rawOutput,
|
|
|
763
386
|
});
|
|
764
387
|
return false;
|
|
765
388
|
}
|
|
766
|
-
const receiptEpisode = receiptEpisodeOfSend(cliToolId, worktreeId, instanceId);
|
|
389
|
+
const receiptEpisode = (0, auto_yes_poller_receipt_log_1.receiptEpisodeOfSend)(cliToolId, worktreeId, instanceId);
|
|
390
|
+
// Issue #3820: taken before the await, so the result goes to this confirmation.
|
|
391
|
+
const ledgerAttempt = (0, auto_yes_confirmation_ledger_1.beginLedgerAttempt)(prompt, 'enter-fallback');
|
|
767
392
|
try {
|
|
768
393
|
await (0, tmux_1.sendSpecialKeys)(sessionName, ['Enter']);
|
|
769
394
|
}
|
|
770
395
|
catch (error) {
|
|
771
396
|
// Issue #3796: the Enter may or may not have reached the pane.
|
|
772
|
-
noteAnswerSent(cliToolId, worktreeId, instanceId, true, receiptEpisode);
|
|
397
|
+
(0, auto_yes_poller_receipt_log_1.noteAnswerSent)(cliToolId, worktreeId, instanceId, true, receiptEpisode);
|
|
398
|
+
(0, auto_yes_confirmation_ledger_1.settleLedgerAttempt)(ledgerAttempt, 'failed');
|
|
773
399
|
throw error;
|
|
774
400
|
}
|
|
775
401
|
finally {
|
|
776
402
|
(0, tmux_capture_cache_1.invalidateCache)(sessionName);
|
|
777
403
|
}
|
|
778
404
|
// Issue #3796 review E: the Enter is out — for the episode it began for only.
|
|
779
|
-
noteAnswerSent(cliToolId, worktreeId, instanceId, false, receiptEpisode);
|
|
405
|
+
(0, auto_yes_poller_receipt_log_1.noteAnswerSent)(cliToolId, worktreeId, instanceId, false, receiptEpisode);
|
|
406
|
+
(0, auto_yes_confirmation_ledger_1.settleLedgerAttempt)(ledgerAttempt, 'ok');
|
|
780
407
|
// Issue #3706: the Enter is out, but the per-screen record is the CURRENT
|
|
781
408
|
// session's: when the poller was stopped (the record was forgotten with it)
|
|
782
409
|
// or a new session began while `send-keys` was awaited, the return of this
|
|
783
410
|
// send must not put the record back. The audit row below is kept either way.
|
|
784
|
-
if (generation === undefined || (isPollerCurrent(generation) && isSameSession(generation))) {
|
|
411
|
+
if (generation === undefined || ((0, auto_yes_poller_generation_1.isPollerCurrent)(generation) && (0, auto_yes_poller_generation_1.isSameSession)(generation))) {
|
|
785
412
|
pollerState.enterFallbackSentKey = frameKey;
|
|
786
413
|
pollerState.enterFallbackCandidateKey = null;
|
|
787
414
|
(0, auto_yes_enter_fallback_1.recordEnterFallbackSent)(worktreeId, cliToolId, instanceId, {
|
|
@@ -799,7 +426,7 @@ async function tryEnterFallback(prompt, promptDetection, dialogGate, rawOutput,
|
|
|
799
426
|
refusalReason: judgement.refusalReason,
|
|
800
427
|
composerState: judgement.composerState,
|
|
801
428
|
});
|
|
802
|
-
await finishAnsweredPrompt(prompt, promptDetection,
|
|
429
|
+
await finishAnsweredPrompt(prompt, promptDetection, auto_yes_poller_enter_fallback_1.AUTO_YES_ENTER_FALLBACK_ANSWER, generation);
|
|
803
430
|
return true;
|
|
804
431
|
}
|
|
805
432
|
/**
|
|
@@ -827,11 +454,11 @@ async function finishAnsweredPrompt(prompt, promptDetection, answer, generation)
|
|
|
827
454
|
// process's identical question), not the poller's response time, not the
|
|
828
455
|
// task event (the task looked up now may be the new session's). Only the
|
|
829
456
|
// audit row is, and it may not adopt a pending row saved after the tick began.
|
|
830
|
-
const sameSession = generation === undefined || isSameSession(generation);
|
|
457
|
+
const sameSession = generation === undefined || (0, auto_yes_poller_generation_1.isSameSession)(generation);
|
|
831
458
|
if (sameSession) {
|
|
832
459
|
// 6. Update timestamp and reset error count
|
|
833
|
-
updateLastServerResponseTimestamp(compositeKey, Date.now(), generation?.pollerState);
|
|
834
|
-
resetErrorCount(compositeKey, generation?.pollerState);
|
|
460
|
+
(0, auto_yes_poller_generation_1.updateLastServerResponseTimestamp)(compositeKey, Date.now(), generation?.pollerState);
|
|
461
|
+
(0, auto_yes_poller_generation_1.resetErrorCount)(compositeKey, generation?.pollerState);
|
|
835
462
|
// 7. Record answered prompt key and timestamp
|
|
836
463
|
pollerState.lastAnsweredPromptKey = promptKey;
|
|
837
464
|
pollerState.lastAnsweredAt = Date.now();
|
|
@@ -906,11 +533,152 @@ async function finishAnsweredPrompt(prompt, promptDetection, answer, generation)
|
|
|
906
533
|
]);
|
|
907
534
|
// Re-read after the await, not the `sameSession` taken before the audit: a
|
|
908
535
|
// relaunch while the modules loaded makes the restart about the new process.
|
|
909
|
-
if (!sameSession || (generation !== undefined && !isSameSession(generation)))
|
|
536
|
+
if (!sameSession || (generation !== undefined && !(0, auto_yes_poller_generation_1.isSameSession)(generation)))
|
|
910
537
|
return;
|
|
911
538
|
startResponsePolling(worktreeId, cliToolId, instanceId);
|
|
912
539
|
void broadcastTerminalSnapshotAfterInteraction(worktreeId, cliToolId, instanceId);
|
|
913
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Step 1 of `detectAndRespondToPrompt`: normalise the tick's frame once and
|
|
543
|
+
* read the prompt on it.
|
|
544
|
+
*/
|
|
545
|
+
function readPromptFrame(worktreeId, cliToolId, cleanOutput, precomputedLines, instanceId, rawOutput) {
|
|
546
|
+
const receiptScope = { worktreeId, instanceId };
|
|
547
|
+
// Issue #3183: the ONE frame every judgement below reads — normalised once,
|
|
548
|
+
// from the capture as captured (the input-box markers are rule rows the
|
|
549
|
+
// cleaned spelling has blanked), and handed as the same object to the
|
|
550
|
+
// prompt reading, the codex launch guards and the dialog gate. That is what
|
|
551
|
+
// makes "the status chain and Auto-Yes read the same live region" a fact
|
|
552
|
+
// rather than a hope: there is no second normalisation to disagree with.
|
|
553
|
+
const frame = (0, frame_1.normalizeFrame)(rawOutput ?? cleanOutput, cliToolId);
|
|
554
|
+
// Issue #3767: bracket the read so the receipt gate can tell when an agy
|
|
555
|
+
// dialog first appeared, not only what time this tick is.
|
|
556
|
+
if (cliToolId === 'antigravity')
|
|
557
|
+
(0, antigravity_receipt_episodes_1.beginAntigravityFrameRead)(worktreeId, instanceId);
|
|
558
|
+
const promptDetection = (0, response_checker_1.detectPromptOnCleanFrame)(cleanOutput, cliToolId, precomputedLines, rawOutput, receiptScope, frame);
|
|
559
|
+
if (cliToolId === 'antigravity')
|
|
560
|
+
(0, antigravity_receipt_episodes_1.endAntigravityFrameRead)(worktreeId, instanceId);
|
|
561
|
+
return { frame, promptDetection };
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* What `detectAndRespondToPrompt` does to the poller state on a frame with no
|
|
565
|
+
* prompt to answer, before it returns `no_prompt`.
|
|
566
|
+
*/
|
|
567
|
+
function noteNoPromptOnScreen(tick) {
|
|
568
|
+
const { worktreeId, cliToolId, instanceId, compositeKey, pollerState, frame, promptDetection, cleanOutput, precomputedLines, rawOutput, } = tick;
|
|
569
|
+
(0, auto_yes_poller_state_1.forgetPartialAnswer)(compositeKey);
|
|
570
|
+
pollerState.lastAnsweredPromptKey = null;
|
|
571
|
+
pollerState.lastAnsweredAt = null;
|
|
572
|
+
pollerState.enterFallbackCandidateKey = null;
|
|
573
|
+
// Issue #3757: agy's trust screen reads as no prompt (unnumbered: neither
|
|
574
|
+
// reader takes it), but it is one nobody here answers — record why, still
|
|
575
|
+
// as `no_prompt`. Before the warn key is cleared, so the WARN stays once
|
|
576
|
+
// per screen.
|
|
577
|
+
// Issue #3820: the trust screen records itself in the ledger when it records
|
|
578
|
+
// its reason (`suppressAntigravityTrustScreen`).
|
|
579
|
+
if (cliToolId === 'antigravity' &&
|
|
580
|
+
(0, auto_yes_prompt_suppression_1.suppressAntigravityTrustScreen)(worktreeId, instanceId, pollerState, frame, manager_1.CLIToolManager.getInstance().getTool(cliToolId).getSessionName(worktreeId, instanceId))) {
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
pollerState.lastSkipWarnKey = null;
|
|
584
|
+
if (cliToolId === 'antigravity' && !promptDetection.isPrompt) {
|
|
585
|
+
const seen = (0, auto_yes_poller_receipt_log_1.logIfWithheldForWantOfReceipt)(worktreeId, instanceId, compositeKey, () => (0, response_checker_1.detectPromptOnCleanFrame)(cleanOutput, cliToolId, precomputedLines, rawOutput));
|
|
586
|
+
// Issue #3820: past the receipt window the gated reading says "no prompt"
|
|
587
|
+
// while the dialog is still up. The ungated reading says it is, so the
|
|
588
|
+
// ledger keeps the same confirmation (and the same withheld interval)
|
|
589
|
+
// rather than closing it on every tick outside the window.
|
|
590
|
+
if (seen !== null) {
|
|
591
|
+
const scope = { compositeKey, worktreeId, cliToolId, instanceId };
|
|
592
|
+
(0, auto_yes_confirmation_ledger_1.observeLedgerScreen)(scope, (0, auto_yes_poller_state_1.ledgerScreenKey)(seen.promptData), seen.promptData.type, ledgerCallOf(cliToolId, worktreeId, instanceId));
|
|
593
|
+
if (seen.reason !== null)
|
|
594
|
+
(0, auto_yes_confirmation_ledger_1.withholdLedgerConfirmation)(scope, seen.reason);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Issue #3820 (design §2.4, PR 3): the agy call the receipt episode on screen
|
|
600
|
+
* was accepted for, for the ledger to tie the confirmation to. Asked after the
|
|
601
|
+
* frame was judged; read only to record, and never throws.
|
|
602
|
+
*/
|
|
603
|
+
function ledgerCallOf(cliToolId, worktreeId, instanceId) {
|
|
604
|
+
if (cliToolId !== 'antigravity')
|
|
605
|
+
return {};
|
|
606
|
+
try {
|
|
607
|
+
const callId = (0, antigravity_receipt_episodes_1.getAntigravityAcceptedReceiptCallId)(worktreeId, instanceId);
|
|
608
|
+
return callId === null ? {} : { callId };
|
|
609
|
+
}
|
|
610
|
+
catch {
|
|
611
|
+
// Recording only: a failure here ties nothing and changes nothing else.
|
|
612
|
+
return {};
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Issue #3820: the result of a send that threw, as the ledger counts it.
|
|
617
|
+
* `keysSent` is what the sender said (#3706); a throw that says nothing is a
|
|
618
|
+
* failure whose keys may or may not be on the pane.
|
|
619
|
+
*/
|
|
620
|
+
function attemptResultOfThrow(keysSent) {
|
|
621
|
+
if (keysSent === true)
|
|
622
|
+
return 'partial';
|
|
623
|
+
if (keysSent === false)
|
|
624
|
+
return 'no-keys-sent';
|
|
625
|
+
return 'failed';
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Issue #3820: the evidence an answer on the screen path is given on (design
|
|
629
|
+
* §7 PR 1). A tool's own dialog detector vouched for the frame: `L3`. The
|
|
630
|
+
* gate did not judge it (a `legacy` tool, a non-multiple-choice prompt): the
|
|
631
|
+
* generic reading alone, `L4`.
|
|
632
|
+
*
|
|
633
|
+
* agy's gate is `legacy` (`gated: false`), yet its prompts are read by its own
|
|
634
|
+
* reader first (`detectPromptOnCleanFrame` returns that reader's result
|
|
635
|
+
* whenever it reads the frame). Which reader it was is not on the detection
|
|
636
|
+
* result, so it is asked of the same reader on the same text here — for the
|
|
637
|
+
* label only; the answer was decided before this is called. Read by agy's own
|
|
638
|
+
* reader, and through the receipt gate (the tick's reading carried the
|
|
639
|
+
* receipt scope): `L3`, with `receiptAccepted` on the attempt.
|
|
640
|
+
*/
|
|
641
|
+
function answerBasisOf(prompt, cleanOutput) {
|
|
642
|
+
if (prompt.cliToolId === 'antigravity') {
|
|
643
|
+
return (0, dialog_1.detectAntigravityNumberedDialogPrompt)(cleanOutput) !== null ? 'L3' : 'L4';
|
|
644
|
+
}
|
|
645
|
+
const gate = prompt.dialogGate;
|
|
646
|
+
return gate !== undefined && gate.gated && gate.allowed && gate.dialog !== null ? 'L3' : 'L4';
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* The `catch` of `detectAndRespondToPrompt`: settles the send in flight and
|
|
650
|
+
* tells an abandoned tick from a failed one.
|
|
651
|
+
*/
|
|
652
|
+
function settleFailedTick(error, tick) {
|
|
653
|
+
const { worktreeId, cliToolId, instanceId, compositeKey, generation, attempt, sendInFlight, receiptEpisode } = tick;
|
|
654
|
+
const keysSent = error instanceof Error && 'keysSent' in error ? Boolean(error.keysSent) : null;
|
|
655
|
+
// Issue #3820: the send that was cut short, in the ledger — before the send
|
|
656
|
+
// record below is settled, whose state says whether it had expired.
|
|
657
|
+
if (attempt !== null && sendInFlight) {
|
|
658
|
+
(0, auto_yes_confirmation_ledger_1.settleLedgerAttempt)(attempt.ledger, attemptResultOfThrow(keysSent), { expired: attempt.state === 'expired' });
|
|
659
|
+
}
|
|
660
|
+
// Issue #3706: a tick that lost its generation — the send stopped part-way
|
|
661
|
+
// (`PromptAnswerAbortedError`), or failed after the grant went — is not a
|
|
662
|
+
// failure of the poller that now holds the key, and not an answer either.
|
|
663
|
+
if (generation !== undefined && !(0, auto_yes_poller_generation_1.isTickCurrent)(generation)) {
|
|
664
|
+
// A stop with keys already on the pane: the next tick must not type the
|
|
665
|
+
// answer again over them (step 2.5). Recorded under the attempt's key as
|
|
666
|
+
// it is now — the new one when a worktree ID move carried it (#3713).
|
|
667
|
+
if (attempt !== null)
|
|
668
|
+
(0, auto_yes_poller_state_1.settleSendAttempt)(attempt, keysSent === true);
|
|
669
|
+
if (sendInFlight)
|
|
670
|
+
(0, auto_yes_poller_receipt_log_1.noteAnswerSent)(cliToolId, worktreeId, instanceId, true, receiptEpisode);
|
|
671
|
+
logger.info('poller:auto-yes-answer-abandoned', { worktreeId, cliToolId, instanceId, keysSent });
|
|
672
|
+
return 'no_answer';
|
|
673
|
+
}
|
|
674
|
+
if (attempt !== null)
|
|
675
|
+
(0, auto_yes_poller_state_1.settleSendAttempt)(attempt, false);
|
|
676
|
+
if (sendInFlight)
|
|
677
|
+
(0, auto_yes_poller_receipt_log_1.noteAnswerSent)(cliToolId, worktreeId, instanceId, true, receiptEpisode);
|
|
678
|
+
incrementErrorCount(compositeKey, generation?.pollerState);
|
|
679
|
+
logger.warn('poller:detect-respond-error', { worktreeId, cliToolId, instanceId });
|
|
680
|
+
return 'error';
|
|
681
|
+
}
|
|
914
682
|
/**
|
|
915
683
|
* Detect prompt in terminal output, resolve auto-answer, and send response.
|
|
916
684
|
*
|
|
@@ -940,6 +708,10 @@ async function detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, clea
|
|
|
940
708
|
// the send short, and the agy receipt gate is told so (`noteAnswerSent`).
|
|
941
709
|
let sendInFlight = false;
|
|
942
710
|
let receiptEpisode = null;
|
|
711
|
+
// Issue #3820: the ledger's tick. A tick that read the screen and saw no
|
|
712
|
+
// confirmation closes the open one as gone when it ends (`endLedgerTick`).
|
|
713
|
+
const ledgerScope = { compositeKey, worktreeId, cliToolId, instanceId };
|
|
714
|
+
const ledgerTick = (0, auto_yes_confirmation_ledger_1.beginLedgerTick)(ledgerScope);
|
|
943
715
|
try {
|
|
944
716
|
// 1. Detect prompt.
|
|
945
717
|
//
|
|
@@ -980,52 +752,38 @@ async function detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, clea
|
|
|
980
752
|
// machine whose hook does not reach us. The price is that Auto-Yes leaves
|
|
981
753
|
// such a machine's dialogs alone, which is why `logIfWithheldForWantOfReceipt`
|
|
982
754
|
// says so.
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
const epoch = (0, auto_yes_enter_fallback_1.getEnterFallbackSessionEpoch)(compositeKey);
|
|
986
|
-
if ((pollerState.enterFallbackEpoch ?? 0) !== epoch) {
|
|
987
|
-
pollerState.enterFallbackSentKey = null;
|
|
988
|
-
pollerState.enterFallbackCandidateKey = null;
|
|
989
|
-
pollerState.enterFallbackEpoch = epoch;
|
|
990
|
-
}
|
|
991
|
-
const receiptScope = { worktreeId, instanceId };
|
|
992
|
-
// Issue #3183: the ONE frame every judgement below reads — normalised once,
|
|
993
|
-
// from the capture as captured (the input-box markers are rule rows the
|
|
994
|
-
// cleaned spelling has blanked), and handed as the same object to the
|
|
995
|
-
// prompt reading, the codex launch guards and the dialog gate. That is what
|
|
996
|
-
// makes "the status chain and Auto-Yes read the same live region" a fact
|
|
997
|
-
// rather than a hope: there is no second normalisation to disagree with.
|
|
998
|
-
const frame = (0, frame_1.normalizeFrame)(rawOutput ?? cleanOutput, cliToolId);
|
|
999
|
-
// Issue #3767: bracket the read so the receipt gate can tell when an agy
|
|
1000
|
-
// dialog first appeared, not only what time this tick is.
|
|
1001
|
-
if (cliToolId === 'antigravity')
|
|
1002
|
-
(0, antigravity_receipt_episodes_1.beginAntigravityFrameRead)(worktreeId, instanceId);
|
|
1003
|
-
const promptDetection = (0, response_checker_1.detectPromptOnCleanFrame)(cleanOutput, cliToolId, precomputedLines, rawOutput, receiptScope, frame);
|
|
1004
|
-
if (cliToolId === 'antigravity')
|
|
1005
|
-
(0, antigravity_receipt_episodes_1.endAntigravityFrameRead)(worktreeId, instanceId);
|
|
755
|
+
const epoch = (0, auto_yes_poller_enter_fallback_1.syncEnterFallbackEpoch)(compositeKey, pollerState);
|
|
756
|
+
const { frame, promptDetection } = readPromptFrame(worktreeId, cliToolId, cleanOutput, precomputedLines, instanceId, rawOutput);
|
|
1006
757
|
if (!promptDetection.isPrompt || !promptDetection.promptData) {
|
|
1007
|
-
(
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
}
|
|
1019
|
-
pollerState.lastSkipWarnKey = null;
|
|
1020
|
-
if (cliToolId === 'antigravity' && !promptDetection.isPrompt) {
|
|
1021
|
-
logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, () => (0, response_checker_1.detectPromptOnCleanFrame)(cleanOutput, cliToolId, precomputedLines, rawOutput));
|
|
1022
|
-
}
|
|
758
|
+
noteNoPromptOnScreen({
|
|
759
|
+
worktreeId,
|
|
760
|
+
cliToolId,
|
|
761
|
+
instanceId,
|
|
762
|
+
compositeKey,
|
|
763
|
+
pollerState,
|
|
764
|
+
frame,
|
|
765
|
+
promptDetection,
|
|
766
|
+
cleanOutput,
|
|
767
|
+
precomputedLines,
|
|
768
|
+
rawOutput,
|
|
769
|
+
});
|
|
1023
770
|
return 'no_prompt';
|
|
1024
771
|
}
|
|
772
|
+
// Issue #3820: computed here, before the duplicate check, so the ledger
|
|
773
|
+
// sees the confirmation on every tick it is on screen (step 2.5 below
|
|
774
|
+
// reads the same key).
|
|
775
|
+
// The ledger's own key keeps the body (`ledgerScreenKey`): two commands
|
|
776
|
+
// that differ by a `>` or an indent are two confirmations to count.
|
|
777
|
+
const screenKey = (0, auto_yes_poller_state_1.partialAnswerScreenKey)(promptDetection.promptData);
|
|
778
|
+
// agy (PR 3): tied to the call the receipt that let it through asked about.
|
|
779
|
+
(0, auto_yes_confirmation_ledger_1.observeLedgerScreen)(ledgerScope, (0, auto_yes_poller_state_1.ledgerScreenKey)(promptDetection.promptData), promptDetection.promptData.type, ledgerCallOf(cliToolId, worktreeId, instanceId));
|
|
1025
780
|
// 2. Check for duplicate prompt (Issue #306)
|
|
1026
781
|
const promptKey = (0, prompt_key_1.generatePromptKey)(promptDetection.promptData);
|
|
1027
782
|
const frameKey = (0, auto_yes_poller_state_1.promptFrameKey)(promptDetection.promptData);
|
|
1028
|
-
if (isDuplicatePrompt(pollerState, promptKey)) {
|
|
783
|
+
if ((0, auto_yes_poller_generation_1.isDuplicatePrompt)(pollerState, promptKey)) {
|
|
784
|
+
// Issue #3820: not answered on this tick either — an interval of its own
|
|
785
|
+
// reason, so the count can tell the wait for an answer to land apart.
|
|
786
|
+
(0, auto_yes_confirmation_ledger_1.withholdLedgerConfirmation)(ledgerScope, 'answered-recently');
|
|
1029
787
|
return 'duplicate';
|
|
1030
788
|
}
|
|
1031
789
|
const judged = {
|
|
@@ -1046,27 +804,7 @@ async function detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, clea
|
|
|
1046
804
|
// (`partialAnswerScreenKey`: options and approvalTarget count, the cursor
|
|
1047
805
|
// does not), or the session is relaunched. Recorded as a suppression, so
|
|
1048
806
|
// the prompt Push and `cmate wait` see "withheld", not "answering".
|
|
1049
|
-
|
|
1050
|
-
const partial = (0, auto_yes_poller_state_1.getPartialAnswer)(compositeKey, epoch);
|
|
1051
|
-
if (partial !== null) {
|
|
1052
|
-
if (partial.screenKey === screenKey) {
|
|
1053
|
-
(0, auto_yes_prompt_suppression_1.suppressAndWarnOnce)(judged, {
|
|
1054
|
-
reason: auto_yes_suppression_reason_1.PARTIAL_ANSWER_SUPPRESSION_REASON,
|
|
1055
|
-
mode: null,
|
|
1056
|
-
promptType: promptDetection.promptData.type,
|
|
1057
|
-
}, `${frameKey}\u0000partial-answer`, 'poller:auto-yes-skipped-partial-answer', { promptType: promptDetection.promptData.type, stoppedAt: partial.at });
|
|
1058
|
-
return 'no_answer';
|
|
1059
|
-
}
|
|
1060
|
-
// Another prompt is on screen: only the sends at the forgotten one's
|
|
1061
|
-
// screen go with it (#3713) — one in flight at this screen keeps its hold.
|
|
1062
|
-
(0, auto_yes_poller_state_1.forgetPartialAnswer)(compositeKey, partial.screenKey);
|
|
1063
|
-
}
|
|
1064
|
-
// Issue #3713: a worktree ID move carried an answer still being sent to
|
|
1065
|
-
// this session's key. Its keys may already be on the pane, and how its send
|
|
1066
|
-
// ends is not known yet — so this screen gets no keys until it comes back
|
|
1067
|
-
// (recorded as a partial answer above, or gone).
|
|
1068
|
-
if ((0, auto_yes_poller_state_1.hasMovedSendInFlight)(compositeKey, epoch, screenKey)) {
|
|
1069
|
-
(0, auto_yes_poller_state_1.warnOncePerFrame)(pollerState, `${frameKey}\u0000moved-send-in-flight`, 'poller:auto-yes-skipped-moved-send-in-flight', { worktreeId, cliToolId, instanceId, promptType: promptDetection.promptData.type });
|
|
807
|
+
if ((0, auto_yes_poller_steps_1.withheldForEarlierSend)(judged, screenKey, epoch)) {
|
|
1070
808
|
return 'no_answer';
|
|
1071
809
|
}
|
|
1072
810
|
// 3., 3.2., 3.5. Frames that are not Auto-Yes's to answer: see
|
|
@@ -1092,25 +830,7 @@ async function detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, clea
|
|
|
1092
830
|
// auto-answer: a prompt the policy withholds is left for a human, and the
|
|
1093
831
|
// response poller's prompt path (WS broadcast + Web Push, see
|
|
1094
832
|
// polling/response-checker.ts) is what tells them it is waiting.
|
|
1095
|
-
const
|
|
1096
|
-
const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(promptDetection.promptData, policy);
|
|
1097
|
-
if (resolution.suppressedBy) {
|
|
1098
|
-
// Issue #1684: the log line alone leaves a CLI-driven pipeline blind to
|
|
1099
|
-
// why its worker stalled. Record the suppression so buildCurrentOutput
|
|
1100
|
-
// can publish it (`autoYes.lastSuppression` in capture --json).
|
|
1101
|
-
(0, auto_yes_prompt_suppression_1.suppressAndWarnOnce)(judged, {
|
|
1102
|
-
reason: resolution.suppressedBy,
|
|
1103
|
-
mode: policy?.mode ?? null,
|
|
1104
|
-
promptType: promptDetection.promptData.type,
|
|
1105
|
-
pattern: resolution.pattern,
|
|
1106
|
-
}, `${frameKey}\u0000${resolution.suppressedBy}\u0000${policy?.mode ?? ''}\u0000${resolution.pattern ?? ''}`, 'poller:auto-yes-suppressed-by-policy', {
|
|
1107
|
-
reason: resolution.suppressedBy,
|
|
1108
|
-
mode: policy?.mode ?? null,
|
|
1109
|
-
pattern: resolution.pattern,
|
|
1110
|
-
promptType: promptDetection.promptData.type,
|
|
1111
|
-
});
|
|
1112
|
-
}
|
|
1113
|
-
const answer = resolution.answer;
|
|
833
|
+
const answer = (0, auto_yes_poller_steps_1.resolveAnswerUnderPolicy)(judged);
|
|
1114
834
|
if (answer === null) {
|
|
1115
835
|
return 'no_answer';
|
|
1116
836
|
}
|
|
@@ -1121,21 +841,17 @@ async function detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, clea
|
|
|
1121
841
|
// Issue #2865: never auto-answer a same-named session another CommandMate
|
|
1122
842
|
// server created. The poller keeps running; it just does not type.
|
|
1123
843
|
const ownership = await (0, worktree_session_ownership_1.checkWorktreeSessionOwnership)(worktreeId, sessionName);
|
|
1124
|
-
if (generation !== undefined && !isTickCurrent(generation))
|
|
844
|
+
if (generation !== undefined && !(0, auto_yes_poller_generation_1.isTickCurrent)(generation))
|
|
1125
845
|
return 'no_answer';
|
|
1126
|
-
if (
|
|
1127
|
-
(0, auto_yes_poller_state_1.warnOncePerFrame)(pollerState, `${frameKey}\u0000${sessionName}\u0000${ownership ? 'foreign' : 'worktree_not_found'}`, 'poller:auto-yes-skipped-foreign-session', {
|
|
1128
|
-
worktreeId,
|
|
1129
|
-
cliToolId,
|
|
1130
|
-
instanceId,
|
|
1131
|
-
sessionName,
|
|
1132
|
-
sessionPath: ownership?.sessionPath ?? null,
|
|
1133
|
-
reason: ownership ? 'foreign' : 'worktree_not_found',
|
|
1134
|
-
});
|
|
846
|
+
if ((0, auto_yes_poller_steps_1.skippedForUnownedSession)(judged, sessionName, ownership)) {
|
|
1135
847
|
return 'no_answer';
|
|
1136
848
|
}
|
|
1137
|
-
attempt = (0, auto_yes_poller_state_1.beginSendAttempt)(compositeKey, screenKey, generation?.sessionEpoch ?? epoch
|
|
1138
|
-
|
|
849
|
+
attempt = (0, auto_yes_poller_state_1.beginSendAttempt)(compositeKey, screenKey, generation?.sessionEpoch ?? epoch,
|
|
850
|
+
// Issue #3820: an agy prompt read past the gate is one a hook receipt let through.
|
|
851
|
+
(0, auto_yes_confirmation_ledger_1.beginLedgerAttempt)(ledgerScope, answerBasisOf(judged, cleanOutput), {
|
|
852
|
+
receiptAccepted: cliToolId === 'antigravity',
|
|
853
|
+
}));
|
|
854
|
+
receiptEpisode = (0, auto_yes_poller_receipt_log_1.receiptEpisodeOfSend)(cliToolId, worktreeId, instanceId);
|
|
1139
855
|
sendInFlight = true;
|
|
1140
856
|
try {
|
|
1141
857
|
await (0, prompt_answer_sender_1.sendPromptAnswer)({
|
|
@@ -1144,43 +860,35 @@ async function detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, clea
|
|
|
1144
860
|
cliToolId,
|
|
1145
861
|
promptData: promptDetection.promptData,
|
|
1146
862
|
// Issue #3706: asked after each wait inside the send.
|
|
1147
|
-
...(generation !== undefined ? { stillCurrent: () => isTickCurrent(generation) } : {}),
|
|
863
|
+
...(generation !== undefined ? { stillCurrent: () => (0, auto_yes_poller_generation_1.isTickCurrent)(generation) } : {}),
|
|
1148
864
|
});
|
|
1149
865
|
}
|
|
1150
866
|
finally {
|
|
1151
867
|
(0, tmux_capture_cache_1.invalidateCache)(sessionName);
|
|
1152
868
|
}
|
|
1153
869
|
sendInFlight = false;
|
|
870
|
+
(0, auto_yes_confirmation_ledger_1.settleLedgerAttempt)(attempt.ledger, 'ok', { expired: attempt.state === 'expired' });
|
|
1154
871
|
(0, auto_yes_poller_state_1.settleSendAttempt)(attempt, false);
|
|
1155
872
|
// Issue #3796 review E: the episode the send began for, as on the failure side.
|
|
1156
|
-
noteAnswerSent(cliToolId, worktreeId, instanceId, false, receiptEpisode);
|
|
873
|
+
(0, auto_yes_poller_receipt_log_1.noteAnswerSent)(cliToolId, worktreeId, instanceId, false, receiptEpisode);
|
|
1157
874
|
// 6., 7. The answer reached tmux: see `finishAnsweredPrompt`.
|
|
1158
875
|
await finishAnsweredPrompt(judged, promptDetection, answer, generation);
|
|
1159
876
|
return 'responded';
|
|
1160
877
|
}
|
|
1161
878
|
catch (error) {
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
return 'no_answer';
|
|
1176
|
-
}
|
|
1177
|
-
if (attempt !== null)
|
|
1178
|
-
(0, auto_yes_poller_state_1.settleSendAttempt)(attempt, false);
|
|
1179
|
-
if (sendInFlight)
|
|
1180
|
-
noteAnswerSent(cliToolId, worktreeId, instanceId, true, receiptEpisode);
|
|
1181
|
-
incrementErrorCount(compositeKey, generation?.pollerState);
|
|
1182
|
-
logger.warn('poller:detect-respond-error', { worktreeId, cliToolId, instanceId });
|
|
1183
|
-
return 'error';
|
|
879
|
+
return settleFailedTick(error, {
|
|
880
|
+
worktreeId,
|
|
881
|
+
cliToolId,
|
|
882
|
+
instanceId,
|
|
883
|
+
compositeKey,
|
|
884
|
+
generation,
|
|
885
|
+
attempt,
|
|
886
|
+
sendInFlight,
|
|
887
|
+
receiptEpisode,
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
finally {
|
|
891
|
+
(0, auto_yes_confirmation_ledger_1.endLedgerTick)(ledgerScope, ledgerTick);
|
|
1184
892
|
}
|
|
1185
893
|
}
|
|
1186
894
|
/**
|
|
@@ -1195,7 +903,7 @@ async function detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, clea
|
|
|
1195
903
|
async function pollAutoYes(worktreeId, cliToolId, instanceId, owner) {
|
|
1196
904
|
const compositeKey = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
1197
905
|
// 1. Validate context
|
|
1198
|
-
const pollerState = getPollerState(compositeKey);
|
|
906
|
+
const pollerState = (0, auto_yes_poller_generation_1.getPollerState)(compositeKey);
|
|
1199
907
|
if (owner !== undefined && pollerState !== owner)
|
|
1200
908
|
return;
|
|
1201
909
|
const contextResult = validatePollingContext(compositeKey, pollerState);
|
|
@@ -1229,8 +937,8 @@ async function pollAutoYes(worktreeId, cliToolId, instanceId, owner) {
|
|
|
1229
937
|
// step below exactly as it did; the raw one is carried to the prompt reading
|
|
1230
938
|
// so a dialog anchored on box drawing is not invisible to the one path that
|
|
1231
939
|
// can answer it without a human.
|
|
1232
|
-
const { raw: rawOutput, clean: cleanOutput } = await capturePollerFrame(worktreeId, cliToolId, captureLines, instanceId);
|
|
1233
|
-
if (!isTickCurrent(generation)) {
|
|
940
|
+
const { raw: rawOutput, clean: cleanOutput } = await (0, auto_yes_poller_capture_1.capturePollerFrame)(worktreeId, cliToolId, captureLines, instanceId);
|
|
941
|
+
if (!(0, auto_yes_poller_generation_1.isTickCurrent)(generation)) {
|
|
1234
942
|
endStaleTick(generation);
|
|
1235
943
|
return;
|
|
1236
944
|
}
|
|
@@ -1247,7 +955,7 @@ async function pollAutoYes(worktreeId, cliToolId, instanceId, owner) {
|
|
|
1247
955
|
}
|
|
1248
956
|
// 4. Detect and respond to prompt
|
|
1249
957
|
const result = await detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, cleanOutput, lines, instanceId, rawOutput, generation);
|
|
1250
|
-
if (!isTickCurrent(generation)) {
|
|
958
|
+
if (!(0, auto_yes_poller_generation_1.isTickCurrent)(generation)) {
|
|
1251
959
|
endStaleTick(generation);
|
|
1252
960
|
return;
|
|
1253
961
|
}
|
|
@@ -1256,7 +964,7 @@ async function pollAutoYes(worktreeId, cliToolId, instanceId, owner) {
|
|
|
1256
964
|
// over hours. Not on 'error': a capture that works followed by an answer
|
|
1257
965
|
// that fails every time must still back off and stop.
|
|
1258
966
|
if (result !== 'error') {
|
|
1259
|
-
resetErrorCount(compositeKey, generation.pollerState);
|
|
967
|
+
(0, auto_yes_poller_generation_1.resetErrorCount)(compositeKey, generation.pollerState);
|
|
1260
968
|
}
|
|
1261
969
|
if (result === 'responded') {
|
|
1262
970
|
scheduleNextPoll(generation, auto_yes_state_1.COOLDOWN_INTERVAL_MS);
|
|
@@ -1277,7 +985,7 @@ async function pollAutoYes(worktreeId, cliToolId, instanceId, owner) {
|
|
|
1277
985
|
// enables it before the session starts — so wait until `expiresAt`, at the
|
|
1278
986
|
// backoff cap, instead of counting toward `consecutive_errors`.
|
|
1279
987
|
const sessionMissing = await isSessionMissing(worktreeId, cliToolId, instanceId);
|
|
1280
|
-
if (!isTickCurrent(generation)) {
|
|
988
|
+
if (!(0, auto_yes_poller_generation_1.isTickCurrent)(generation)) {
|
|
1281
989
|
endStaleTick(generation);
|
|
1282
990
|
return;
|
|
1283
991
|
}
|
|
@@ -1320,7 +1028,7 @@ async function isSessionMissing(worktreeId, cliToolId, instanceId) {
|
|
|
1320
1028
|
* @param options.sessionWait - The tick waits for a session to appear (Issue #3791)
|
|
1321
1029
|
*/
|
|
1322
1030
|
function scheduleNextPoll(generation, overrideInterval, options = {}) {
|
|
1323
|
-
if (!isPollerCurrent(generation))
|
|
1031
|
+
if (!(0, auto_yes_poller_generation_1.isPollerCurrent)(generation))
|
|
1324
1032
|
return;
|
|
1325
1033
|
const { worktreeId, cliToolId, instanceId, pollerState } = generation;
|
|
1326
1034
|
const interval = Math.max(overrideInterval ?? pollerState.currentInterval, auto_yes_state_1.POLLING_INTERVAL_MS);
|
|
@@ -1373,7 +1081,7 @@ function armSessionWaitWake(generation, timerId) {
|
|
|
1373
1081
|
if (wake === undefined || wake.timerId !== timerId)
|
|
1374
1082
|
return;
|
|
1375
1083
|
sessionWaitWakes.delete(compositeKey);
|
|
1376
|
-
if (!isPollerCurrent(generation) || pollerState.timerId !== timerId)
|
|
1084
|
+
if (!(0, auto_yes_poller_generation_1.isPollerCurrent)(generation) || pollerState.timerId !== timerId)
|
|
1377
1085
|
return;
|
|
1378
1086
|
clearTimeout(timerId);
|
|
1379
1087
|
logger.info('poller:session-created-wake', { worktreeId, cliToolId, instanceId });
|
|
@@ -1416,8 +1124,8 @@ function startAutoYesPolling(worktreeId, cliToolId, instanceId) {
|
|
|
1416
1124
|
}
|
|
1417
1125
|
const compositeKey = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, effectiveInstanceId);
|
|
1418
1126
|
// Check concurrent poller limit (DoS protection)
|
|
1419
|
-
const existingPollerState = getPollerState(compositeKey);
|
|
1420
|
-
if (!existingPollerState && autoYesPollerStates.size >= auto_yes_state_1.MAX_CONCURRENT_POLLERS) {
|
|
1127
|
+
const existingPollerState = (0, auto_yes_poller_generation_1.getPollerState)(compositeKey);
|
|
1128
|
+
if (!existingPollerState && auto_yes_poller_generation_1.autoYesPollerStates.size >= auto_yes_state_1.MAX_CONCURRENT_POLLERS) {
|
|
1421
1129
|
return { started: false, reason: 'max concurrent pollers reached' };
|
|
1422
1130
|
}
|
|
1423
1131
|
// Issue #501: Idempotency check (key already encodes the instance, so a matching
|
|
@@ -1442,7 +1150,7 @@ function startAutoYesPolling(worktreeId, cliToolId, instanceId) {
|
|
|
1442
1150
|
stopCheckBaselineLength: -1,
|
|
1443
1151
|
lastSkipWarnKey: null,
|
|
1444
1152
|
};
|
|
1445
|
-
autoYesPollerStates.set(compositeKey, pollerState);
|
|
1153
|
+
auto_yes_poller_generation_1.autoYesPollerStates.set(compositeKey, pollerState);
|
|
1446
1154
|
// A task may have been recorded moments ago; start from a fresh policy read.
|
|
1447
1155
|
(0, auto_yes_policy_1.invalidateSessionAutoYesPolicy)(compositeKey);
|
|
1448
1156
|
// Start polling immediately
|
|
@@ -1471,14 +1179,17 @@ function stopAutoYesPolling(compositeKey, reason) {
|
|
|
1471
1179
|
// cleanup call this for an instance whose poller may already be gone, and the
|
|
1472
1180
|
// Enter record must not outlive the grant or the session either way.
|
|
1473
1181
|
(0, auto_yes_enter_fallback_1.forgetEnterFallback)(compositeKey);
|
|
1474
|
-
|
|
1182
|
+
// Issue #3820: before the early return too — a session ended after its
|
|
1183
|
+
// poller had already stopped still abandons the confirmation left on it.
|
|
1184
|
+
(0, auto_yes_confirmation_ledger_1.noteLedgerPollerStopped)(compositeKey, (0, auto_yes_poller_stop_reason_1.resolvePollerStopReason)(reason, 'unspecified'));
|
|
1185
|
+
const pollerState = (0, auto_yes_poller_generation_1.getPollerState)(compositeKey);
|
|
1475
1186
|
if (!pollerState)
|
|
1476
1187
|
return;
|
|
1477
1188
|
if (pollerState.timerId) {
|
|
1478
1189
|
clearTimeout(pollerState.timerId);
|
|
1479
1190
|
}
|
|
1480
1191
|
dropSessionWaitWake(compositeKey);
|
|
1481
|
-
autoYesPollerStates.delete(compositeKey);
|
|
1192
|
+
auto_yes_poller_generation_1.autoYesPollerStates.delete(compositeKey);
|
|
1482
1193
|
(0, auto_yes_policy_1.invalidateSessionAutoYesPolicy)(compositeKey);
|
|
1483
1194
|
logger.info('poller:stopped', { compositeKey, reason: (0, auto_yes_poller_stop_reason_1.resolvePollerStopReason)(reason, 'unspecified') });
|
|
1484
1195
|
}
|
|
@@ -1492,15 +1203,16 @@ function stopAutoYesPolling(compositeKey, reason) {
|
|
|
1492
1203
|
*/
|
|
1493
1204
|
function stopAllAutoYesPolling() {
|
|
1494
1205
|
const reason = (0, auto_yes_poller_stop_reason_1.resolvePollerStopReason)(undefined, 'shutdown');
|
|
1495
|
-
for (const [key, pollerState] of autoYesPollerStates.entries()) {
|
|
1206
|
+
for (const [key, pollerState] of auto_yes_poller_generation_1.autoYesPollerStates.entries()) {
|
|
1496
1207
|
if (pollerState.timerId) {
|
|
1497
1208
|
clearTimeout(pollerState.timerId);
|
|
1498
1209
|
}
|
|
1499
1210
|
dropSessionWaitWake(key);
|
|
1500
1211
|
(0, auto_yes_policy_1.invalidateSessionAutoYesPolicy)(key);
|
|
1212
|
+
(0, auto_yes_confirmation_ledger_1.noteLedgerPollerStopped)(key, reason);
|
|
1501
1213
|
logger.info('poller:stopped', { compositeKey: key, reason });
|
|
1502
1214
|
}
|
|
1503
|
-
autoYesPollerStates.clear();
|
|
1215
|
+
auto_yes_poller_generation_1.autoYesPollerStates.clear();
|
|
1504
1216
|
(0, auto_yes_enter_fallback_1.clearEnterFallbacks)();
|
|
1505
1217
|
(0, auto_yes_poller_state_1.clearPartialAnswers)();
|
|
1506
1218
|
}
|
|
@@ -1512,7 +1224,7 @@ function stopAllAutoYesPolling() {
|
|
|
1512
1224
|
* @returns Array of composite keys present in the autoYesPollerStates Map
|
|
1513
1225
|
*/
|
|
1514
1226
|
function getAutoYesPollerCompositeKeys() {
|
|
1515
|
-
return Array.from(autoYesPollerStates.keys());
|
|
1227
|
+
return Array.from(auto_yes_poller_generation_1.autoYesPollerStates.keys());
|
|
1516
1228
|
}
|
|
1517
1229
|
// =============================================================================
|
|
1518
1230
|
// byWorktree Helpers (Issue #525)
|
|
@@ -1531,11 +1243,14 @@ function getAutoYesPollerCompositeKeys() {
|
|
|
1531
1243
|
* `auto-yes-lifecycle`), both are dropped and a late send records nothing.
|
|
1532
1244
|
*/
|
|
1533
1245
|
function stopAutoYesPollingByWorktree(worktreeId, options) {
|
|
1534
|
-
const pollerKeys = (0, auto_yes_state_1.filterCompositeKeysByWorktree)(Array.from(autoYesPollerStates.keys()), worktreeId);
|
|
1246
|
+
const pollerKeys = (0, auto_yes_state_1.filterCompositeKeysByWorktree)(Array.from(auto_yes_poller_generation_1.autoYesPollerStates.keys()), worktreeId);
|
|
1535
1247
|
// Issue #3730: `options.reason`, else the enclosing scope's (the lifecycle table).
|
|
1536
1248
|
pollerKeys.forEach(key => stopAutoYesPolling(key, options?.reason));
|
|
1537
1249
|
// Issue #3397: and the records of instances whose poller had already stopped.
|
|
1538
1250
|
(0, auto_yes_enter_fallback_1.forgetEnterFallbacksByWorktree)(worktreeId);
|
|
1251
|
+
// Issue #3820: and the ledger's confirmations on them — an API approval is
|
|
1252
|
+
// opened with Auto-Yes off too, so the running pollers do not name them all.
|
|
1253
|
+
(0, auto_yes_confirmation_ledger_1.noteLedgerWorktreeStopped)(worktreeId, (0, auto_yes_poller_stop_reason_1.resolvePollerStopReason)(options?.reason, 'unspecified'));
|
|
1539
1254
|
if (!options?.keepPartialAnswers)
|
|
1540
1255
|
(0, auto_yes_poller_state_1.forgetPartialAnswersByWorktree)(worktreeId);
|
|
1541
1256
|
}
|
|
@@ -1547,5 +1262,5 @@ function stopAutoYesPollingByWorktree(worktreeId, options) {
|
|
|
1547
1262
|
* @returns true if any poller is active for this worktree
|
|
1548
1263
|
*/
|
|
1549
1264
|
function isAnyPollerActiveForWorktree(worktreeId) {
|
|
1550
|
-
return (0, auto_yes_state_1.filterCompositeKeysByWorktree)(Array.from(autoYesPollerStates.keys()), worktreeId).length > 0;
|
|
1265
|
+
return (0, auto_yes_state_1.filterCompositeKeysByWorktree)(Array.from(auto_yes_poller_generation_1.autoYesPollerStates.keys()), worktreeId).length > 0;
|
|
1551
1266
|
}
|