commandmate 0.47.2 → 0.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +180 -180
- package/.next/app-path-routes-manifest.json +30 -30
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +9 -9
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/release-notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route.js +3 -3
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js +2 -2
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route.js +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/route.js +1 -1
- package/.next/server/app/api/relays/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +3 -3
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -103
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +1 -1
- package/.next/server/app/sessions/page.js.nft.json +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page.js +1 -1
- package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js +2 -2
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +12 -12
- package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +30 -30
- package/.next/server/chunks/1191.js +11 -4
- package/.next/server/chunks/1501.js +1 -1
- package/.next/server/chunks/1601.js +2 -2
- package/.next/server/chunks/1656.js +2 -2
- package/.next/server/chunks/1945.js +3 -3
- package/.next/server/chunks/1990.js +103 -0
- package/.next/server/chunks/2069.js +1 -0
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/2422.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/2534.js +1 -1
- package/.next/server/chunks/255.js +1 -1
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3505.js +2 -2
- package/.next/server/chunks/4243.js +1 -1
- package/.next/server/chunks/4248.js +1 -1
- package/.next/server/chunks/4280.js +1 -0
- package/.next/server/chunks/5209.js +1 -1
- package/.next/server/chunks/6119.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/6486.js +9 -8
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/720.js +103 -0
- package/.next/server/chunks/7604.js +2 -0
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8581.js +8 -8
- package/.next/server/chunks/8728.js +3 -3
- package/.next/server/chunks/8791.js +1 -1
- package/.next/server/chunks/8807.js +19 -18
- package/.next/server/chunks/8918.js +2 -104
- package/.next/server/chunks/936.js +1 -1
- package/.next/server/chunks/9390.js +1 -1
- package/.next/server/chunks/9540.js +1 -1
- package/.next/server/chunks/9627.js +5 -5
- package/.next/server/chunks/9731.js +2 -2
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/1128-914c559913546bbc.js +1 -0
- package/.next/static/chunks/{2407-a6533805a86d05bd.js → 2407-ab92ae9837c39dce.js} +1 -1
- package/.next/static/chunks/{2863-6a07ec82fb52f4dd.js → 2863-7173dc305dffc4f6.js} +1 -1
- package/.next/static/chunks/6288-6fadbba6e84393b2.js +1 -0
- package/.next/static/chunks/7665-e9ef6e0a85b9fa49.js +1 -0
- package/.next/static/chunks/8407-35bbfc84793d7004.js +1 -0
- package/.next/static/chunks/9079-987939d231704218.js +1 -0
- package/.next/static/chunks/app/{layout-538d8d2746ad1588.js → layout-aa8e66164a4367af.js} +1 -1
- package/.next/static/chunks/app/sessions/page-cfd645305e25fd33.js +1 -0
- package/.next/static/chunks/app/skills/[skillId]/{page-52ba58712faf3378.js → page-cb6e74fd9a6a571d.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/files/[...path]/page-704086656fb45699.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-a8d7886703ffc7b4.js +1 -0
- package/.next/static/css/{743f79ff19ab91e9.css → db8959555c3d9c96.css} +1 -1
- package/.next/trace +13 -13
- package/dist/cli/commands/auto-yes.d.ts +24 -0
- package/dist/cli/commands/auto-yes.d.ts.map +1 -1
- package/dist/cli/commands/auto-yes.js +76 -8
- package/dist/cli/commands/capture.d.ts.map +1 -1
- package/dist/cli/commands/capture.js +5 -0
- package/dist/cli/commands/instances.d.ts.map +1 -1
- package/dist/cli/commands/instances.js +10 -1
- package/dist/cli/commands/prompt.d.ts.map +1 -1
- package/dist/cli/commands/prompt.js +5 -3
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +19 -6
- package/dist/cli/commands/verify.d.ts.map +1 -1
- package/dist/cli/commands/verify.js +8 -1
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +101 -13
- package/dist/cli/config/duration-constants.d.ts +16 -13
- package/dist/cli/config/duration-constants.d.ts.map +1 -1
- package/dist/cli/config/duration-constants.js +21 -21
- package/dist/cli/docs/agent-operations.d.ts +2 -2
- package/dist/cli/docs/agent-operations.d.ts.map +1 -1
- package/dist/cli/docs/agent-operations.js +29 -1
- package/dist/cli/types/api-responses.d.ts +145 -3
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/types/index.d.ts +4 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/utils/resource-resolvers.d.ts +0 -18
- package/dist/cli/utils/resource-resolvers.d.ts.map +1 -1
- package/dist/cli/utils/resource-resolvers.js +1 -51
- package/dist/cli/utils/verify-runner.d.ts +24 -1
- package/dist/cli/utils/verify-runner.d.ts.map +1 -1
- package/dist/cli/utils/verify-runner.js +54 -1
- package/dist/config/auto-yes-duration.d.ts +56 -0
- package/dist/config/auto-yes-duration.d.ts.map +1 -0
- package/dist/config/auto-yes-duration.js +76 -0
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts +54 -2
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts.map +1 -1
- package/dist/lib/polling/auto-yes-suppression-reason.js +33 -2
- package/dist/lib/prompt-observation/types.d.ts +13 -0
- package/dist/lib/prompt-observation/types.d.ts.map +1 -1
- package/dist/server/locales/en/worktree.json +2 -1
- package/dist/server/locales/ja/worktree.json +2 -1
- package/dist/server/src/config/auto-yes-config.js +14 -19
- package/dist/server/src/config/auto-yes-duration.js +76 -0
- package/dist/server/src/lib/auto-yes-poller-answer-target.js +38 -0
- package/dist/server/src/lib/auto-yes-poller-keys.js +35 -0
- package/dist/server/src/lib/auto-yes-poller-session-presence.js +26 -0
- package/dist/server/src/lib/auto-yes-poller-tick.js +233 -0
- package/dist/server/src/lib/auto-yes-poller.js +337 -376
- package/dist/server/src/lib/auto-yes-state.js +59 -4
- package/dist/server/src/lib/cli-tools/submit-verified-sender.js +235 -19
- package/dist/server/src/lib/db/chat-db.js +5 -1
- package/dist/server/src/lib/db/verification-db.js +23 -2
- package/dist/server/src/lib/detection/composer-text.js +215 -11
- package/dist/server/src/lib/detection/option-recommendation.js +120 -0
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice-approval-context.js +290 -0
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice-chrome.js +193 -0
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +402 -539
- package/dist/server/src/lib/detection/prompt-detector.js +92 -21
- package/dist/server/src/lib/detection/prompt-screen-key.js +60 -0
- package/dist/server/src/lib/detection/tools/antigravity/dialog.js +158 -35
- package/dist/server/src/lib/detection/tools/claude/detect.js +111 -10
- package/dist/server/src/lib/detection/tools/command-code/dialog.js +67 -0
- package/dist/server/src/lib/detection/tools/dialog-block.js +16 -0
- package/dist/server/src/lib/detection/upstream-faults.js +19 -2
- package/dist/server/src/lib/detection/waiting-screen-reading.js +98 -0
- package/dist/server/src/lib/hooks/permission-decision-service.js +7 -0
- package/dist/server/src/lib/hooks/structured-decision-response.js +1 -1
- package/dist/server/src/lib/polling/auto-yes-confirm-page.js +2 -2
- package/dist/server/src/lib/polling/auto-yes-confirmation-ledger-types.js +3 -0
- package/dist/server/src/lib/polling/auto-yes-confirmation-ledger.js +34 -3
- package/dist/server/src/lib/polling/auto-yes-decision-state.js +195 -0
- package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +139 -10
- package/dist/server/src/lib/polling/auto-yes-enter-fallback.js +14 -0
- package/dist/server/src/lib/polling/auto-yes-manual-answer.js +124 -0
- package/dist/server/src/lib/polling/auto-yes-option-effect.js +157 -0
- package/dist/server/src/lib/polling/auto-yes-policy.js +11 -5
- package/dist/server/src/lib/polling/auto-yes-poller-capture.js +15 -2
- package/dist/server/src/lib/polling/auto-yes-poller-generation.js +42 -1
- package/dist/server/src/lib/polling/auto-yes-poller-receipt-log.js +42 -5
- package/dist/server/src/lib/polling/auto-yes-poller-state.js +147 -49
- package/dist/server/src/lib/polling/auto-yes-poller-steps.js +172 -2
- package/dist/server/src/lib/polling/auto-yes-prompt-suppression.js +2 -2
- package/dist/server/src/lib/polling/auto-yes-question-choice.js +57 -0
- package/dist/server/src/lib/polling/auto-yes-resolver.js +96 -21
- package/dist/server/src/lib/polling/auto-yes-suppression-reason.js +33 -2
- package/dist/server/src/lib/polling/auto-yes-suppression-state.js +25 -1
- package/dist/server/src/lib/polling/prompt-screen-reading.js +232 -0
- package/dist/server/src/lib/polling/response-checker-dialog-gate.js +39 -0
- package/dist/server/src/lib/polling/response-checker.js +145 -58
- package/dist/server/src/lib/prompt-answer-sender.js +104 -10
- package/dist/server/src/lib/push/notification-dedup.js +15 -2
- package/dist/server/src/lib/push/prompt-card-state.js +140 -19
- package/dist/server/src/lib/push/prompt-push-gate.js +158 -12
- package/dist/server/src/lib/push/push-sender.js +23 -3
- package/dist/server/src/lib/push/resolution-push-notifier.js +14 -0
- package/dist/server/src/lib/push/waiting-push-notifier.js +139 -17
- package/dist/server/src/lib/realtime/terminal-broadcast.js +16 -0
- package/dist/server/src/lib/session/agent-event-state.js +25 -5
- package/dist/server/src/lib/session/agent-event-turn.js +140 -46
- package/dist/server/src/lib/session/cli-session.js +21 -2
- package/dist/server/src/lib/session/composer-clear.js +56 -4
- package/dist/server/src/lib/session/current-output-builder.js +66 -12
- package/dist/server/src/lib/session/send-attempt-state.js +24 -7
- package/dist/server/src/lib/session/waiting-episode-binding-observation.js +289 -0
- package/dist/server/src/lib/session/waiting-episode-binding-resolve.js +38 -0
- package/dist/server/src/lib/session/waiting-episode-binding.js +276 -0
- package/dist/server/src/lib/session/waiting-episode-state-ops.js +152 -0
- package/dist/server/src/lib/session/waiting-episode-state-store.js +202 -0
- package/dist/server/src/lib/session/waiting-episode-state-types.js +6 -0
- package/dist/server/src/lib/session/waiting-episode-state.js +68 -91
- package/dist/server/src/lib/session/waiting-episode-verdict.js +174 -0
- package/dist/server/src/lib/tmux/tmux-capture-cache.js +76 -11
- package/dist/server/src/lib/tmux/tmux.js +79 -9
- package/dist/server/src/lib/verification/gate-runner.js +172 -16
- package/dist/server/src/lib/verification/machine-lock.js +5 -0
- package/dist/server/src/lib/ws-server.js +18 -3
- package/dist/server/src/types/auto-yes-answer-mode.js +38 -0
- package/dist/server/src/types/auto-yes-decision.js +61 -0
- package/dist/server/src/types/auto-yes.js +6 -0
- package/dist/server/src/types/prompt-reading.js +32 -0
- package/dist/types/auto-yes-answer-mode.d.ts +35 -0
- package/dist/types/auto-yes-answer-mode.d.ts.map +1 -0
- package/dist/types/auto-yes-answer-mode.js +38 -0
- package/docs/en/user-guide/webapp-guide.md +47 -13
- package/package.json +1 -1
- package/public/sw.js +76 -4
- package/release-notes/0.48.0.json +57 -0
- package/release-notes/0.49.0.json +45 -0
- package/.next/server/chunks/1559.js +0 -2
- package/.next/server/chunks/2460.js +0 -1
- package/.next/server/chunks/5595.js +0 -1
- package/.next/server/chunks/610.js +0 -1
- package/.next/server/chunks/6722.js +0 -1
- package/.next/static/chunks/5371-a549a0d2c2044d41.js +0 -1
- package/.next/static/chunks/602-1c1488959215e140.js +0 -1
- package/.next/static/chunks/6288-09feba367cc2c65e.js +0 -1
- package/.next/static/chunks/8407-155f84e5ba05f1d5.js +0 -1
- package/.next/static/chunks/9079-24f9fa549ed298f1.js +0 -1
- package/.next/static/chunks/app/sessions/page-e02f1adb1d1c1ccc.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/files/[...path]/page-9cf1ecc59e36a004.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-46aced20b2b1c010.js +0 -1
- /package/.next/static/{etorRtpxbQqqOzdUeXdw2 → 3_JtAZaKMJEDFIIfkHv4n}/_buildManifest.js +0 -0
- /package/.next/static/{etorRtpxbQqqOzdUeXdw2 → 3_JtAZaKMJEDFIIfkHv4n}/_ssgManifest.js +0 -0
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.reopenedTurns = exports.agentTurns = exports.generationStartedAt = void 0;
|
|
13
|
+
exports.registerTurnOutcomeSink = registerTurnOutcomeSink;
|
|
14
|
+
exports.toGenerationRef = toGenerationRef;
|
|
15
|
+
exports.liveDecisionCount = liveDecisionCount;
|
|
13
16
|
exports.currentGeneration = currentGeneration;
|
|
14
17
|
exports.effectiveTurn = effectiveTurn;
|
|
15
18
|
exports.livePendingDecisions = livePendingDecisions;
|
|
@@ -71,6 +74,38 @@ exports.reopenedTurns = (0, global_state_1.getOrInitGlobal)('__agentEventReopene
|
|
|
71
74
|
* boundary rather than a cosmetic clash.
|
|
72
75
|
*/
|
|
73
76
|
const turnSequence = (0, global_state_1.getOrInitGlobal)('__agentEventTurnSeq', () => ({ value: 0 }));
|
|
77
|
+
/**
|
|
78
|
+
* Install the sink for outcomes this module produces outside a
|
|
79
|
+
* `recordAgentEvent` call. Registered by `waiting-episode-binding`, through
|
|
80
|
+
* `globalThis`, so this module imports nothing that imports it back.
|
|
81
|
+
*/
|
|
82
|
+
function registerTurnOutcomeSink(sink) {
|
|
83
|
+
globalThis.__agentEventTurnOutcomeSink = sink;
|
|
84
|
+
}
|
|
85
|
+
/** A generation as the waiting episode names it. */
|
|
86
|
+
function toGenerationRef(generation) {
|
|
87
|
+
return generation === null ? { kind: 'none' } : { kind: 'opened', at: generation };
|
|
88
|
+
}
|
|
89
|
+
/** Live decisions held by a record, counted without retiring the expired ones. */
|
|
90
|
+
function liveDecisionCount(turn, now) {
|
|
91
|
+
return turn.pendingDecisions.filter((decision) => (0, provisional_turn_1.isDecisionLive)(decision, now)).length;
|
|
92
|
+
}
|
|
93
|
+
/** Describe the instance's record before a transition rewrites it. */
|
|
94
|
+
function describePrevious(turn, eventSessionId, at) {
|
|
95
|
+
if (turn === null)
|
|
96
|
+
return { kind: 'none' };
|
|
97
|
+
if (turn.closedAt !== null)
|
|
98
|
+
return { kind: 'closed', turnId: turn.turnId, closedBy: turn.closedBy ?? 'stop' };
|
|
99
|
+
if (turn.openedAt === null) {
|
|
100
|
+
const decisions = liveDecisionCount(turn, at);
|
|
101
|
+
return decisions > 0
|
|
102
|
+
? { kind: 'dialog-only', turnId: turn.turnId, decisions, sessionId: turn.sessionId }
|
|
103
|
+
: { kind: 'display-only', turnId: turn.turnId };
|
|
104
|
+
}
|
|
105
|
+
return (0, provisional_turn_1.closesTurn)(turn, eventSessionId)
|
|
106
|
+
? { kind: 'open-same-session', turnId: turn.turnId }
|
|
107
|
+
: { kind: 'open-other-session', turnId: turn.turnId };
|
|
108
|
+
}
|
|
74
109
|
// =============================================================================
|
|
75
110
|
// Turn model (Issue #1930)
|
|
76
111
|
// =============================================================================
|
|
@@ -283,10 +318,18 @@ function observeScraperCompletionEvidence(worktreeId, cliToolId, instanceId, com
|
|
|
283
318
|
* were raised by a process that no longer exists, and answering one would
|
|
284
319
|
* deliver a verdict into a slot nobody is holding.
|
|
285
320
|
*/
|
|
286
|
-
function fenceTurnForNewGeneration(key, at) {
|
|
321
|
+
function fenceTurnForNewGeneration(key, at, source = 'session-start') {
|
|
287
322
|
const turn = exports.agentTurns.get(key);
|
|
323
|
+
// Issue #3798: reported whether or not a turn existed — the waiting episode
|
|
324
|
+
// is fenced by its own generation, not by the turn's.
|
|
325
|
+
const outcome = {
|
|
326
|
+
kind: 'generation-fenced',
|
|
327
|
+
source,
|
|
328
|
+
generation: toGenerationRef(currentGeneration(key)),
|
|
329
|
+
fencedTurnId: turn?.turnId ?? null,
|
|
330
|
+
};
|
|
288
331
|
if (!turn)
|
|
289
|
-
return;
|
|
332
|
+
return outcome;
|
|
290
333
|
evictDecisions(key, turn);
|
|
291
334
|
// A turn that had ALREADY ended is left where it is, which means the fence in
|
|
292
335
|
// `fencedTurn` hides it from here on. That asymmetry is deliberate: the
|
|
@@ -295,7 +338,7 @@ function fenceTurnForNewGeneration(key, at) {
|
|
|
295
338
|
// nobody has typed into yet. Before #1930 the same protection came from
|
|
296
339
|
// comparing the event's timestamp against the generation.
|
|
297
340
|
if (turn.closedAt !== null)
|
|
298
|
-
return;
|
|
341
|
+
return outcome;
|
|
299
342
|
// An OPEN turn is closed and carried across, so `capture --json` can say
|
|
300
343
|
// `closedBy: 'generation'` rather than going quiet. `getStructuredSessionState`
|
|
301
344
|
// reads that reason as "nothing is known", so it publishes no verdict either
|
|
@@ -304,6 +347,7 @@ function fenceTurnForNewGeneration(key, at) {
|
|
|
304
347
|
turn.closedAt = at;
|
|
305
348
|
turn.closedBy = 'generation';
|
|
306
349
|
turn.generationAt = at;
|
|
350
|
+
return outcome;
|
|
307
351
|
}
|
|
308
352
|
/**
|
|
309
353
|
* The turn transition: what one delivery does to {@link TurnRecord}
|
|
@@ -406,23 +450,32 @@ function applyTurnTransition(key, record) {
|
|
|
406
450
|
// An event stamped before the current generation was produced by a process
|
|
407
451
|
// that has been replaced. Refusing it here is what makes re-recording a stale
|
|
408
452
|
// `user_prompt_submit` at its original timestamp a no-op.
|
|
409
|
-
if (generation !== null && record.at < generation)
|
|
410
|
-
|
|
453
|
+
if (generation !== null && record.at < generation) {
|
|
454
|
+
if (record.event === 'stop')
|
|
455
|
+
return { kind: 'stop-rejected', reason: 'before-generation' };
|
|
456
|
+
if (record.event === 'session_end')
|
|
457
|
+
return { kind: 'session-end-rejected', reason: 'before-generation' };
|
|
458
|
+
return { kind: 'none' };
|
|
459
|
+
}
|
|
411
460
|
switch (record.event) {
|
|
412
|
-
case 'user_prompt_submit':
|
|
461
|
+
case 'user_prompt_submit': {
|
|
413
462
|
// Issue #3330: a queued notice the agent attached to its running turn
|
|
414
463
|
// continues that turn; any other prompt is a new one.
|
|
415
|
-
openTurn(key, record, generation, {
|
|
464
|
+
const outcome = openTurn(key, record, 'user_prompt_submit', generation, {
|
|
465
|
+
continueOpen: record.joinsOpenTurn === true,
|
|
466
|
+
});
|
|
416
467
|
releaseAllDecisions(key);
|
|
417
|
-
return;
|
|
418
|
-
|
|
419
|
-
|
|
468
|
+
return outcome;
|
|
469
|
+
}
|
|
470
|
+
case 'post_tool_use': {
|
|
471
|
+
const outcome = openTurn(key, record, 'post_tool_use', generation, { continueOpen: true });
|
|
420
472
|
// The tool call the dialog was gating has finished, so somebody answered
|
|
421
473
|
// it (Issue #1726). This is the release #1725 could not have: it had no
|
|
422
474
|
// event meaning "the human answered", only `Stop` meaning "the turn
|
|
423
475
|
// ended", which can be minutes later.
|
|
424
476
|
releaseAllDecisions(key);
|
|
425
|
-
return;
|
|
477
|
+
return outcome;
|
|
478
|
+
}
|
|
426
479
|
case 'pre_tool_use':
|
|
427
480
|
// Deliberately leaves the dialog alone (Issue #1726). It is the
|
|
428
481
|
// `AskUserQuestion` invocation, and a picker being *about to be drawn* is
|
|
@@ -432,28 +485,26 @@ function applyTurnTransition(key, record) {
|
|
|
432
485
|
// start of a turn when the agent's own `Stop` is the last thing that
|
|
433
486
|
// ended one. See the `after its stop` row above.
|
|
434
487
|
if (record.promptOpensTurns === true && endedByOwnStop(key))
|
|
435
|
-
return;
|
|
436
|
-
openTurn(key, record, generation, { continueOpen: true });
|
|
437
|
-
return;
|
|
488
|
+
return { kind: 'none' };
|
|
489
|
+
return openTurn(key, record, 'pre_tool_use', generation, { continueOpen: true });
|
|
438
490
|
case 'stop':
|
|
439
|
-
applyStopToTurn(key, record, generation);
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
applySessionEndToTurn(key, record);
|
|
491
|
+
return applyStopToTurn(key, record, generation);
|
|
492
|
+
case 'session_end': {
|
|
493
|
+
const outcome = applySessionEndToTurn(key, record);
|
|
443
494
|
releaseAllDecisions(key);
|
|
444
|
-
return;
|
|
495
|
+
return outcome;
|
|
496
|
+
}
|
|
445
497
|
case 'session_start':
|
|
446
498
|
// The generation was opened by `recordAgentEvent` before this ran, and
|
|
447
499
|
// `fenceTurnForNewGeneration` closed the turn with it. Nothing further:
|
|
448
500
|
// the frame carries no verdict, so it is not the displayed event either.
|
|
449
|
-
return;
|
|
501
|
+
return { kind: 'none' };
|
|
450
502
|
case 'notification':
|
|
451
|
-
applyNotificationToTurn(key, record, generation);
|
|
452
|
-
return;
|
|
503
|
+
return applyNotificationToTurn(key, record, generation);
|
|
453
504
|
default:
|
|
454
505
|
// exhaustive check: a new AgentEventType must decide its transition here
|
|
455
506
|
record.event;
|
|
456
|
-
return;
|
|
507
|
+
return { kind: 'none' };
|
|
457
508
|
}
|
|
458
509
|
}
|
|
459
510
|
/**
|
|
@@ -494,8 +545,10 @@ function displayOf(record) {
|
|
|
494
545
|
* this event's turn. False for `user_prompt_submit`, which IS a new turn —
|
|
495
546
|
* unless the source marked it as joining the running one (Issue #3330).
|
|
496
547
|
*/
|
|
497
|
-
function openTurn(key, record, generation, { continueOpen }) {
|
|
548
|
+
function openTurn(key, record, event, generation, { continueOpen }) {
|
|
498
549
|
const turn = fencedTurn(key);
|
|
550
|
+
// Issue #3798: read before anything below rewrites the record.
|
|
551
|
+
const previous = describePrevious(turn, record.sessionId, record.at);
|
|
499
552
|
const openHere = turn !== null &&
|
|
500
553
|
turn.closedAt === null &&
|
|
501
554
|
turn.openedAt !== null &&
|
|
@@ -506,7 +559,7 @@ function openTurn(key, record, generation, { continueOpen }) {
|
|
|
506
559
|
// partway through. Learning it is what lets a later `stop` be matched.
|
|
507
560
|
turn.sessionId ??= record.sessionId;
|
|
508
561
|
turn.scraperCompletionPolls = 0;
|
|
509
|
-
return;
|
|
562
|
+
return { kind: 'continued', turnId: turn.turnId };
|
|
510
563
|
}
|
|
511
564
|
// A dialog-only record (openedAt null) is not a turn; its decisions belong to
|
|
512
565
|
// the turn that is opening now, because that is when they were raised.
|
|
@@ -532,6 +585,7 @@ function openTurn(key, record, generation, { continueOpen }) {
|
|
|
532
585
|
exports.reopenedTurns.set(key, { turnId: opened.turnId, replaced: turn });
|
|
533
586
|
(0, agent_event_dedup_1.trimOldestEntries)(exports.reopenedTurns, agent_event_dedup_1.MAX_RECENT_EVENT_KEYS);
|
|
534
587
|
}
|
|
588
|
+
return { kind: 'opened', turnId: opened.turnId, event, generation: toGenerationRef(generation), previous };
|
|
535
589
|
}
|
|
536
590
|
/**
|
|
537
591
|
* Give a dropped copy's queued-notice mark its effect (Issue #3330).
|
|
@@ -590,6 +644,11 @@ function joinOpenTurnFromDuplicate(worktreeId, cliToolId, instanceId, record) {
|
|
|
590
644
|
scraperCompletionPolls: 0,
|
|
591
645
|
});
|
|
592
646
|
exports.reopenedTurns.delete(key);
|
|
647
|
+
// Issue #3798: a wait that opened under the discarded turn belongs to the
|
|
648
|
+
// turn put back. Told through the sink — this runs outside `recordAgentEvent`.
|
|
649
|
+
globalThis.__agentEventTurnOutcomeSink?.({ worktreeId, cliToolId, instanceId }, [
|
|
650
|
+
{ kind: 'restored', restoredTurnId: replaced.turnId, discardedTurnId: current.turnId },
|
|
651
|
+
]);
|
|
593
652
|
return true;
|
|
594
653
|
}
|
|
595
654
|
/**
|
|
@@ -604,15 +663,27 @@ function applyStopToTurn(key, record, generation) {
|
|
|
604
663
|
const turn = fencedTurn(key);
|
|
605
664
|
if (turn !== null && turn.closedAt === null && turn.openedAt !== null) {
|
|
606
665
|
if (!(0, provisional_turn_1.closesTurn)(turn, record.sessionId))
|
|
607
|
-
return;
|
|
666
|
+
return { kind: 'stop-rejected', reason: 'other-session' };
|
|
608
667
|
turn.closedAt = record.at;
|
|
609
668
|
turn.closedBy = 'stop';
|
|
610
669
|
turn.displayEvent = displayOf(record);
|
|
611
670
|
releaseAllDecisions(key);
|
|
612
|
-
return;
|
|
671
|
+
return { kind: 'stopped', turnId: turn.turnId, generation: toGenerationRef(generation) };
|
|
672
|
+
}
|
|
673
|
+
const previous = describePrevious(turn, record.sessionId, record.at);
|
|
674
|
+
// Issue #3798: a dialog raised by one agent session is not ended by another
|
|
675
|
+
// session's stop. Both ids are needed to tell — a record or a stop with no id
|
|
676
|
+
// is read as the same session, as `closesTurn` reads it. opencode publishes
|
|
677
|
+
// `session.idle` for every session its server holds (#1758 §5.6).
|
|
678
|
+
if (previous.kind === 'dialog-only' &&
|
|
679
|
+
previous.sessionId !== null &&
|
|
680
|
+
record.sessionId !== null &&
|
|
681
|
+
previous.sessionId !== record.sessionId) {
|
|
682
|
+
return { kind: 'stop-rejected', reason: 'other-session' };
|
|
613
683
|
}
|
|
684
|
+
const recordTurnId = nextTurnId(record.at);
|
|
614
685
|
exports.agentTurns.set(key, {
|
|
615
|
-
turnId:
|
|
686
|
+
turnId: recordTurnId,
|
|
616
687
|
sessionId: record.sessionId,
|
|
617
688
|
openedAt: null,
|
|
618
689
|
closedAt: record.at,
|
|
@@ -623,6 +694,7 @@ function applyStopToTurn(key, record, generation) {
|
|
|
623
694
|
scraperCompletionPolls: 0,
|
|
624
695
|
});
|
|
625
696
|
boundTurnMap();
|
|
697
|
+
return { kind: 'stop-without-turn', recordTurnId, generation: toGenerationRef(generation), previous };
|
|
626
698
|
}
|
|
627
699
|
/**
|
|
628
700
|
* `session_end`: the agent session this instance was talking to is gone.
|
|
@@ -643,11 +715,12 @@ function applyStopToTurn(key, record, generation) {
|
|
|
643
715
|
function applySessionEndToTurn(key, record) {
|
|
644
716
|
const turn = fencedTurn(key);
|
|
645
717
|
if (turn === null)
|
|
646
|
-
return;
|
|
718
|
+
return { kind: 'session-end-rejected', reason: 'no-turn' };
|
|
647
719
|
if (!(0, provisional_turn_1.closesTurn)(turn, record.sessionId))
|
|
648
|
-
return;
|
|
720
|
+
return { kind: 'session-end-rejected', reason: 'other-session' };
|
|
649
721
|
turn.closedAt = record.at;
|
|
650
722
|
turn.closedBy = 'session_end';
|
|
723
|
+
return { kind: 'session-ended', turnId: turn.turnId };
|
|
651
724
|
}
|
|
652
725
|
/**
|
|
653
726
|
* The notification rows of the transition table.
|
|
@@ -663,10 +736,9 @@ function applyNotificationToTurn(key, record, generation) {
|
|
|
663
736
|
// reached the agent. There is no dialog and there never was one for a
|
|
664
737
|
// human to answer — opening a record for it published `waiting` for the
|
|
665
738
|
// whole of the tool call that followed (measured at eight seconds).
|
|
666
|
-
releaseSettledDecision(key, record);
|
|
667
|
-
return;
|
|
739
|
+
return releaseSettledDecision(key, record);
|
|
668
740
|
}
|
|
669
|
-
openDecision(key, generation, {
|
|
741
|
+
const opened = openDecision(key, generation, {
|
|
670
742
|
source: 'notification',
|
|
671
743
|
at: record.at,
|
|
672
744
|
message: record.message ?? null,
|
|
@@ -679,16 +751,17 @@ function applyNotificationToTurn(key, record, generation) {
|
|
|
679
751
|
patterns: record.decisionPatterns ?? null,
|
|
680
752
|
decisionId: record.decisionId ?? null,
|
|
681
753
|
bootstrapDisplay: displayOf(record),
|
|
754
|
+
sessionId: record.sessionId,
|
|
682
755
|
});
|
|
683
|
-
return;
|
|
756
|
+
return { kind: 'decision-opened', ...opened };
|
|
684
757
|
}
|
|
685
758
|
if (record.detail === agent_event_types_1.PERMISSION_REPLIED_DETAIL) {
|
|
686
759
|
// Issue #1898. The agent's own statement that the dialog is gone — whoever
|
|
687
760
|
// answered it. Not a word this build reads a status from, so it decides
|
|
688
761
|
// nothing; all it does is retire the record.
|
|
689
762
|
if (record.promptSettled === true)
|
|
690
|
-
releaseSettledDecision(key, record);
|
|
691
|
-
return;
|
|
763
|
+
return releaseSettledDecision(key, record);
|
|
764
|
+
return { kind: 'none' };
|
|
692
765
|
}
|
|
693
766
|
if (record.detail === 'idle_prompt') {
|
|
694
767
|
// The agent reporting it is sitting at the composer waiting for input is the
|
|
@@ -697,10 +770,10 @@ function applyNotificationToTurn(key, record, generation) {
|
|
|
697
770
|
const turn = fencedTurn(key);
|
|
698
771
|
if (turn !== null && turn.closedAt === null) {
|
|
699
772
|
turn.displayEvent = displayOf(record);
|
|
700
|
-
return;
|
|
773
|
+
return { kind: 'none' };
|
|
701
774
|
}
|
|
702
775
|
if (turn !== null)
|
|
703
|
-
return;
|
|
776
|
+
return { kind: 'none' };
|
|
704
777
|
// Nothing to attach it to — the first thing this instance ever said, or the
|
|
705
778
|
// first since a generation. It still carries a verdict (`ready`), and #1723
|
|
706
779
|
// publishes it, so a display-only record is opened to hold it. `openedAt`
|
|
@@ -718,10 +791,11 @@ function applyNotificationToTurn(key, record, generation) {
|
|
|
718
791
|
scraperCompletionPolls: 0,
|
|
719
792
|
});
|
|
720
793
|
boundTurnMap();
|
|
721
|
-
return;
|
|
794
|
+
return { kind: 'none' };
|
|
722
795
|
}
|
|
723
796
|
// An unrecognised notification type is not evidence of anything, and guessing
|
|
724
797
|
// would be worse than the scraper.
|
|
798
|
+
return { kind: 'none' };
|
|
725
799
|
}
|
|
726
800
|
/**
|
|
727
801
|
* Open, or refresh, a dialog record on this instance's turn.
|
|
@@ -736,7 +810,7 @@ function openDecision(key, generation, input) {
|
|
|
736
810
|
if (turn === null) {
|
|
737
811
|
turn = {
|
|
738
812
|
turnId: nextTurnId(input.at),
|
|
739
|
-
sessionId: null,
|
|
813
|
+
sessionId: input.sessionId ?? null,
|
|
740
814
|
openedAt: null,
|
|
741
815
|
closedAt: null,
|
|
742
816
|
closedBy: null,
|
|
@@ -754,7 +828,7 @@ function openDecision(key, generation, input) {
|
|
|
754
828
|
// late. Re-open a dialog-only record rather than resurrecting the turn.
|
|
755
829
|
turn = {
|
|
756
830
|
turnId: nextTurnId(input.at),
|
|
757
|
-
sessionId: null,
|
|
831
|
+
sessionId: input.sessionId ?? null,
|
|
758
832
|
openedAt: null,
|
|
759
833
|
closedAt: null,
|
|
760
834
|
closedBy: null,
|
|
@@ -766,6 +840,15 @@ function openDecision(key, generation, input) {
|
|
|
766
840
|
exports.agentTurns.set(key, turn);
|
|
767
841
|
boundTurnMap();
|
|
768
842
|
}
|
|
843
|
+
else if (turn.openedAt === null && turn.sessionId === null) {
|
|
844
|
+
// A dialog-only record bootstrapped by a forecast with no session learns
|
|
845
|
+
// the session from the report that confirms it.
|
|
846
|
+
turn.sessionId = input.sessionId ?? null;
|
|
847
|
+
}
|
|
848
|
+
const opened = {
|
|
849
|
+
recordTurnId: turn.turnId,
|
|
850
|
+
recordKind: turn.openedAt !== null ? 'turn' : 'dialog-only',
|
|
851
|
+
};
|
|
769
852
|
// Issue #1930 / S1: an id that fails validation is DISCARDED, not truncated —
|
|
770
853
|
// a truncated id compares equal to a different id sharing its prefix, and the
|
|
771
854
|
// reply to one approval would then retire another's record.
|
|
@@ -807,14 +890,14 @@ function openDecision(key, generation, input) {
|
|
|
807
890
|
existing.source = 'notification';
|
|
808
891
|
existing.confirmedAt ??= input.at;
|
|
809
892
|
}
|
|
810
|
-
return;
|
|
893
|
+
return opened;
|
|
811
894
|
}
|
|
812
895
|
if (turn.pendingDecisions.length >= provisional_turn_1.MAX_PENDING_DECISIONS_PER_TURN) {
|
|
813
896
|
// S14(d). Counted rather than dropped in silence: an agent raising more
|
|
814
897
|
// approvals than this in one turn is a fact an operator has to be able to
|
|
815
898
|
// see, and the oldest is the one a human has been looking at.
|
|
816
899
|
(0, agent_event_dedup_1.dropsFor)(key).decisionOverflow += 1;
|
|
817
|
-
return;
|
|
900
|
+
return opened;
|
|
818
901
|
}
|
|
819
902
|
turn.pendingDecisions.push({
|
|
820
903
|
decisionId,
|
|
@@ -827,6 +910,7 @@ function openDecision(key, generation, input) {
|
|
|
827
910
|
scraperCorroborated: false,
|
|
828
911
|
recorded: false,
|
|
829
912
|
});
|
|
913
|
+
return opened;
|
|
830
914
|
}
|
|
831
915
|
/** Retire every dialog this instance was holding. */
|
|
832
916
|
function releaseAllDecisions(key) {
|
|
@@ -846,15 +930,25 @@ function releaseAllDecisions(key) {
|
|
|
846
930
|
function releaseSettledDecision(key, record) {
|
|
847
931
|
const turn = fencedTurn(key);
|
|
848
932
|
if (turn === null || turn.pendingDecisions.length === 0)
|
|
849
|
-
return;
|
|
933
|
+
return { kind: 'none' };
|
|
934
|
+
const before = turn.pendingDecisions.length;
|
|
850
935
|
const settledId = record.decisionId === null || record.decisionId === undefined
|
|
851
936
|
? null
|
|
852
937
|
: (0, provisional_turn_1.acceptExternalId)(record.decisionId);
|
|
853
938
|
if (settledId === null) {
|
|
854
939
|
turn.pendingDecisions = [];
|
|
855
|
-
return;
|
|
856
940
|
}
|
|
857
|
-
|
|
941
|
+
else {
|
|
942
|
+
turn.pendingDecisions = turn.pendingDecisions.filter((decision) => decision.decisionId !== null && decision.decisionId !== settledId);
|
|
943
|
+
}
|
|
944
|
+
// Issue #3798: an explicit answer — the one release that ends a wait.
|
|
945
|
+
return {
|
|
946
|
+
kind: 'decision-answered',
|
|
947
|
+
recordTurnId: turn.turnId,
|
|
948
|
+
recordKind: turn.openedAt !== null ? 'turn' : 'dialog-only',
|
|
949
|
+
before,
|
|
950
|
+
remaining: turn.pendingDecisions.length,
|
|
951
|
+
};
|
|
858
952
|
}
|
|
859
953
|
/** Keep the turn map bounded the way every other map in this module is. */
|
|
860
954
|
function boundTurnMap() {
|
|
@@ -35,6 +35,14 @@ const session_status_options_1 = require("../../lib/tmux/session-status-options"
|
|
|
35
35
|
const tmux_1 = require("../../lib/tmux/tmux");
|
|
36
36
|
const tmux_session_surface_1 = require("./tmux-session-surface");
|
|
37
37
|
const logger = (0, logger_1.createLogger)('cli-session');
|
|
38
|
+
/** Tell the observer this capture runs for, if any, where its frame came from (Issue #3798). */
|
|
39
|
+
function reportFrameMeta(meta) {
|
|
40
|
+
globalThis.__captureFrameMetaSink?.getStore()?.(meta);
|
|
41
|
+
}
|
|
42
|
+
/** Tell the observer this capture runs for, if any, whether its window cut the pane's top (Issue #3881 N4). */
|
|
43
|
+
function reportHeadCut(headCut) {
|
|
44
|
+
globalThis.__captureHeadCutSink?.getStore()?.(headCut);
|
|
45
|
+
}
|
|
38
46
|
function getDefaultTransport() {
|
|
39
47
|
return (0, polling_tmux_transport_1.getPollingTmuxTransport)();
|
|
40
48
|
}
|
|
@@ -95,7 +103,11 @@ async function captureSessionOutput(worktreeId, cliToolId, lines = 1000, instanc
|
|
|
95
103
|
throw new Error(`${cliTool.name} session ${sessionName} does not exist`);
|
|
96
104
|
}
|
|
97
105
|
return await transport.captureSnapshot(sessionName, { startLine: -tmux_capture_cache_1.CACHE_MAX_CAPTURE_LINES });
|
|
98
|
-
}
|
|
106
|
+
},
|
|
107
|
+
// Issue #3798: this call's own frame, to the observer it runs for
|
|
108
|
+
reportFrameMeta,
|
|
109
|
+
// Issue #3881 (third review N4): and whether the window cut its top
|
|
110
|
+
reportHeadCut);
|
|
99
111
|
log.debug('captureSessionOutput:success', {
|
|
100
112
|
actualLines: output.split('\n').length,
|
|
101
113
|
lastFewLines: output.split('\n').slice(-3).join(' | '),
|
|
@@ -132,18 +144,25 @@ async function captureSessionOutputFresh(worktreeId, cliToolId, lines = 5000, in
|
|
|
132
144
|
const transport = getDefaultTransport();
|
|
133
145
|
// Issue #3734: snapshot the generation before the capture starts
|
|
134
146
|
const generation = (0, tmux_capture_cache_1.getCaptureGeneration)(sessionName);
|
|
147
|
+
// Issue #3798: and the time, so the cache says when this frame was fetched,
|
|
148
|
+
// not when a slow capture came back
|
|
149
|
+
const fetchStartedAt = Date.now();
|
|
135
150
|
try {
|
|
136
151
|
const output = await transport.captureSnapshot(sessionName, { startLine: -lines });
|
|
137
152
|
// Write back to cache if non-empty [SEC4-007]. Skip it when the session was
|
|
138
153
|
// invalidated while waiting: the output may predate a send (Issue #3734).
|
|
139
154
|
if (output.length > 0) {
|
|
140
155
|
if ((0, tmux_capture_cache_1.isCaptureGenerationCurrent)(sessionName, generation)) {
|
|
141
|
-
(0, tmux_capture_cache_1.setCachedCapture)(sessionName, output, lines);
|
|
156
|
+
(0, tmux_capture_cache_1.setCachedCapture)(sessionName, output, lines, fetchStartedAt);
|
|
142
157
|
}
|
|
143
158
|
}
|
|
144
159
|
else {
|
|
145
160
|
(0, tmux_capture_cache_1.invalidateCache)(sessionName);
|
|
146
161
|
}
|
|
162
|
+
reportFrameMeta({ fetchStartedAt, source: 'fetched' });
|
|
163
|
+
const headCutSink = globalThis.__captureHeadCutSink?.getStore();
|
|
164
|
+
if (headCutSink)
|
|
165
|
+
headCutSink((0, tmux_capture_cache_1.sliceCutsHead)(output, lines));
|
|
147
166
|
return (0, tmux_capture_cache_1.sliceOutput)(output, lines);
|
|
148
167
|
}
|
|
149
168
|
catch (error) {
|
|
@@ -30,13 +30,60 @@
|
|
|
30
30
|
* frame back to the browser.
|
|
31
31
|
*/
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
exports.COMPOSER_CLEAR_REDRAW_DELAY_MS = exports.MAX_COMPOSER_CLEAR_PASSES = void 0;
|
|
33
|
+
exports.COMPOSER_CLEAR_REDRAW_DELAY_MS = exports.MAX_COMPOSER_CLEAR_PASSES = exports.findCodexLiveComposerRow = exports.codexDialogBelow = void 0;
|
|
34
|
+
exports.isCodexPasteTokenOnly = isCodexPasteTokenOnly;
|
|
34
35
|
exports.clearComposer = clearComposer;
|
|
35
36
|
const tmux_1 = require("../../lib/tmux/tmux");
|
|
36
37
|
const tmux_capture_cache_1 = require("../../lib/tmux/tmux-capture-cache");
|
|
37
38
|
const composer_text_1 = require("../../lib/detection/composer-text");
|
|
39
|
+
Object.defineProperty(exports, "codexDialogBelow", { enumerable: true, get: function () { return composer_text_1.codexDialogBelow; } });
|
|
40
|
+
Object.defineProperty(exports, "findCodexLiveComposerRow", { enumerable: true, get: function () { return composer_text_1.findCodexLiveComposerRow; } });
|
|
38
41
|
const logger_1 = require("../../lib/logger");
|
|
39
42
|
const logger = (0, logger_1.createLogger)('composer-clear');
|
|
43
|
+
/**
|
|
44
|
+
* The composer as this loop reads it.
|
|
45
|
+
*
|
|
46
|
+
* {@link extractLiveComposerText} — the reading the unsent bar is drawn from
|
|
47
|
+
* (Issue #3927) — and for codex one more reading when it finds no
|
|
48
|
+
* composer (Issue #3906): a body of more paragraphs than the extractor's four
|
|
49
|
+
* blocks — the partly arrived paste the sender reads as `pasting` and withdraws
|
|
50
|
+
* through this function — is still a composer holding text. Only `content` is
|
|
51
|
+
* taken from that reading; anything else stays `no_composer`, so a frame this
|
|
52
|
+
* reading cannot vouch for is never reported as emptied.
|
|
53
|
+
*
|
|
54
|
+
* A composer the extractor does find is still not the live one when a dialog
|
|
55
|
+
* option is drawn below it ({@link codexDialogBelow}): that frame is
|
|
56
|
+
* `no_composer`, so no `C-e`+`C-u` goes into the dialog.
|
|
57
|
+
*/
|
|
58
|
+
function readClearComposer(capture, cliToolId) {
|
|
59
|
+
const read = (0, composer_text_1.extractLiveComposerText)(capture, cliToolId);
|
|
60
|
+
if (cliToolId !== 'codex' || read.state !== 'no_composer')
|
|
61
|
+
return read;
|
|
62
|
+
const rows = capture.split('\n');
|
|
63
|
+
const row = (0, composer_text_1.findCodexLiveComposerRow)(rows);
|
|
64
|
+
if (row < 0)
|
|
65
|
+
return read;
|
|
66
|
+
const held = (0, composer_text_1.readCodexComposerFrom)(rows, row);
|
|
67
|
+
return held.state === 'content' ? held : read;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A codex composer holding exactly one collapsed paste placeholder and nothing
|
|
71
|
+
* else (Issue #3937) — the one frame a pass sends `C-e`+`BSpace` for instead of
|
|
72
|
+
* `C-e`+`C-u` ({@link clearComposerPasteToken}).
|
|
73
|
+
*
|
|
74
|
+
* Anything more than the bare placeholder keeps the `C-e`+`C-u` pass, because
|
|
75
|
+
* none of it has been measured on a live codex: a placeholder with typed text
|
|
76
|
+
* after it (`C-e`+`BSpace` would eat the last typed character, not the
|
|
77
|
+
* placeholder), two placeholders, and a body quoting the placeholder's wording
|
|
78
|
+
* among other text. A body that is nothing but that wording typed out is not
|
|
79
|
+
* told apart here; one `BSpace` takes its `]`, and from the next read on it is
|
|
80
|
+
* ordinary text again — `C-e`+`C-u` — so the read-back still decides.
|
|
81
|
+
*/
|
|
82
|
+
const CODEX_PASTE_TOKEN_ONLY = /^\[Pasted Content \d+ chars?\]$/;
|
|
83
|
+
/** Whether a pass over this reading should send `C-e`+`BSpace` (Issue #3937). */
|
|
84
|
+
function isCodexPasteTokenOnly(read, cliToolId) {
|
|
85
|
+
return cliToolId === 'codex' && read.state === 'content' && CODEX_PASTE_TOKEN_ONLY.test(read.text.trim());
|
|
86
|
+
}
|
|
40
87
|
/**
|
|
41
88
|
* Upper bound on `C-e`+`C-u` passes.
|
|
42
89
|
*
|
|
@@ -67,15 +114,20 @@ async function clearComposer(sessionName, cliToolId, options = {}) {
|
|
|
67
114
|
const delay = options.delay ?? defaultDelay;
|
|
68
115
|
const maxPasses = options.maxPasses ?? exports.MAX_COMPOSER_CLEAR_PASSES;
|
|
69
116
|
let passes = 0;
|
|
70
|
-
let result = (
|
|
117
|
+
let result = readClearComposer(await capture(sessionName), cliToolId);
|
|
71
118
|
// Snapshot before the first pass: every later read shows less of it (a pass
|
|
72
119
|
// eats one row), so this is the only moment the full text exists.
|
|
73
120
|
const discardedText = result.state === 'content' ? result.text : '';
|
|
74
121
|
while (result.state === 'content' && passes < maxPasses) {
|
|
75
|
-
|
|
122
|
+
if (isCodexPasteTokenOnly(result, cliToolId)) {
|
|
123
|
+
await (options.sendClearPasteToken ?? tmux_1.clearComposerPasteToken)(sessionName);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
await sendClear(sessionName);
|
|
127
|
+
}
|
|
76
128
|
passes++;
|
|
77
129
|
await delay(exports.COMPOSER_CLEAR_REDRAW_DELAY_MS);
|
|
78
|
-
result = (
|
|
130
|
+
result = readClearComposer(await capture(sessionName), cliToolId);
|
|
79
131
|
}
|
|
80
132
|
// Whatever happened above, the cached frame is now stale: the poller and the
|
|
81
133
|
// WebSocket push both read through `captureSessionOutput`, and serving the
|