commandmate 0.32.1 → 0.33.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 +277 -270
- package/.next/app-path-routes-manifest.json +39 -38
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +12 -12
- 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/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/assistant/conversation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/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_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_client-reference-manifest.js +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_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +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/[id]/todos/[todoId]/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +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_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/todos/route.js +1 -1
- package/.next/server/app/api/todos/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_client-reference-manifest.js +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_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_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 -0
- package/.next/server/app/api/worktrees/[id]/instances/notes/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -0
- 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_client-reference-manifest.js +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_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_client-reference-manifest.js +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 +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_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_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_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/chat/page_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.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.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +12 -12
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +39 -38
- package/.next/server/chunks/1191.js +1 -1
- package/.next/server/chunks/1886.js +2 -2
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/5354.js +1 -1
- package/.next/server/chunks/6337.js +1 -1
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/6661.js +1 -1
- package/.next/server/chunks/6838.js +1 -1
- package/.next/server/chunks/7875.js +1 -1
- package/.next/server/chunks/8807.js +163 -131
- package/.next/server/chunks/8918.js +4 -4
- package/.next/server/chunks/9584.js +1 -1
- 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/{4718-9d63107c612a065d.js → 4718-2bc5cdf06573bf54.js} +1 -1
- package/.next/static/chunks/app/api/agents/{versions/route-8bc5b680c5f3eae4.js → update/route-c4d2d5016c5f2a0a.js} +1 -1
- package/.next/static/chunks/app/api/{app/update-check/route-8bc5b680c5f3eae4.js → agents/versions/route-c4d2d5016c5f2a0a.js} +1 -1
- package/.next/static/chunks/app/api/{agents/update/route-8bc5b680c5f3eae4.js → app/update/route-c4d2d5016c5f2a0a.js} +1 -1
- package/.next/static/chunks/app/api/app/{update/route-8bc5b680c5f3eae4.js → update-check/route-c4d2d5016c5f2a0a.js} +1 -1
- package/.next/static/chunks/app/api/assistant/conversation/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/assistant/current-output/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/assistant/messages/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/assistant/session/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/assistant/start/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/assistant/terminal/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/assistant/tools/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/auth/login/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/auth/status/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/capabilities/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/status/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/external-apps/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/fs/browse/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/fs/recent-paths/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/hooks/agent-event/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/hooks/claude-done/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/hooks/permission-request/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/metrics/vibe/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/ollama/models/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/push/escalation/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/push/subscriptions/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/push/vapid/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/relays/[relayId]/cancel/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/relays/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/remote/pair/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/repositories/excluded/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/repositories/restore/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/repositories/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/repositories/scan/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/repositories/sync/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/repositories/validate-path/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/settings/default-agents/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/settings/default-surface-mode/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/sidebar/group-order/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/skills/[id]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/skills/installations/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/skills/operations/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/skills/reindex/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/skills/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/slash-commands/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/templates/[id]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/templates/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/todos/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/instances/notes/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/manifest.webmanifest/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/{page-6871cca022b24807.js → page-022090bf6f932818.js} +1 -1
- package/.next/static/chunks/app/proxy/[...path]/route-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/repositories/{page-788ded1b72963d94.js → page-2576158c8420fda0.js} +1 -1
- package/.next/static/chunks/app/sessions/page-584adf11ae51df10.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/layout-c4d2d5016c5f2a0a.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-13ca0ba551fe5cfb.js +1 -0
- package/.next/static/css/acd46e25427a2080.css +1 -0
- package/.next/trace +14 -13
- package/.next/types/app/api/worktrees/[id]/instances/notes/route.ts +347 -0
- package/.next/types/routes.d.ts +2 -1
- package/.next/types/validator.ts +9 -0
- package/dist/server/locales/en/worktree.json +8 -0
- package/dist/server/locales/ja/worktree.json +8 -0
- package/dist/server/src/lib/cli-tools/base.js +311 -1
- package/dist/server/src/lib/cli-tools/start-availability.js +52 -0
- package/dist/server/src/lib/db/agent-instances-db.js +213 -1
- package/dist/server/src/lib/db/migrations/index.js +2 -0
- package/dist/server/src/lib/db/migrations/runner.js +1 -1
- package/dist/server/src/lib/db/migrations/v61-session-notes.js +85 -0
- package/dist/server/src/lib/hooks/sources/codex/transcript.js +88 -6
- package/dist/server/src/lib/hooks/sources/turn-body.js +3 -1
- package/dist/server/src/lib/push/failure-push-notifier.js +68 -1
- package/dist/server/src/lib/push/push-sender.js +16 -5
- package/dist/server/src/lib/session/current-output-builder.js +156 -4
- package/package.json +1 -1
- package/.next/static/chunks/app/api/assistant/conversation/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/assistant/current-output/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/assistant/messages/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/assistant/session/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/assistant/start/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/assistant/terminal/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/assistant/tools/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/auth/login/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/auth/status/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/capabilities/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/status/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/external-apps/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/fs/browse/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/fs/recent-paths/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/hooks/agent-event/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/hooks/claude-done/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/hooks/permission-request/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/metrics/vibe/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/ollama/models/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/push/escalation/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/push/subscriptions/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/push/vapid/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/relays/[relayId]/cancel/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/relays/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/remote/pair/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/repositories/excluded/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/repositories/restore/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/repositories/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/repositories/scan/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/repositories/sync/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/repositories/validate-path/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/settings/default-agents/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/settings/default-surface-mode/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/sidebar/group-order/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/skills/[id]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/skills/installations/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/skills/operations/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/skills/reindex/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/skills/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/slash-commands/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/templates/[id]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/templates/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/todos/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/proxy/[...path]/route-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/sessions/page-fa2d62f3e8436c69.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/layout-8bc5b680c5f3eae4.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-3d82a9355d5612d9.js +0 -1
- package/.next/static/css/96d94a4ba771efc3.css +0 -1
- /package/.next/static/{Lno4w_zWXdGdlfXg06Vp8 → 9lgw9hA727UMyFhXryGWG}/_buildManifest.js +0 -0
- /package/.next/static/{Lno4w_zWXdGdlfXg06Vp8 → 9lgw9hA727UMyFhXryGWG}/_ssgManifest.js +0 -0
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.BaseCLITool = void 0;
|
|
8
|
+
exports.resetHookUrlProbesForTest = resetHookUrlProbesForTest;
|
|
9
|
+
exports.readLaunchLineHookUrl = readLaunchLineHookUrl;
|
|
10
|
+
exports.hookUrlPort = hookUrlPort;
|
|
11
|
+
exports.probeRunningSessionHookUrl = probeRunningSessionHookUrl;
|
|
8
12
|
const child_process_1 = require("child_process");
|
|
9
13
|
const util_1 = require("util");
|
|
10
14
|
const session_name_1 = require("./session-name");
|
|
@@ -15,11 +19,121 @@ const graceful_exit_1 = require("./graceful-exit");
|
|
|
15
19
|
const liveness_spec_1 = require("./liveness-spec");
|
|
16
20
|
const session_liveness_1 = require("./session-liveness");
|
|
17
21
|
const start_availability_1 = require("./start-availability");
|
|
22
|
+
const ansi_1 = require("../detection/ansi");
|
|
23
|
+
const env_1 = require("../env");
|
|
24
|
+
const launch_command_1 = require("../hooks/sources/launch-command");
|
|
18
25
|
const logger_1 = require("../logger");
|
|
19
26
|
const terminal_keys_1 = require("../../types/terminal-keys");
|
|
20
27
|
const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
|
|
28
|
+
const tmux_pane_config_1 = require("../../config/tmux-pane-config");
|
|
21
29
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
22
30
|
const logger = (0, logger_1.createLogger)('cli-tools/base');
|
|
31
|
+
/**
|
|
32
|
+
* `CM_HOOK_URL='…'` as a launch line spells it (Issue #2429).
|
|
33
|
+
*
|
|
34
|
+
* Built from {@link AGENT_EVENT_URL_ENV_VAR} rather than from a literal, for
|
|
35
|
+
* the reason `launch-command` gives for owning that constant: a drifted name
|
|
36
|
+
* here would read a variable CommandMate never wrote and report every session
|
|
37
|
+
* as fine.
|
|
38
|
+
*
|
|
39
|
+
* All three quoting forms, because the reader is a pane and not a parser:
|
|
40
|
+
* `resolveAgentLaunchEnv` renders single quotes today, and a line typed by hand
|
|
41
|
+
* or by an older build may carry double quotes or none.
|
|
42
|
+
*/
|
|
43
|
+
const HOOK_URL_ASSIGNMENT_PATTERN = new RegExp(`${launch_command_1.AGENT_EVENT_URL_ENV_VAR}=(?:'([^']*)'|"([^"]*)"|(\\S+))`, 'g');
|
|
44
|
+
/**
|
|
45
|
+
* Session names whose launch took the REUSE branch (Issue #2429).
|
|
46
|
+
*
|
|
47
|
+
* The adopt marker, and the reason it is a set rather than a return value:
|
|
48
|
+
* {@link BaseCLITool.reconcileExistingSession} is the one line every tool's
|
|
49
|
+
* reuse branch calls and it is handed only a session name, while the identity
|
|
50
|
+
* the warning needs — worktree, instance, tool name — is `startSession`'s. A
|
|
51
|
+
* signature change would have to reach seven `launchSession` implementations to
|
|
52
|
+
* carry one boolean back up.
|
|
53
|
+
*
|
|
54
|
+
* Written by the reconcile, consumed by `startSession` (see
|
|
55
|
+
* {@link BaseCLITool.takeAdoptionMark}), so a pane this server CREATED never
|
|
56
|
+
* reaches the probe: its launch line is one this process just typed, and asking
|
|
57
|
+
* tmux to prove that would cost a full-scrollback `capture-pane` on every
|
|
58
|
+
* session start for an answer that is known.
|
|
59
|
+
*/
|
|
60
|
+
const adoptedSessions = new Set();
|
|
61
|
+
/**
|
|
62
|
+
* Session names whose launch line this process has already read (Issue #2433).
|
|
63
|
+
*
|
|
64
|
+
* The reason the send path can ask at all. #2429 put the hook-URL probe behind
|
|
65
|
+
* the adopt marker, and measured on this tree that marker is unreachable for
|
|
66
|
+
* every tool that writes `CM_HOOK_URL` onto its launch line: antigravity,
|
|
67
|
+
* command-code and gemini all answer `isRunning()` with `hasSession()`, so the
|
|
68
|
+
* reuse branch that sets the mark needs a pane to exist while `startSession()`
|
|
69
|
+
* — the only caller of `launchSession()` — is reached only when one does not.
|
|
70
|
+
* The situation #2429 actually reported (a pane raised by a server on another
|
|
71
|
+
* port, still being typed into) is exactly the situation in which the pane is
|
|
72
|
+
* alive, so the probe never ran.
|
|
73
|
+
*
|
|
74
|
+
* Moving the question to "we are about to send into an existing session" makes
|
|
75
|
+
* it reachable, and this set is what keeps it cheap: reading the launch line
|
|
76
|
+
* costs a full-scrollback `capture-pane`, and a send happens as often as an
|
|
77
|
+
* operator presses Enter. A launch line does not change while a pane lives —
|
|
78
|
+
* {@link BaseCLITool.relaunchIfToolExited} re-types it with THIS server's port,
|
|
79
|
+
* which is never the mismatch — so one read per session per process answers it
|
|
80
|
+
* for good.
|
|
81
|
+
*
|
|
82
|
+
* Recorded only after a capture that actually returned, so a pane that could not
|
|
83
|
+
* be read (a session that vanished between `isRunning` and here) is asked again
|
|
84
|
+
* rather than silently written off.
|
|
85
|
+
*/
|
|
86
|
+
const hookUrlProbedSessions = new Set();
|
|
87
|
+
/**
|
|
88
|
+
* Forget every hook-URL probe made so far (Issue #2433).
|
|
89
|
+
*
|
|
90
|
+
* Test-only, and named so, for the same reason
|
|
91
|
+
* `resetStaleHookUrlReportsForTest` is: the set above is process-lifetime state
|
|
92
|
+
* and a suite that asserts "the pane is read once" needs the first read to be
|
|
93
|
+
* the first one.
|
|
94
|
+
*/
|
|
95
|
+
function resetHookUrlProbesForTest() {
|
|
96
|
+
hookUrlProbedSessions.clear();
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The last `CM_HOOK_URL` a pane's scrollback names, or null (Issue #2429).
|
|
100
|
+
*
|
|
101
|
+
* **Last**, not first. An adopted pane carries only the launch line that
|
|
102
|
+
* started the agent — the stale one. A pane whose tool exited and was relaunched
|
|
103
|
+
* by {@link BaseCLITool.relaunchIfToolExited} carries both, oldest first, and
|
|
104
|
+
* the newest is the one in force. Taking the first match would report a
|
|
105
|
+
* mismatch this server had already repaired.
|
|
106
|
+
*
|
|
107
|
+
* Exported for the unit suite: the whole rule is "what does this text say", and
|
|
108
|
+
* pinning it against real launch lines needs no tmux.
|
|
109
|
+
*/
|
|
110
|
+
function readLaunchLineHookUrl(pane) {
|
|
111
|
+
let last = null;
|
|
112
|
+
for (const match of (0, ansi_1.stripAnsi)(pane).matchAll(HOOK_URL_ASSIGNMENT_PATTERN)) {
|
|
113
|
+
const value = match[1] ?? match[2] ?? match[3] ?? null;
|
|
114
|
+
if (value)
|
|
115
|
+
last = value;
|
|
116
|
+
}
|
|
117
|
+
return last;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The port a hook URL posts to, or null when it is not a URL (Issue #2429).
|
|
121
|
+
*
|
|
122
|
+
* The default port is filled in from the scheme rather than left null, so a
|
|
123
|
+
* `http://127.0.0.1/api/hooks/...` line is compared as 80 instead of being
|
|
124
|
+
* waved through as unreadable.
|
|
125
|
+
*/
|
|
126
|
+
function hookUrlPort(url) {
|
|
127
|
+
try {
|
|
128
|
+
const parsed = new URL(url);
|
|
129
|
+
if (parsed.port !== '')
|
|
130
|
+
return Number(parsed.port);
|
|
131
|
+
return parsed.protocol === 'https:' ? 443 : 80;
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
23
137
|
/**
|
|
24
138
|
* Abstract base class for CLI tools
|
|
25
139
|
* Implements common functionality and defines abstract methods for specific implementations
|
|
@@ -100,6 +214,10 @@ class BaseCLITool {
|
|
|
100
214
|
await this.launchSession(worktreeId, worktreePath, instanceId, model);
|
|
101
215
|
}
|
|
102
216
|
catch (error) {
|
|
217
|
+
// Issue #2429: a launch that threw is reported as a failed start and as
|
|
218
|
+
// nothing else. The mark is dropped rather than left behind so a later,
|
|
219
|
+
// successful start of the same session does not inherit it.
|
|
220
|
+
this.takeAdoptionMark(worktreeId, instanceId);
|
|
103
221
|
(0, start_availability_1.reportSessionStartFailure)({
|
|
104
222
|
worktreeId,
|
|
105
223
|
cliToolId: this.id,
|
|
@@ -108,11 +226,177 @@ class BaseCLITool {
|
|
|
108
226
|
}, error);
|
|
109
227
|
throw error;
|
|
110
228
|
}
|
|
229
|
+
const adopted = this.takeAdoptionMark(worktreeId, instanceId);
|
|
230
|
+
if (adopted !== null)
|
|
231
|
+
await this.warnIfHookUrlIsStale(worktreeId, adopted, instanceId);
|
|
111
232
|
}
|
|
112
|
-
/**
|
|
233
|
+
/**
|
|
234
|
+
* Repair geometry when reusing a tmux session that predates the current
|
|
235
|
+
* defaults, and record that this launch reused one (Issue #2429).
|
|
236
|
+
*/
|
|
113
237
|
async reconcileExistingSession(sessionName, options) {
|
|
238
|
+
adoptedSessions.add(sessionName);
|
|
114
239
|
await (0, tmux_1.reconcileSessionGeometry)(sessionName, options);
|
|
115
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* The reused pane's session name, or null when this launch created one
|
|
243
|
+
* (Issue #2429).
|
|
244
|
+
*
|
|
245
|
+
* Consumes the mark, so one launch asks one question. `getSessionName` can
|
|
246
|
+
* throw on an id that would not validate — the tool's own `launchSession`
|
|
247
|
+
* would have thrown on it first, so reaching that catch means something more
|
|
248
|
+
* interesting than a stale hook URL is wrong and this must not be what
|
|
249
|
+
* reports it.
|
|
250
|
+
*/
|
|
251
|
+
takeAdoptionMark(worktreeId, instanceId) {
|
|
252
|
+
try {
|
|
253
|
+
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
254
|
+
return adoptedSessions.delete(sessionName) ? sessionName : null;
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Warn when an adopted pane's hooks are addressed to another server
|
|
262
|
+
* (Issue #2429).
|
|
263
|
+
*
|
|
264
|
+
* ## What goes wrong without it
|
|
265
|
+
*
|
|
266
|
+
* `CM_HOOK_URL` is written onto the launch line by the server that starts the
|
|
267
|
+
* agent, and it is the whole of the correlation channel: it names the port the
|
|
268
|
+
* relay posts every lifecycle event to. A tmux session outlives the server
|
|
269
|
+
* that created it, so a pane started by a server on :3010 and later adopted by
|
|
270
|
+
* one on :3000 — {@link reconcileExistingSession}'s branch, which repairs the
|
|
271
|
+
* window geometry and nothing else — goes on posting to :3010. Measured
|
|
272
|
+
* 2026-09-08: every `commandmate wait` on that session held for #1975's full
|
|
273
|
+
* 60 s and then completed `basis=scraper_ready` with `Its hooks are not
|
|
274
|
+
* answering`, because from :3000's side the agent had simply gone silent.
|
|
275
|
+
*
|
|
276
|
+
* Nothing on any surface said so. The pane looked healthy, the CLI was
|
|
277
|
+
* reachable, and the only evidence was a port number in a launch line
|
|
278
|
+
* thousands of scrollback rows up.
|
|
279
|
+
*
|
|
280
|
+
* ## Why it warns rather than repairs
|
|
281
|
+
*
|
|
282
|
+
* The repair is to restart the agent, and restarting it is exactly what must
|
|
283
|
+
* not happen automatically: the adopted session may be mid-turn, and killing a
|
|
284
|
+
* generating agent to fix its telemetry costs the work. So this reports and
|
|
285
|
+
* stops. `reportStaleHookUrl` is what makes it once — see that function.
|
|
286
|
+
*
|
|
287
|
+
* ## Who asks, and why the create path still does not
|
|
288
|
+
*
|
|
289
|
+
* Two callers. {@link startSession} asks when the launch REUSED a pane —
|
|
290
|
+
* {@link reconcileExistingSession}'s mark — and
|
|
291
|
+
* {@link warnIfRunningSessionHookUrlIsStale} asks when a send is about to type
|
|
292
|
+
* into a session that is already running. The second was added by Issue #2433
|
|
293
|
+
* because the first, alone, is unreachable for every tool that puts
|
|
294
|
+
* `CM_HOOK_URL` on its launch line: see {@link hookUrlProbedSessions}.
|
|
295
|
+
*
|
|
296
|
+
* A pane this server CREATED is asked by neither. Its launch line is one this
|
|
297
|
+
* process typed a moment ago, so the comparison is this server's port against
|
|
298
|
+
* itself and the answer is known without asking; asking anyway would put a
|
|
299
|
+
* full-scrollback `capture-pane` in front of every session start, which is a
|
|
300
|
+
* real cost on the path an operator is waiting on.
|
|
301
|
+
*
|
|
302
|
+
* The #2070 relaunch (the tool died, so the pane is reused but the launch
|
|
303
|
+
* line is re-typed) goes through the adopt mark too, and is why
|
|
304
|
+
* {@link readLaunchLineHookUrl} takes the NEWEST assignment: such a pane
|
|
305
|
+
* carries both, and the new one is in force.
|
|
306
|
+
*
|
|
307
|
+
* Never throws, never blocks a start and never blocks a send: a tool whose
|
|
308
|
+
* hook URL cannot be read — claude and opencode keep theirs out of the launch
|
|
309
|
+
* line entirely — simply yields null and is left alone.
|
|
310
|
+
*/
|
|
311
|
+
async warnIfHookUrlIsStale(worktreeId, sessionName, instanceId) {
|
|
312
|
+
// Issue #2433: at most one read per session per process. The send path calls
|
|
313
|
+
// this on every message to an already-running session, and without this line
|
|
314
|
+
// that would put a full-scrollback capture in front of every Enter.
|
|
315
|
+
if (hookUrlProbedSessions.has(sessionName))
|
|
316
|
+
return;
|
|
317
|
+
try {
|
|
318
|
+
// The whole scrollback: the launch line is the OLDEST thing in an adopted
|
|
319
|
+
// pane, and `TMUX_HISTORY_LIMIT` is the ceiling tmux was told to keep.
|
|
320
|
+
const pane = await (0, tmux_1.capturePane)(sessionName, { startLine: -tmux_pane_config_1.TMUX_HISTORY_LIMIT });
|
|
321
|
+
hookUrlProbedSessions.add(sessionName);
|
|
322
|
+
const sessionHookUrl = readLaunchLineHookUrl(pane);
|
|
323
|
+
if (sessionHookUrl === null)
|
|
324
|
+
return;
|
|
325
|
+
const sessionPort = hookUrlPort(sessionHookUrl);
|
|
326
|
+
const serverPort = (0, env_1.getServerPort)();
|
|
327
|
+
if (sessionPort === null || sessionPort === serverPort)
|
|
328
|
+
return;
|
|
329
|
+
logger.warn('session:hook-url-stale', {
|
|
330
|
+
cliToolId: this.id,
|
|
331
|
+
sessionName,
|
|
332
|
+
sessionPort,
|
|
333
|
+
serverPort,
|
|
334
|
+
});
|
|
335
|
+
(0, start_availability_1.reportStaleHookUrl)({
|
|
336
|
+
worktreeId,
|
|
337
|
+
cliToolId: this.id,
|
|
338
|
+
instanceId,
|
|
339
|
+
toolName: this.name,
|
|
340
|
+
sessionPort,
|
|
341
|
+
serverPort,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
logger.debug('session:hook-url-probe-failed', {
|
|
346
|
+
cliToolId: this.id,
|
|
347
|
+
worktreeId,
|
|
348
|
+
error: error instanceof Error ? error.message : String(error),
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Ask the same question of a session that is ALREADY running (Issue #2433).
|
|
354
|
+
*
|
|
355
|
+
* ## Why the send path is where it has to be asked
|
|
356
|
+
*
|
|
357
|
+
* #2429's probe hangs off the adopt marker, and the marker is set inside a
|
|
358
|
+
* tool's `launchSession()` reuse branch — which `startSession()` reaches only
|
|
359
|
+
* when the pane already exists, while `POST /api/worktrees/:id/send` calls
|
|
360
|
+
* `startSession()` only when `isRunning()` said it does not. For antigravity,
|
|
361
|
+
* command-code and gemini — the three tools that write `CM_HOOK_URL` onto the
|
|
362
|
+
* launch line at all — `isRunning()` IS `hasSession()`, so those two
|
|
363
|
+
* conditions cannot both hold and the probe never ran. claude's `isRunning()`
|
|
364
|
+
* does look at the process, but claude keeps its endpoint out of the launch
|
|
365
|
+
* line, so {@link readLaunchLineHookUrl} answers null for it.
|
|
366
|
+
*
|
|
367
|
+
* The result was that the one situation #2429 was written for — a pane raised
|
|
368
|
+
* by a server on another port, still being typed into, its hooks posting into
|
|
369
|
+
* the void — was precisely the situation in which the pane is alive and
|
|
370
|
+
* therefore never examined. Measured 2026-09-08 against a live
|
|
371
|
+
* `mcbd-command-code-…` session whose launch line named :3000 while the server
|
|
372
|
+
* was :3010: zero `session:hook-url-stale` lines from either a capture or a
|
|
373
|
+
* send.
|
|
374
|
+
*
|
|
375
|
+
* ## What it costs
|
|
376
|
+
*
|
|
377
|
+
* One `capture-pane` per session per server process, and nothing after that —
|
|
378
|
+
* {@link hookUrlProbedSessions} is checked before tmux is touched, so the
|
|
379
|
+
* second and every later send to the same pane reach no further than a `Set`
|
|
380
|
+
* lookup. The per-send capture count the launch-readiness suites pin is
|
|
381
|
+
* unchanged.
|
|
382
|
+
*
|
|
383
|
+
* Nothing here can fail a send: {@link warnIfHookUrlIsStale} contains its own
|
|
384
|
+
* faults, and a session id that would not validate is simply not probed (the
|
|
385
|
+
* send that follows will fail on its own account, with a better message).
|
|
386
|
+
*
|
|
387
|
+
* @param worktreeId - Worktree the running session belongs to
|
|
388
|
+
* @param instanceId - Agent instance ID (defaults to the primary instance)
|
|
389
|
+
*/
|
|
390
|
+
async warnIfRunningSessionHookUrlIsStale(worktreeId, instanceId) {
|
|
391
|
+
let sessionName;
|
|
392
|
+
try {
|
|
393
|
+
sessionName = this.getSessionName(worktreeId, instanceId);
|
|
394
|
+
}
|
|
395
|
+
catch {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
await this.warnIfHookUrlIsStale(worktreeId, sessionName, instanceId);
|
|
399
|
+
}
|
|
116
400
|
/**
|
|
117
401
|
* Interrupt processing by sending Escape key
|
|
118
402
|
* Default implementation: send Escape key to tmux session
|
|
@@ -314,3 +598,29 @@ class BaseCLITool {
|
|
|
314
598
|
}
|
|
315
599
|
}
|
|
316
600
|
exports.BaseCLITool = BaseCLITool;
|
|
601
|
+
/**
|
|
602
|
+
* Probe a running session's hook URL, for a caller holding an `ICLITool`
|
|
603
|
+
* (Issue #2433).
|
|
604
|
+
*
|
|
605
|
+
* `POST /api/worktrees/:id/send` gets its tool from
|
|
606
|
+
* `CLIToolManager.getTool()`, which is typed as the {@link ICLITool} interface;
|
|
607
|
+
* the probe is a {@link BaseCLITool} concern and deliberately not part of that
|
|
608
|
+
* interface, because it is not something a tool has to implement — it is
|
|
609
|
+
* something every tool inherits. The narrowing lives here, next to the class it
|
|
610
|
+
* narrows to, rather than as an `instanceof` in the route.
|
|
611
|
+
*
|
|
612
|
+
* Fire-and-forget on purpose. The answer changes nothing about the message
|
|
613
|
+
* being sent — the Issue's decision, inherited from #2429, is to warn and NOT
|
|
614
|
+
* restart, because the adopted session may be mid-turn — so making the operator
|
|
615
|
+
* wait on a `capture-pane` for it would be paying latency for a notification.
|
|
616
|
+
* The returned promise cannot reject; the `.catch` is the belt.
|
|
617
|
+
*
|
|
618
|
+
* @param tool - The tool whose session is about to be typed into
|
|
619
|
+
* @param worktreeId - Worktree the running session belongs to
|
|
620
|
+
* @param instanceId - Agent instance ID (defaults to the primary instance)
|
|
621
|
+
*/
|
|
622
|
+
function probeRunningSessionHookUrl(tool, worktreeId, instanceId) {
|
|
623
|
+
if (!(tool instanceof BaseCLITool))
|
|
624
|
+
return;
|
|
625
|
+
void tool.warnIfRunningSessionHookUrlIsStale(worktreeId, instanceId).catch(() => { });
|
|
626
|
+
}
|
|
@@ -62,6 +62,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
62
62
|
})();
|
|
63
63
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
64
64
|
exports.reportSessionStartFailure = reportSessionStartFailure;
|
|
65
|
+
exports.reportStaleHookUrl = reportStaleHookUrl;
|
|
66
|
+
exports.resetStaleHookUrlReportsForTest = resetStaleHookUrlReportsForTest;
|
|
65
67
|
exports.assertToolStartable = assertToolStartable;
|
|
66
68
|
exports.reportToolUnavailable = reportToolUnavailable;
|
|
67
69
|
const install_hints_1 = require("./install-hints");
|
|
@@ -87,6 +89,56 @@ function reportSessionStartFailure(report, error) {
|
|
|
87
89
|
void Promise.resolve().then(() => __importStar(require('../push/failure-push-notifier'))).then(({ notifySessionStartFailurePush }) => notifySessionStartFailurePush({ ...report, error }))
|
|
88
90
|
.catch(() => { });
|
|
89
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Which (instance, port pair) has already been reported (Issue #2429).
|
|
94
|
+
*
|
|
95
|
+
* The "once" in the Issue's acceptance, and it is keyed on the *facts* rather
|
|
96
|
+
* than on the session name so the two ways this can recur read correctly:
|
|
97
|
+
*
|
|
98
|
+
* - the same pane asked about again by the same server — adopted a second
|
|
99
|
+
* time, or sent to a hundred times more — is the same sentence, and is
|
|
100
|
+
* dropped;
|
|
101
|
+
* - a pane that moves to a different mismatch — a third server, or the one it
|
|
102
|
+
* was pointing at coming back — is a different sentence and is told.
|
|
103
|
+
*
|
|
104
|
+
* Process-lifetime, like every other in-memory notification ledger here: a
|
|
105
|
+
* server that restarts is a server whose port may have changed, and re-asking
|
|
106
|
+
* is cheaper than a stale answer.
|
|
107
|
+
*/
|
|
108
|
+
const reportedStaleHookUrls = new Set();
|
|
109
|
+
/**
|
|
110
|
+
* Report a session whose hook URL names another server, at most once.
|
|
111
|
+
*
|
|
112
|
+
* Fire-and-forget through the same one窓口 as {@link reportSessionStartFailure},
|
|
113
|
+
* and deferred behind `await import()` for the same reason: this file is loaded
|
|
114
|
+
* by `./base`, which every tool module loads, and `push/failure-push-notifier`
|
|
115
|
+
* pulls the database and `web-push` behind it.
|
|
116
|
+
*
|
|
117
|
+
* @param report - The pane, the port it posts to, and the port that is listening
|
|
118
|
+
*/
|
|
119
|
+
function reportStaleHookUrl(report) {
|
|
120
|
+
const key = [
|
|
121
|
+
report.worktreeId,
|
|
122
|
+
report.instanceId ?? report.cliToolId,
|
|
123
|
+
report.sessionPort,
|
|
124
|
+
report.serverPort,
|
|
125
|
+
].join(':');
|
|
126
|
+
if (reportedStaleHookUrls.has(key))
|
|
127
|
+
return;
|
|
128
|
+
reportedStaleHookUrls.add(key);
|
|
129
|
+
void Promise.resolve().then(() => __importStar(require('../push/failure-push-notifier'))).then(({ notifyStaleHookUrlPush }) => notifyStaleHookUrlPush(report))
|
|
130
|
+
.catch(() => { });
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Forget every stale-hook-URL report made so far (Issue #2429).
|
|
134
|
+
*
|
|
135
|
+
* Test-only, and named so: the ledger above is process-lifetime state, and a
|
|
136
|
+
* suite that asserts "the second call says nothing" needs the first call to be
|
|
137
|
+
* the first one.
|
|
138
|
+
*/
|
|
139
|
+
function resetStaleHookUrlReportsForTest() {
|
|
140
|
+
reportedStaleHookUrls.clear();
|
|
141
|
+
}
|
|
90
142
|
/**
|
|
91
143
|
* Refuse a start this tool cannot perform, reporting it exactly as a failed
|
|
92
144
|
* launch does (Issue #2022).
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* exceed it throw AgentInstanceLimitError.
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.InvalidAgentInstanceError = exports.AgentInstanceLimitError = void 0;
|
|
15
|
+
exports.SessionNoteTooLongError = exports.MAX_SESSION_NOTE_LENGTH = exports.InvalidAgentInstanceError = exports.AgentInstanceLimitError = void 0;
|
|
16
16
|
exports.getAgentInstances = getAgentInstances;
|
|
17
17
|
exports.getAgentInstance = getAgentInstance;
|
|
18
18
|
exports.resolveInstanceCliTool = resolveInstanceCliTool;
|
|
@@ -24,6 +24,13 @@ exports.getOpencodeInstanceSettings = getOpencodeInstanceSettings;
|
|
|
24
24
|
exports.getOpencodeInstanceSettingsByWorktree = getOpencodeInstanceSettingsByWorktree;
|
|
25
25
|
exports.setOpencodeInstanceSettings = setOpencodeInstanceSettings;
|
|
26
26
|
exports.pruneOpencodeInstanceSettings = pruneOpencodeInstanceSettings;
|
|
27
|
+
exports.normalizeSessionNoteText = normalizeSessionNoteText;
|
|
28
|
+
exports.sessionNoteLength = sessionNoteLength;
|
|
29
|
+
exports.getSessionNote = getSessionNote;
|
|
30
|
+
exports.getSessionNotesByWorktree = getSessionNotesByWorktree;
|
|
31
|
+
exports.getAllSessionNotes = getAllSessionNotes;
|
|
32
|
+
exports.setSessionNote = setSessionNote;
|
|
33
|
+
exports.pruneSessionNotes = pruneSessionNotes;
|
|
27
34
|
const opencode_instance_settings_1 = require("../../types/opencode-instance-settings");
|
|
28
35
|
const types_1 = require("../../lib/cli-tools/types");
|
|
29
36
|
/**
|
|
@@ -199,6 +206,13 @@ function setAgentInstances(db, worktreeId, instances) {
|
|
|
199
206
|
// is a full replace, so an instance dropped from the roster would otherwise
|
|
200
207
|
// leave its opencode settings behind for whoever next claimed that id.
|
|
201
208
|
pruneOpencodeInstanceSettings(db, worktreeId, instances.map((instance) => instance.id));
|
|
209
|
+
// Issue #2427: the same rule for the session notes, and the same rule read
|
|
210
|
+
// the other way round — this prunes only the ids that LEFT the roster, so
|
|
211
|
+
// the note of every surviving instance outlives the delete/re-insert that
|
|
212
|
+
// renaming an alias or reordering the list performs. That survival is the
|
|
213
|
+
// Issue's third acceptance condition; a mutation that drops this call makes
|
|
214
|
+
// the note of a *removed* instance haunt the next instance to claim its id.
|
|
215
|
+
pruneSessionNotes(db, worktreeId, instances.map((instance) => instance.id));
|
|
202
216
|
const insertStmt = db.prepare(`
|
|
203
217
|
INSERT INTO agent_instances
|
|
204
218
|
(worktree_id, instance_id, cli_tool_id, alias, sort_order, created_at)
|
|
@@ -251,6 +265,11 @@ function removeAgentInstance(db, worktreeId, instanceId) {
|
|
|
251
265
|
// it was configured to launch opencode with is gone with it.
|
|
252
266
|
db.prepare(`
|
|
253
267
|
DELETE FROM opencode_instance_settings WHERE worktree_id = ? AND instance_id = ?
|
|
268
|
+
`).run(worktreeId, instanceId);
|
|
269
|
+
// Issue #2427: and the memo written about it. A note names a session; the
|
|
270
|
+
// session is gone.
|
|
271
|
+
db.prepare(`
|
|
272
|
+
DELETE FROM session_notes WHERE worktree_id = ? AND instance_id = ?
|
|
254
273
|
`).run(worktreeId, instanceId);
|
|
255
274
|
return result.changes > 0;
|
|
256
275
|
}
|
|
@@ -369,3 +388,196 @@ function pruneOpencodeInstanceSettings(db, worktreeId, keepInstanceIds) {
|
|
|
369
388
|
WHERE worktree_id = ? AND instance_id NOT IN (${placeholders})
|
|
370
389
|
`).run(worktreeId, ...keepInstanceIds).changes;
|
|
371
390
|
}
|
|
391
|
+
// ============================================================================
|
|
392
|
+
// Session notes (Issue #2427). Appended after the opencode block for the same
|
|
393
|
+
// reason that one was appended after the roster CRUD: everything below is
|
|
394
|
+
// additive and touches no export above it, so `AgentInstance` — which is the
|
|
395
|
+
// roster PATCH's INPUT shape as much as its output — is unchanged, and so is
|
|
396
|
+
// every resolution path that reads it.
|
|
397
|
+
//
|
|
398
|
+
// A note is a memo a human reads. It is NOT an alias: since Issue #2376
|
|
399
|
+
// `--instance レビュー担当` resolves through `agent_instances.alias`, so an alias
|
|
400
|
+
// decides where a `send` lands. Nothing in this section is read by
|
|
401
|
+
// `resolveInstanceCliTool` or by `/resolve-target`, and that is the whole reason
|
|
402
|
+
// the two are stored apart.
|
|
403
|
+
// ============================================================================
|
|
404
|
+
/**
|
|
405
|
+
* Longest note this server will store, in code points (Issue #2427).
|
|
406
|
+
*
|
|
407
|
+
* One line beside a session title, so the bound is about what can be READ in a
|
|
408
|
+
* split header rather than about storage. Code points rather than UTF-16 units
|
|
409
|
+
* because the operator counts characters: an emoji is one character to whoever
|
|
410
|
+
* typed it and two to `String.prototype.length`, and a limit that charges two
|
|
411
|
+
* for one is a limit that cannot be explained.
|
|
412
|
+
*
|
|
413
|
+
* The client mirrors it as the input's `maxLength` (`SESSION_NOTE_MAX_LENGTH` in
|
|
414
|
+
* `TerminalSplitPane`), which is a convenience; THIS is the enforcement, because
|
|
415
|
+
* the route is reachable without the UI.
|
|
416
|
+
*/
|
|
417
|
+
exports.MAX_SESSION_NOTE_LENGTH = 100;
|
|
418
|
+
/** Thrown when a note is longer than {@link MAX_SESSION_NOTE_LENGTH}. */
|
|
419
|
+
class SessionNoteTooLongError extends Error {
|
|
420
|
+
constructor(limit = exports.MAX_SESSION_NOTE_LENGTH) {
|
|
421
|
+
super(`Session note exceeds ${limit} characters`);
|
|
422
|
+
this.name = 'SessionNoteTooLongError';
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
exports.SessionNoteTooLongError = SessionNoteTooLongError;
|
|
426
|
+
/** Below this code point (plus DEL) a character cannot be typed into a memo. */
|
|
427
|
+
const FIRST_PRINTABLE_CODE_POINT = 0x20;
|
|
428
|
+
const DELETE_CODE_POINT = 0x7f;
|
|
429
|
+
/**
|
|
430
|
+
* Fold a submitted note into the one line that is actually stored.
|
|
431
|
+
*
|
|
432
|
+
* Control characters — a pasted newline above all, which is how a multi-line
|
|
433
|
+
* clipboard reaches a one-line input — become spaces rather than being rejected:
|
|
434
|
+
* the operator pasting two lines of a commit message means the text, not the
|
|
435
|
+
* line break, and a refusal there would read as a bug. Runs of whitespace
|
|
436
|
+
* collapse and the ends are trimmed, so the stored value is what the header will
|
|
437
|
+
* render, and the length limit is measured against that rather than against
|
|
438
|
+
* padding.
|
|
439
|
+
*
|
|
440
|
+
* Iterating code points rather than matching a control-character class keeps the
|
|
441
|
+
* repository's own `scripts/check-control-chars.mjs` discipline — the escape
|
|
442
|
+
* sequence for a control character is still a control character to a reviewer
|
|
443
|
+
* skimming the line — and gets surrogate pairs right for free.
|
|
444
|
+
*
|
|
445
|
+
* Returns `''` for anything that folds away to nothing, which is the caller's
|
|
446
|
+
* signal to DELETE rather than to store.
|
|
447
|
+
*/
|
|
448
|
+
function normalizeSessionNoteText(raw) {
|
|
449
|
+
if (typeof raw !== 'string')
|
|
450
|
+
return '';
|
|
451
|
+
let folded = '';
|
|
452
|
+
for (const char of raw) {
|
|
453
|
+
const code = char.codePointAt(0) ?? 0;
|
|
454
|
+
folded += code < FIRST_PRINTABLE_CODE_POINT || code === DELETE_CODE_POINT ? ' ' : char;
|
|
455
|
+
}
|
|
456
|
+
return folded.replace(/\s+/g, ' ').trim();
|
|
457
|
+
}
|
|
458
|
+
/** How long a normalized note is, counted the way the limit is defined. */
|
|
459
|
+
function sessionNoteLength(text) {
|
|
460
|
+
return Array.from(text).length;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* The note kept beside one session, or null when there is none.
|
|
464
|
+
*
|
|
465
|
+
* @param db - Database instance
|
|
466
|
+
* @param worktreeId - Worktree ID
|
|
467
|
+
* @param instanceId - Instance ID (the primary instance uses the CLI tool id)
|
|
468
|
+
*/
|
|
469
|
+
function getSessionNote(db, worktreeId, instanceId) {
|
|
470
|
+
const row = db.prepare(`
|
|
471
|
+
SELECT instance_id, note, updated_at
|
|
472
|
+
FROM session_notes
|
|
473
|
+
WHERE worktree_id = ? AND instance_id = ?
|
|
474
|
+
`).get(worktreeId, instanceId);
|
|
475
|
+
return row ? { text: row.note, updatedAt: row.updated_at } : null;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Every note kept for a worktree, keyed by instance id.
|
|
479
|
+
*
|
|
480
|
+
* One statement rather than one per roster entry: the split header asks for the
|
|
481
|
+
* whole worktree at once, and an instance with no row is simply absent from the
|
|
482
|
+
* result — which is also how the UI decides to render nothing.
|
|
483
|
+
*/
|
|
484
|
+
function getSessionNotesByWorktree(db, worktreeId) {
|
|
485
|
+
const rows = db.prepare(`
|
|
486
|
+
SELECT instance_id, note, updated_at
|
|
487
|
+
FROM session_notes
|
|
488
|
+
WHERE worktree_id = ?
|
|
489
|
+
`).all(worktreeId);
|
|
490
|
+
const notes = {};
|
|
491
|
+
for (const row of rows) {
|
|
492
|
+
notes[row.instance_id] = { text: row.note, updatedAt: row.updated_at };
|
|
493
|
+
}
|
|
494
|
+
return notes;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Every note on the server, grouped by worktree id then instance id.
|
|
498
|
+
*
|
|
499
|
+
* `GET /api/worktrees` composes one payload for every worktree at once and is
|
|
500
|
+
* polled by every open client, so it reads this table ONCE rather than issuing a
|
|
501
|
+
* point query per row of the list. The whole table is a handful of rows per
|
|
502
|
+
* worktree by construction (at most `MAX_AGENT_INSTANCES`, and only for the
|
|
503
|
+
* sessions somebody annotated), so grouping in JS costs less than the round
|
|
504
|
+
* trips it replaces — and it is immune to SQLite's bound-parameter ceiling,
|
|
505
|
+
* which an `IN (...)` over every worktree id would not be.
|
|
506
|
+
*/
|
|
507
|
+
function getAllSessionNotes(db) {
|
|
508
|
+
const rows = db.prepare(`
|
|
509
|
+
SELECT worktree_id, instance_id, note, updated_at
|
|
510
|
+
FROM session_notes
|
|
511
|
+
`).all();
|
|
512
|
+
const byWorktree = {};
|
|
513
|
+
for (const row of rows) {
|
|
514
|
+
const notes = byWorktree[row.worktree_id] ?? (byWorktree[row.worktree_id] = {});
|
|
515
|
+
notes[row.instance_id] = { text: row.note, updatedAt: row.updated_at };
|
|
516
|
+
}
|
|
517
|
+
return byWorktree;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Write one session's note, or clear it.
|
|
521
|
+
*
|
|
522
|
+
* A note that normalizes to nothing DELETES the row instead of storing `''`, for
|
|
523
|
+
* the reason {@link setOpencodeInstanceSettings} deletes an all-unset write: the
|
|
524
|
+
* two states are indistinguishable to every reader, and absence is what lets the
|
|
525
|
+
* split header render nothing at all rather than an empty chip.
|
|
526
|
+
*
|
|
527
|
+
* @param at - Epoch ms recorded as the note's time; injectable so a test can
|
|
528
|
+
* assert the displayed timestamp without racing the clock
|
|
529
|
+
* @returns The stored note, or null when the note was cleared
|
|
530
|
+
* @throws InvalidAgentInstanceError when the instance id is not a valid one
|
|
531
|
+
* @throws SessionNoteTooLongError when the note is over the limit
|
|
532
|
+
*/
|
|
533
|
+
function setSessionNote(db, worktreeId, instanceId, text, at = Date.now()) {
|
|
534
|
+
if (!(0, types_1.isValidInstanceId)(instanceId)) {
|
|
535
|
+
throw new InvalidAgentInstanceError(`Invalid instance id: ${String(instanceId)}`);
|
|
536
|
+
}
|
|
537
|
+
const normalized = normalizeSessionNoteText(text);
|
|
538
|
+
if (sessionNoteLength(normalized) > exports.MAX_SESSION_NOTE_LENGTH) {
|
|
539
|
+
throw new SessionNoteTooLongError();
|
|
540
|
+
}
|
|
541
|
+
if (normalized.length === 0) {
|
|
542
|
+
db.prepare(`
|
|
543
|
+
DELETE FROM session_notes WHERE worktree_id = ? AND instance_id = ?
|
|
544
|
+
`).run(worktreeId, instanceId);
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
db.prepare(`
|
|
548
|
+
INSERT INTO session_notes (worktree_id, instance_id, note, updated_at)
|
|
549
|
+
VALUES (?, ?, ?, ?)
|
|
550
|
+
ON CONFLICT(worktree_id, instance_id) DO UPDATE SET
|
|
551
|
+
note = excluded.note,
|
|
552
|
+
updated_at = excluded.updated_at
|
|
553
|
+
`).run(worktreeId, instanceId, normalized, at);
|
|
554
|
+
return { text: normalized, updatedAt: at };
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Drop the notes of instances that are no longer in the roster.
|
|
558
|
+
*
|
|
559
|
+
* Called by {@link setAgentInstances} and {@link removeAgentInstance} for the
|
|
560
|
+
* reason {@link pruneOpencodeInstanceSettings} is: `session_notes` is keyed on an
|
|
561
|
+
* instance id and nothing else would ever remove a row for an instance the
|
|
562
|
+
* operator deleted, so re-adding an instance under the same id would inherit a
|
|
563
|
+
* memo written about a session that no longer exists as if it were its own.
|
|
564
|
+
*
|
|
565
|
+
* The counterpart matters just as much: this prunes the ids that are GONE and
|
|
566
|
+
* leaves every surviving id alone, which is what makes a note survive the roster
|
|
567
|
+
* replace that an alias edit performs.
|
|
568
|
+
*
|
|
569
|
+
* @param keepInstanceIds - The ids that survive; every other row is deleted
|
|
570
|
+
* @returns How many rows were removed
|
|
571
|
+
*/
|
|
572
|
+
function pruneSessionNotes(db, worktreeId, keepInstanceIds) {
|
|
573
|
+
if (keepInstanceIds.length === 0) {
|
|
574
|
+
return db.prepare(`
|
|
575
|
+
DELETE FROM session_notes WHERE worktree_id = ?
|
|
576
|
+
`).run(worktreeId).changes;
|
|
577
|
+
}
|
|
578
|
+
const placeholders = keepInstanceIds.map(() => '?').join(', ');
|
|
579
|
+
return db.prepare(`
|
|
580
|
+
DELETE FROM session_notes
|
|
581
|
+
WHERE worktree_id = ? AND instance_id NOT IN (${placeholders})
|
|
582
|
+
`).run(worktreeId, ...keepInstanceIds).changes;
|
|
583
|
+
}
|
|
@@ -44,6 +44,7 @@ const v57_push_subscription_defaults_notice_1 = require("./v57-push-subscription
|
|
|
44
44
|
const v58_agent_session_costs_1 = require("./v58-agent-session-costs");
|
|
45
45
|
const v59_opencode_instance_settings_1 = require("./v59-opencode-instance-settings");
|
|
46
46
|
const v60_session_relays_1 = require("./v60-session-relays");
|
|
47
|
+
const v61_session_notes_1 = require("./v61-session-notes");
|
|
47
48
|
/**
|
|
48
49
|
* Complete ordered list of all migrations.
|
|
49
50
|
* Used internally by the barrel file (db-migrations.ts); NOT exported from the barrel (DR2-004).
|
|
@@ -91,4 +92,5 @@ exports.migrations = [
|
|
|
91
92
|
...v58_agent_session_costs_1.v58_migrations,
|
|
92
93
|
...v59_opencode_instance_settings_1.v59_migrations,
|
|
93
94
|
...v60_session_relays_1.v60_migrations,
|
|
95
|
+
...v61_session_notes_1.v61_migrations,
|
|
94
96
|
];
|