commandmate 0.44.1 → 0.44.3
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 +169 -169
- package/.next/app-path-routes-manifest.json +35 -35
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +3 -3
- package/.next/react-loadable-manifest.json +0 -6
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/update/route.js +1 -1
- package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/versions/route.js +1 -1
- package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/release-notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route.js +2 -2
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route.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_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js +2 -2
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route.js +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route.js +2 -2
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/route.js +1 -1
- package/.next/server/app/api/relays/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route.js +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route.js +2 -2
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route.js +2 -2
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +3 -3
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +2 -2
- 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_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -2
- 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 -2
- 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]/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 +2 -2
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +3 -3
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +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_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +1 -1
- package/.next/server/app/sessions/page.js.nft.json +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +11 -11
- package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +35 -35
- package/.next/server/chunks/1191.js +2 -2
- package/.next/server/chunks/1210.js +1 -1
- package/.next/server/chunks/1559.js +2 -0
- package/.next/server/chunks/1789.js +1 -0
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/2460.js +1 -0
- package/.next/server/chunks/2710.js +1 -1
- package/.next/server/chunks/2908.js +1 -0
- package/.next/server/chunks/2980.js +1 -1
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3480.js +1 -1
- package/.next/server/chunks/3718.js +1 -1
- package/.next/server/chunks/4207.js +2 -2
- package/.next/server/chunks/450.js +1 -1
- package/.next/server/chunks/4672.js +5 -0
- package/.next/server/chunks/{9353.js → 4718.js} +2 -2
- package/.next/server/chunks/4837.js +14 -0
- package/.next/server/chunks/5048.js +1 -1
- package/.next/server/chunks/5209.js +1 -0
- package/.next/server/chunks/5595.js +1 -0
- package/.next/server/chunks/5625.js +25 -0
- package/.next/server/chunks/5845.js +1 -0
- package/.next/server/chunks/611.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/6793.js +3 -3
- package/.next/server/chunks/7491.js +2 -2
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/850.js +1 -0
- package/.next/server/chunks/8543.js +1 -1
- package/.next/server/chunks/8728.js +3 -3
- package/.next/server/chunks/8791.js +1 -1
- package/.next/server/chunks/8800.js +1 -1
- package/.next/server/chunks/8918.js +7 -7
- package/.next/server/chunks/9130.js +1 -5
- package/.next/server/chunks/9390.js +2 -3
- package/.next/server/chunks/9584.js +1 -1
- package/.next/server/chunks/9627.js +6 -6
- package/.next/server/chunks/9731.js +3 -3
- 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/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{1642-fb2e176aaadbd137.js → 1642-767aed8e7c61ef7f.js} +1 -1
- package/.next/static/chunks/{2407-f1f258d4a1d92620.js → 2407-06d35bb1aa02de80.js} +1 -1
- package/.next/static/chunks/{2619-04bc32f026a0d946.js → 2619-a305ad4810f1393a.js} +1 -1
- package/.next/static/chunks/4727-5d695d71e3fdf97b.js +1 -0
- package/.next/static/chunks/{8165-3853772f6ae1299b.js → 8165-3525fb42f1b4976e.js} +1 -1
- package/.next/static/chunks/app/{layout-da66300cc20244ed.js → layout-0d1750b833f5cc3e.js} +1 -1
- package/.next/static/chunks/app/sessions/page-2af68c63211c751f.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-e36898c3a80e7302.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/terminal/{page-373ea37b16d930c7.js → page-c601f3b3ece6557e.js} +1 -1
- package/.next/static/css/057f64a65726c439.css +1 -0
- package/.next/trace +13 -13
- package/dist/cli/commands/ask.d.ts.map +1 -1
- package/dist/cli/commands/ask.js +120 -119
- package/dist/cli/commands/attach.d.ts +94 -0
- package/dist/cli/commands/attach.d.ts.map +1 -1
- package/dist/cli/commands/attach.js +145 -7
- package/dist/cli/commands/auto-yes.js +1 -1
- package/dist/cli/commands/capture.d.ts.map +1 -1
- package/dist/cli/commands/capture.js +10 -13
- package/dist/cli/commands/command-target.d.ts +23 -0
- package/dist/cli/commands/command-target.d.ts.map +1 -0
- package/dist/cli/commands/command-target.js +25 -0
- package/dist/cli/commands/instances.d.ts.map +1 -1
- package/dist/cli/commands/instances.js +41 -2
- package/dist/cli/commands/message-dispatch.d.ts +36 -0
- package/dist/cli/commands/message-dispatch.d.ts.map +1 -0
- package/dist/cli/commands/message-dispatch.js +63 -0
- package/dist/cli/commands/reply.d.ts.map +1 -1
- package/dist/cli/commands/reply.js +2 -5
- package/dist/cli/commands/respond.d.ts.map +1 -1
- package/dist/cli/commands/respond.js +3 -6
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +149 -146
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +608 -416
- package/dist/cli/types/api-responses.d.ts +174 -27
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/types/api-responses.js +4 -2
- package/dist/cli/utils/api-client.d.ts +25 -5
- package/dist/cli/utils/api-client.d.ts.map +1 -1
- package/dist/cli/utils/api-client.js +87 -55
- package/dist/cli/utils/server-url.d.ts +1 -0
- package/dist/cli/utils/server-url.d.ts.map +1 -1
- package/dist/cli/utils/server-url.js +7 -0
- package/dist/config/uat-isolation.d.ts +140 -0
- package/dist/config/uat-isolation.d.ts.map +1 -0
- package/dist/config/uat-isolation.js +246 -0
- package/dist/lib/global-state.d.ts +12 -0
- package/dist/lib/global-state.d.ts.map +1 -0
- package/dist/lib/global-state.js +16 -0
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts +33 -0
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts.map +1 -0
- package/dist/lib/polling/auto-yes-suppression-reason.js +2 -0
- package/dist/lib/session/prompt-view.d.ts +228 -0
- package/dist/lib/session/prompt-view.d.ts.map +1 -0
- package/dist/lib/session/prompt-view.js +290 -0
- package/dist/lib/session/status-evidence-type.d.ts +16 -0
- package/dist/lib/session/status-evidence-type.d.ts.map +1 -0
- package/dist/lib/session/status-evidence-type.js +2 -0
- package/dist/lib/tmux/legacy-session-alias.d.ts.map +1 -1
- package/dist/lib/tmux/legacy-session-alias.js +2 -1
- package/dist/server/locales/en/worktree.json +3 -1
- package/dist/server/locales/ja/worktree.json +3 -1
- package/dist/server/server.js +5 -3
- package/dist/server/src/cli/types/api-responses.js +4 -2
- package/dist/server/src/config/cli-tool-timing-config.js +1 -6
- package/dist/server/src/config/uat-isolation.js +246 -0
- package/dist/server/src/lib/assistant-response-saver.js +62 -3
- package/dist/server/src/lib/auto-yes-lifecycle.js +139 -0
- package/dist/server/src/lib/auto-yes-poller.js +465 -160
- package/dist/server/src/lib/auto-yes-state.js +2 -2
- package/dist/server/src/lib/cli-tools/antigravity.js +39 -80
- package/dist/server/src/lib/cli-tools/base.js +151 -0
- package/dist/server/src/lib/cli-tools/codex.js +44 -80
- package/dist/server/src/lib/cli-tools/command-code.js +24 -56
- package/dist/server/src/lib/cli-tools/copilot.js +25 -67
- package/dist/server/src/lib/cli-tools/direct-input.js +8 -0
- package/dist/server/src/lib/cli-tools/gemini.js +23 -73
- package/dist/server/src/lib/cli-tools/opencode-pane-width.js +53 -0
- package/dist/server/src/lib/cli-tools/opencode-v2.js +9 -7
- package/dist/server/src/lib/cli-tools/opencode.js +21 -85
- package/dist/server/src/lib/cli-tools/submit-verified-sender.js +127 -4
- package/dist/server/src/lib/cli-tools/vibe-local.js +21 -66
- package/dist/server/src/lib/detection/cli-patterns.js +374 -3047
- package/dist/server/src/lib/detection/idle-evidence-observation.js +2 -2
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +7 -32
- package/dist/server/src/lib/detection/prompt-detector.js +2 -35
- package/dist/server/src/lib/detection/selection-shape-patterns.js +69 -0
- package/dist/server/src/lib/detection/selection-shape.js +32 -520
- package/dist/server/src/lib/detection/shared/pasted-text.js +41 -0
- package/dist/server/src/lib/detection/shared/shell-pane-command.js +16 -0
- package/dist/server/src/lib/detection/shared/strip-box-drawing.js +25 -0
- package/dist/server/src/lib/detection/status-detector.js +1 -1
- package/dist/server/src/lib/detection/tools/antigravity/detect.js +12 -60
- package/dist/server/src/lib/detection/tools/antigravity/dialog.js +2 -15
- package/dist/server/src/lib/detection/tools/antigravity/live-region.js +39 -0
- package/dist/server/src/lib/detection/tools/antigravity/patterns.js +286 -0
- package/dist/server/src/lib/detection/tools/claude/detect.js +11 -17
- package/dist/server/src/lib/detection/tools/claude/live-region.js +26 -0
- package/dist/server/src/lib/detection/tools/claude/patterns.js +264 -4
- package/dist/server/src/lib/detection/tools/claude/prompt.js +2 -10
- package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +1 -1
- package/dist/server/src/lib/detection/tools/codex/detect.js +71 -130
- package/dist/server/src/lib/detection/tools/codex/live-region.js +104 -0
- package/dist/server/src/lib/detection/tools/codex/patterns.js +855 -0
- package/dist/server/src/lib/detection/tools/codex/prompt.js +2 -10
- package/dist/server/src/lib/detection/tools/command-code/detect.js +19 -50
- package/dist/server/src/lib/detection/tools/command-code/dialog.js +2 -18
- package/dist/server/src/lib/detection/tools/command-code/live-region.js +36 -0
- package/dist/server/src/lib/detection/tools/command-code/patterns.js +234 -0
- package/dist/server/src/lib/detection/tools/command-code/selection-shape.js +461 -0
- package/dist/server/src/lib/detection/tools/context-above.js +20 -0
- package/dist/server/src/lib/detection/tools/copilot/detect.js +13 -35
- package/dist/server/src/lib/detection/tools/copilot/live-region.js +52 -0
- package/dist/server/src/lib/detection/tools/copilot/patterns.js +640 -0
- package/dist/server/src/lib/detection/tools/copilot/prompt.js +2 -10
- package/dist/server/src/lib/detection/tools/frame.js +36 -2
- package/dist/server/src/lib/detection/tools/gemini/patterns.js +29 -0
- package/dist/server/src/lib/detection/tools/live-region-specs.js +31 -0
- package/dist/server/src/lib/detection/tools/live-region.js +204 -0
- package/dist/server/src/lib/detection/tools/opencode/detect.js +11 -49
- package/dist/server/src/lib/detection/tools/opencode/live-region.js +24 -0
- package/dist/server/src/lib/detection/tools/opencode/patterns.js +508 -0
- package/dist/server/src/lib/detection/tools/opencode-gutter-live-region.js +72 -0
- package/dist/server/src/lib/detection/tools/opencode-v2/detect.js +10 -42
- package/dist/server/src/lib/detection/tools/opencode-v2/live-region.js +24 -0
- package/dist/server/src/lib/detection/tools/opencode-v2/patterns.js +63 -0
- package/dist/server/src/lib/detection/tools/run-detection.js +31 -50
- package/dist/server/src/lib/detection/tools/verdicts.js +59 -0
- package/dist/server/src/lib/detection/tools/vibe-local/patterns.js +20 -0
- package/dist/server/src/lib/detection/truncate-raw-content.js +38 -0
- package/dist/server/src/lib/detection/turn-abandoned.js +66 -0
- package/dist/server/src/lib/detection/unclassified-frame-tracker.js +2 -2
- package/dist/server/src/lib/global-state.js +16 -0
- package/dist/server/src/lib/hooks/agent-session-telemetry.js +4 -6
- package/dist/server/src/lib/hooks/permission-decision-state.js +2 -2
- package/dist/server/src/lib/hooks/sources/antigravity/history.js +11 -76
- package/dist/server/src/lib/hooks/sources/antigravity/hooks-config.js +63 -1
- package/dist/server/src/lib/hooks/sources/antigravity/source.js +16 -0
- package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +3 -12
- package/dist/server/src/lib/hooks/sources/claude/history.js +17 -156
- package/dist/server/src/lib/hooks/sources/claude/queued-notice.js +53 -0
- package/dist/server/src/lib/hooks/sources/claude/source.js +33 -3
- package/dist/server/src/lib/hooks/sources/claude/transcript.js +3 -13
- package/dist/server/src/lib/hooks/sources/codex/history.js +11 -74
- package/dist/server/src/lib/hooks/sources/codex/hooks-config.js +147 -11
- package/dist/server/src/lib/hooks/sources/codex/relay-install.js +64 -21
- package/dist/server/src/lib/hooks/sources/codex/transcript.js +5 -15
- package/dist/server/src/lib/hooks/sources/command-code/history.js +20 -121
- package/dist/server/src/lib/hooks/sources/command-code/transcript.js +3 -13
- package/dist/server/src/lib/hooks/sources/copilot/hook-settings.js +161 -31
- package/dist/server/src/lib/hooks/sources/define-source.js +40 -55
- package/dist/server/src/lib/hooks/sources/event-mapper.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode/diff.js +3 -4
- package/dist/server/src/lib/hooks/sources/opencode/history.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode/launch-settings.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode/payloads.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode/ports.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode/subscription.js +4 -3
- package/dist/server/src/lib/hooks/sources/opencode/transcript.js +3 -16
- package/dist/server/src/lib/hooks/sources/opencode-v2/history.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode-v2/mappers.js +5 -4
- package/dist/server/src/lib/hooks/sources/opencode-v2/ports.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode-v2/subscription.js +3 -7
- package/dist/server/src/lib/hooks/sources/opencode-v2/usage.js +2 -1
- package/dist/server/src/lib/hooks/sources/pending-decisions.js +2 -1
- package/dist/server/src/lib/hooks/sources/registry.js +3 -2
- package/dist/server/src/lib/hooks/sources/transcript-history.js +262 -0
- package/dist/server/src/lib/hooks/sources/turn-body.js +31 -0
- package/dist/server/src/lib/hooks/tool-input-normalization-state.js +2 -2
- package/dist/server/src/lib/polling/antigravity-permission-receipts.js +2 -2
- package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +16 -4
- package/dist/server/src/lib/polling/auto-yes-enter-fallback-state.js +142 -0
- package/dist/server/src/lib/polling/auto-yes-enter-fallback.js +187 -0
- package/dist/server/src/lib/polling/auto-yes-resolver.js +9 -3
- package/dist/server/src/lib/polling/auto-yes-suppression-reason.js +2 -0
- package/dist/server/src/lib/polling/auto-yes-suppression-state.js +2 -2
- package/dist/server/src/lib/polling/pending-scraped-response.js +190 -0
- package/dist/server/src/lib/polling/prompt-dedup-state.js +2 -2
- package/dist/server/src/lib/polling/prompt-dedup.js +2 -2
- package/dist/server/src/lib/polling/response-checker-dialog-gate.js +95 -0
- package/dist/server/src/lib/polling/response-checker-extraction-result.js +50 -0
- package/dist/server/src/lib/polling/response-checker-extraction-steps.js +670 -0
- package/dist/server/src/lib/polling/response-checker.js +666 -1162
- package/dist/server/src/lib/polling/response-dedup.js +3 -4
- package/dist/server/src/lib/polling/response-poller-constants.js +17 -0
- package/dist/server/src/lib/polling/response-poller-core.js +54 -20
- package/dist/server/src/lib/polling/startup-screen.js +142 -0
- package/dist/server/src/lib/polling/structured-history-gate.js +3 -2
- package/dist/server/src/lib/prompt-answer-semantic.js +178 -0
- package/dist/server/src/lib/prompt-answer-sender.js +6 -5
- package/dist/server/src/lib/push/failure-episode-state.js +2 -2
- package/dist/server/src/lib/push/notification-dedup.js +3 -4
- package/dist/server/src/lib/push/prompt-card-state.js +2 -2
- package/dist/server/src/lib/push/waiting-push-notifier.js +3 -4
- package/dist/server/src/lib/realtime/publisher-registry.js +3 -2
- package/dist/server/src/lib/realtime/terminal-broadcast.js +38 -2
- package/dist/server/src/lib/realtime/terminal-session-ownership.js +45 -0
- package/dist/server/src/lib/relay/relay-delivery.js +6 -2
- package/dist/server/src/lib/relay/relay-readiness.js +38 -1
- package/dist/server/src/lib/relay/relay-triggers.js +9 -0
- package/dist/server/src/lib/resource-cleanup.js +6 -4
- package/dist/server/src/lib/response-cleaner.js +24 -1
- package/dist/server/src/lib/response-extractor.js +16 -0
- package/dist/server/src/lib/schedule-manager.js +8 -10
- package/dist/server/src/lib/session/agent-event-ask-user-question.js +168 -0
- package/dist/server/src/lib/session/agent-event-awaiting-instruction.js +104 -0
- package/dist/server/src/lib/session/agent-event-dedup.js +539 -0
- package/dist/server/src/lib/session/agent-event-model.js +562 -0
- package/dist/server/src/lib/session/agent-event-record.js +10 -0
- package/dist/server/src/lib/session/agent-event-state.js +106 -1854
- package/dist/server/src/lib/session/agent-event-structured-state.js +109 -0
- package/dist/server/src/lib/session/agent-event-turn.js +811 -0
- package/dist/server/src/lib/session/agent-session-lifecycle.js +11 -2
- package/dist/server/src/lib/session/chat-turn-progress.js +322 -0
- package/dist/server/src/lib/session/claude-executor.js +45 -5
- package/dist/server/src/lib/session/claude-session.js +21 -65
- package/dist/server/src/lib/session/cli-session.js +17 -0
- package/dist/server/src/lib/session/current-output-builder.js +454 -1103
- package/dist/server/src/lib/session/current-output-history-writers.js +255 -0
- package/dist/server/src/lib/session/current-output-types.js +9 -0
- package/dist/server/src/lib/session/detection-divergence.js +55 -0
- package/dist/server/src/lib/session/global-session-constants.js +2 -13
- package/dist/server/src/lib/session/hook-turn-hold.js +102 -0
- package/dist/server/src/lib/session/layer-disagreement.js +2 -2
- package/dist/server/src/lib/session/opencode-session-store.js +2 -1
- package/dist/server/src/lib/session/prompt-view.js +290 -0
- package/dist/server/src/lib/session/prompt-waiting-composition.js +35 -0
- package/dist/server/src/lib/session/provisional-turn.js +3 -1
- package/dist/server/src/lib/session/send-user-message.js +1 -1
- package/dist/server/src/lib/session/session-starting-state.js +4 -6
- package/dist/server/src/lib/session/status-evidence-type.js +2 -0
- package/dist/server/src/lib/session/status-evidence.js +2 -2
- package/dist/server/src/lib/session/structured-status-merge.js +335 -0
- package/dist/server/src/lib/session/waiting-episode-state.js +3 -4
- package/dist/server/src/lib/session/waiting-kind.js +3 -0
- package/dist/server/src/lib/session-cleanup.js +6 -8
- package/dist/server/src/lib/skills/install-plan.js +2 -1
- package/dist/server/src/lib/skills/snapshot-store.js +2 -2
- package/dist/server/src/lib/skills/uninstall-plan.js +2 -2
- package/dist/server/src/lib/timer-manager.js +6 -8
- package/dist/server/src/lib/tmux/geometry-delegation.js +3 -4
- package/dist/server/src/lib/tmux/legacy-session-alias.js +2 -1
- package/dist/server/src/lib/tmux/session-hooks.js +2 -1
- package/dist/server/src/lib/tmux/session-status-options.js +3 -3
- package/dist/server/src/lib/tmux/tmux-capture-cache.js +3 -2
- package/dist/server/src/lib/tmux/tmux.js +33 -59
- package/dist/server/src/lib/tui-accumulator.js +2 -2
- package/dist/server/src/lib/version-checker.js +6 -6
- package/dist/server/src/lib/ws-server.js +47 -11
- package/docs/en/user-guide/webapp-guide.md +27 -3
- package/package.json +1 -1
- package/release-notes/0.44.2.json +33 -0
- package/release-notes/0.44.3.json +82 -0
- package/scripts/hooks/cmate-agent-event.sh +18 -0
- package/.next/server/chunks/1068.js +0 -1
- package/.next/server/chunks/434.js +0 -1
- package/.next/server/chunks/5775.js +0 -1
- package/.next/server/chunks/6474.js +0 -14
- package/.next/server/chunks/650.js +0 -1
- package/.next/server/chunks/6661.js +0 -1
- package/.next/server/chunks/8583.js +0 -1
- package/.next/server/chunks/964.js +0 -1
- package/.next/server/chunks/967.js +0 -1
- package/.next/server/chunks/9882.js +0 -25
- package/.next/static/chunks/591-308072f285c34787.js +0 -1
- package/.next/static/chunks/app/sessions/page-049e06335187aa91.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-040c5f0f585e6812.js +0 -1
- package/.next/static/css/38070d879efa1371.css +0 -1
- package/dist/server/src/lib/cli-tools/index.js +0 -41
- package/dist/server/src/lib/polling/global-session-poller.js +0 -140
- /package/.next/static/{57lOiz8zSEHdw97XIm0af → tWwHQzmvc-rv9KKUtDWfQ}/_buildManifest.js +0 -0
- /package/.next/static/{57lOiz8zSEHdw97XIm0af → tWwHQzmvc-rv9KKUtDWfQ}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The agent's own "I am waiting for instructions" (Issue #1786).
|
|
4
|
+
*
|
|
5
|
+
* Split out of `agent-event-state` (Issue #3375), which re-exports the public
|
|
6
|
+
* names and applies the transition from `recordAgentEvent`.
|
|
7
|
+
*
|
|
8
|
+
* @module lib/session/agent-event-awaiting-instruction
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.awaitingInstruction = void 0;
|
|
12
|
+
exports.applyAwaitingInstructionTransition = applyAwaitingInstructionTransition;
|
|
13
|
+
exports.getAwaitingInstruction = getAwaitingInstruction;
|
|
14
|
+
exports.isAwaitingInstruction = isAwaitingInstruction;
|
|
15
|
+
const auto_yes_state_1 = require("../../lib/auto-yes-state");
|
|
16
|
+
const agent_event_turn_1 = require("../../lib/session/agent-event-turn");
|
|
17
|
+
const global_state_1 = require("../global-state");
|
|
18
|
+
/** compositeKey -> the agent's own "I am waiting for instructions" (#1786). */
|
|
19
|
+
exports.awaitingInstruction = (0, global_state_1.getOrInitGlobal)('__agentEventAwaitingInstruction', () => new Map());
|
|
20
|
+
/**
|
|
21
|
+
* The third state: "this turn is over and nobody has told me what to do next"
|
|
22
|
+
* (Issue #1786).
|
|
23
|
+
*
|
|
24
|
+
* | event | effect on awaiting_instruction |
|
|
25
|
+
* |-----------------------------------|--------------------------------|
|
|
26
|
+
* | `notification(idle_prompt)` | **set** |
|
|
27
|
+
* | `user_prompt_submit` | release |
|
|
28
|
+
* | `session_start` / `session_end` | release |
|
|
29
|
+
* | everything else | unchanged |
|
|
30
|
+
*
|
|
31
|
+
* It is a boolean beside the status rather than a fifth `SessionStatus`, because
|
|
32
|
+
* `idle_prompt` already maps to `ready` (`agentEventToSessionStatus`) and
|
|
33
|
+
* `ready` means "you can send a message" everywhere in this codebase — the
|
|
34
|
+
* sidebar, `deriveCliStatus`, `getNextAction`, `commandmate wait`. Widening that
|
|
35
|
+
* vocabulary to carry "and it is *asking* you to" would have every consumer of
|
|
36
|
+
* the four values re-decide what they mean; the boolean asks nothing of anyone
|
|
37
|
+
* who does not want it.
|
|
38
|
+
*
|
|
39
|
+
* `stop` deliberately does NOT set it. `Stop` fires when the turn ends, which is
|
|
40
|
+
* most of the time the agent has simply finished a step of its own plan;
|
|
41
|
+
* `Notification(idle_prompt)` is Claude's separate, later "waiting for your
|
|
42
|
+
* input" signal, and using the turn boundary instead would mark every
|
|
43
|
+
* intermediate stop as a request for instructions.
|
|
44
|
+
*
|
|
45
|
+
* `pre_tool_use` / `post_tool_use` / `notification(permission_prompt)` leave it
|
|
46
|
+
* alone, and that is not a gap: a tool call or a dialog can only happen inside a
|
|
47
|
+
* turn, and the turn's own `user_prompt_submit` has already released it. Adding
|
|
48
|
+
* them would only paper over a `UserPromptSubmit` that never arrived — and an
|
|
49
|
+
* operator whose `UserPromptSubmit` hook is missing has no `Notification` hook
|
|
50
|
+
* either, so there would be nothing to release.
|
|
51
|
+
*
|
|
52
|
+
* There is deliberately no age bound here, unlike every other state in this
|
|
53
|
+
* module. Those bound the damage of an event that may never arrive (a lost
|
|
54
|
+
* `Stop`, a dialog answered with no event to say so). This one is released by
|
|
55
|
+
* events that cannot be missed while the fact is still true: typing into the
|
|
56
|
+
* composer — from the app or straight into the tmux pane — raises
|
|
57
|
+
* `UserPromptSubmit`, and ending the session raises `SessionEnd`. An agent that
|
|
58
|
+
* has been idle for six hours genuinely is still awaiting instructions, and
|
|
59
|
+
* expiring the flag would erase the notification #1790 exists to send. The
|
|
60
|
+
* generation fence in {@link isAwaitingInstruction} still applies, so the flag
|
|
61
|
+
* never survives the process that reported it.
|
|
62
|
+
*/
|
|
63
|
+
function applyAwaitingInstructionTransition(key, record) {
|
|
64
|
+
switch (record.event) {
|
|
65
|
+
case 'notification':
|
|
66
|
+
if (record.detail === 'idle_prompt') {
|
|
67
|
+
exports.awaitingInstruction.set(key, { at: record.at, message: record.message ?? null });
|
|
68
|
+
}
|
|
69
|
+
return;
|
|
70
|
+
case 'user_prompt_submit':
|
|
71
|
+
case 'session_start':
|
|
72
|
+
case 'session_end':
|
|
73
|
+
exports.awaitingInstruction.delete(key);
|
|
74
|
+
return;
|
|
75
|
+
case 'stop':
|
|
76
|
+
case 'pre_tool_use':
|
|
77
|
+
case 'post_tool_use':
|
|
78
|
+
return;
|
|
79
|
+
default:
|
|
80
|
+
// exhaustive check: a new AgentEventType must decide its transition here
|
|
81
|
+
record.event;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The agent's own "waiting for your input", or null (Issue #1786).
|
|
87
|
+
*
|
|
88
|
+
* Fenced by generation like the rest of this module: an `idle_prompt` from the
|
|
89
|
+
* Claude process that used to live in this pane is not this one's.
|
|
90
|
+
*/
|
|
91
|
+
function getAwaitingInstruction(worktreeId, cliToolId, instanceId) {
|
|
92
|
+
const key = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
93
|
+
const record = exports.awaitingInstruction.get(key);
|
|
94
|
+
if (!record)
|
|
95
|
+
return null;
|
|
96
|
+
const generation = agent_event_turn_1.generationStartedAt.get(key);
|
|
97
|
+
if (generation !== undefined && record.at < generation)
|
|
98
|
+
return null;
|
|
99
|
+
return record;
|
|
100
|
+
}
|
|
101
|
+
/** {@link getAwaitingInstruction} as the boolean the list API publishes. */
|
|
102
|
+
function isAwaitingInstruction(worktreeId, cliToolId, instanceId) {
|
|
103
|
+
return getAwaitingInstruction(worktreeId, cliToolId, instanceId) !== null;
|
|
104
|
+
}
|
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* De-duplication of agent event deliveries — the time window and the identity
|
|
4
|
+
* rule — and the per-instance tally of what was dropped.
|
|
5
|
+
*
|
|
6
|
+
* Split out of `agent-event-state` (Issue #3375), which re-exports the public
|
|
7
|
+
* names. The bound helpers ({@link MAX_RECENT_EVENT_KEYS},
|
|
8
|
+
* {@link trimOldestEntries}) live here and are shared by the sibling modules.
|
|
9
|
+
*
|
|
10
|
+
* @module lib/session/agent-event-dedup
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.LIFECYCLE_AGENT_EVENT_TYPES = exports.MAX_RECENT_EVENT_KEYS = exports.AGENT_EVENT_DEDUP_WINDOW_MS = exports.recentEventIdentities = exports.recentEventKeys = exports.dropCounts = void 0;
|
|
14
|
+
exports.dropsFor = dropsFor;
|
|
15
|
+
exports.getAgentEventDropCounts = getAgentEventDropCounts;
|
|
16
|
+
exports.isDuplicateAgentEvent = isDuplicateAgentEvent;
|
|
17
|
+
exports.agentEventKeyClaimedAt = agentEventKeyClaimedAt;
|
|
18
|
+
exports.shortSessionTag = shortSessionTag;
|
|
19
|
+
exports.getRecentEventKeyCount = getRecentEventKeyCount;
|
|
20
|
+
exports.classifyAgentEventDelivery = classifyAgentEventDelivery;
|
|
21
|
+
exports.trimOldestEntries = trimOldestEntries;
|
|
22
|
+
exports.getRecentEventIdentityCount = getRecentEventIdentityCount;
|
|
23
|
+
const crypto_1 = require("crypto");
|
|
24
|
+
const auto_yes_state_1 = require("../../lib/auto-yes-state");
|
|
25
|
+
const provisional_turn_1 = require("../../lib/session/provisional-turn");
|
|
26
|
+
const global_state_1 = require("../global-state");
|
|
27
|
+
/** compositeKey -> what this instance has had dropped, and why (Issue #1930). */
|
|
28
|
+
exports.dropCounts = (0, global_state_1.getOrInitGlobal)('__agentEventDrops', () => new Map());
|
|
29
|
+
/** dedup key -> epoch ms it was first seen. See {@link isDuplicateAgentEvent}. */
|
|
30
|
+
exports.recentEventKeys = (0, global_state_1.getOrInitGlobal)('__agentEventRecentKeys', () => new Map());
|
|
31
|
+
/**
|
|
32
|
+
* compositeKey -> (identity key -> epoch ms it was first seen) (Issue #1899).
|
|
33
|
+
*
|
|
34
|
+
* Nested rather than flat so the bound is *per instance*, which the flat
|
|
35
|
+
* {@link recentEventKeys} is not: one chatty agent must not be able to evict
|
|
36
|
+
* another's ids and let a genuine re-delivery through on a quiet pane. See
|
|
37
|
+
* {@link claimEventIdentity}.
|
|
38
|
+
*/
|
|
39
|
+
exports.recentEventIdentities = (0, global_state_1.getOrInitGlobal)('__agentEventRecentIdentities', () => new Map());
|
|
40
|
+
/**
|
|
41
|
+
* How long two identical events count as one delivery.
|
|
42
|
+
*
|
|
43
|
+
* Issue #1722 injects hooks at session start, and `--settings` hooks are
|
|
44
|
+
* *concatenated* with the user's own rather than replacing them, so anyone who
|
|
45
|
+
* followed the #1549 manual setup now has two `Stop` hooks posting the same
|
|
46
|
+
* turn. `applyAgentStopEvent` is idempotent for the timestamp, but
|
|
47
|
+
* `applyTaskEvent` is not: each delivery writes its own `agent_idle` row, and a
|
|
48
|
+
* reader counting rows would see one turn as two.
|
|
49
|
+
*
|
|
50
|
+
* Both deliveries carry the same `session_id` and land milliseconds apart, so
|
|
51
|
+
* the window is generous relative to the real signal. It is not tight relative
|
|
52
|
+
* to what it can wrongly swallow, which is what this comment used to say: "a
|
|
53
|
+
* turn cannot end twice in three seconds" is false of a turn the agent starts
|
|
54
|
+
* for itself, and Issue #3289 measured the `Stop`s of two turns 1473 ms apart.
|
|
55
|
+
* The clock cannot tell those from two deliveries of one, so for `stop` the
|
|
56
|
+
* window is reset by the start of a turn — and for the start of a turn, which
|
|
57
|
+
* happens twice in three seconds just as readily (Issue #3301), by a `stop`.
|
|
58
|
+
* See {@link isDuplicateAgentEvent}, which also records what the window turned
|
|
59
|
+
* out to be dropping for `user_prompt_submit`: not a second hook's delivery.
|
|
60
|
+
*/
|
|
61
|
+
exports.AGENT_EVENT_DEDUP_WINDOW_MS = 3000;
|
|
62
|
+
/** Cap on retained dedup keys, so a long-lived server cannot grow one per turn. */
|
|
63
|
+
exports.MAX_RECENT_EVENT_KEYS = 512;
|
|
64
|
+
/** A zeroed tally. */
|
|
65
|
+
function emptyDropCounts() {
|
|
66
|
+
return {
|
|
67
|
+
dedupDropped: { identity: 0, timeWindow: 0 },
|
|
68
|
+
decisionEvicted: 0,
|
|
69
|
+
idsDiscarded: 0,
|
|
70
|
+
dialogTimedOut: 0,
|
|
71
|
+
decisionOverflow: 0,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** The live tally for one instance, created on first use. */
|
|
75
|
+
function dropsFor(key) {
|
|
76
|
+
let counts = exports.dropCounts.get(key);
|
|
77
|
+
if (!counts) {
|
|
78
|
+
counts = emptyDropCounts();
|
|
79
|
+
exports.dropCounts.set(key, counts);
|
|
80
|
+
// The composite key is (worktree, tool, instance) and a long-lived server
|
|
81
|
+
// accumulates worktrees; bounded like every other map here (DR4-009).
|
|
82
|
+
trimOldestEntries(exports.dropCounts, exports.MAX_RECENT_EVENT_KEYS);
|
|
83
|
+
}
|
|
84
|
+
return counts;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* What this instance has had dropped, or a zeroed tally when nothing has.
|
|
88
|
+
*
|
|
89
|
+
* A copy, not the live object: this is published on the hot path and a caller
|
|
90
|
+
* that could mutate it would be able to erase the evidence.
|
|
91
|
+
*/
|
|
92
|
+
function getAgentEventDropCounts(worktreeId, cliToolId, instanceId) {
|
|
93
|
+
const counts = exports.dropCounts.get((0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId));
|
|
94
|
+
if (!counts)
|
|
95
|
+
return emptyDropCounts();
|
|
96
|
+
return { ...counts, dedupDropped: { ...counts.dedupDropped } };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Whether this event is a second copy of one already handled, and should be
|
|
100
|
+
* dropped.
|
|
101
|
+
*
|
|
102
|
+
* Only events that name a `sessionId` can be deduplicated, and calling this
|
|
103
|
+
* *claims* the key: a first call answers false and marks it, so the caller must
|
|
104
|
+
* ask once per request and act on the answer. Events with no session id are
|
|
105
|
+
* never suppressed — a caller that omits it (the #1549 relay run without a hook
|
|
106
|
+
* payload, a hand-rolled `curl`) has given us nothing to tell two deliveries of
|
|
107
|
+
* one turn from two genuine turns, and inventing a match there would silently
|
|
108
|
+
* drop real events.
|
|
109
|
+
*
|
|
110
|
+
* The subtype is part of the key (Issue #1726). It has to be, now that
|
|
111
|
+
* `pre_tool_use` exists: that event's subtype is the tool name, several tool
|
|
112
|
+
* calls a second is ordinary, and a key without it would read a `Bash` call and
|
|
113
|
+
* the `AskUserQuestion` that follows it as one delivery and drop the second. The
|
|
114
|
+
* same correction applies to two `Notification`s of different types inside the
|
|
115
|
+
* window, which were previously collapsed as well.
|
|
116
|
+
*
|
|
117
|
+
* ## A `stop` after a turn start is another turn's (Issue #3289)
|
|
118
|
+
*
|
|
119
|
+
* Nothing in the key names a turn, and a `session_id` outlives one: every turn
|
|
120
|
+
* of a conversation carries the same id. So two `stop`s of one session inside
|
|
121
|
+
* the window share a key whether they are two deliveries of one turn or the
|
|
122
|
+
* ends of two, and the second used to be dropped either way. Claude 2.1.289
|
|
123
|
+
* was measured doing the latter — the completion notice of a background task
|
|
124
|
+
* opens a turn the moment the previous one ends, and that turn ended 1473 ms
|
|
125
|
+
* after the first `Stop`. Its `stop` was dropped, the turn it should have
|
|
126
|
+
* closed stayed open, and `commandmate wait` blocked on a finished agent until
|
|
127
|
+
* {@link STRUCTURED_STATE_MAX_AGE_MS}.
|
|
128
|
+
*
|
|
129
|
+
* What tells the two apart is what arrived in between. A delivery in
|
|
130
|
+
* {@link TURN_ACTIVITY_EVENTS} that is itself applied releases every `stop`
|
|
131
|
+
* its session has claimed ({@link releaseStopClaims}), so the next `stop` is a
|
|
132
|
+
* first delivery again, and that `stop`'s own copy is dropped behind it.
|
|
133
|
+
*
|
|
134
|
+
* - **Those three events, not `user_prompt_submit` alone**, because they are
|
|
135
|
+
* the ones the turn model opens a turn on, and the property is stated in its
|
|
136
|
+
* terms: a turn this server opened is never left open by a `stop` dropped as
|
|
137
|
+
* a copy. antigravity and Command Code send no `user_prompt_submit` at all —
|
|
138
|
+
* their turns are opened by a tool event — and a narrower rule would leave
|
|
139
|
+
* them where Claude was.
|
|
140
|
+
* - **Only a turn start that was applied.** One dropped as a copy is recorded
|
|
141
|
+
* by nobody and opens no turn, so it releases nothing: a turn start and the
|
|
142
|
+
* `stop` that answers it are applied together or not at all.
|
|
143
|
+
* - **Only the session that started the turn.** A turn start with no session
|
|
144
|
+
* id releases nothing, for the reason the second paragraph gives; another
|
|
145
|
+
* session's says nothing about this one's `stop` (codex can file a second
|
|
146
|
+
* instance's turns under the first, #2874).
|
|
147
|
+
* - **By order of arrival, not by timestamp.** The release is a deletion made
|
|
148
|
+
* when the turn start is claimed, so it holds for deliveries inside one
|
|
149
|
+
* millisecond, where comparing "turn started at" with "stop seen at" cannot.
|
|
150
|
+
*
|
|
151
|
+
* What this still cannot tell apart is `stop(A)`, `user_prompt_submit(B)`, and
|
|
152
|
+
* then a *late copy* of `stop(A)`. The copy is read as `stop(B)` and closes
|
|
153
|
+
* turn B early. Nothing it carries says otherwise — the copy that can be late
|
|
154
|
+
* is the relay's, and the relay rebuilds the body it posts (tool, event, cwd,
|
|
155
|
+
* session id) and drops the rest of the payload — and the order needs a hook
|
|
156
|
+
* the agent does not wait for. Claude Code runs its `Stop` hooks to completion
|
|
157
|
+
* before the next turn's `UserPromptSubmit` (in the measurement the prompt
|
|
158
|
+
* arrives 29 ms after the reply to the `Stop` and 540 ms after the `Stop`
|
|
159
|
+
* itself), `type: "http"` has no async form, and
|
|
160
|
+
* `scripts/hooks/cmate-agent-event.sh` posts with a foreground `curl`. That
|
|
161
|
+
* leaves a hand-written `"async": true` command hook, where the cost is a
|
|
162
|
+
* `wait` that returns one turn early — against a `wait` that does not return
|
|
163
|
+
* at all on the configuration CommandMate itself injects.
|
|
164
|
+
*
|
|
165
|
+
* The alternative was to put the turn in the key: a per-session counter, bumped
|
|
166
|
+
* by a turn start. It decides every case above the same way, the late copy
|
|
167
|
+
* included, and it needs a second map that has to outlive every key built from
|
|
168
|
+
* it — prune the counter while its key is still inside the window and the copy
|
|
169
|
+
* gets a different key and is applied — with a bound, a pruning rule and a test
|
|
170
|
+
* seam of its own. Releasing the claim keeps no state beyond the map that was
|
|
171
|
+
* already here, so {@link MAX_RECENT_EVENT_KEYS} bounds it as before.
|
|
172
|
+
*
|
|
173
|
+
* ## A turn start after a `stop` is another turn's (Issue #3301)
|
|
174
|
+
*
|
|
175
|
+
* The same defect from the other side. A turn start is on the window as well,
|
|
176
|
+
* and a turn can start twice in three seconds: logged on 2026-10-04, the
|
|
177
|
+
* `UserPromptSubmit` of a turn a background task's completion notice opened,
|
|
178
|
+
* that turn's `Stop` 2624 ms later, and the next notice's `UserPromptSubmit`
|
|
179
|
+
* 22 ms after the `Stop`. The second start was dropped as a copy of the first,
|
|
180
|
+
* so this server never opened the turn the agent was in and went on publishing
|
|
181
|
+
* the end of the previous one.
|
|
182
|
+
*
|
|
183
|
+
* So the release runs in both directions: a `stop` that is itself applied
|
|
184
|
+
* releases every turn start its session has claimed
|
|
185
|
+
* ({@link releaseTurnStartClaims}), and the next one is a first delivery
|
|
186
|
+
* again. Together the two releases leave the window comparing a delivery only
|
|
187
|
+
* with what has arrived since the last turn boundary this server applied — the
|
|
188
|
+
* one stretch in which "the same event again" can mean a copy.
|
|
189
|
+
*
|
|
190
|
+
* - **All of {@link TURN_ACTIVITY_EVENTS}, every subtype**, for the reason the
|
|
191
|
+
* other direction gives: antigravity's and Command Code's turns are opened
|
|
192
|
+
* by a tool event, and a short turn of either can open with the tool the
|
|
193
|
+
* previous one used.
|
|
194
|
+
* - **Only a `stop` that names the session.** One with no session id is never
|
|
195
|
+
* judged a copy, and cannot say whose turn it ended either.
|
|
196
|
+
* - **Only a `stop` that was applied**, as with the turn start above — though
|
|
197
|
+
* with both releases in place neither condition decides anything any more:
|
|
198
|
+
* a delivery is dropped only while the one it copies holds its claim, and
|
|
199
|
+
* that one released the other side of the boundary when it was applied.
|
|
200
|
+
* - **Also for a `stop` that never reaches this function.**
|
|
201
|
+
* {@link classifyAgentEventDelivery} lets the `stop` of a source that
|
|
202
|
+
* declares an identity through before the window is consulted, and makes
|
|
203
|
+
* the release itself. OpenCode V2 is the source that needs it: its
|
|
204
|
+
* `session.execution.started` carries no id and is judged here.
|
|
205
|
+
*
|
|
206
|
+
* What the window still drops on this side is not the double delivery its
|
|
207
|
+
* constant describes. The injected settings register one `UserPromptSubmit`
|
|
208
|
+
* hook, and in the server logs of 2026-10-02 to 2026-10-05 a `Stop` —
|
|
209
|
+
* registered the same way — was dropped once, by the defect #3289 fixed. A
|
|
210
|
+
* `UserPromptSubmit` was dropped in 15 bursts, and the session transcripts say
|
|
211
|
+
* what each one was. Thirteen are Claude Code taking two or three
|
|
212
|
+
* background-task notices off its queue at once, after a tool result, and
|
|
213
|
+
* attaching them to the turn that is already running: it fires the hook once
|
|
214
|
+
* per notice, 4–21 ms apart, and the deliveries match the transcript's
|
|
215
|
+
* `queue-operation: remove` entries one for one. One is the operator
|
|
216
|
+
* submitting a prompt 804 ms into a running turn. One is the defect above.
|
|
217
|
+
* These are different prompts joining one turn, not copies of one event.
|
|
218
|
+
* Counting them as one is still right — none of them begins a turn — and none
|
|
219
|
+
* has a `stop` before it, because the turn it joins has not ended. That is what
|
|
220
|
+
* makes a `stop` the thing to release on. Since Issue #3330 it no longer
|
|
221
|
+
* decides the turn either: a notice the window lets through is marked
|
|
222
|
+
* {@link AgentEventRecord.joinsOpenTurn} and continues the running turn, so a
|
|
223
|
+
* burst — and a notice minutes into the turn, which the window never saw as a
|
|
224
|
+
* repeat — leaves `turnId` where it was.
|
|
225
|
+
*
|
|
226
|
+
* What this cannot tell apart:
|
|
227
|
+
*
|
|
228
|
+
* - `start(A)`, `stop(A)`, then a *late copy* of `start(A)`. The copy is read
|
|
229
|
+
* as `start(B)` and opens a turn no `stop` is coming for: `running` is
|
|
230
|
+
* published until the scraper has seen the composer on
|
|
231
|
+
* {@link SCRAPER_COMPLETION_POLLS} polls, and a `commandmate wait` that
|
|
232
|
+
* adopted the turn is left waiting for a `stop`. The copy has to arrive
|
|
233
|
+
* after the whole turn and inside three seconds of the original; any later
|
|
234
|
+
* and it was applied before this change too. Claude Code holds the turn
|
|
235
|
+
* until its `UserPromptSubmit` hooks have answered (a stalled one is
|
|
236
|
+
* cancelled at its timeout and only then does the session go on,
|
|
237
|
+
* `docs/design/agent-hooks-live-verification.md` §5.3.3), `type: "http"`
|
|
238
|
+
* has no async form, and the relay posts with a foreground `curl`; every
|
|
239
|
+
* burst above landed before the model was called. That leaves the
|
|
240
|
+
* hand-written `"async": true` command hook again, beside the injected one
|
|
241
|
+
* and on a turn shorter than its delay — §5.3.6 measured one posting after
|
|
242
|
+
* a four-second session had already finished.
|
|
243
|
+
* - A tool event of turn A that arrives after `stop(A)`, inside three seconds
|
|
244
|
+
* of one for the same tool: read as the first activity of a new turn, at
|
|
245
|
+
* the same cost. It takes a tool hook the agent does not wait for, or a
|
|
246
|
+
* tool call that outlives the turn that made it. Not measured per tool; in
|
|
247
|
+
* the logs above no tool event arrives within three seconds of a `stop` of
|
|
248
|
+
* codex or Command Code, of which there are about thirty.
|
|
249
|
+
* - `start(A)`, `start(B)` with no `stop` of their session applied between
|
|
250
|
+
* them. `start(B)` is dropped, as before. When the `Stop` was lost (every
|
|
251
|
+
* hook failure is fail-open), the turn this server opened for A is still
|
|
252
|
+
* open, so what it publishes stays true and `stop(B)` closes it. When the
|
|
253
|
+
* `Stop` came without a session id, it closed that turn — {@link closesTurn}
|
|
254
|
+
* reads an anonymous `stop` as the open turn's — and released nothing, so
|
|
255
|
+
* the defect is as it was. That takes hand-written hooks that send the
|
|
256
|
+
* session id on the turn start and not on the `Stop`.
|
|
257
|
+
* - The late copy of `stop(A)` above, one step on. Read as `stop(B)`, it is
|
|
258
|
+
* an applied `stop` and releases turn starts like any other, so a copy of
|
|
259
|
+
* `start(B)` behind it is read as `start(C)`. Two unwaited copies in a row.
|
|
260
|
+
*
|
|
261
|
+
* The alternative was the agent's own name for the turn: Claude's payloads
|
|
262
|
+
* carry a `prompt_id` on `UserPromptSubmit` and on `Stop`. It could not be
|
|
263
|
+
* measured here whether a turn the agent starts for itself gets a new one on
|
|
264
|
+
* the hook channel (the transcript's `promptId` does change from one such turn
|
|
265
|
+
* to the next), nor whether the hooks of one burst share one — and if they do
|
|
266
|
+
* not, a key built on it turns each burst into that many turns. It would also
|
|
267
|
+
* cover one tool on one channel: the relay script does not forward the field,
|
|
268
|
+
* codex spells it `turn_id`, and copilot, gemini and antigravity carry nothing
|
|
269
|
+
* of the kind (#1757 R5), so all of them stay on the window either way. The
|
|
270
|
+
* counter described above is the remaining alternative, and it loses to a
|
|
271
|
+
* release here for the reasons it lost there.
|
|
272
|
+
*
|
|
273
|
+
* @param at - Epoch ms; defaults to now
|
|
274
|
+
* @param detail - The event's subtype, when it has one
|
|
275
|
+
*/
|
|
276
|
+
function isDuplicateAgentEvent(worktreeId, cliToolId, instanceId, event, sessionId, at = Date.now(), detail = null) {
|
|
277
|
+
if (!sessionId)
|
|
278
|
+
return false;
|
|
279
|
+
const composite = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
280
|
+
const key = dedupKey(composite, event, detail, sessionId);
|
|
281
|
+
const seenAt = exports.recentEventKeys.get(key);
|
|
282
|
+
if (seenAt !== undefined && at - seenAt < exports.AGENT_EVENT_DEDUP_WINDOW_MS) {
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
exports.recentEventKeys.set(key, at);
|
|
286
|
+
if (provisional_turn_1.TURN_ACTIVITY_EVENTS.has(event))
|
|
287
|
+
releaseStopClaims(composite, sessionId);
|
|
288
|
+
else if (event === 'stop')
|
|
289
|
+
releaseTurnStartClaims(composite, sessionId);
|
|
290
|
+
pruneRecentEventKeys(at);
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
/** The key {@link isDuplicateAgentEvent} claims: `<instance> <event> <detail> <session>`. */
|
|
294
|
+
function dedupKey(composite, event, detail, sessionId) {
|
|
295
|
+
return [composite, event, detail ?? '', sessionId].join(' ');
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* When the delivery that claimed this event's de-duplication key was received
|
|
299
|
+
* (Issue #3311), or null when nothing holds the key.
|
|
300
|
+
*
|
|
301
|
+
* Read by the receiver right after {@link isDuplicateAgentEvent} dropped an
|
|
302
|
+
* event — a drop does not move the claim — so `at - result` is how long after
|
|
303
|
+
* the applied delivery the dropped one came. That interval is what the daily
|
|
304
|
+
* metrics read to tell a copy (a few ms) from a second turn the window
|
|
305
|
+
* swallowed; it changes nothing here.
|
|
306
|
+
*/
|
|
307
|
+
function agentEventKeyClaimedAt(worktreeId, cliToolId, instanceId, event, sessionId, detail = null) {
|
|
308
|
+
if (!sessionId)
|
|
309
|
+
return null;
|
|
310
|
+
const composite = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
311
|
+
return exports.recentEventKeys.get(dedupKey(composite, event, detail, sessionId)) ?? null;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* The agent's session id in a form a log line may carry (Issue #3311): the
|
|
315
|
+
* first 8 hex characters of its SHA-256. Enough to tell the sessions of one
|
|
316
|
+
* instance apart in a day's log; the id itself is never written, because the
|
|
317
|
+
* daily metrics that read these lines are published.
|
|
318
|
+
*/
|
|
319
|
+
function shortSessionTag(sessionId) {
|
|
320
|
+
return (0, crypto_1.createHash)('sha256').update(sessionId).digest('hex').slice(0, 8);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Forget every `stop` one session of one instance has claimed (Issue #3289).
|
|
324
|
+
*
|
|
325
|
+
* Every subtype: antigravity posts `stop` / `self_resume_pending` (#2614)
|
|
326
|
+
* beside the plain one.
|
|
327
|
+
*/
|
|
328
|
+
function releaseStopClaims(composite, sessionId) {
|
|
329
|
+
releaseClaims(composite, ['stop'], sessionId);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Forget every turn start one session of one instance has claimed
|
|
333
|
+
* (Issue #3301) — {@link releaseStopClaims} from the other side of the turn
|
|
334
|
+
* boundary.
|
|
335
|
+
*
|
|
336
|
+
* Every event in {@link TURN_ACTIVITY_EVENTS} and every subtype: a tool event's
|
|
337
|
+
* subtype is the tool's name, and a turn claims one key per tool it called.
|
|
338
|
+
*/
|
|
339
|
+
function releaseTurnStartClaims(composite, sessionId) {
|
|
340
|
+
releaseClaims(composite, provisional_turn_1.TURN_ACTIVITY_EVENTS, sessionId);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Forget every claim one session of one instance holds on `events`, whatever
|
|
344
|
+
* subtype it was made under.
|
|
345
|
+
*
|
|
346
|
+
* A walk instead of a lookup because the subtype sits in the middle of the key
|
|
347
|
+
* {@link isDuplicateAgentEvent} builds — `<instance> <event> <detail>
|
|
348
|
+
* <session>` — and the subtypes that were claimed are not known here. The walk
|
|
349
|
+
* is over at most {@link MAX_RECENT_EVENT_KEYS} entries.
|
|
350
|
+
*/
|
|
351
|
+
function releaseClaims(composite, events, sessionId) {
|
|
352
|
+
const prefixes = Array.from(events, (event) => `${composite} ${event} `);
|
|
353
|
+
const suffix = ` ${sessionId}`;
|
|
354
|
+
const claimedUnder = (key, prefix) => key.length >= prefix.length + suffix.length && key.startsWith(prefix);
|
|
355
|
+
for (const key of exports.recentEventKeys.keys()) {
|
|
356
|
+
if (key.endsWith(suffix) && prefixes.some((prefix) => claimedUnder(key, prefix))) {
|
|
357
|
+
exports.recentEventKeys.delete(key);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/** Drop keys past the window, then the oldest survivors if still over the cap. */
|
|
362
|
+
function pruneRecentEventKeys(now) {
|
|
363
|
+
for (const [key, seenAt] of exports.recentEventKeys) {
|
|
364
|
+
if (now - seenAt >= exports.AGENT_EVENT_DEDUP_WINDOW_MS) {
|
|
365
|
+
exports.recentEventKeys.delete(key);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
// Map iterates in insertion order, so the head is the oldest.
|
|
369
|
+
while (exports.recentEventKeys.size > exports.MAX_RECENT_EVENT_KEYS) {
|
|
370
|
+
const oldest = exports.recentEventKeys.keys().next();
|
|
371
|
+
if (oldest.done)
|
|
372
|
+
break;
|
|
373
|
+
exports.recentEventKeys.delete(oldest.value);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
/** How many dedup keys are currently retained. Test seam for the bound above. */
|
|
377
|
+
function getRecentEventKeyCount() {
|
|
378
|
+
return exports.recentEventKeys.size;
|
|
379
|
+
}
|
|
380
|
+
// =============================================================================
|
|
381
|
+
// Identity de-duplication (Issue #1899)
|
|
382
|
+
// =============================================================================
|
|
383
|
+
/**
|
|
384
|
+
* Event words whose repeat is a fact about the session, not a re-delivery
|
|
385
|
+
* (Issue #1899; design §4 D3 decision 2).
|
|
386
|
+
*
|
|
387
|
+
* These are the two words that end something, and neither of them carries an
|
|
388
|
+
* id on any source measured so far. `session.idle` — opencode's `stop` — is
|
|
389
|
+
* `{ "sessionID": "ses_…" }` and nothing else, which is exactly why
|
|
390
|
+
* `sources/opencode/turn-gate` exists. With no id, a generic deduper has only
|
|
391
|
+
* the clock, and the clock cannot tell a second turn from a second delivery:
|
|
392
|
+
* #1899 measured a real `stop` 2.5 s after the previous one being dropped,
|
|
393
|
+
* which leaves the newest event at `user_prompt_submit`, the instance reading
|
|
394
|
+
* `running`, and `commandmate wait` blocked until the 30-minute staleness
|
|
395
|
+
* bound.
|
|
396
|
+
*
|
|
397
|
+
* **The exemption is conditional on the source declaring an identity**, and
|
|
398
|
+
* that condition is the whole safety argument. A source that declares one is a
|
|
399
|
+
* source with a real deduper elsewhere — on the SSE path, `TurnGate`, which
|
|
400
|
+
* arms on `session.status(busy)` and completes on the first `session.idle`
|
|
401
|
+
* after arming, so the abort double-idle (19 ms apart, §5.3.2) never reaches
|
|
402
|
+
* the ingest at all. Push hooks have no such gate: #1722's concatenated
|
|
403
|
+
* settings really do post two `Stop`s for one turn, so they stay on the window
|
|
404
|
+
* in {@link isDuplicateAgentEvent}, which is what every hook receiver still
|
|
405
|
+
* calls.
|
|
406
|
+
*
|
|
407
|
+
* The window had the same defect there — Claude ends two turns inside three
|
|
408
|
+
* seconds when it resumes itself (Issue #3289) — and it is closed differently,
|
|
409
|
+
* because a push source has no gate to lean on and so cannot be exempted: on
|
|
410
|
+
* the window, a `stop` is released by the start of a turn instead.
|
|
411
|
+
*
|
|
412
|
+
* Being exempt does not make a `stop` any less the end of a turn. The turn
|
|
413
|
+
* starts of a declared source are on the window whenever their frame carries
|
|
414
|
+
* no id, so the `stop` let through here releases them, as a `stop` on the
|
|
415
|
+
* window does (Issue #3301; {@link classifyAgentEventDelivery}).
|
|
416
|
+
*/
|
|
417
|
+
exports.LIFECYCLE_AGENT_EVENT_TYPES = ['stop', 'session_end'];
|
|
418
|
+
/**
|
|
419
|
+
* Whether this delivery is a second copy of one already handled (Issue #1899).
|
|
420
|
+
*
|
|
421
|
+
* The tool-agnostic replacement for calling {@link isDuplicateAgentEvent}
|
|
422
|
+
* directly, and it branches on the source's declared capability rather than on
|
|
423
|
+
* its name — flip opencode's `eventIdentity` to `null` and every case below
|
|
424
|
+
* falls back to the 3-second window it used before this Issue.
|
|
425
|
+
*
|
|
426
|
+
* Three rules, in order:
|
|
427
|
+
*
|
|
428
|
+
* 1. **The frame has an id** — key on it, with no time bound at all. An id is
|
|
429
|
+
* a claim about identity that a clock cannot improve on: two approvals
|
|
430
|
+
* 1 s apart are two approvals, and the same approval replayed by
|
|
431
|
+
* `resyncPending` four minutes later is still one approval. That second
|
|
432
|
+
* half is what the ingest's window was reaching for ("a frame delivered
|
|
433
|
+
* twice by a re-sync racing the live stream") and never actually covered,
|
|
434
|
+
* since a re-sync is not obliged to land within three seconds.
|
|
435
|
+
* 2. **No id, but the word ends something** — never suppressed. See
|
|
436
|
+
* {@link LIFECYCLE_AGENT_EVENT_TYPES}. A `stop` that leaves by this rule
|
|
437
|
+
* releases its session's turn starts from the window on the way (#3301):
|
|
438
|
+
* rule 3 would have done it, and this `stop` never gets there.
|
|
439
|
+
* 3. **Anything else** — the time window, unchanged. That is every push
|
|
440
|
+
* source, and the identity-declaring source's `session.created` /
|
|
441
|
+
* `session.error`, which publish no id either but are not turn boundaries
|
|
442
|
+
* — and OpenCode V2's `session.execution.started`, which is one. A push
|
|
443
|
+
* source's `stop` is on it too, and is released from it by the start of a
|
|
444
|
+
* turn (#3289), as a turn start is by a `stop` (#3301) — rules of
|
|
445
|
+
* {@link isDuplicateAgentEvent}'s, not of this function's.
|
|
446
|
+
*
|
|
447
|
+
* Calling this *claims* the key, exactly as {@link isDuplicateAgentEvent} does:
|
|
448
|
+
* ask once per delivery and act on the answer.
|
|
449
|
+
*/
|
|
450
|
+
function classifyAgentEventDelivery(delivery) {
|
|
451
|
+
const composite = (0, auto_yes_state_1.buildCompositeKey)(delivery.worktreeId, delivery.cliToolId, delivery.instanceId);
|
|
452
|
+
if (delivery.identityKind !== null) {
|
|
453
|
+
// Issue #1930 / S1: the id is the agent's, and it becomes a Map key. One
|
|
454
|
+
// that fails validation is DISCARDED — the delivery then takes the
|
|
455
|
+
// no-id path below, which is a path this function already has — rather than
|
|
456
|
+
// truncated, because a truncated id compares equal to a different id that
|
|
457
|
+
// shares its prefix and would drop a real event as a repeat.
|
|
458
|
+
const identity = delivery.identity === null ? null : (0, provisional_turn_1.acceptExternalId)(delivery.identity);
|
|
459
|
+
if (delivery.identity !== null && identity === null)
|
|
460
|
+
dropsFor(composite).idsDiscarded += 1;
|
|
461
|
+
if (identity !== null) {
|
|
462
|
+
if (claimEventIdentity(delivery, identity)) {
|
|
463
|
+
dropsFor(composite).dedupDropped.identity += 1;
|
|
464
|
+
return { duplicate: true, by: 'identity' };
|
|
465
|
+
}
|
|
466
|
+
return { duplicate: false };
|
|
467
|
+
}
|
|
468
|
+
if (exports.LIFECYCLE_AGENT_EVENT_TYPES.includes(delivery.event)) {
|
|
469
|
+
// Issue #3301: this `stop` is applied without the window ever seeing it,
|
|
470
|
+
// so the release an applied `stop` owes its session's turn starts is made
|
|
471
|
+
// here. Those turn starts ARE on the window whenever their frame carries
|
|
472
|
+
// no id, which is every `session.execution.started` of OpenCode V2.
|
|
473
|
+
if (delivery.event === 'stop' && delivery.sessionId) {
|
|
474
|
+
releaseTurnStartClaims(composite, delivery.sessionId);
|
|
475
|
+
}
|
|
476
|
+
return { duplicate: false };
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
const duplicate = isDuplicateAgentEvent(delivery.worktreeId, delivery.cliToolId, delivery.instanceId, delivery.event, delivery.sessionId, delivery.at, delivery.detail);
|
|
480
|
+
if (!duplicate)
|
|
481
|
+
return { duplicate: false };
|
|
482
|
+
dropsFor(composite).dedupDropped.timeWindow += 1;
|
|
483
|
+
return { duplicate: true, by: 'time-window' };
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Claim `(event, detail, identity)` for one instance, answering whether it was
|
|
487
|
+
* already claimed.
|
|
488
|
+
*
|
|
489
|
+
* `event` and `detail` are in the key and are not decoration: opencode asks an
|
|
490
|
+
* approval under `properties.id` and answers it under `properties.requestID`
|
|
491
|
+
* with **the same `per_…` value** (#1898), so a key made of the identity alone
|
|
492
|
+
* would read `permission.replied` as a repeat of `permission.asked` and drop
|
|
493
|
+
* the one frame that releases the dialog. The same shape covers
|
|
494
|
+
* `pre_tool_use` / `post_tool_use`, which share a `callID`.
|
|
495
|
+
*
|
|
496
|
+
* `sessionId` is deliberately *not* in the key. An id is unique within the
|
|
497
|
+
* agent that issued it, and folding in a field that is null on some deliveries
|
|
498
|
+
* would let the same frame through twice.
|
|
499
|
+
*/
|
|
500
|
+
function claimEventIdentity(delivery, identity) {
|
|
501
|
+
const composite = (0, auto_yes_state_1.buildCompositeKey)(delivery.worktreeId, delivery.cliToolId, delivery.instanceId);
|
|
502
|
+
let claimed = exports.recentEventIdentities.get(composite);
|
|
503
|
+
if (!claimed) {
|
|
504
|
+
claimed = new Map();
|
|
505
|
+
exports.recentEventIdentities.set(composite, claimed);
|
|
506
|
+
// Bound the instances as well as the entries per instance: the composite
|
|
507
|
+
// key is (worktree, tool, instance) and a long-lived server accumulates
|
|
508
|
+
// worktrees (DR4-009).
|
|
509
|
+
trimOldestEntries(exports.recentEventIdentities, exports.MAX_RECENT_EVENT_KEYS);
|
|
510
|
+
}
|
|
511
|
+
const key = [delivery.event, delivery.detail ?? '', identity].join(' ');
|
|
512
|
+
if (claimed.has(key))
|
|
513
|
+
return true;
|
|
514
|
+
claimed.set(key, delivery.at);
|
|
515
|
+
trimOldestEntries(claimed, exports.MAX_RECENT_EVENT_KEYS);
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
518
|
+
/** Drop the oldest entries until the map fits. Maps iterate in insertion order. */
|
|
519
|
+
function trimOldestEntries(entries, max) {
|
|
520
|
+
while (entries.size > max) {
|
|
521
|
+
const oldest = entries.keys().next();
|
|
522
|
+
if (oldest.done)
|
|
523
|
+
break;
|
|
524
|
+
entries.delete(oldest.value);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* How many identities are retained for one instance, or across all of them when
|
|
529
|
+
* no instance is named. Test seam for the bound above.
|
|
530
|
+
*/
|
|
531
|
+
function getRecentEventIdentityCount(worktreeId, cliToolId, instanceId) {
|
|
532
|
+
if (worktreeId === undefined || cliToolId === undefined) {
|
|
533
|
+
let total = 0;
|
|
534
|
+
for (const claimed of exports.recentEventIdentities.values())
|
|
535
|
+
total += claimed.size;
|
|
536
|
+
return total;
|
|
537
|
+
}
|
|
538
|
+
return exports.recentEventIdentities.get((0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId))?.size ?? 0;
|
|
539
|
+
}
|