commandmate 0.29.2 → 0.30.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 +271 -264
- package/.next/app-path-routes-manifest.json +35 -34
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.json +1 -1
- package/.next/routes-manifest.json +8 -8
- 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.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.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route.js +1 -1
- package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route.js +18 -18
- package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/terminal/route.js +19 -19
- package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route.js +1 -1
- package/.next/server/app/api/daily-summary/route_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 +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route.js +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/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_client-reference-manifest.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.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.js +1 -0
- package/.next/server/app/api/settings/default-surface-mode/route.js.nft.json +1 -0
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/cli-reference/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route.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/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.js +2 -2
- package/.next/server/app/more/page.js.nft.json +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_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_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +11 -11
- package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page.js +3 -3
- 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/1058.js +1 -1
- package/.next/server/chunks/1068.js +1 -1
- package/.next/server/chunks/1191.js +1 -1
- package/.next/server/chunks/1341.js +1 -1
- package/.next/server/chunks/1886.js +3 -3
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/261.js +1 -0
- package/.next/server/chunks/2739.js +1 -0
- package/.next/server/chunks/2816.js +1 -1
- package/.next/server/chunks/3099.js +5 -0
- package/.next/server/chunks/3123.js +1 -0
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3543.js +1 -1
- package/.next/server/chunks/3945.js +1 -1
- package/.next/server/chunks/4325.js +1 -0
- package/.next/server/chunks/4390.js +1 -1
- package/.next/server/chunks/4393.js +1 -1
- package/.next/server/chunks/4443.js +6 -0
- package/.next/server/chunks/5017.js +1 -1
- package/.next/server/chunks/5043.js +1 -0
- package/.next/server/chunks/5120.js +1 -0
- package/.next/server/chunks/552.js +25 -0
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6337.js +1 -1
- package/.next/server/chunks/663.js +1 -1
- package/.next/server/chunks/6894.js +8 -0
- package/.next/server/chunks/7685.js +1 -1
- package/.next/server/chunks/7836.js +1 -0
- package/.next/server/chunks/8356.js +1 -1
- package/.next/server/chunks/880.js +1 -1
- package/.next/server/chunks/8807.js +1 -1
- package/.next/server/chunks/9123.js +2 -2
- package/.next/server/chunks/9130.js +3 -3
- package/.next/server/chunks/9627.js +48 -26
- package/.next/server/chunks/9696.js +3 -0
- package/.next/server/chunks/9798.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/server/src/middleware.js +1 -1
- package/.next/server/src/middleware.js.map +1 -1
- package/.next/static/chunks/{4882-388e94fe0a03c2ba.js → 3916-0e929d089282dc5d.js} +1 -1
- package/.next/static/chunks/{5229-b2a81bb8fb5c19e9.js → 5229-6c89475b61bd2c8b.js} +1 -1
- package/.next/static/chunks/6022-7a7d1760fc9814c7.js +1 -0
- package/.next/static/chunks/6381-dbf04a99647f6018.js +1 -0
- package/.next/static/chunks/app/api/agents/update/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/agents/versions/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/app/update/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/app/update-check/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/conversation/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/current-output/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/messages/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/session/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/start/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/terminal/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/assistant/tools/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/auth/login/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/auth/status/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/capabilities/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/status/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/external-apps/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/fs/browse/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/fs/recent-paths/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/hooks/agent-event/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/hooks/claude-done/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/hooks/permission-request/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/metrics/vibe/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/ollama/models/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/push/escalation/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/push/subscriptions/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/push/vapid/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/remote/pair/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/excluded/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/restore/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/scan/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/sync/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/repositories/validate-path/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/settings/default-agents/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/settings/default-surface-mode/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/sidebar/group-order/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/skills/[id]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/skills/installations/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/skills/operations/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/skills/reindex/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/skills/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/slash-commands/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/templates/[id]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/templates/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/todos/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/manifest.webmanifest/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/more/{page-75d3783da0d49a25.js → page-333bba1c8bbc9c11.js} +1 -1
- package/.next/static/chunks/app/proxy/[...path]/route-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/layout-ee11f7b8a34cba8c.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-aac399392ec8c273.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/terminal/page-2631bc5c4b0a9fb8.js +1 -0
- package/.next/static/css/23f9c40ecc458c77.css +1 -0
- package/.next/static/pcpB4K6KreMzu2qbhvuRY/_buildManifest.js +1 -0
- package/.next/trace +13 -13
- package/.next/types/app/api/settings/default-surface-mode/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/{start-polling → cli-reference}/route.ts +3 -3
- package/.next/types/routes.d.ts +3 -2
- package/.next/types/validator.ts +18 -9
- package/dist/server/server.js +58 -0
- package/dist/server/src/lib/claude-output.js +1 -0
- package/dist/server/src/lib/db/app-settings-db.js +60 -0
- package/dist/server/src/lib/db/chat-db.js +120 -7
- package/dist/server/src/lib/detection/status-detector.js +3 -2
- package/dist/server/src/lib/env.js +122 -0
- package/dist/server/src/lib/git/worktrees.js +154 -0
- package/dist/server/src/lib/history/transcript-tail.js +80 -0
- package/dist/server/src/lib/history/user-turn-recorder.js +252 -0
- package/dist/server/src/lib/hooks/agent-event-service.js +40 -6
- package/dist/server/src/lib/hooks/permission-decision-service.js +85 -1
- package/dist/server/src/lib/hooks/sources/antigravity/history.js +607 -0
- package/dist/server/src/lib/hooks/sources/antigravity/source.js +7 -0
- package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +407 -0
- package/dist/server/src/lib/hooks/sources/claude/history.js +797 -0
- package/dist/server/src/lib/hooks/sources/claude/source.js +4 -0
- package/dist/server/src/lib/hooks/sources/claude/transcript.js +518 -0
- package/dist/server/src/lib/hooks/sources/codex/history.js +663 -0
- package/dist/server/src/lib/hooks/sources/codex/source.js +4 -0
- package/dist/server/src/lib/hooks/sources/codex/transcript.js +448 -0
- package/dist/server/src/lib/hooks/sources/copilot/source.js +2 -0
- package/dist/server/src/lib/hooks/sources/gemini/source.js +2 -0
- package/dist/server/src/lib/hooks/sources/legacy-relay.js +3 -0
- package/dist/server/src/lib/hooks/sources/opencode/history.js +57 -0
- package/dist/server/src/lib/hooks/sources/opencode/source.js +4 -0
- package/dist/server/src/lib/hooks/sources/opencode/transcript.js +10 -28
- package/dist/server/src/lib/hooks/sources/turn-body.js +118 -0
- package/dist/server/src/lib/hooks/stop-history-capture.js +161 -0
- package/dist/server/src/lib/polling/prompt-dedup.js +2 -4
- package/dist/server/src/lib/polling/response-checker.js +87 -6
- package/dist/server/src/lib/polling/response-dedup.js +2 -4
- package/dist/server/src/lib/polling/response-poller-core.js +191 -29
- package/dist/server/src/lib/polling/structured-history-gate.js +272 -16
- package/dist/server/src/lib/push/push-sender.js +21 -1
- package/dist/server/src/lib/push/waiting-push-notifier.js +126 -8
- package/dist/server/src/lib/realtime/publisher-registry.js +171 -0
- package/dist/server/src/lib/realtime/terminal-broadcast.js +14 -1
- package/dist/server/src/lib/realtime/types.js +96 -1
- package/dist/server/src/lib/session/current-output-builder.js +365 -4
- package/dist/server/src/lib/session/send-user-message.js +90 -2
- package/dist/server/src/lib/tui-accumulator.js +2 -8
- package/dist/server/src/lib/ws-server.js +143 -6
- package/dist/server/src/types/agent-transcript.js +241 -5
- package/dist/server/src/types/ui-state.js +24 -1
- package/package.json +1 -1
- package/public/sw.js +15 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js +0 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +0 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +0 -1
- package/.next/server/chunks/1714.js +0 -7
- package/.next/server/chunks/2198.js +0 -1
- package/.next/server/chunks/221.js +0 -25
- package/.next/server/chunks/2759.js +0 -8
- package/.next/server/chunks/3558.js +0 -1
- package/.next/server/chunks/6781.js +0 -1
- package/.next/server/chunks/9508.js +0 -1
- package/.next/static/0YoRrahue4Vchxg1z83IQ/_buildManifest.js +0 -1
- package/.next/static/chunks/1379-af7af9e08f47c979.js +0 -1
- package/.next/static/chunks/6381-9ba5198c0a6ff197.js +0 -1
- package/.next/static/chunks/app/api/agents/update/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/agents/versions/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/app/update/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/app/update-check/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/conversation/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/current-output/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/messages/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/session/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/start/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/terminal/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/assistant/tools/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/auth/login/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/auth/status/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/capabilities/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/status/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/external-apps/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/fs/browse/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/fs/recent-paths/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/hooks/agent-event/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/hooks/claude-done/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/hooks/permission-request/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/metrics/vibe/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/ollama/models/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/push/escalation/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/push/subscriptions/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/push/vapid/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/remote/pair/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/excluded/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/restore/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/scan/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/sync/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/repositories/validate-path/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/settings/default-agents/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/sidebar/group-order/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/skills/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/skills/installations/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/skills/operations/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/skills/reindex/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/skills/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/slash-commands/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/templates/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/templates/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/todos/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/proxy/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/layout-1c30fb8d4d6fa6ef.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-ce6279d581d1df95.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/terminal/page-00ad5d9a62a71cab.js +0 -1
- package/.next/static/css/b326c8a734e1928e.css +0 -1
- /package/.next/static/{0YoRrahue4Vchxg1z83IQ → pcpB4K6KreMzu2qbhvuRY}/_ssgManifest.js +0 -0
|
@@ -6,13 +6,15 @@
|
|
|
6
6
|
* Issue #479: Extracted from db.ts for single-responsibility separation
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.ACTIVE_FILTER = void 0;
|
|
9
|
+
exports.UNKEYED_USER_MESSAGE_LIMIT = exports.ACTIVE_FILTER = void 0;
|
|
10
10
|
exports.getLastAssistantMessageAt = getLastAssistantMessageAt;
|
|
11
11
|
exports.createMessage = createMessage;
|
|
12
12
|
exports.updateMessageContent = updateMessageContent;
|
|
13
13
|
exports.getMessages = getMessages;
|
|
14
14
|
exports.getLastUserMessage = getLastUserMessage;
|
|
15
15
|
exports.findMessageByRequestId = findMessageByRequestId;
|
|
16
|
+
exports.findUnkeyedUserMessages = findUnkeyedUserMessages;
|
|
17
|
+
exports.setMessageRequestId = setMessageRequestId;
|
|
16
18
|
exports.getLastMessage = getLastMessage;
|
|
17
19
|
exports.deleteAllMessages = deleteAllMessages;
|
|
18
20
|
exports.deleteMessageById = deleteMessageById;
|
|
@@ -125,7 +127,7 @@ function updateMessageContent(db, messageId, content, options) {
|
|
|
125
127
|
* Get messages for a worktree, optionally filtered by CLI tool
|
|
126
128
|
*/
|
|
127
129
|
function getMessages(db, worktreeId, options = {}) {
|
|
128
|
-
const { before, limit = 50, cliToolId, instanceId, includeArchived = false, messageType, limitUnit = 'messages' } = options;
|
|
130
|
+
const { before, limit = 50, cliToolId, instanceId, includeArchived = false, messageType, limitUnit = 'messages', matchResolvedInstance = false } = options;
|
|
129
131
|
// Build the shared scope clause (worktree + before cursor + archived + instance/cli
|
|
130
132
|
// filter) and its bound params. Used for both the message-unit and pair-unit paths
|
|
131
133
|
// so their filtering stays identical.
|
|
@@ -138,7 +140,19 @@ function getMessages(db, worktreeId, options = {}) {
|
|
|
138
140
|
clause += ` ${exports.ACTIVE_FILTER}`;
|
|
139
141
|
}
|
|
140
142
|
// Issue #868: instance filter takes precedence; otherwise fall back to CLI tool filter.
|
|
141
|
-
|
|
143
|
+
// Issue #2219: `matchResolvedInstance` reads both columns through the same
|
|
144
|
+
// COALESCE defaults `mapChatMessage` applies, so pre-#868 rows
|
|
145
|
+
// (`instance_id IS NULL`) count as the primary instance instead of
|
|
146
|
+
// vanishing. See the option's doc comment for why the tool filter joins in.
|
|
147
|
+
if (instanceId && matchResolvedInstance) {
|
|
148
|
+
if (cliToolId) {
|
|
149
|
+
clause += ` AND COALESCE(cli_tool_id, 'claude') = ?`;
|
|
150
|
+
params.push(cliToolId);
|
|
151
|
+
}
|
|
152
|
+
clause += ` AND COALESCE(instance_id, cli_tool_id, 'claude') = ?`;
|
|
153
|
+
params.push(instanceId);
|
|
154
|
+
}
|
|
155
|
+
else if (instanceId) {
|
|
142
156
|
clause += ` AND instance_id = ?`;
|
|
143
157
|
params.push(instanceId);
|
|
144
158
|
}
|
|
@@ -229,6 +243,80 @@ function findMessageByRequestId(db, worktreeId, requestId) {
|
|
|
229
243
|
const row = stmt.get(worktreeId, requestId);
|
|
230
244
|
return row ? mapChatMessage(row) : null;
|
|
231
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* How many candidate rows {@link findUnkeyedUserMessages} returns.
|
|
248
|
+
*
|
|
249
|
+
* The caller compares content in JavaScript, so this bounds the work rather than
|
|
250
|
+
* the correctness. Twenty is far above the number of user rows one instance can
|
|
251
|
+
* accumulate inside the caller's few-minute window and still small enough that
|
|
252
|
+
* the query is never the expensive part of a poll.
|
|
253
|
+
*/
|
|
254
|
+
exports.UNKEYED_USER_MESSAGE_LIMIT = 20;
|
|
255
|
+
/**
|
|
256
|
+
* User rows for one instance that no producer has claimed yet (Issue #2196).
|
|
257
|
+
*
|
|
258
|
+
* The lookup behind "the operator's input is already in History — `/send` put it
|
|
259
|
+
* there". A row qualifies when it is this instance's, is a `user` row, sits in
|
|
260
|
+
* the caller's time window, and has **no `request_id`**: that last condition is
|
|
261
|
+
* what makes the query safe to answer a *claim* with, because a row that already
|
|
262
|
+
* carries a key belongs to whoever wrote it and must not be re-pointed at
|
|
263
|
+
* another turn.
|
|
264
|
+
*
|
|
265
|
+
* Content is deliberately not compared here. "The same text" is a normalisation
|
|
266
|
+
* question (trailing whitespace, `\r\n`, a composer that reflowed the body), and
|
|
267
|
+
* SQL is the wrong place to decide it — see `normalizeUserTurnContent` in
|
|
268
|
+
* `lib/history/user-turn-recorder`, which owns that rule and is the only thing
|
|
269
|
+
* that has to change when the rule does.
|
|
270
|
+
*
|
|
271
|
+
* `COALESCE` on both tool columns is not defensive noise: rows written before
|
|
272
|
+
* Issue #868 carry `instance_id IS NULL`, and `mapChatMessage` reads those as
|
|
273
|
+
* the primary instance. A bare `instance_id = ?` would make those rows
|
|
274
|
+
* invisible here while the UI still shows them, so the operator would see their
|
|
275
|
+
* `/send` row *and* a second row this Issue inserted.
|
|
276
|
+
*
|
|
277
|
+
* `ACTIVE_FILTER` applies: an archived row has been cleared out of History, and
|
|
278
|
+
* adopting one would key a turn to a row nobody can see.
|
|
279
|
+
*
|
|
280
|
+
* @returns Candidate rows, newest first
|
|
281
|
+
*/
|
|
282
|
+
function findUnkeyedUserMessages(db, query) {
|
|
283
|
+
const stmt = db.prepare(`
|
|
284
|
+
SELECT id, worktree_id, role, content, summary, timestamp, log_file_name, request_id, message_type, prompt_data, cli_tool_id, instance_id, archived
|
|
285
|
+
FROM chat_messages
|
|
286
|
+
WHERE worktree_id = ?
|
|
287
|
+
AND role = 'user'
|
|
288
|
+
AND request_id IS NULL
|
|
289
|
+
AND COALESCE(cli_tool_id, 'claude') = ?
|
|
290
|
+
AND COALESCE(instance_id, cli_tool_id, 'claude') = ?
|
|
291
|
+
AND timestamp >= ? AND timestamp <= ?
|
|
292
|
+
${exports.ACTIVE_FILTER}
|
|
293
|
+
ORDER BY timestamp DESC
|
|
294
|
+
LIMIT ?
|
|
295
|
+
`);
|
|
296
|
+
const rows = stmt.all(query.worktreeId, query.cliToolId, query.instanceId, query.fromMs, query.toMs, query.limit ?? exports.UNKEYED_USER_MESSAGE_LIMIT);
|
|
297
|
+
return rows.map(mapChatMessage);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Claim an unkeyed row for a producer, without touching anything else on it
|
|
301
|
+
* (Issue #2196).
|
|
302
|
+
*
|
|
303
|
+
* A compare-and-set and not an `UPDATE … WHERE id = ?`: the `request_id IS NULL`
|
|
304
|
+
* in the predicate is what makes two pollers racing on the same row safe, since
|
|
305
|
+
* the loser changes nothing and is told so. {@link updateMessageContent} could
|
|
306
|
+
* set the column too, but it also rewrites `content`, and rewriting the
|
|
307
|
+
* operator's own words as a side effect of keying their row is exactly the
|
|
308
|
+
* failure this Issue is trying not to introduce.
|
|
309
|
+
*
|
|
310
|
+
* @returns Whether this call is the one that claimed the row
|
|
311
|
+
*/
|
|
312
|
+
function setMessageRequestId(db, messageId, requestId) {
|
|
313
|
+
const stmt = db.prepare(`
|
|
314
|
+
UPDATE chat_messages
|
|
315
|
+
SET request_id = ?
|
|
316
|
+
WHERE id = ? AND request_id IS NULL
|
|
317
|
+
`);
|
|
318
|
+
return stmt.run(requestId, messageId).changes > 0;
|
|
319
|
+
}
|
|
232
320
|
/**
|
|
233
321
|
* Fetch the most recent message for a worktree (any role).
|
|
234
322
|
* Used to determine if waiting for Claude's response.
|
|
@@ -431,14 +519,27 @@ function updatePromptData(db, messageId, promptData) {
|
|
|
431
519
|
* Mark all pending prompts as answered for a worktree/CLI tool
|
|
432
520
|
* This is called when we detect Claude has started processing (new response detected)
|
|
433
521
|
* which means any pending prompts must have been answered via terminal
|
|
522
|
+
*
|
|
523
|
+
* @param onUpdated - Issue #2195. Invoked once per row that was actually
|
|
524
|
+
* stamped, with the row as it now reads. This sweep is the one prompt-status
|
|
525
|
+
* writer that produced no realtime frame, so a prompt card stayed "pending"
|
|
526
|
+
* in every open pane until the next history poll — up to 15s once #2195
|
|
527
|
+
* demoted that poll to a fallback. The caller supplies the broadcast rather
|
|
528
|
+
* than this module reaching for `ws-server`: the DB layer has no business
|
|
529
|
+
* importing the socket, and the two sweep callers that are *not* a poller
|
|
530
|
+
* (the worktree list/detail routes) have no room to broadcast into anyway.
|
|
531
|
+
* Throwing from the callback is the caller's problem; it is not caught here.
|
|
434
532
|
*/
|
|
435
|
-
function markPendingPromptsAsAnswered(db, worktreeId, cliToolId, instanceId) {
|
|
533
|
+
function markPendingPromptsAsAnswered(db, worktreeId, cliToolId, instanceId, onUpdated) {
|
|
436
534
|
// Find all pending prompt messages for this worktree/CLI tool.
|
|
437
535
|
// Issue #868: When instanceId is provided, scope to that instance only;
|
|
438
536
|
// otherwise fall back to the legacy cli_tool_id scoping.
|
|
439
537
|
const resolvedInstanceId = instanceId ?? cliToolId;
|
|
538
|
+
// Issue #2195: the full column set, not just (id, prompt_data) — `onUpdated`
|
|
539
|
+
// publishes a `ChatMessage`, and re-reading each row afterwards would be a
|
|
540
|
+
// second query per prompt for data this statement already has to visit.
|
|
440
541
|
const selectStmt = db.prepare(`
|
|
441
|
-
SELECT id, prompt_data
|
|
542
|
+
SELECT id, worktree_id, role, content, summary, timestamp, log_file_name, request_id, message_type, prompt_data, cli_tool_id, instance_id, archived
|
|
442
543
|
FROM chat_messages
|
|
443
544
|
WHERE worktree_id = ?
|
|
444
545
|
AND instance_id = ?
|
|
@@ -458,9 +559,12 @@ function markPendingPromptsAsAnswered(db, worktreeId, cliToolId, instanceId) {
|
|
|
458
559
|
WHERE id = ?
|
|
459
560
|
`);
|
|
460
561
|
let updatedCount = 0;
|
|
562
|
+
const updated = [];
|
|
461
563
|
for (const row of rows) {
|
|
462
564
|
try {
|
|
463
|
-
const promptData = JSON.parse(row.prompt_data);
|
|
565
|
+
const promptData = JSON.parse(row.prompt_data ?? 'null');
|
|
566
|
+
if (!promptData || typeof promptData !== 'object')
|
|
567
|
+
continue;
|
|
464
568
|
promptData.status = 'answered';
|
|
465
569
|
promptData.answer = '(answered via terminal)';
|
|
466
570
|
promptData.answeredAt = new Date().toISOString();
|
|
@@ -468,13 +572,22 @@ function markPendingPromptsAsAnswered(db, worktreeId, cliToolId, instanceId) {
|
|
|
468
572
|
// prompts nothing else claimed, so all that is known is that the agent
|
|
469
573
|
// moved on — i.e. someone acted in the terminal.
|
|
470
574
|
promptData.answeredBy = 'terminal';
|
|
471
|
-
|
|
575
|
+
const serialized = JSON.stringify(promptData);
|
|
576
|
+
updateStmt.run(serialized, row.id);
|
|
472
577
|
updatedCount++;
|
|
578
|
+
if (onUpdated) {
|
|
579
|
+
updated.push(mapChatMessage({ ...row, prompt_data: serialized }));
|
|
580
|
+
}
|
|
473
581
|
}
|
|
474
582
|
catch {
|
|
475
583
|
// Skip if prompt_data is invalid JSON
|
|
476
584
|
}
|
|
477
585
|
}
|
|
586
|
+
// Published after every write lands, so a listener that reacts by reading the
|
|
587
|
+
// table back cannot observe a half-swept instance.
|
|
588
|
+
for (const message of updated) {
|
|
589
|
+
onUpdated?.(message);
|
|
590
|
+
}
|
|
478
591
|
return updatedCount;
|
|
479
592
|
}
|
|
480
593
|
/**
|
|
@@ -72,8 +72,9 @@ exports.SELECTION_LIST_REASONS = new Set([
|
|
|
72
72
|
* one: branch A of the opencode block answers `opencode_processing_indicator`
|
|
73
73
|
* for the footer that reads `esc interrupt`, which is opencode's ONLY signal
|
|
74
74
|
* while it is between the submitted prompt and the first transcript row. A
|
|
75
|
-
* scraper-only session (no hooks) therefore showed no thinking indicator
|
|
76
|
-
*
|
|
75
|
+
* scraper-only session (no hooks) therefore showed no thinking indicator on the
|
|
76
|
+
* chat surface for exactly the stretch where one is wanted. The consumer is
|
|
77
|
+
* `ChatSurface`, which reads this through `current-output`'s `thinking` flag.
|
|
77
78
|
*
|
|
78
79
|
* `DEFAULT` is deliberately absent: it is the "output changed recently" fallback
|
|
79
80
|
* and says nothing about the agent having announced itself, so promoting it
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Issue #135: DB path resolution fix
|
|
10
10
|
* Uses getDefaultDbPath() from db-path-resolver.ts for consistent DB path handling
|
|
11
|
+
*
|
|
12
|
+
* Issue #2132: startup self-check for ".env exists but nothing was loaded"
|
|
13
|
+
* See {@link runDotenvSelfCheck}.
|
|
11
14
|
*/
|
|
12
15
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
16
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -17,12 +20,17 @@ exports.ENV_MAPPING = void 0;
|
|
|
17
20
|
exports.resetWarnedKeys = resetWarnedKeys;
|
|
18
21
|
exports.getEnvWithFallback = getEnvWithFallback;
|
|
19
22
|
exports.getEnvByKey = getEnvByKey;
|
|
23
|
+
exports.parseDotenvKeys = parseDotenvKeys;
|
|
24
|
+
exports.inspectDotenvLoad = inspectDotenvLoad;
|
|
25
|
+
exports.formatDotenvReportLines = formatDotenvReportLines;
|
|
26
|
+
exports.runDotenvSelfCheck = runDotenvSelfCheck;
|
|
20
27
|
exports.resetDatabasePathWarning = resetDatabasePathWarning;
|
|
21
28
|
exports.getDatabasePathWithDeprecationWarning = getDatabasePathWithDeprecationWarning;
|
|
22
29
|
exports.getLogConfig = getLogConfig;
|
|
23
30
|
exports.getServerPort = getServerPort;
|
|
24
31
|
exports.getEnv = getEnv;
|
|
25
32
|
exports.validateEnv = validateEnv;
|
|
33
|
+
const fs_1 = __importDefault(require("fs"));
|
|
26
34
|
const path_1 = __importDefault(require("path"));
|
|
27
35
|
const db_path_resolver_1 = require("./db/db-path-resolver");
|
|
28
36
|
// ============================================================
|
|
@@ -84,6 +92,120 @@ function getEnvWithFallback(newKey, oldKey) {
|
|
|
84
92
|
function getEnvByKey(key) {
|
|
85
93
|
return getEnvWithFallback(key, exports.ENV_MAPPING[key]);
|
|
86
94
|
}
|
|
95
|
+
/** `KEY`, `export KEY`, ` KEY ` — the assignment forms a `.env` line can take. */
|
|
96
|
+
const DOTENV_ASSIGNMENT = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
|
|
97
|
+
/**
|
|
98
|
+
* The variable names a `.env` file declares, in file order, without duplicates.
|
|
99
|
+
*
|
|
100
|
+
* Values are never returned. `CM_VAPID_PRIVATE_KEY` lives in this file, and the
|
|
101
|
+
* only reason to parse it here is to count how many of its NAMES arrived.
|
|
102
|
+
*/
|
|
103
|
+
function parseDotenvKeys(contents) {
|
|
104
|
+
const keys = [];
|
|
105
|
+
const seen = new Set();
|
|
106
|
+
for (const line of contents.split(/\r?\n/)) {
|
|
107
|
+
const match = DOTENV_ASSIGNMENT.exec(line);
|
|
108
|
+
if (!match)
|
|
109
|
+
continue;
|
|
110
|
+
const key = match[1];
|
|
111
|
+
if (seen.has(key))
|
|
112
|
+
continue;
|
|
113
|
+
seen.add(key);
|
|
114
|
+
keys.push(key);
|
|
115
|
+
}
|
|
116
|
+
return keys;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Compare the `.env` on disk against the environment this process actually got.
|
|
120
|
+
*
|
|
121
|
+
* @returns `null` when there is nothing to compare — no `.env`, an unreadable
|
|
122
|
+
* one, or one that declares no variables. None of those is a fault worth a
|
|
123
|
+
* line of startup output.
|
|
124
|
+
*/
|
|
125
|
+
function inspectDotenvLoad(options = {}) {
|
|
126
|
+
const { cwd = process.cwd(), env = process.env } = options;
|
|
127
|
+
const envPath = path_1.default.join(cwd, '.env');
|
|
128
|
+
let contents;
|
|
129
|
+
try {
|
|
130
|
+
if (!fs_1.default.existsSync(envPath))
|
|
131
|
+
return null;
|
|
132
|
+
contents = fs_1.default.readFileSync(envPath, 'utf8');
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// Unreadable is a permissions question, not a loading question.
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const declaredKeys = parseDotenvKeys(contents);
|
|
139
|
+
if (declaredKeys.length === 0)
|
|
140
|
+
return null;
|
|
141
|
+
const presentKeys = declaredKeys.filter((key) => env[key] !== undefined);
|
|
142
|
+
return {
|
|
143
|
+
envPath,
|
|
144
|
+
declaredKeys,
|
|
145
|
+
presentKeys,
|
|
146
|
+
loadFailed: presentKeys.length === 0,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/** How many key names the report is willing to print before it says "and N more". */
|
|
150
|
+
const DOTENV_REPORT_KEY_LIMIT = 8;
|
|
151
|
+
/**
|
|
152
|
+
* The lines {@link runDotenvSelfCheck} prints — empty when the load worked.
|
|
153
|
+
*
|
|
154
|
+
* Exported so the wording is pinned by a test rather than by a screenshot.
|
|
155
|
+
*/
|
|
156
|
+
function formatDotenvReportLines(inspection) {
|
|
157
|
+
if (!inspection.loadFailed)
|
|
158
|
+
return [];
|
|
159
|
+
const shown = inspection.declaredKeys.slice(0, DOTENV_REPORT_KEY_LIMIT);
|
|
160
|
+
const omitted = inspection.declaredKeys.length - shown.length;
|
|
161
|
+
const names = omitted > 0 ? `${shown.join(', ')}, and ${omitted} more` : shown.join(', ');
|
|
162
|
+
return [
|
|
163
|
+
`[env] ${inspection.envPath} declares ${inspection.declaredKeys.length} variable(s) `
|
|
164
|
+
+ 'and NOT ONE of them is set in this process: '
|
|
165
|
+
+ `${names}.`,
|
|
166
|
+
'[env] The server is running on defaults. Web Push, the database path and the '
|
|
167
|
+
+ 'worktree root are all configured through those variables, so this is very '
|
|
168
|
+
+ 'unlikely to be what you wanted.',
|
|
169
|
+
'[env] Most likely cause (Issue #2132): the server was started by hand after '
|
|
170
|
+
+ '`source scripts/load-env.sh` from a shell that is not bash. That script now '
|
|
171
|
+
+ 'refuses instead of exporting nothing, so re-run it and read what it says.',
|
|
172
|
+
'[env] Supported restart, no rebuild: ./scripts/restart-nobuild.sh '
|
|
173
|
+
+ '(or ./scripts/start.sh --daemon)',
|
|
174
|
+
];
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Report, in one place at startup, that `.env` exists and none of it arrived.
|
|
178
|
+
*
|
|
179
|
+
* Same contract as `runVapidSelfCheck` in `lib/push/vapid.ts`, deliberately:
|
|
180
|
+
* fail-open, never throws, never blocks `listen`, and a healthy install prints
|
|
181
|
+
* NOTHING — which is what makes the presence of a line meaningful.
|
|
182
|
+
*
|
|
183
|
+
* It exists because the failure it names is invisible from inside the process.
|
|
184
|
+
* Every consumer of these variables has a defensible default, so a server that
|
|
185
|
+
* received none of them starts, listens, and answers requests; what it does not
|
|
186
|
+
* do is send a single push notification, and it may open a different database
|
|
187
|
+
* than the one the operator believes they are looking at. During the Epic #2002
|
|
188
|
+
* device UAT the only signal was the VAPID warning, and reading it as "push is
|
|
189
|
+
* broken" rather than "the environment is empty" cost two UAT rounds.
|
|
190
|
+
*
|
|
191
|
+
* @returns The inspection, or `null` when there was nothing to check.
|
|
192
|
+
*/
|
|
193
|
+
function runDotenvSelfCheck(options = {}) {
|
|
194
|
+
const { warn = (message) => console.warn(message) } = options;
|
|
195
|
+
try {
|
|
196
|
+
const inspection = inspectDotenvLoad(options);
|
|
197
|
+
if (!inspection)
|
|
198
|
+
return null;
|
|
199
|
+
for (const line of formatDotenvReportLines(inspection)) {
|
|
200
|
+
warn(line);
|
|
201
|
+
}
|
|
202
|
+
return inspection;
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// A diagnostic must never be the reason a server fails to start.
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
87
209
|
// ============================================================
|
|
88
210
|
// [Issue #135] DATABASE_PATH Deprecation Support
|
|
89
211
|
// ============================================================
|
|
@@ -16,6 +16,8 @@ exports.scanMultipleRepositories = scanMultipleRepositories;
|
|
|
16
16
|
exports.deriveIdIgnoringOwnHistory = deriveIdIgnoringOwnHistory;
|
|
17
17
|
exports.syncWorktreesToDB = syncWorktreesToDB;
|
|
18
18
|
exports.repositoryExistsOnDisk = repositoryExistsOnDisk;
|
|
19
|
+
exports.directoryIsConfirmedAbsent = directoryIsConfirmedAbsent;
|
|
20
|
+
exports.reclaimGhostRepositories = reclaimGhostRepositories;
|
|
19
21
|
exports.pruneStaleRepositoryWorktrees = pruneStaleRepositoryWorktrees;
|
|
20
22
|
const child_process_1 = require("child_process");
|
|
21
23
|
const util_1 = require("util");
|
|
@@ -179,6 +181,27 @@ function getRepositoryPaths() {
|
|
|
179
181
|
*/
|
|
180
182
|
async function scanWorktrees(rootDir) {
|
|
181
183
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
184
|
+
// Issue #2165: a repository whose directory has been removed used to reach
|
|
185
|
+
// `execAsync` with a `cwd` that no longer exists, and Node reports that as
|
|
186
|
+
// `spawn /bin/sh ENOENT` — an error about the *shell*, not about the missing
|
|
187
|
+
// directory. It is neither `not a git repository` nor exit 128, so the catch
|
|
188
|
+
// below re-threw it and `scanMultipleRepositories` logged it at ERROR. Two
|
|
189
|
+
// costs: a wasted child process per repository per scan, and a permanent
|
|
190
|
+
// ERROR line whose text sends the reader after `/bin/sh` and `PATH` (that
|
|
191
|
+
// misdiagnosis actually happened — see the Issue).
|
|
192
|
+
//
|
|
193
|
+
// Deliberately {@link directoryIsConfirmedAbsent} rather than
|
|
194
|
+
// `fs.existsSync`: only a positively-confirmed absence is allowed to skip the
|
|
195
|
+
// scan. An unreadable or unreachable path (EACCES, EIO, a hung network mount)
|
|
196
|
+
// still goes to git, still fails, and is still reported at ERROR — that IS a
|
|
197
|
+
// real failure and must not be silently downgraded to "the directory is gone".
|
|
198
|
+
//
|
|
199
|
+
// A directory that exists but is no longer a git repository is untouched by
|
|
200
|
+
// this guard: it keeps taking the git exit-128 path below and returns [].
|
|
201
|
+
if (directoryIsConfirmedAbsent(rootDir)) {
|
|
202
|
+
logger.warn('repository:scan-skipped-missing-dir', { repoPath: rootDir });
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
182
205
|
try {
|
|
183
206
|
const { stdout } = await execAsync('git worktree list', {
|
|
184
207
|
cwd: rootDir,
|
|
@@ -479,6 +502,137 @@ function repositoryExistsOnDisk(repoPath) {
|
|
|
479
502
|
return true;
|
|
480
503
|
}
|
|
481
504
|
}
|
|
505
|
+
/**
|
|
506
|
+
* Whether a path is **positively confirmed** not to exist.
|
|
507
|
+
*
|
|
508
|
+
* Issue #2165. `fs.existsSync()` cannot answer this: it collapses "the entry is
|
|
509
|
+
* not there" and "I could not find out" into the same `false`. It is
|
|
510
|
+
* `accessSync(F_OK)` underneath, so an unreadable parent directory (EACCES), a
|
|
511
|
+
* hung or disconnected network mount (EIO / ETIMEDOUT / ESTALE / EHOSTDOWN) and
|
|
512
|
+
* a genuinely deleted directory are indistinguishable through it. That
|
|
513
|
+
* distinction is the whole safety question for {@link reclaimGhostRepositories}:
|
|
514
|
+
* a repository on an unreachable volume must never be treated as gone.
|
|
515
|
+
*
|
|
516
|
+
* `lstatSync` keeps the errno, so the answer can be narrowed to the two codes
|
|
517
|
+
* that mean the kernel walked the path successfully and the entry was not
|
|
518
|
+
* there:
|
|
519
|
+
*
|
|
520
|
+
* - `ENOENT` — a component of the path does not exist;
|
|
521
|
+
* - `ENOTDIR` — a component that must be a directory is a file, so no such
|
|
522
|
+
* entry can exist under it either.
|
|
523
|
+
*
|
|
524
|
+
* Every other outcome — the path resolved, or the lookup failed for any other
|
|
525
|
+
* reason — answers `false`, i.e. "not confirmed absent, leave it alone".
|
|
526
|
+
* `lstat` rather than `stat` so a dangling symlink is reported as present: the
|
|
527
|
+
* link is a real entry that the user still has to remove.
|
|
528
|
+
*
|
|
529
|
+
* @param repoPath - Absolute path to test
|
|
530
|
+
* @returns `true` only when the path is confirmed to be absent
|
|
531
|
+
*/
|
|
532
|
+
function directoryIsConfirmedAbsent(repoPath) {
|
|
533
|
+
if (!repoPath)
|
|
534
|
+
return false;
|
|
535
|
+
try {
|
|
536
|
+
fs_1.default.lstatSync(repoPath);
|
|
537
|
+
return false;
|
|
538
|
+
}
|
|
539
|
+
catch (error) {
|
|
540
|
+
const code = error.code;
|
|
541
|
+
return code === 'ENOENT' || code === 'ENOTDIR';
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Take ghost `repositories` rows out of the scan set (Issue #2165).
|
|
546
|
+
*
|
|
547
|
+
* A row whose directory has been deleted stays `enabled = 1` forever: nothing
|
|
548
|
+
* removes it, so every server start and every sync re-derives the scan set from
|
|
549
|
+
* it, spawns a shell into a `cwd` that does not exist and logs an ERROR. Rows
|
|
550
|
+
* registered under `/tmp` were still doing this seven months after the
|
|
551
|
+
* directory they name was collected by the OS.
|
|
552
|
+
*
|
|
553
|
+
* {@link pruneStaleRepositoryWorktrees} cannot reach them. It deletes *worktree*
|
|
554
|
+
* rows, and it iterates {@link getRepositories}, which is a `GROUP BY` over the
|
|
555
|
+
* `worktrees` table — a repository with no worktree rows is not in its result
|
|
556
|
+
* at all, and its `ids.length === 0` early-continue would skip it even if it
|
|
557
|
+
* were. This function is the missing half: it works the `repositories` table.
|
|
558
|
+
*
|
|
559
|
+
* ## What it does — demote, not delete
|
|
560
|
+
*
|
|
561
|
+
* The row is set to `enabled = 0`, exactly as the Repositories screen's Scan
|
|
562
|
+
* toggle does (#1658). It is NOT deleted. `enabled` is the flag that decides
|
|
563
|
+
* what gets scanned, so demotion is sufficient — the row leaves `allPaths` at
|
|
564
|
+
* the next startup and sync, and the ERROR stops for good. Choosing it over
|
|
565
|
+
* `deleteRepository()` buys three things:
|
|
566
|
+
*
|
|
567
|
+
* 1. **Reversibility.** No filesystem test can prove a directory is gone
|
|
568
|
+
* *forever* — an unmounted volume looks exactly like a deleted one from
|
|
569
|
+
* userspace. A demoted row keeps its id, display name, `visible` flag and
|
|
570
|
+
* clone URL, is listed on the Repositories screen with a Disabled badge, and
|
|
571
|
+
* is one click from coming back. A wrong delete is unrecoverable.
|
|
572
|
+
* 2. **Agreement with #1666.** That Issue settled that exclusion is where the
|
|
573
|
+
* app *stops*, not where it deletes; startup used to purge excluded
|
|
574
|
+
* repositories and that was the bug. Reclaiming by deletion would re-open
|
|
575
|
+
* the same argument from the other end.
|
|
576
|
+
* 3. **No dangling references.** `clone_jobs.repository_id` points at this row.
|
|
577
|
+
*
|
|
578
|
+
* ## The line — what is NOT reclaimed
|
|
579
|
+
*
|
|
580
|
+
* Every guard fails toward keeping the row enabled:
|
|
581
|
+
*
|
|
582
|
+
* - **Already disabled** — nothing to fix; it is out of the scan set already,
|
|
583
|
+
* and touching it would rewrite state the user owns.
|
|
584
|
+
* - **Still listed in `WORKTREE_REPOS`** — the environment is a live
|
|
585
|
+
* declaration that the operator wants this path scanned. Same reasoning as
|
|
586
|
+
* migration v43's guard 2 (#1339): never overrule a path the env still asks
|
|
587
|
+
* for. Such a path is re-registered on every boot anyway.
|
|
588
|
+
* - **Not confirmed absent** — see {@link directoryIsConfirmedAbsent}. This is
|
|
589
|
+
* the "temporarily invisible" line: a repository under an unreachable network
|
|
590
|
+
* mount answers EIO / ETIMEDOUT / ESTALE / EACCES, not ENOENT, and is kept.
|
|
591
|
+
* - **Owns worktree rows** — the condition the Issue names, and the one that
|
|
592
|
+
* makes this provably lossless. Chat history, memos, todos, timers,
|
|
593
|
+
* schedules, tasks and verification runs all hang off `worktrees`, so a
|
|
594
|
+
* repository with zero worktree rows has no history to lose by definition.
|
|
595
|
+
* It is also good evidence that the directory was never successfully scanned:
|
|
596
|
+
* a scan of a present repository always yields at least its main worktree.
|
|
597
|
+
*
|
|
598
|
+
* @param db - Database instance
|
|
599
|
+
* @param envRepositoryPaths - Paths the environment still declares
|
|
600
|
+
* (`getRepositoryPaths()`); rows at these paths are never demoted
|
|
601
|
+
* @returns The rows that were demoted, in `getAllRepositories` order
|
|
602
|
+
*/
|
|
603
|
+
function reclaimGhostRepositories(db, envRepositoryPaths = []) {
|
|
604
|
+
const envPaths = new Set(envRepositoryPaths.filter(p => !!p).map(p => path_1.default.resolve(p)));
|
|
605
|
+
const reclaimed = [];
|
|
606
|
+
for (const repo of (0, db_1.getAllRepositories)(db)) {
|
|
607
|
+
if (!repo.path)
|
|
608
|
+
continue;
|
|
609
|
+
if (!repo.enabled)
|
|
610
|
+
continue;
|
|
611
|
+
if (envPaths.has(repo.path))
|
|
612
|
+
continue;
|
|
613
|
+
if (!directoryIsConfirmedAbsent(repo.path))
|
|
614
|
+
continue;
|
|
615
|
+
if ((0, db_1.countWorktreesByRepositoryPath)(db, repo.path) > 0)
|
|
616
|
+
continue;
|
|
617
|
+
try {
|
|
618
|
+
(0, db_1.setRepositoryEnabled)(db, repo.id, false);
|
|
619
|
+
}
|
|
620
|
+
catch (error) {
|
|
621
|
+
// SEC-SF-004's disabled-row ceiling is the only expected failure. It
|
|
622
|
+
// guards against unbounded *growth* of the table, which this pass cannot
|
|
623
|
+
// cause — it creates no rows — so a refusal here just means one ghost
|
|
624
|
+
// keeps logging. Report it and move on rather than aborting startup.
|
|
625
|
+
logger.warn('repository:ghost-row-reclaim-failed', {
|
|
626
|
+
repoPath: repo.path,
|
|
627
|
+
error: error instanceof Error ? error.message : String(error),
|
|
628
|
+
});
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
reclaimed.push({ id: repo.id, path: repo.path });
|
|
632
|
+
logger.info('repository:ghost-row-reclaimed', { repoPath: repo.path });
|
|
633
|
+
}
|
|
634
|
+
return reclaimed;
|
|
635
|
+
}
|
|
482
636
|
/**
|
|
483
637
|
* Prune DB worktree rows for repositories that have vanished from disk.
|
|
484
638
|
*
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Reading the end of an agent's own transcript file (Issue #2197).
|
|
4
|
+
*
|
|
5
|
+
* The second half of the pull-mode reader that is the same whatever the agent
|
|
6
|
+
* is, alongside `./user-turn-recorder`: every one of them keeps a file that
|
|
7
|
+
* grows for the life of a session, and every one of them only ever needs its
|
|
8
|
+
* newest turn.
|
|
9
|
+
*
|
|
10
|
+
* The shape is `lib/hooks/sources/claude/history`'s, which #2121 wrote inline
|
|
11
|
+
* because it was the only reader. It is here rather than there because #2197
|
|
12
|
+
* added the second and #2198 adds the third, and three private copies of "read
|
|
13
|
+
* the last 4 MiB and drop the partial first line" is how the bound and the
|
|
14
|
+
* partial-line rule quietly stop agreeing with each other.
|
|
15
|
+
*
|
|
16
|
+
* @module lib/history/transcript-tail
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.TRANSCRIPT_TAIL_BYTES = void 0;
|
|
20
|
+
exports.readTranscriptTail = readTranscriptTail;
|
|
21
|
+
const promises_1 = require("fs/promises");
|
|
22
|
+
const logger_1 = require("../../lib/logger");
|
|
23
|
+
const logger = (0, logger_1.createLogger)('lib/history/transcript-tail');
|
|
24
|
+
/**
|
|
25
|
+
* How much of a transcript's tail is read.
|
|
26
|
+
*
|
|
27
|
+
* These files grow for the life of a session and a long one is tens of
|
|
28
|
+
* megabytes — the largest claude transcript on this machine was 23 MB on
|
|
29
|
+
* 2026-08-31, and the largest codex rollout was **273 MB** on 2026-09-01 — so
|
|
30
|
+
* reading one whole on every finished turn would be the most expensive thing the
|
|
31
|
+
* poller does. Only the newest turn is ever written, so only the newest turn has
|
|
32
|
+
* to be in the window.
|
|
33
|
+
*
|
|
34
|
+
* 4 MiB is roughly two orders of magnitude above the measured size of a single
|
|
35
|
+
* turn and still small enough to read and parse in one tick. A turn that
|
|
36
|
+
* genuinely does not fit produces a turn with no prompt in it, which each reader
|
|
37
|
+
* detects and reports rather than writing as a headless reply.
|
|
38
|
+
*/
|
|
39
|
+
exports.TRANSCRIPT_TAIL_BYTES = 4 * 1024 * 1024;
|
|
40
|
+
/**
|
|
41
|
+
* The last {@link TRANSCRIPT_TAIL_BYTES} of a file, as UTF-8.
|
|
42
|
+
*
|
|
43
|
+
* Read at an offset rather than whole, and the first line of a windowed read is
|
|
44
|
+
* dropped: starting mid-line would hand the caller's parser a fragment that it
|
|
45
|
+
* would count as malformed anyway, and dropping it deliberately keeps that
|
|
46
|
+
* counter meaning "the writer was mid-append", which is the thing worth seeing.
|
|
47
|
+
*
|
|
48
|
+
* Never throws.
|
|
49
|
+
*
|
|
50
|
+
* @param path - An absolute path the caller has already validated
|
|
51
|
+
* @returns The text, or null when the file could not be read
|
|
52
|
+
*/
|
|
53
|
+
async function readTranscriptTail(path) {
|
|
54
|
+
let handle;
|
|
55
|
+
try {
|
|
56
|
+
handle = await (0, promises_1.open)(path, 'r');
|
|
57
|
+
const { size } = await handle.stat();
|
|
58
|
+
const offset = Math.max(0, size - exports.TRANSCRIPT_TAIL_BYTES);
|
|
59
|
+
const length = size - offset;
|
|
60
|
+
if (length <= 0)
|
|
61
|
+
return '';
|
|
62
|
+
const buffer = Buffer.alloc(length);
|
|
63
|
+
const { bytesRead } = await handle.read(buffer, 0, length, offset);
|
|
64
|
+
const text = buffer.subarray(0, bytesRead).toString('utf8');
|
|
65
|
+
if (offset === 0)
|
|
66
|
+
return text;
|
|
67
|
+
const firstBreak = text.indexOf('\n');
|
|
68
|
+
return firstBreak === -1 ? '' : text.slice(firstBreak + 1);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
logger.warn('transcript-tail-read-failed', {
|
|
72
|
+
path,
|
|
73
|
+
error: error instanceof Error ? error.message : String(error),
|
|
74
|
+
});
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
await handle?.close().catch(() => { });
|
|
79
|
+
}
|
|
80
|
+
}
|