commandmate 0.48.0 → 0.49.1
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 +292 -285
- package/.next/app-path-routes-manifest.json +35 -34
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +9 -9
- package/.next/required-server-files.json +1 -1
- package/.next/routes-manifest.json +8 -0
- 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_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.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/[relayId]/route.js +1 -0
- package/.next/server/app/api/relays/[relayId]/route.js.nft.json +1 -0
- package/.next/server/app/api/relays/[relayId]/route_client-reference-manifest.js +1 -0
- 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.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.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.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.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 +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.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.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.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.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.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.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.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.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.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.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.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.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_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.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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_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 +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route.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 +144 -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.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 +103 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_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.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.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.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 +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 -34
- package/.next/server/chunks/1601.js +2 -2
- package/.next/server/chunks/1656.js +2 -2
- 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/3241.js +1 -1
- package/.next/server/chunks/3773.js +1 -0
- package/.next/server/chunks/3801.js +31 -0
- package/.next/server/chunks/4243.js +1 -1
- package/.next/server/chunks/4248.js +1 -1
- package/.next/server/chunks/5209.js +1 -1
- package/.next/server/chunks/5354.js +1 -1
- package/.next/server/chunks/{9130.js → 5630.js} +1 -1
- package/.next/server/chunks/5775.js +1 -0
- package/.next/server/chunks/610.js +1 -0
- 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 +1 -1
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/6808.js +4 -0
- package/.next/server/chunks/7023.js +14 -0
- package/.next/server/chunks/7604.js +2 -2
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8581.js +16 -16
- package/.next/server/chunks/8728.js +3 -3
- package/.next/server/chunks/8782.js +1 -1
- package/.next/server/chunks/8791.js +1 -1
- package/.next/server/chunks/8807.js +63 -53
- package/.next/server/chunks/8918.js +103 -1
- package/.next/server/chunks/9198.js +144 -0
- package/.next/server/chunks/9390.js +1 -1
- package/.next/server/chunks/9584.js +1 -1
- package/.next/server/chunks/9627.js +4 -4
- package/.next/server/chunks/9731.js +3 -3
- 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-26139a8a2f1adbe8.js → 2407-675ba6b21844dc3b.js} +1 -1
- package/.next/static/chunks/{2619-a305ad4810f1393a.js → 2619-04bc32f026a0d946.js} +1 -1
- package/.next/static/chunks/{2863-f0121af1cbbedb3b.js → 2863-7173dc305dffc4f6.js} +1 -1
- package/.next/static/chunks/3931-1a1abab16248f14d.js +1 -0
- package/.next/static/chunks/6288-6fadbba6e84393b2.js +1 -0
- package/.next/static/chunks/7665-e9ef6e0a85b9fa49.js +1 -0
- package/.next/static/chunks/{8165-c68b3dc844210e6a.js → 8165-263172c17ae8e8c3.js} +1 -1
- package/.next/static/chunks/8606-ce17ffa77f39608e.js +1 -0
- package/.next/static/chunks/app/api/agents/update/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/agents/versions/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/app/release-notes/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/app/update/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/app/update-check/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/auth/login/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/auth/status/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/capabilities/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/status/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/external-apps/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/fs/browse/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/fs/recent-paths/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/hooks/agent-event/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/hooks/claude-done/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/hooks/permission-request/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/metrics/vibe/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/ollama/models/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/push/escalation/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/push/subscriptions/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/push/vapid/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/relays/[relayId]/cancel/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/relays/[relayId]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/relays/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/remote/pair/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/repositories/excluded/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/repositories/restore/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/repositories/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/repositories/scan/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/repositories/sync/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/repositories/validate-path/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/settings/default-agents/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/settings/default-surface-mode/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/sidebar/group-order/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/skills/[id]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/skills/installations/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/skills/operations/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/skills/reindex/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/skills/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/slash-commands/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/templates/[id]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/templates/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/direct-input/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/instances/notes/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/strict/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/layout-8bfac4724277b47f.js +1 -0
- package/.next/static/chunks/app/manifest.webmanifest/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/proxy/[...path]/route-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/sessions/page-890fd50ec9739973.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]/layout-a4f129c451de7859.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-f6d3ab8185d93aae.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/terminal/{page-c601f3b3ece6557e.js → page-373ea37b16d930c7.js} +1 -1
- package/.next/static/css/c1e307d05daf93b6.css +1 -0
- package/.next/trace +13 -13
- package/.next/types/app/api/relays/[relayId]/route.ts +347 -0
- package/.next/types/routes.d.ts +2 -1
- package/.next/types/validator.ts +9 -0
- package/dist/cli/commands/ask.d.ts.map +1 -1
- package/dist/cli/commands/ask.js +178 -13
- package/dist/cli/commands/auto-yes.d.ts.map +1 -1
- package/dist/cli/commands/auto-yes.js +3 -5
- package/dist/cli/commands/capture.d.ts.map +1 -1
- package/dist/cli/commands/capture.js +5 -0
- package/dist/cli/commands/message-dispatch.d.ts +25 -5
- package/dist/cli/commands/message-dispatch.d.ts.map +1 -1
- package/dist/cli/commands/message-dispatch.js +92 -6
- package/dist/cli/commands/relays.d.ts +25 -2
- package/dist/cli/commands/relays.d.ts.map +1 -1
- package/dist/cli/commands/relays.js +69 -5
- package/dist/cli/commands/respond.d.ts +12 -0
- package/dist/cli/commands/respond.d.ts.map +1 -1
- package/dist/cli/commands/respond.js +63 -1
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +10 -10
- package/dist/cli/commands/verify.d.ts.map +1 -1
- package/dist/cli/commands/verify.js +8 -1
- package/dist/cli/commands/wait-hook-stop-settle.d.ts +66 -0
- package/dist/cli/commands/wait-hook-stop-settle.d.ts.map +1 -0
- package/dist/cli/commands/wait-hook-stop-settle.js +150 -0
- package/dist/cli/commands/wait-instance.d.ts +21 -0
- package/dist/cli/commands/wait-instance.d.ts.map +1 -0
- package/dist/cli/commands/wait-instance.js +41 -0
- package/dist/cli/commands/wait-notices.d.ts +87 -0
- package/dist/cli/commands/wait-notices.d.ts.map +1 -0
- package/dist/cli/commands/wait-notices.js +301 -0
- package/dist/cli/commands/wait-poll-bookkeeping.d.ts +15 -0
- package/dist/cli/commands/wait-poll-bookkeeping.d.ts.map +1 -0
- package/dist/cli/commands/wait-poll-bookkeeping.js +57 -0
- package/dist/cli/commands/wait-poll-state.d.ts +118 -0
- package/dist/cli/commands/wait-poll-state.d.ts.map +1 -0
- package/dist/cli/commands/wait-poll-state.js +6 -0
- package/dist/cli/commands/wait-timing.d.ts +46 -0
- package/dist/cli/commands/wait-timing.d.ts.map +1 -0
- package/dist/cli/commands/wait-timing.js +99 -0
- package/dist/cli/commands/wait-turn-boundary.d.ts +284 -0
- package/dist/cli/commands/wait-turn-boundary.d.ts.map +1 -0
- package/dist/cli/commands/wait-turn-boundary.js +427 -0
- package/dist/cli/commands/wait-verify.d.ts +50 -0
- package/dist/cli/commands/wait-verify.d.ts.map +1 -0
- package/dist/cli/commands/wait-verify.js +124 -0
- package/dist/cli/commands/wait.d.ts +6 -105
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +207 -959
- 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 +25 -2
- package/dist/cli/types/api-responses.d.ts +76 -4
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/utils/api-client.d.ts +15 -1
- package/dist/cli/utils/api-client.d.ts.map +1 -1
- package/dist/cli/utils/api-client.js +7 -1
- package/dist/cli/utils/reply-ledger.d.ts +79 -0
- package/dist/cli/utils/reply-ledger.d.ts.map +1 -1
- package/dist/cli/utils/reply-ledger.js +141 -1
- 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/session/send-attempt-types.d.ts +23 -1
- package/dist/lib/session/send-attempt-types.d.ts.map +1 -1
- package/dist/lib/session/send-attempt-types.js +9 -1
- package/dist/server/locales/en/worktree.json +18 -3
- package/dist/server/locales/ja/worktree.json +18 -3
- 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.js +49 -10
- package/dist/server/src/lib/auto-yes-state.js +9 -2
- package/dist/server/src/lib/cli-tools/antigravity.js +40 -7
- package/dist/server/src/lib/cli-tools/codex.js +60 -11
- package/dist/server/src/lib/cli-tools/command-code-plan-review.js +24 -2
- package/dist/server/src/lib/cli-tools/copilot.js +120 -30
- package/dist/server/src/lib/cli-tools/gemini.js +28 -9
- package/dist/server/src/lib/cli-tools/opencode.js +55 -13
- package/dist/server/src/lib/cli-tools/submit-composer-read.js +580 -0
- package/dist/server/src/lib/cli-tools/submit-verified-sender.js +374 -516
- package/dist/server/src/lib/db/migrations/index.js +2 -0
- package/dist/server/src/lib/db/migrations/pre-migration-backup.js +266 -0
- package/dist/server/src/lib/db/migrations/runner.js +37 -4
- package/dist/server/src/lib/db/migrations/v62-session-relays-bind.js +102 -0
- package/dist/server/src/lib/db/relay-bind-db.js +437 -0
- package/dist/server/src/lib/db/relay-db.js +59 -96
- package/dist/server/src/lib/detection/composer-text.js +215 -11
- 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 +8 -191
- package/dist/server/src/lib/detection/upstream-faults.js +56 -5
- package/dist/server/src/lib/hooks/sources/opencode/client.js +12 -6
- package/dist/server/src/lib/hooks/structured-decision-response.js +1 -1
- package/dist/server/src/lib/polling/auto-yes-manual-answer.js +4 -2
- package/dist/server/src/lib/polling/response-checker.js +15 -16
- package/dist/server/src/lib/prompt-answer-errors.js +288 -0
- package/dist/server/src/lib/prompt-answer-sender.js +264 -288
- package/dist/server/src/lib/push/failure-episode-state.js +4 -1
- package/dist/server/src/lib/realtime/terminal-broadcast.js +1 -4
- package/dist/server/src/lib/realtime-snippet.js +54 -0
- package/dist/server/src/lib/relay/relay-bind.js +294 -0
- package/dist/server/src/lib/relay/relay-boot.js +51 -0
- package/dist/server/src/lib/relay/relay-bound-reply.js +519 -0
- package/dist/server/src/lib/relay/relay-delivery.js +134 -220
- package/dist/server/src/lib/relay/relay-messages.js +39 -4
- package/dist/server/src/lib/relay/relay-overlap.js +92 -0
- package/dist/server/src/lib/relay/relay-system-line.js +3 -2
- package/dist/server/src/lib/relay/types.js +12 -1
- package/dist/server/src/lib/session/agent-session-lifecycle.js +18 -0
- package/dist/server/src/lib/session/claude-session.js +41 -6
- package/dist/server/src/lib/session/composer-clear.js +109 -4
- package/dist/server/src/lib/session/current-output-builder.js +23 -6
- package/dist/server/src/lib/session/instance-input-lock.js +664 -0
- package/dist/server/src/lib/session/send-attempt-state.js +19 -1
- package/dist/server/src/lib/session/send-attempt-types.js +9 -1
- package/dist/server/src/lib/session/send-user-message.js +82 -13
- 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 +26 -339
- package/dist/server/src/lib/tmux/tmux.js +25 -0
- package/dist/server/src/lib/verification/gate-runner.js +11 -4
- package/docs/en/user-guide/webapp-guide.md +15 -10
- package/package.json +1 -1
- package/release-notes/0.49.0.json +45 -0
- package/release-notes/0.49.1.json +66 -0
- package/.next/server/chunks/1210.js +0 -1
- package/.next/server/chunks/1945.js +0 -14
- package/.next/server/chunks/1990.js +0 -103
- package/.next/server/chunks/4194.js +0 -67
- package/.next/server/chunks/4280.js +0 -1
- package/.next/server/chunks/5845.js +0 -1
- package/.next/server/chunks/6722.js +0 -1
- package/.next/server/chunks/720.js +0 -103
- package/.next/server/chunks/936.js +0 -1
- package/.next/server/chunks/9540.js +0 -1
- package/.next/static/chunks/2099-c3e0ab70a1b95dd3.js +0 -1
- package/.next/static/chunks/5371-a549a0d2c2044d41.js +0 -1
- package/.next/static/chunks/6288-09feba367cc2c65e.js +0 -1
- package/.next/static/chunks/8606-cf6bdbff44a764cf.js +0 -1
- package/.next/static/chunks/9079-406b84d3cc891a87.js +0 -1
- package/.next/static/chunks/app/api/agents/update/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/agents/versions/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/app/release-notes/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/app/update/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/app/update-check/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/auth/login/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/auth/status/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/capabilities/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/status/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/external-apps/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/fs/browse/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/fs/recent-paths/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/hooks/agent-event/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/hooks/claude-done/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/hooks/permission-request/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/metrics/vibe/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/ollama/models/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/push/escalation/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/push/subscriptions/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/push/vapid/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/relays/[relayId]/cancel/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/relays/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/remote/pair/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/repositories/excluded/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/repositories/restore/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/repositories/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/repositories/scan/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/repositories/sync/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/repositories/validate-path/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/settings/default-agents/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/settings/default-surface-mode/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/sidebar/group-order/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/skills/[id]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/skills/installations/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/skills/operations/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/skills/reindex/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/skills/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/slash-commands/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/templates/[id]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/templates/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/direct-input/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/instances/notes/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/strict/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/layout-46b4cbf07520d9b6.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/proxy/[...path]/route-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/sessions/page-fb241bed579c67aa.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/files/[...path]/page-9cf1ecc59e36a004.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/layout-c81284a9d8b35304.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-cbc7749a33450cc5.js +0 -1
- package/.next/static/css/743f79ff19ab91e9.css +0 -1
- /package/.next/static/{PTlAswXLq8PAe2vUJ8dVP → fqfSDqQMweROeHUzOt_m1}/_buildManifest.js +0 -0
- /package/.next/static/{PTlAswXLq8PAe2vUJ8dVP → fqfSDqQMweROeHUzOt_m1}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,664 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* One writer at a time per agent composer (Issue #3945).
|
|
4
|
+
*
|
|
5
|
+
* Several entry points type into the same tmux composer — `POST /send` (CLI
|
|
6
|
+
* `send` / `ask`, chat, phone, session tiles), the timer manager, relay
|
|
7
|
+
* delivery, the terminal route — and until this module nothing ordered them.
|
|
8
|
+
* A send that took the composer back (`withdrawUnsentBody`, the pre-send clear)
|
|
9
|
+
* could therefore erase another send's text, and a late codex paste placeholder
|
|
10
|
+
* (`[Pasted Content N chars]`, #3937) could not be told apart from the next
|
|
11
|
+
* send's: the placeholder carries only a count.
|
|
12
|
+
*
|
|
13
|
+
* Four things live here, all per tmux session name (one per worktree+instance,
|
|
14
|
+
* `resolveSessionName`):
|
|
15
|
+
*
|
|
16
|
+
* 1. **The lock.** {@link withInstanceInputLock} runs a function as the
|
|
17
|
+
* composer's only writer. Waiters queue FIFO; a waiter that is not admitted
|
|
18
|
+
* within {@link INSTANCE_INPUT_LOCK_WAIT_MS} is removed from the queue and
|
|
19
|
+
* never runs (`InstanceInputLockTimeoutError`, nothing typed). Once admitted
|
|
20
|
+
* there is no processing deadline: ownership passes on only when the owner's
|
|
21
|
+
* function settles, on every path (`finally`).
|
|
22
|
+
* 2. **The ticket.** Every admission takes a fresh, never-reused number. The
|
|
23
|
+
* owner's ticket is "current" until it releases or the session is replaced
|
|
24
|
+
* ({@link invalidateInstanceInput}); every key a sender sends is preceded by
|
|
25
|
+
* `ticket.isCurrent()`, so work a stale owner still has in flight cannot
|
|
26
|
+
* reach the next owner's composer.
|
|
27
|
+
* 3. **Ownership in the async context.** A call made inside an owner's function
|
|
28
|
+
* (the sender inside `sendUserMessage`'s lock) joins the owner's ticket
|
|
29
|
+
* instead of queueing behind itself; no lock is ever acquired twice. A
|
|
30
|
+
* context whose ticket was revoked is refused, never given a new one.
|
|
31
|
+
* 4. **The carried paste mark.** A send whose body may still arrive after it
|
|
32
|
+
* has given up (an `unseen` paste, a read that threw, a clear that could not
|
|
33
|
+
* be confirmed) leaves a mark. The next owner does not start typing until the
|
|
34
|
+
* mark expires ({@link CARRIED_PASTE_MARK_TTL_MS}): a placeholder of the same
|
|
35
|
+
* count as its own body would be indistinguishable from it. The mark belongs
|
|
36
|
+
* to the session, not to the send that left it, so the next owner is the one
|
|
37
|
+
* that handles it, and the stale sender cannot resume.
|
|
38
|
+
*
|
|
39
|
+
* Issue #3952 adds a second way to hold it. The answers the server types at a
|
|
40
|
+
* screen it read — prompt answers, Auto-Yes, the strict respond, plan-review
|
|
41
|
+
* keys, readiness dialogs — are `shared` writers: kept off a send's composer
|
|
42
|
+
* and a send off theirs, but not ordered against each other
|
|
43
|
+
* ({@link InstanceInputMode}). {@link answerUnderInstanceInputLock} reads the
|
|
44
|
+
* screen again when a send came between the answer's read and its keys. A
|
|
45
|
+
* person's own keys (the terminal, `direct-input`, special keys) and the
|
|
46
|
+
* interrupt's Escape do not take part, by decision.
|
|
47
|
+
*
|
|
48
|
+
* In memory and on `globalThis` (`getOrInitGlobal`) for the reason every shared
|
|
49
|
+
* map in this subsystem is: the send route, the terminal route and the clear
|
|
50
|
+
* route are separate bundles under `next dev`, and a lock per bundle would order
|
|
51
|
+
* nothing. A server restart forgets every mark — a placeholder that arrives
|
|
52
|
+
* after a restart is left to the next send's pre-send clear, as it was before
|
|
53
|
+
* this module. The lock is per process: two servers sharing one tmux server are
|
|
54
|
+
* not ordered by it (out of scope for #3945).
|
|
55
|
+
*
|
|
56
|
+
* @module lib/session/instance-input-lock
|
|
57
|
+
*/
|
|
58
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
|
+
exports.InputBoundaryRefusedError = exports.INPUT_BOUNDARY_REFUSED_CODE = exports.InstanceInputSessionReplacedError = exports.InstanceInputOwnershipLostError = exports.InstanceInputLockTimeoutError = exports.INSTANCE_INPUT_OWNERSHIP_LOST_CODE = exports.INSTANCE_INPUT_SESSION_REPLACED_CODE = exports.INSTANCE_INPUT_LOCK_TIMEOUT_CODE = exports.CARRIED_PASTE_MARK_TTL_MS = exports.LATE_PASTE_OBSERVE_MS = exports.INSTANCE_INPUT_LOCK_WAIT_MS = void 0;
|
|
60
|
+
exports.currentInstanceInputTicket = currentInstanceInputTicket;
|
|
61
|
+
exports.withInstanceInputLock = withInstanceInputLock;
|
|
62
|
+
exports.instanceInputReadMark = instanceInputReadMark;
|
|
63
|
+
exports.instanceInputLaunchReadMark = instanceInputLaunchReadMark;
|
|
64
|
+
exports.answerUnderInstanceInputLock = answerUnderInstanceInputLock;
|
|
65
|
+
exports.leaveCarriedPasteMark = leaveCarriedPasteMark;
|
|
66
|
+
exports.getCarriedPasteMark = getCarriedPasteMark;
|
|
67
|
+
exports.clearExpiredCarriedPasteMark = clearExpiredCarriedPasteMark;
|
|
68
|
+
exports.waitOutCarriedPasteMark = waitOutCarriedPasteMark;
|
|
69
|
+
exports.invalidateInstanceInput = invalidateInstanceInput;
|
|
70
|
+
exports.isInputBoundaryRefusal = isInputBoundaryRefusal;
|
|
71
|
+
exports.observeInputStart = observeInputStart;
|
|
72
|
+
exports.noteInputStart = noteInputStart;
|
|
73
|
+
exports.noteDispatchStart = noteDispatchStart;
|
|
74
|
+
exports.noteDispatchFailed = noteDispatchFailed;
|
|
75
|
+
exports.resetInstanceInputLocks = resetInstanceInputLocks;
|
|
76
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
77
|
+
const global_state_1 = require("../../lib/global-state");
|
|
78
|
+
const logger_1 = require("../../lib/logger");
|
|
79
|
+
const logger = (0, logger_1.createLogger)('session/instance-input-lock');
|
|
80
|
+
/**
|
|
81
|
+
* How long a writer waits to be admitted before it gives up without typing.
|
|
82
|
+
*
|
|
83
|
+
* Has to cover what can be ahead of it: an owner's whole send (a pasted body's
|
|
84
|
+
* 2 s check plus {@link LATE_PASTE_OBSERVE_MS}, a typed codex body's 5 s,
|
|
85
|
+
* the clear passes and the read-back), and a carried mark's
|
|
86
|
+
* {@link CARRIED_PASTE_MARK_TTL_MS}. A unit test pins mark < this.
|
|
87
|
+
*/
|
|
88
|
+
exports.INSTANCE_INPUT_LOCK_WAIT_MS = 60_000;
|
|
89
|
+
/**
|
|
90
|
+
* How long a send that saw nothing of its paste keeps watching the composer,
|
|
91
|
+
* still holding the lock, before it gives up (Issue #3945 stage 4).
|
|
92
|
+
*
|
|
93
|
+
* PROVISIONAL: #3937 has not yet measured how late codex 0.164.0 draws a
|
|
94
|
+
* placeholder. Three seconds beyond the 2 s check is a guess, to be replaced by
|
|
95
|
+
* that measurement.
|
|
96
|
+
*/
|
|
97
|
+
exports.LATE_PASTE_OBSERVE_MS = 3_000;
|
|
98
|
+
/**
|
|
99
|
+
* How long a carried paste mark holds the next send off the composer.
|
|
100
|
+
*
|
|
101
|
+
* PROVISIONAL, as {@link LATE_PASTE_OBSERVE_MS}. It must stay below
|
|
102
|
+
* {@link INSTANCE_INPUT_LOCK_WAIT_MS}, or waiting it out would itself make the
|
|
103
|
+
* next send `not-sent`.
|
|
104
|
+
*/
|
|
105
|
+
exports.CARRIED_PASTE_MARK_TTL_MS = 8_000;
|
|
106
|
+
/** `code` on the error a writer gets when it was not admitted in time. */
|
|
107
|
+
exports.INSTANCE_INPUT_LOCK_TIMEOUT_CODE = 'INSTANCE_INPUT_LOCK_TIMEOUT';
|
|
108
|
+
/** `code` on the error a waiter gets when its session was replaced while it waited. */
|
|
109
|
+
exports.INSTANCE_INPUT_SESSION_REPLACED_CODE = 'INSTANCE_INPUT_SESSION_REPLACED';
|
|
110
|
+
/** `code` on the error a call from a revoked owner's context gets. */
|
|
111
|
+
exports.INSTANCE_INPUT_OWNERSHIP_LOST_CODE = 'INSTANCE_INPUT_OWNERSHIP_LOST';
|
|
112
|
+
class TicketImpl {
|
|
113
|
+
sessionName;
|
|
114
|
+
generation;
|
|
115
|
+
waited;
|
|
116
|
+
mode;
|
|
117
|
+
released = false;
|
|
118
|
+
revoked = false;
|
|
119
|
+
constructor(sessionName, generation, waited, mode = 'exclusive') {
|
|
120
|
+
this.sessionName = sessionName;
|
|
121
|
+
this.generation = generation;
|
|
122
|
+
this.waited = waited;
|
|
123
|
+
this.mode = mode;
|
|
124
|
+
}
|
|
125
|
+
isCurrent() {
|
|
126
|
+
if (this.released || this.revoked)
|
|
127
|
+
return false;
|
|
128
|
+
const entry = entries.get(this.sessionName);
|
|
129
|
+
return this.mode === 'shared' ? entry?.shared.has(this) === true : entry?.owner === this;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** Thrown, before anything runs, by a writer that was not admitted in time. */
|
|
133
|
+
class InstanceInputLockTimeoutError extends Error {
|
|
134
|
+
code = exports.INSTANCE_INPUT_LOCK_TIMEOUT_CODE;
|
|
135
|
+
constructor(sessionName, waitedMs) {
|
|
136
|
+
super(`Another send to session ${sessionName} held its composer for over ${waitedMs}ms; ` +
|
|
137
|
+
'input lock not acquired, nothing was typed (Issue #3945).');
|
|
138
|
+
this.name = 'InstanceInputLockTimeoutError';
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.InstanceInputLockTimeoutError = InstanceInputLockTimeoutError;
|
|
142
|
+
/**
|
|
143
|
+
* Thrown, before anything runs, by a call made from a context whose ticket was
|
|
144
|
+
* revoked (review-1 #1): the session was replaced while the owner was working
|
|
145
|
+
* (a readiness wait, a relaunch check). Such a call is the old request; it must
|
|
146
|
+
* not take a fresh ticket and type into the new session.
|
|
147
|
+
*/
|
|
148
|
+
class InstanceInputOwnershipLostError extends Error {
|
|
149
|
+
code = exports.INSTANCE_INPUT_OWNERSHIP_LOST_CODE;
|
|
150
|
+
constructor(sessionName) {
|
|
151
|
+
super(`Session ${sessionName} was replaced while this send held its composer; ` +
|
|
152
|
+
'input lock lost, nothing was typed (Issue #3945).');
|
|
153
|
+
this.name = 'InstanceInputOwnershipLostError';
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
exports.InstanceInputOwnershipLostError = InstanceInputOwnershipLostError;
|
|
157
|
+
/** Thrown to a waiter whose session was killed or recreated while it waited. */
|
|
158
|
+
class InstanceInputSessionReplacedError extends Error {
|
|
159
|
+
code = exports.INSTANCE_INPUT_SESSION_REPLACED_CODE;
|
|
160
|
+
constructor(sessionName) {
|
|
161
|
+
super(`Session ${sessionName} was replaced while this send waited for its composer; ` +
|
|
162
|
+
'input lock not acquired, nothing was typed (Issue #3945).');
|
|
163
|
+
this.name = 'InstanceInputSessionReplacedError';
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
exports.InstanceInputSessionReplacedError = InstanceInputSessionReplacedError;
|
|
167
|
+
const entries = (0, global_state_1.getOrInitGlobal)('__instanceInputLocks', () => new Map());
|
|
168
|
+
const generationSeq = (0, global_state_1.getOrInitGlobal)('__instanceInputGeneration', () => ({
|
|
169
|
+
last: 0,
|
|
170
|
+
lastExclusive: 0,
|
|
171
|
+
exclusiveEvents: 0,
|
|
172
|
+
sharedReleases: 0,
|
|
173
|
+
}));
|
|
174
|
+
/**
|
|
175
|
+
* Count an `exclusive` writer coming or going (Issue #3952 review P2-2). The
|
|
176
|
+
* read mark moves on both, so a read taken while a send held the composer is
|
|
177
|
+
* read again once that send has let go, even when no other send came in.
|
|
178
|
+
*/
|
|
179
|
+
function noteExclusiveEvent() {
|
|
180
|
+
generationSeq.exclusiveEvents = (generationSeq.exclusiveEvents ?? 0) + 1;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Count a `shared` writer letting go (Issue #3975 review P2-1). Only the
|
|
184
|
+
* launch's mark ({@link instanceInputLaunchReadMark}) reads it: an answer that
|
|
185
|
+
* finished between a launch's read and its key may have closed the dialog,
|
|
186
|
+
* while `shared` answers keep their #3952 behaviour toward one another.
|
|
187
|
+
*/
|
|
188
|
+
function noteSharedRelease() {
|
|
189
|
+
generationSeq.sharedReleases = (generationSeq.sharedReleases ?? 0) + 1;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Tickets revoked by a session replacement (review-2 P1). On `globalThis`, not
|
|
193
|
+
* a field read through `instanceof`: under `next dev` a ticket can be issued by
|
|
194
|
+
* one load of this module (the releasing owner's) and read by another (the
|
|
195
|
+
* waiter's), and a per-load class would not recognise it.
|
|
196
|
+
*/
|
|
197
|
+
const revokedTickets = (0, global_state_1.getOrInitGlobal)('__instanceInputRevoked', () => new WeakSet());
|
|
198
|
+
const ownerScope = (0, global_state_1.getOrInitGlobal)('__instanceInputOwnerScope', () => new node_async_hooks_1.AsyncLocalStorage());
|
|
199
|
+
function entryOf(sessionName) {
|
|
200
|
+
let entry = entries.get(sessionName);
|
|
201
|
+
if (entry === undefined) {
|
|
202
|
+
entry = { owner: null, shared: new Set(), queue: [], mark: null };
|
|
203
|
+
entries.set(sessionName, entry);
|
|
204
|
+
}
|
|
205
|
+
return entry;
|
|
206
|
+
}
|
|
207
|
+
/** Drop an entry that holds nothing, so the map stays bounded by live sessions. */
|
|
208
|
+
function pruneEntry(sessionName) {
|
|
209
|
+
const entry = entries.get(sessionName);
|
|
210
|
+
if (entry === undefined)
|
|
211
|
+
return;
|
|
212
|
+
if (entry.mark !== null && entry.mark.expiresAt <= Date.now())
|
|
213
|
+
entry.mark = null;
|
|
214
|
+
if (entry.owner === null && entry.shared.size === 0 && entry.queue.length === 0 && entry.mark === null) {
|
|
215
|
+
entries.delete(sessionName);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function issueTicket(sessionName, waited, mode = 'exclusive') {
|
|
219
|
+
generationSeq.last += 1;
|
|
220
|
+
if (mode === 'exclusive') {
|
|
221
|
+
generationSeq.lastExclusive = generationSeq.last;
|
|
222
|
+
noteExclusiveEvent();
|
|
223
|
+
}
|
|
224
|
+
return new TicketImpl(sessionName, generationSeq.last, waited, mode);
|
|
225
|
+
}
|
|
226
|
+
/** Whether a writer of `mode` may be admitted now, ahead of nobody. */
|
|
227
|
+
function admissible(entry, mode) {
|
|
228
|
+
return entry.owner === null && (mode === 'shared' || entry.shared.size === 0);
|
|
229
|
+
}
|
|
230
|
+
function grant(entry, ticket) {
|
|
231
|
+
if (ticket.mode === 'shared')
|
|
232
|
+
entry.shared.add(ticket);
|
|
233
|
+
else
|
|
234
|
+
entry.owner = ticket;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Admit waiters from the head of the queue, in arrival order: an `exclusive`
|
|
238
|
+
* one once the composer is free, a run of `shared` ones together while no
|
|
239
|
+
* `exclusive` writer owns it. A `shared` waiter behind a queued `exclusive`
|
|
240
|
+
* one is not let past it.
|
|
241
|
+
*/
|
|
242
|
+
function admitWaiters(sessionName, entry) {
|
|
243
|
+
while (entry.queue.length > 0 && admissible(entry, entry.queue[0].mode)) {
|
|
244
|
+
const next = entry.queue.shift();
|
|
245
|
+
clearTimeout(next.timer);
|
|
246
|
+
const nextTicket = issueTicket(sessionName, true, next.mode);
|
|
247
|
+
grant(entry, nextTicket);
|
|
248
|
+
next.admit(nextTicket);
|
|
249
|
+
if (next.mode === 'exclusive')
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function acquire(sessionName, waitMs, mode = 'exclusive') {
|
|
254
|
+
const entry = entryOf(sessionName);
|
|
255
|
+
if (entry.queue.length === 0 && admissible(entry, mode)) {
|
|
256
|
+
const ticket = issueTicket(sessionName, false, mode);
|
|
257
|
+
grant(entry, ticket);
|
|
258
|
+
return Promise.resolve(ticket);
|
|
259
|
+
}
|
|
260
|
+
return new Promise((resolve, reject) => {
|
|
261
|
+
const waiter = {
|
|
262
|
+
mode,
|
|
263
|
+
admit: resolve,
|
|
264
|
+
reject,
|
|
265
|
+
timer: setTimeout(() => {
|
|
266
|
+
// Cancelled, not run: the waiter leaves the queue and its function is
|
|
267
|
+
// never called, so it cannot type after the owner it was waiting on.
|
|
268
|
+
const index = entry.queue.indexOf(waiter);
|
|
269
|
+
if (index >= 0)
|
|
270
|
+
entry.queue.splice(index, 1);
|
|
271
|
+
logger.warn('instance-input-lock-timeout', { sessionName, waitedMs: waitMs, mode });
|
|
272
|
+
// An `exclusive` waiter that gave up may have been all that held the
|
|
273
|
+
// `shared` ones behind it back.
|
|
274
|
+
admitWaiters(sessionName, entry);
|
|
275
|
+
pruneEntry(sessionName);
|
|
276
|
+
reject(new InstanceInputLockTimeoutError(sessionName, waitMs));
|
|
277
|
+
}, waitMs),
|
|
278
|
+
};
|
|
279
|
+
entry.queue.push(waiter);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function release(ticket) {
|
|
283
|
+
ticket.released = true;
|
|
284
|
+
const entry = entries.get(ticket.sessionName);
|
|
285
|
+
if (entry === undefined)
|
|
286
|
+
return;
|
|
287
|
+
if (ticket.mode === 'shared') {
|
|
288
|
+
if (!entry.shared.delete(ticket))
|
|
289
|
+
return;
|
|
290
|
+
noteSharedRelease();
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
if (entry.owner !== ticket)
|
|
294
|
+
return;
|
|
295
|
+
entry.owner = null;
|
|
296
|
+
noteExclusiveEvent();
|
|
297
|
+
}
|
|
298
|
+
admitWaiters(ticket.sessionName, entry);
|
|
299
|
+
pruneEntry(ticket.sessionName);
|
|
300
|
+
}
|
|
301
|
+
/** The ticket the calling async context already owns for `sessionName`, if any. */
|
|
302
|
+
function currentInstanceInputTicket(sessionName) {
|
|
303
|
+
const ticket = ownerScope.getStore()?.get(sessionName);
|
|
304
|
+
return ticket !== undefined && ticket.isCurrent() ? ticket : null;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Run `fn` as the only writer to `sessionName`'s composer.
|
|
308
|
+
*
|
|
309
|
+
* A call from inside a function that already owns the session joins that
|
|
310
|
+
* ownership (same ticket, no second acquisition, released by the outer call).
|
|
311
|
+
* A call from inside an owner whose ticket was revoked (the session was
|
|
312
|
+
* replaced) is refused instead: it belongs to the old request, and acquiring
|
|
313
|
+
* afresh would let that request type into the new session (review-1 #1). A
|
|
314
|
+
* context whose owner simply finished is not an owner any more and acquires as
|
|
315
|
+
* any other caller does.
|
|
316
|
+
*
|
|
317
|
+
* @throws InstanceInputOwnershipLostError when the calling context's ticket was revoked; `fn` did not run
|
|
318
|
+
* @throws InstanceInputLockTimeoutError when not admitted within `waitMs`; `fn` did not run
|
|
319
|
+
* @throws InstanceInputSessionReplacedError when the session was replaced while waiting; `fn` did not run
|
|
320
|
+
*/
|
|
321
|
+
async function withInstanceInputLock(sessionName, fn, options = {}) {
|
|
322
|
+
const inScope = ownerScope.getStore()?.get(sessionName);
|
|
323
|
+
if (inScope !== undefined) {
|
|
324
|
+
if (inScope.isCurrent())
|
|
325
|
+
return fn(inScope);
|
|
326
|
+
if (revokedTickets.has(inScope)) {
|
|
327
|
+
logger.warn('instance-input-stale-context-refused', { sessionName, generation: inScope.generation });
|
|
328
|
+
throw new InstanceInputOwnershipLostError(sessionName);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
const ticket = await acquire(sessionName, options.waitMs ?? exports.INSTANCE_INPUT_LOCK_WAIT_MS, options.mode);
|
|
332
|
+
try {
|
|
333
|
+
const scope = new Map(ownerScope.getStore() ?? []);
|
|
334
|
+
scope.set(sessionName, ticket);
|
|
335
|
+
return await ownerScope.run(scope, () => fn(ticket));
|
|
336
|
+
}
|
|
337
|
+
finally {
|
|
338
|
+
release(ticket);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Where the order of `exclusive` writers stands now (Issue #3952). An answer
|
|
343
|
+
* takes it right before it reads the screen it will answer, and hands it to
|
|
344
|
+
* {@link answerUnderInstanceInputLock}: a send admitted after it may have typed
|
|
345
|
+
* between that read and the answer's keys. It moves when a send is admitted
|
|
346
|
+
* and when one lets go (review P2-2): a read taken while a send held the
|
|
347
|
+
* composer saw a screen that send was still typing at, and an answer admitted
|
|
348
|
+
* after that send let go — without queueing, and with no other send since —
|
|
349
|
+
* must read it again as well. The count is process-wide, not per session: a
|
|
350
|
+
* send to another session costs a needless re-read, never a missed one.
|
|
351
|
+
*/
|
|
352
|
+
function instanceInputReadMark() {
|
|
353
|
+
return generationSeq.exclusiveEvents ?? 0;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* The read mark a launch's own key (`mode: 'exclusive'` in
|
|
357
|
+
* {@link answerUnderInstanceInputLock}) is decided on (Issue #3975 review
|
|
358
|
+
* P2-1). It moves as {@link instanceInputReadMark} does and also when a
|
|
359
|
+
* `shared` answer lets go: a `respond` that started and finished between the
|
|
360
|
+
* launch's read and its key never makes the launch wait, yet may have answered
|
|
361
|
+
* the dialog the key was for. Both counts only grow, so their sum moves
|
|
362
|
+
* whenever either does.
|
|
363
|
+
*/
|
|
364
|
+
function instanceInputLaunchReadMark() {
|
|
365
|
+
return (generationSeq.exclusiveEvents ?? 0) + (generationSeq.sharedReleases ?? 0);
|
|
366
|
+
}
|
|
367
|
+
function skipOfLockError(error) {
|
|
368
|
+
const code = typeof error === 'object' && error !== null ? error.code : undefined;
|
|
369
|
+
if (code === exports.INSTANCE_INPUT_LOCK_TIMEOUT_CODE)
|
|
370
|
+
return 'input-lock-timeout';
|
|
371
|
+
if (code === exports.INSTANCE_INPUT_SESSION_REPLACED_CODE)
|
|
372
|
+
return 'session-replaced';
|
|
373
|
+
if (code === exports.INSTANCE_INPUT_OWNERSHIP_LOST_CODE)
|
|
374
|
+
return 'input-lock-lost';
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Type an answer the server decided on its own reading of the screen — a
|
|
379
|
+
* readiness dialog, a prompt answer, a plan-review step — as a `shared` writer
|
|
380
|
+
* (Issue #3952): after any send that holds the composer, and with every send
|
|
381
|
+
* held off until it is done.
|
|
382
|
+
*
|
|
383
|
+
* The screen was read before the lock. When a send was admitted or let go
|
|
384
|
+
* after that read (`readMark`, from {@link instanceInputReadMark}) or the
|
|
385
|
+
* answer had to queue, the screen may have moved under it: `stillApplies` reads it again,
|
|
386
|
+
* and the answer is typed only when it still says yes. A call that joins its
|
|
387
|
+
* context's own ticket (the readiness wait inside a send that holds the lock)
|
|
388
|
+
* held the composer since before its read, so nothing is read again.
|
|
389
|
+
*
|
|
390
|
+
* Never types after a refusal, and never throws for one: a lock that was not
|
|
391
|
+
* admitted in time, a session replaced, a ticket lost, a screen that moved or
|
|
392
|
+
* could not be read all come back as `{ answered: false }`. Errors thrown by
|
|
393
|
+
* `answer` itself propagate.
|
|
394
|
+
*
|
|
395
|
+
* Issue #3975: `mode: 'exclusive'` is for a launch's own keys (gemini's launch
|
|
396
|
+
* line and trust Enter, Claude's trust keys): kept off a send's composer as an
|
|
397
|
+
* answer is, and also ordered against the answers — a `respond` to the same
|
|
398
|
+
* dialog then reads the screen again after the launch's key. The mark is
|
|
399
|
+
* compared before admission there, since the launch's own admission moves it,
|
|
400
|
+
* and `readMark` is {@link instanceInputLaunchReadMark}, so a `shared` answer
|
|
401
|
+
* that finished after the launch's read also makes it read again (review P2-1).
|
|
402
|
+
*/
|
|
403
|
+
async function answerUnderInstanceInputLock(sessionName, readMark, stillApplies, answer, options = {}) {
|
|
404
|
+
// A context that already owns the composer (a send's own readiness wait)
|
|
405
|
+
// has held it since before its read: it joins, and nothing is read again.
|
|
406
|
+
const joined = currentInstanceInputTicket(sessionName) !== null;
|
|
407
|
+
const mode = options.mode ?? 'shared';
|
|
408
|
+
const movedBeforeAdmission = (mode === 'exclusive' ? instanceInputLaunchReadMark() : instanceInputReadMark()) !== readMark;
|
|
409
|
+
let admitted = false;
|
|
410
|
+
try {
|
|
411
|
+
return await withInstanceInputLock(sessionName, async (ticket) => {
|
|
412
|
+
admitted = true;
|
|
413
|
+
const sendSinceRead = !joined &&
|
|
414
|
+
(ticket.waited || movedBeforeAdmission || (mode === 'shared' && instanceInputReadMark() !== readMark));
|
|
415
|
+
if (sendSinceRead) {
|
|
416
|
+
let applies;
|
|
417
|
+
try {
|
|
418
|
+
applies = await stillApplies();
|
|
419
|
+
}
|
|
420
|
+
catch (error) {
|
|
421
|
+
logger.warn('instance-input-answer-recheck-failed', {
|
|
422
|
+
sessionName,
|
|
423
|
+
error: error instanceof Error ? error.message : String(error),
|
|
424
|
+
});
|
|
425
|
+
return { answered: false, reason: 'recheck-failed' };
|
|
426
|
+
}
|
|
427
|
+
if (!applies) {
|
|
428
|
+
logger.info('instance-input-answer-target-changed', { sessionName, generation: ticket.generation });
|
|
429
|
+
return { answered: false, reason: 'target-changed' };
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
if (!ticket.isCurrent())
|
|
433
|
+
return { answered: false, reason: 'input-lock-lost' };
|
|
434
|
+
return { answered: true, value: await answer(ticket) };
|
|
435
|
+
}, { waitMs: options.waitMs, mode });
|
|
436
|
+
}
|
|
437
|
+
catch (error) {
|
|
438
|
+
// Only the lock's own refusals, before `fn` ran; anything `answer` threw
|
|
439
|
+
// after it was admitted may have typed, and is the caller's to judge.
|
|
440
|
+
const skip = admitted ? null : skipOfLockError(error);
|
|
441
|
+
if (skip === null)
|
|
442
|
+
throw error;
|
|
443
|
+
logger.warn('instance-input-answer-not-admitted', { sessionName, reason: skip });
|
|
444
|
+
return { answered: false, reason: skip };
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Leave a mark that a body may still arrive in the composer (stage 4).
|
|
449
|
+
*
|
|
450
|
+
* Only the current owner may leave one; a stale ticket's mark is dropped (its
|
|
451
|
+
* send no longer speaks for the composer).
|
|
452
|
+
*/
|
|
453
|
+
function leaveCarriedPasteMark(ticket, now = Date.now()) {
|
|
454
|
+
if (!ticket.isCurrent()) {
|
|
455
|
+
logger.warn('carried-paste-mark-skipped-not-owner', {
|
|
456
|
+
sessionName: ticket.sessionName,
|
|
457
|
+
generation: ticket.generation,
|
|
458
|
+
});
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
const entry = entryOf(ticket.sessionName);
|
|
462
|
+
entry.mark = { originGeneration: ticket.generation, at: now, expiresAt: now + exports.CARRIED_PASTE_MARK_TTL_MS };
|
|
463
|
+
logger.warn('carried-paste-mark-left', {
|
|
464
|
+
sessionName: ticket.sessionName,
|
|
465
|
+
generation: ticket.generation,
|
|
466
|
+
expiresAt: entry.mark.expiresAt,
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
/** The session's unexpired mark, or null. */
|
|
470
|
+
function getCarriedPasteMark(sessionName, now = Date.now()) {
|
|
471
|
+
const mark = entries.get(sessionName)?.mark ?? null;
|
|
472
|
+
return mark !== null && mark.expiresAt > now ? mark : null;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Take the mark down after waiting it out. Only the current owner may, and only
|
|
476
|
+
* once it has expired: a failed or refused send leaves it in place, with its
|
|
477
|
+
* original expiry.
|
|
478
|
+
*/
|
|
479
|
+
function clearExpiredCarriedPasteMark(ticket, now = Date.now()) {
|
|
480
|
+
if (!ticket.isCurrent())
|
|
481
|
+
return;
|
|
482
|
+
const entry = entries.get(ticket.sessionName);
|
|
483
|
+
if (entry?.mark && entry.mark.expiresAt <= now)
|
|
484
|
+
entry.mark = null;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Hold the owner off the composer until the session's carried paste mark
|
|
488
|
+
* expires, then take it down (review-1 #5). For writers that cannot read the
|
|
489
|
+
* composer — copilot's own `/model` and selection-list keys; the shared sender
|
|
490
|
+
* reads and withdraws while it waits (`waitOutCarriedPaste`). Returns early when
|
|
491
|
+
* the ticket stops being current; the caller's owner check then refuses.
|
|
492
|
+
*
|
|
493
|
+
* @returns Whether there was a mark to wait out
|
|
494
|
+
*/
|
|
495
|
+
async function waitOutCarriedPasteMark(ticket) {
|
|
496
|
+
const mark = getCarriedPasteMark(ticket.sessionName);
|
|
497
|
+
if (mark === null)
|
|
498
|
+
return false;
|
|
499
|
+
logger.warn('carried-paste-mark-wait', {
|
|
500
|
+
sessionName: ticket.sessionName,
|
|
501
|
+
originGeneration: mark.originGeneration,
|
|
502
|
+
generation: ticket.generation,
|
|
503
|
+
remainingMs: mark.expiresAt - Date.now(),
|
|
504
|
+
});
|
|
505
|
+
while (Date.now() < mark.expiresAt && ticket.isCurrent()) {
|
|
506
|
+
await new Promise((resolve) => setTimeout(resolve, mark.expiresAt - Date.now()));
|
|
507
|
+
}
|
|
508
|
+
clearExpiredCarriedPasteMark(ticket);
|
|
509
|
+
return true;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* The session is being killed or recreated (Issue #3945 review #7): its mark
|
|
513
|
+
* no longer describes the new process's composer, its waiters must not type into
|
|
514
|
+
* the new process, and an owner that is not the caller (a send still in flight
|
|
515
|
+
* against the old pane) loses its ticket.
|
|
516
|
+
*
|
|
517
|
+
* The caller's own ticket survives — that is a send relaunching its own pane
|
|
518
|
+
* (codex's `requireSession({ relaunch: true })`), which goes on to type into the
|
|
519
|
+
* pane it just created.
|
|
520
|
+
*/
|
|
521
|
+
function invalidateInstanceInput(sessionName) {
|
|
522
|
+
const entry = entries.get(sessionName);
|
|
523
|
+
if (entry === undefined)
|
|
524
|
+
return;
|
|
525
|
+
entry.mark = null;
|
|
526
|
+
const own = currentInstanceInputTicket(sessionName);
|
|
527
|
+
if (entry.owner !== null && entry.owner !== own) {
|
|
528
|
+
entry.owner.revoked = true;
|
|
529
|
+
revokedTickets.add(entry.owner);
|
|
530
|
+
entry.owner = null;
|
|
531
|
+
noteExclusiveEvent();
|
|
532
|
+
}
|
|
533
|
+
for (const holder of [...entry.shared]) {
|
|
534
|
+
if (holder === own)
|
|
535
|
+
continue;
|
|
536
|
+
holder.revoked = true;
|
|
537
|
+
revokedTickets.add(holder);
|
|
538
|
+
entry.shared.delete(holder);
|
|
539
|
+
noteSharedRelease();
|
|
540
|
+
}
|
|
541
|
+
const waiters = entry.queue.splice(0, entry.queue.length);
|
|
542
|
+
for (const waiter of waiters) {
|
|
543
|
+
clearTimeout(waiter.timer);
|
|
544
|
+
waiter.reject(new InstanceInputSessionReplacedError(sessionName));
|
|
545
|
+
}
|
|
546
|
+
if (waiters.length > 0)
|
|
547
|
+
logger.info('instance-input-waiters-expired', { sessionName, waiters: waiters.length });
|
|
548
|
+
pruneEntry(sessionName);
|
|
549
|
+
}
|
|
550
|
+
/** `code` on the error a refused {@link InputBoundaryHooks.beforeInput} becomes. */
|
|
551
|
+
exports.INPUT_BOUNDARY_REFUSED_CODE = 'INPUT_BOUNDARY_REFUSED';
|
|
552
|
+
/** The boundary hook refused the input: nothing was typed or dispatched (Issue #3957). */
|
|
553
|
+
class InputBoundaryRefusedError extends Error {
|
|
554
|
+
code = exports.INPUT_BOUNDARY_REFUSED_CODE;
|
|
555
|
+
constructor(cause) {
|
|
556
|
+
super(`Input boundary could not be recorded (${cause instanceof Error ? cause.message : String(cause)}); ` +
|
|
557
|
+
'nothing was typed (Issue #3957)');
|
|
558
|
+
this.name = 'InputBoundaryRefusedError';
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
exports.InputBoundaryRefusedError = InputBoundaryRefusedError;
|
|
562
|
+
/** Whether an error (or the message a wrapper copied from it) is a boundary refusal. */
|
|
563
|
+
function isInputBoundaryRefusal(error) {
|
|
564
|
+
if (error instanceof InputBoundaryRefusedError)
|
|
565
|
+
return true;
|
|
566
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
567
|
+
return /Input boundary could not be recorded \(.*\); nothing was typed \(Issue #3957\)/s.test(message);
|
|
568
|
+
}
|
|
569
|
+
const inputStartScope = (0, global_state_1.getOrInitGlobal)('__instanceInputStartScope', () => new node_async_hooks_1.AsyncLocalStorage());
|
|
570
|
+
/**
|
|
571
|
+
* Run `fn` and report when the body it sends started going into the composer
|
|
572
|
+
* (Issue #3953).
|
|
573
|
+
*
|
|
574
|
+
* A send's stamp is what `wait`'s #1975 gate compares with the agent's last
|
|
575
|
+
* `stop`. Read before the input lock, it was older than a previous turn that
|
|
576
|
+
* ended while this send queued for the lock, waited out a carried paste mark,
|
|
577
|
+
* re-read the pane or cleared the composer — and that turn's `stop` read as the
|
|
578
|
+
* end of this one. The sender calls {@link noteInputStart} right before the
|
|
579
|
+
* first key of the body, after all of those, so the stamp is later than any
|
|
580
|
+
* turn that ended before the body and earlier than the `stop` of the turn it
|
|
581
|
+
* starts.
|
|
582
|
+
*
|
|
583
|
+
* @param onStart - Called once, synchronously inside the first
|
|
584
|
+
* {@link noteInputStart}, so a caller can read state as of the moment the
|
|
585
|
+
* body started going in (Issue #3957: the send route's open-turn reading). A
|
|
586
|
+
* throw is logged and does not fail the send.
|
|
587
|
+
* @returns `fn`'s value, and the moment input started — null when nothing in
|
|
588
|
+
* `fn` noted one (a path that never types a body: opencode's HTTP delivery,
|
|
589
|
+
* or a send refused before its first key). Never set when `fn` throws.
|
|
590
|
+
*/
|
|
591
|
+
async function observeInputStart(fn, onStart, boundary) {
|
|
592
|
+
const observer = { at: null, onStart, boundary, dispatchOpen: false };
|
|
593
|
+
const value = await inputStartScope.run(observer, fn);
|
|
594
|
+
return { value, inputStartedAt: observer.at };
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Note that the body is about to be typed or pasted (Issue #3953): the first
|
|
598
|
+
* call in an {@link observeInputStart} context fixes the moment; later ones (a
|
|
599
|
+
* second body, a retry) and calls outside one do nothing.
|
|
600
|
+
*/
|
|
601
|
+
function noteInputStart(now = new Date()) {
|
|
602
|
+
const observer = inputStartScope.getStore();
|
|
603
|
+
if (observer === undefined || observer.at !== null)
|
|
604
|
+
return;
|
|
605
|
+
// Issue #3957: the required hook first, and outside the catch below — a
|
|
606
|
+
// refusal must stop the sender before its first key.
|
|
607
|
+
runBoundaryHook(observer, now, 'input_start');
|
|
608
|
+
observer.at = now;
|
|
609
|
+
try {
|
|
610
|
+
observer.onStart?.(now);
|
|
611
|
+
}
|
|
612
|
+
catch (error) {
|
|
613
|
+
logger.warn('input-start-observer-failed', { error: error instanceof Error ? error.message : String(error) });
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
function runBoundaryHook(observer, at, kind) {
|
|
617
|
+
if (!observer.boundary)
|
|
618
|
+
return;
|
|
619
|
+
try {
|
|
620
|
+
observer.boundary.beforeInput(at, kind);
|
|
621
|
+
}
|
|
622
|
+
catch (error) {
|
|
623
|
+
throw error instanceof InputBoundaryRefusedError ? error : new InputBoundaryRefusedError(error);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Note that a body is about to be DISPATCHED without being typed (Issue #3957):
|
|
628
|
+
* opencode's HTTP send, which reports no input start. Runs the required
|
|
629
|
+
* boundary hook with kind `dispatch`; a refusal throws
|
|
630
|
+
* {@link InputBoundaryRefusedError} and the dispatch must not happen. Does not
|
|
631
|
+
* fix the input-start stamp — a keyboard fallback still reports its own.
|
|
632
|
+
*/
|
|
633
|
+
function noteDispatchStart(now = new Date()) {
|
|
634
|
+
const observer = inputStartScope.getStore();
|
|
635
|
+
if (observer === undefined || observer.at !== null)
|
|
636
|
+
return;
|
|
637
|
+
runBoundaryHook(observer, now, 'dispatch');
|
|
638
|
+
observer.dispatchOpen = true;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Say how a dispatch noted by {@link noteDispatchStart} ended when it did not
|
|
642
|
+
* deliver (Issue #3957): `not_sent` when the receiver confirmed nothing exists,
|
|
643
|
+
* `unknown` when it could not be told. Called before any fallback. Never throws.
|
|
644
|
+
*/
|
|
645
|
+
function noteDispatchFailed(verdict) {
|
|
646
|
+
const observer = inputStartScope.getStore();
|
|
647
|
+
if (observer === undefined || !observer.dispatchOpen)
|
|
648
|
+
return;
|
|
649
|
+
observer.dispatchOpen = false;
|
|
650
|
+
try {
|
|
651
|
+
observer.boundary?.onDispatchFailed?.(verdict);
|
|
652
|
+
}
|
|
653
|
+
catch (error) {
|
|
654
|
+
logger.warn('dispatch-failure-observer-failed', { error: error instanceof Error ? error.message : String(error) });
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
/** Forget every lock, waiter and mark (tests). */
|
|
658
|
+
function resetInstanceInputLocks() {
|
|
659
|
+
for (const entry of entries.values()) {
|
|
660
|
+
for (const waiter of entry.queue)
|
|
661
|
+
clearTimeout(waiter.timer);
|
|
662
|
+
}
|
|
663
|
+
entries.clear();
|
|
664
|
+
}
|