commandmate 0.10.2 → 0.10.4
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 +149 -149
- package/.next/app-path-routes-manifest.json +30 -30
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +15 -15
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route.js +3 -3
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.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 +1 -1
- 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 +3 -2
- 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/daily-summary/route.js +1 -1
- package/.next/server/app/api/daily-summary/route.js.nft.json +1 -1
- package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route.js +1 -1
- package/.next/server/app/api/daily-summary/status/route.js.nft.json +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route_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/hooks/claude-done/route.js +1 -1
- 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/ollama/models/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.js.nft.json +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/repositories/[id]/route.js +1 -47
- package/.next/server/app/api/repositories/[id]/route.js.nft.json +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.js.nft.json +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.js.nft.json +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.js +1 -47
- package/.next/server/app/api/repositories/excluded/route.js.nft.json +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/sidebar/group-order/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/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.js.nft.json +1 -1
- package/.next/server/app/api/todos/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]/cli-tool/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route.js.nft.json +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.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +2 -2
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js.nft.json +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.js.nft.json +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 +2 -2
- package/.next/server/app/api/worktrees/[id]/marp-render/route.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/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]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route.js +2 -2
- package/.next/server/app/api/worktrees/[id]/schedules/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +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]/slash-commands/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js.nft.json +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]/start-polling/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js.nft.json +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.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +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]/viewed/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/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.js +1 -1
- package/.next/server/app/chat/page.js.nft.json +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.js +1 -1
- package/.next/server/app/page.js.nft.json +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.js.nft.json +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page.js +1 -1
- package/.next/server/app/review/page.js.nft.json +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +1 -1
- package/.next/server/app/sessions/page.js.nft.json +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +8 -8
- package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +30 -30
- package/.next/server/chunks/1068.js +1 -1
- package/.next/server/chunks/1117.js +1 -0
- package/.next/server/chunks/233.js +1 -1
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/3270.js +1 -1
- package/.next/server/chunks/3480.js +2 -2
- package/.next/server/chunks/3543.js +1 -1
- package/.next/server/chunks/3945.js +1 -1
- package/.next/server/chunks/406.js +47 -0
- package/.next/server/chunks/4444.js +1 -1
- package/.next/server/chunks/5381.js +1 -47
- package/.next/server/chunks/5959.js +2 -2
- package/.next/server/chunks/646.js +33 -0
- package/.next/server/chunks/8681.js +1 -0
- package/.next/server/chunks/8807.js +305 -300
- package/.next/server/chunks/9355.js +1 -1
- package/.next/server/chunks/9687.js +1 -1
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/4560-2bf9cb6504cc4425.js +1 -0
- package/.next/static/chunks/7347-a013a163a75030ec.js +1 -0
- package/.next/static/chunks/app/chat/page-5d20240f98c07cee.js +1 -0
- package/.next/static/chunks/app/layout-fe5857360dfba2b9.js +1 -0
- package/.next/static/chunks/app/more/page-af1d2af13ea901d2.js +1 -0
- package/.next/static/chunks/app/page-3bbe737ec910d1fb.js +1 -0
- package/.next/static/chunks/app/repositories/page-ace9134ac165a6de.js +1 -0
- package/.next/static/chunks/app/review/page-331b80f4f58582bc.js +1 -0
- package/.next/static/chunks/app/sessions/page-d694149a7e8649b6.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-932a52f8d11971f7.js +1 -0
- package/.next/static/css/d7e2e8d1b8d69d36.css +1 -0
- package/.next/trace +10 -10
- package/dist/cli/commands/quickstart.d.ts.map +1 -1
- package/dist/cli/commands/quickstart.js +27 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +19 -0
- package/dist/cli/types/index.d.ts +6 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/utils/agent-instances.d.ts +1 -1
- package/dist/cli/utils/agent-instances.d.ts.map +1 -1
- package/dist/cli/utils/agent-instances.js +8 -1
- package/dist/cli/utils/api-client.d.ts +36 -0
- package/dist/cli/utils/api-client.d.ts.map +1 -1
- package/dist/cli/utils/api-client.js +82 -0
- package/dist/cli/utils/daemon.d.ts.map +1 -1
- package/dist/cli/utils/daemon.js +44 -9
- package/dist/cli/utils/package-info.d.ts +17 -0
- package/dist/cli/utils/package-info.d.ts.map +1 -0
- package/dist/cli/utils/package-info.js +31 -0
- package/dist/cli/utils/pid-manager.d.ts +65 -9
- package/dist/cli/utils/pid-manager.d.ts.map +1 -1
- package/dist/cli/utils/pid-manager.js +81 -21
- package/dist/cli/utils/process-inspector.d.ts +27 -0
- package/dist/cli/utils/process-inspector.d.ts.map +1 -0
- package/dist/cli/utils/process-inspector.js +37 -0
- package/dist/server/src/config/github-links.js +22 -0
- package/dist/server/src/lib/db/db-instance.js +22 -3
- package/dist/server/src/lib/db/db-repository.js +107 -19
- package/dist/server/src/lib/db/db.js +3 -2
- package/dist/server/src/lib/db/memo-db.js +32 -1
- package/dist/server/src/lib/db/migrations/index.js +2 -0
- package/dist/server/src/lib/db/migrations/runner.js +11 -1
- package/dist/server/src/lib/db/migrations/v43-remove-cm-root-dir-ghost-repository.js +126 -0
- package/dist/server/src/lib/git/worktrees.js +90 -0
- package/dist/server/src/lib/job-executor.js +8 -2
- package/dist/server/src/lib/realtime/types.js +76 -0
- package/dist/server/src/lib/schedule-manager.js +9 -1
- package/dist/server/src/lib/version-checker.js +297 -0
- package/dist/server/src/lib/ws-server.js +37 -0
- package/package.json +1 -1
- package/.next/server/chunks/2464.js +0 -33
- package/.next/server/chunks/6791.js +0 -47
- package/.next/static/chunks/7347-4a031aecf4664a6d.js +0 -1
- package/.next/static/chunks/8954-ce15ee4d0423f1b1.js +0 -1
- package/.next/static/chunks/app/chat/page-dee86bdf87516e40.js +0 -1
- package/.next/static/chunks/app/layout-d02f4691a4eff86b.js +0 -1
- package/.next/static/chunks/app/more/page-39ec8b5f27cf52e7.js +0 -1
- package/.next/static/chunks/app/page-ebf1db9826b4065d.js +0 -1
- package/.next/static/chunks/app/repositories/page-2be54cae5fcc1f7a.js +0 -1
- package/.next/static/chunks/app/review/page-ac4efe6857a0f3bf.js +0 -1
- package/.next/static/chunks/app/sessions/page-dc545a3d45374187.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-562c763045f66200.js +0 -1
- package/.next/static/css/eabd34bf2ab147a4.css +0 -1
- /package/.next/static/{SZPCFMNuIVbWNY8xv93Lf → uBCIYS1Hth7V4unroKqGu}/_buildManifest.js +0 -0
- /package/.next/static/{SZPCFMNuIVbWNY8xv93Lf → uBCIYS1Hth7V4unroKqGu}/_ssgManifest.js +0 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* PID File Manager
|
|
3
|
+
* PID / Daemon State File Manager
|
|
4
4
|
* Issue #96: npm install CLI support
|
|
5
5
|
* Issue #136: Phase 2 - Task 2.4 - Added factory functions for Issue number support
|
|
6
|
+
* Issue #1354/#1355/#1358: the file now records the daemon's version, effective settings, and
|
|
7
|
+
* a process-identity signature, not just the PID. See DaemonState.
|
|
6
8
|
* SF-1: SRP - Separated from daemon.ts for single responsibility
|
|
7
9
|
* MF-SEC-2: TOCTOU protection with O_EXCL atomic writes
|
|
8
10
|
*/
|
|
@@ -12,53 +14,80 @@ exports.createPidManager = createPidManager;
|
|
|
12
14
|
exports.createIssuePidManager = createIssuePidManager;
|
|
13
15
|
const fs_1 = require("fs");
|
|
14
16
|
const resource_resolvers_1 = require("./resource-resolvers");
|
|
17
|
+
const process_inspector_1 = require("./process-inspector");
|
|
15
18
|
/**
|
|
16
19
|
* PID file manager for daemon process tracking
|
|
17
20
|
*/
|
|
18
21
|
class PidManager {
|
|
19
22
|
pidFilePath;
|
|
20
|
-
|
|
23
|
+
readStartTime;
|
|
24
|
+
/**
|
|
25
|
+
* @param pidFilePath - Path to the state file for this server
|
|
26
|
+
* @param readStartTime - Injectable process-identity reader (Issue #1358); defaults to `ps`.
|
|
27
|
+
* Overridden in tests to avoid spawning a real process.
|
|
28
|
+
*/
|
|
29
|
+
constructor(pidFilePath, readStartTime = process_inspector_1.getProcessStartTime) {
|
|
21
30
|
this.pidFilePath = pidFilePath;
|
|
31
|
+
this.readStartTime = readStartTime;
|
|
22
32
|
}
|
|
23
33
|
/**
|
|
24
|
-
* Check if
|
|
34
|
+
* Check if the state file exists
|
|
25
35
|
*/
|
|
26
36
|
exists() {
|
|
27
37
|
return (0, fs_1.existsSync)(this.pidFilePath);
|
|
28
38
|
}
|
|
29
39
|
/**
|
|
30
|
-
* Read
|
|
31
|
-
*
|
|
40
|
+
* Read the daemon state from file.
|
|
41
|
+
*
|
|
42
|
+
* Tolerates the legacy format (a bare integer PID) by returning `{ pid }`, so a state file
|
|
43
|
+
* written by an older running daemon is still understood after a CLI upgrade (Issue #1354).
|
|
44
|
+
*
|
|
45
|
+
* @returns The daemon state, or null when the file is missing or invalid
|
|
32
46
|
*/
|
|
33
|
-
|
|
47
|
+
readState() {
|
|
34
48
|
if (!this.exists()) {
|
|
35
49
|
return null;
|
|
36
50
|
}
|
|
37
51
|
try {
|
|
38
52
|
const content = (0, fs_1.readFileSync)(this.pidFilePath, 'utf-8').trim();
|
|
39
|
-
|
|
40
|
-
if (isNaN(pid) || pid <= 0) {
|
|
53
|
+
if (content.length === 0) {
|
|
41
54
|
return null;
|
|
42
55
|
}
|
|
43
|
-
|
|
56
|
+
// Legacy format: the file held only the PID as a bare integer.
|
|
57
|
+
if (/^\d+$/.test(content)) {
|
|
58
|
+
const pid = parseInt(content, 10);
|
|
59
|
+
return pid > 0 ? { pid } : null;
|
|
60
|
+
}
|
|
61
|
+
const parsed = JSON.parse(content);
|
|
62
|
+
if (typeof parsed.pid !== 'number' || !Number.isInteger(parsed.pid) || parsed.pid <= 0) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return parsed;
|
|
44
66
|
}
|
|
45
67
|
catch {
|
|
46
68
|
return null;
|
|
47
69
|
}
|
|
48
70
|
}
|
|
49
71
|
/**
|
|
50
|
-
*
|
|
72
|
+
* Read PID from the state file
|
|
73
|
+
* @returns PID number or null if file doesn't exist or is invalid
|
|
74
|
+
*/
|
|
75
|
+
readPid() {
|
|
76
|
+
return this.readState()?.pid ?? null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Write the daemon state to file atomically
|
|
51
80
|
* MF-SEC-2: Uses O_EXCL to prevent TOCTOU race conditions
|
|
52
81
|
*
|
|
53
82
|
* @returns true if successful, false if file already exists
|
|
54
83
|
* @throws Error for other filesystem errors
|
|
55
84
|
*/
|
|
56
|
-
|
|
85
|
+
writeState(state) {
|
|
57
86
|
try {
|
|
58
87
|
// O_EXCL: Fail if file already exists (atomic check-and-create)
|
|
59
88
|
const fd = (0, fs_1.openSync)(this.pidFilePath, fs_1.constants.O_WRONLY | fs_1.constants.O_CREAT | fs_1.constants.O_EXCL, 0o600);
|
|
60
89
|
try {
|
|
61
|
-
(0, fs_1.writeSync)(fd,
|
|
90
|
+
(0, fs_1.writeSync)(fd, JSON.stringify(state));
|
|
62
91
|
return true;
|
|
63
92
|
}
|
|
64
93
|
finally {
|
|
@@ -74,7 +103,17 @@ class PidManager {
|
|
|
74
103
|
}
|
|
75
104
|
}
|
|
76
105
|
/**
|
|
77
|
-
*
|
|
106
|
+
* Read a live process's start-time signature via the injected reader.
|
|
107
|
+
* Used by start() to record the daemon's identity at launch (Issue #1358).
|
|
108
|
+
*
|
|
109
|
+
* @param pid - Process ID to inspect
|
|
110
|
+
* @returns The start-time signature, or null when it cannot be read
|
|
111
|
+
*/
|
|
112
|
+
getStartTime(pid) {
|
|
113
|
+
return this.readStartTime(pid);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Remove the state file
|
|
78
117
|
*/
|
|
79
118
|
removePid() {
|
|
80
119
|
if (this.exists()) {
|
|
@@ -87,29 +126,50 @@ class PidManager {
|
|
|
87
126
|
}
|
|
88
127
|
}
|
|
89
128
|
/**
|
|
90
|
-
* Check if the process recorded in
|
|
129
|
+
* Check if the process recorded in the state file is the daemon we started.
|
|
91
130
|
* NTH-1: ISP - Lightweight process check API
|
|
92
131
|
*
|
|
93
|
-
*
|
|
132
|
+
* Issue #1358: `process.kill(pid, 0)` alone only proves the PID is in use. When the state
|
|
133
|
+
* records a start-time signature, the live process's is compared to catch PID reuse; a
|
|
134
|
+
* mismatch is treated as not-running so stop() never kills, and start() never defers to, an
|
|
135
|
+
* unrelated process. EPERM (the PID was reused by a process we don't own) is likewise treated
|
|
136
|
+
* as stale rather than thrown, so a reused PID no longer crashes the command.
|
|
137
|
+
*
|
|
138
|
+
* @returns true if the daemon is running, false otherwise
|
|
94
139
|
*/
|
|
95
140
|
isProcessRunning() {
|
|
96
|
-
const
|
|
97
|
-
if (
|
|
141
|
+
const state = this.readState();
|
|
142
|
+
if (state === null) {
|
|
98
143
|
return false;
|
|
99
144
|
}
|
|
100
145
|
try {
|
|
101
146
|
// Sending signal 0 checks if process exists without killing it
|
|
102
|
-
process.kill(pid, 0);
|
|
103
|
-
return true;
|
|
147
|
+
process.kill(state.pid, 0);
|
|
104
148
|
}
|
|
105
149
|
catch (err) {
|
|
106
|
-
|
|
150
|
+
const code = err.code;
|
|
151
|
+
if (code === 'ESRCH') {
|
|
107
152
|
// Process not found
|
|
108
153
|
return false;
|
|
109
154
|
}
|
|
110
|
-
|
|
155
|
+
if (code === 'EPERM') {
|
|
156
|
+
// Issue #1358: the PID now belongs to a process we don't own — i.e. it was reused by
|
|
157
|
+
// an unrelated (possibly other-user) process. Treat as stale, not an error.
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
// Other, genuinely unexpected errors still surface
|
|
111
161
|
throw err;
|
|
112
162
|
}
|
|
163
|
+
// Issue #1358: the PID exists, but on a long-running machine the OS may have reused it for
|
|
164
|
+
// an unrelated process after our daemon died. If we recorded the start time, verify the live
|
|
165
|
+
// process still has it. A null reading (no `ps`, etc.) leaves the best-effort answer intact.
|
|
166
|
+
if (state.startTime) {
|
|
167
|
+
const current = this.readStartTime(state.pid);
|
|
168
|
+
if (current !== null && current !== state.startTime) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
113
173
|
}
|
|
114
174
|
}
|
|
115
175
|
exports.PidManager = PidManager;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process Inspector
|
|
3
|
+
* Issue #1358: verify a PID still belongs to the daemon we started
|
|
4
|
+
*
|
|
5
|
+
* `process.kill(pid, 0)` only proves *some* process owns the PID. On a long-running machine
|
|
6
|
+
* the OS reuses PIDs, so after the daemon crashes the same PID can belong to an unrelated
|
|
7
|
+
* process. Recording the OS-reported start time at launch and comparing it later lets us tell
|
|
8
|
+
* "our daemon is still running" from "the PID was reused".
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* A function that returns a stable identity signature for a PID, or null when it cannot be
|
|
12
|
+
* determined. Injected into PidManager so tests can supply a deterministic reader.
|
|
13
|
+
*/
|
|
14
|
+
export type ProcessStartTimeReader = (pid: number) => string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Read a process's start time via `ps`, as an absolute wall-clock string.
|
|
17
|
+
*
|
|
18
|
+
* `-o lstart=` prints e.g. "Sat Jul 18 01:03:24 2026" and is stable across invocations (unlike
|
|
19
|
+
* `etime`, which advances), so two reads of the same live process return the same value while a
|
|
20
|
+
* reused PID returns a different one. Works on macOS and Linux; any failure (no `ps`, unknown
|
|
21
|
+
* PID, permission) returns null so callers fall back to best-effort behaviour instead of erroring.
|
|
22
|
+
*
|
|
23
|
+
* @param pid - Process ID to inspect
|
|
24
|
+
* @returns The start-time signature, or null when it cannot be read
|
|
25
|
+
*/
|
|
26
|
+
export declare function getProcessStartTime(pid: number): string | null;
|
|
27
|
+
//# sourceMappingURL=process-inspector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-inspector.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/process-inspector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW9D"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Process Inspector
|
|
4
|
+
* Issue #1358: verify a PID still belongs to the daemon we started
|
|
5
|
+
*
|
|
6
|
+
* `process.kill(pid, 0)` only proves *some* process owns the PID. On a long-running machine
|
|
7
|
+
* the OS reuses PIDs, so after the daemon crashes the same PID can belong to an unrelated
|
|
8
|
+
* process. Recording the OS-reported start time at launch and comparing it later lets us tell
|
|
9
|
+
* "our daemon is still running" from "the PID was reused".
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getProcessStartTime = getProcessStartTime;
|
|
13
|
+
const child_process_1 = require("child_process");
|
|
14
|
+
/**
|
|
15
|
+
* Read a process's start time via `ps`, as an absolute wall-clock string.
|
|
16
|
+
*
|
|
17
|
+
* `-o lstart=` prints e.g. "Sat Jul 18 01:03:24 2026" and is stable across invocations (unlike
|
|
18
|
+
* `etime`, which advances), so two reads of the same live process return the same value while a
|
|
19
|
+
* reused PID returns a different one. Works on macOS and Linux; any failure (no `ps`, unknown
|
|
20
|
+
* PID, permission) returns null so callers fall back to best-effort behaviour instead of erroring.
|
|
21
|
+
*
|
|
22
|
+
* @param pid - Process ID to inspect
|
|
23
|
+
* @returns The start-time signature, or null when it cannot be read
|
|
24
|
+
*/
|
|
25
|
+
function getProcessStartTime(pid) {
|
|
26
|
+
try {
|
|
27
|
+
const out = (0, child_process_1.execFileSync)('ps', ['-o', 'lstart=', '-p', String(pid)], {
|
|
28
|
+
encoding: 'utf-8',
|
|
29
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
30
|
+
timeout: 2000,
|
|
31
|
+
}).trim();
|
|
32
|
+
return out.length > 0 ? out : null;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GitHub URL Constants (Centralized)
|
|
4
|
+
* Issue #264: DRY - All GitHub URLs derived from GITHUB_REPO_BASE_URL
|
|
5
|
+
*
|
|
6
|
+
* [SEC-001] SSRF Prevention: GITHUB_API_URL is NOT included here.
|
|
7
|
+
* It remains hardcoded in version-checker.ts for security reasons.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.GITHUB_SECURITY_GUIDE_URL = exports.GITHUB_RELEASE_URL_PREFIX = exports.GITHUB_QUESTION_URL = exports.GITHUB_FEATURE_REQUEST_URL = exports.GITHUB_BUG_REPORT_URL = exports.GITHUB_NEW_ISSUE_URL = exports.GITHUB_ISSUES_URL = exports.GITHUB_REPO_BASE_URL = void 0;
|
|
11
|
+
exports.GITHUB_REPO_BASE_URL = 'https://github.com/Kewton/CommandMate';
|
|
12
|
+
// Issue URLs
|
|
13
|
+
exports.GITHUB_ISSUES_URL = `${exports.GITHUB_REPO_BASE_URL}/issues`;
|
|
14
|
+
exports.GITHUB_NEW_ISSUE_URL = `${exports.GITHUB_REPO_BASE_URL}/issues/new`;
|
|
15
|
+
// Template URLs (UI: uses filename in query parameter)
|
|
16
|
+
exports.GITHUB_BUG_REPORT_URL = `${exports.GITHUB_NEW_ISSUE_URL}?template=bug_report.md`;
|
|
17
|
+
exports.GITHUB_FEATURE_REQUEST_URL = `${exports.GITHUB_NEW_ISSUE_URL}?template=feature_request.md`;
|
|
18
|
+
exports.GITHUB_QUESTION_URL = `${exports.GITHUB_NEW_ISSUE_URL}?template=question.md`;
|
|
19
|
+
// Release URL (moved from version-checker.ts, re-exported there for backward compatibility)
|
|
20
|
+
exports.GITHUB_RELEASE_URL_PREFIX = `${exports.GITHUB_REPO_BASE_URL}/releases/`;
|
|
21
|
+
// Security Guide URL (moved from security-messages.ts)
|
|
22
|
+
exports.GITHUB_SECURITY_GUIDE_URL = `${exports.GITHUB_REPO_BASE_URL}/blob/main/docs/security-guide.md`;
|
|
@@ -45,11 +45,30 @@ function getDbInstance() {
|
|
|
45
45
|
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
46
46
|
}
|
|
47
47
|
// Issue #1263: recover from a better-sqlite3 ABI mismatch (Node.js version switch)
|
|
48
|
-
|
|
48
|
+
const db = (0, abi_recovery_1.openDatabaseWithAbiRecovery)(dbPath);
|
|
49
49
|
// Issue #294: Enable foreign key enforcement BEFORE migrations
|
|
50
50
|
// This ensures ON DELETE CASCADE works correctly for all tables
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
db.pragma('foreign_keys = ON');
|
|
52
|
+
// Issue #1360: harden against SQLITE_BUSY when the same DB file is opened by
|
|
53
|
+
// more than one process (e.g. a misconfigured worktree server sharing
|
|
54
|
+
// CM_DB_PATH). WAL lets readers and a single writer coexist instead of
|
|
55
|
+
// taking an exclusive lock, and busy_timeout makes a contended write wait
|
|
56
|
+
// for the lock (up to 5s) rather than failing immediately with the default
|
|
57
|
+
// busy_timeout of 0. Set before migrations so migration writes benefit too.
|
|
58
|
+
db.pragma('journal_mode = WAL');
|
|
59
|
+
db.pragma('busy_timeout = 5000');
|
|
60
|
+
// Issue #1353: only publish the connection once its schema is verified.
|
|
61
|
+
// Assigning before runMigrations() cached a database whose migrations had
|
|
62
|
+
// thrown, so every later caller was handed it back without the failure —
|
|
63
|
+
// the guard would fire once and be bypassed for the rest of the process.
|
|
64
|
+
try {
|
|
65
|
+
(0, db_migrations_1.runMigrations)(db);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
db.close();
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
dbInstance = db;
|
|
53
72
|
}
|
|
54
73
|
return dbInstance;
|
|
55
74
|
}
|
|
@@ -8,11 +8,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
8
8
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
9
|
};
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.MAX_DISABLED_REPOSITORIES = void 0;
|
|
11
|
+
exports.MAX_DISABLED_REPOSITORIES = exports.RepositoryDbError = void 0;
|
|
12
12
|
exports.createRepository = createRepository;
|
|
13
13
|
exports.getRepositoryByNormalizedUrl = getRepositoryByNormalizedUrl;
|
|
14
14
|
exports.getRepositoryById = getRepositoryById;
|
|
15
15
|
exports.getRepositoryByPath = getRepositoryByPath;
|
|
16
|
+
exports.deleteRepository = deleteRepository;
|
|
17
|
+
exports.countWorktreesByRepositoryPath = countWorktreesByRepositoryPath;
|
|
16
18
|
exports.updateRepository = updateRepository;
|
|
17
19
|
exports.getAllRepositories = getAllRepositories;
|
|
18
20
|
exports.getAllRepositoriesWithWorktreeCount = getAllRepositoriesWithWorktreeCount;
|
|
@@ -22,6 +24,7 @@ exports.ensureEnvRepositoriesRegistered = ensureEnvRepositoriesRegistered;
|
|
|
22
24
|
exports.filterExcludedPaths = filterExcludedPaths;
|
|
23
25
|
exports.registerAndFilterRepositories = registerAndFilterRepositories;
|
|
24
26
|
exports.disableRepository = disableRepository;
|
|
27
|
+
exports.disableExistingRepository = disableExistingRepository;
|
|
25
28
|
exports.getExcludedRepositoryPaths = getExcludedRepositoryPaths;
|
|
26
29
|
exports.getExcludedRepositories = getExcludedRepositories;
|
|
27
30
|
exports.restoreRepository = restoreRepository;
|
|
@@ -33,6 +36,28 @@ exports.getCloneJobsByStatus = getCloneJobsByStatus;
|
|
|
33
36
|
const crypto_1 = require("crypto");
|
|
34
37
|
const path_1 = __importDefault(require("path"));
|
|
35
38
|
const system_directories_1 = require("../../config/system-directories");
|
|
39
|
+
/**
|
|
40
|
+
* Typed error for repositories-table operations.
|
|
41
|
+
*
|
|
42
|
+
* Issue #1352: `createRepository()` used to let a raw better-sqlite3
|
|
43
|
+
* `SqliteError: UNIQUE constraint failed` propagate. A concurrent clone of the
|
|
44
|
+
* same URL has a TOCTOU window where both jobs pass the duplicate checks and
|
|
45
|
+
* the losing `createRepository()` throws that raw error, which the background
|
|
46
|
+
* clone path only logs (#1340). Convert UNIQUE violations to an explicit
|
|
47
|
+
* `DUPLICATE` code here so callers can distinguish the collision from other DB
|
|
48
|
+
* failures. Mirrors `ExternalAppDbError` in `external-apps/db.ts`.
|
|
49
|
+
*/
|
|
50
|
+
class RepositoryDbError extends Error {
|
|
51
|
+
code;
|
|
52
|
+
cause;
|
|
53
|
+
constructor(message, code, cause) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.code = code;
|
|
56
|
+
this.cause = cause;
|
|
57
|
+
this.name = 'RepositoryDbError';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.RepositoryDbError = RepositoryDbError;
|
|
36
61
|
/**
|
|
37
62
|
* Map repository row to Repository model
|
|
38
63
|
*/
|
|
@@ -94,7 +119,22 @@ function createRepository(db, data) {
|
|
|
94
119
|
)
|
|
95
120
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
96
121
|
`);
|
|
97
|
-
|
|
122
|
+
// Issue #1352: `repositories.path` is UNIQUE and `normalized_clone_url` has a
|
|
123
|
+
// partial UNIQUE index. A concurrent clone of the same URL can race past the
|
|
124
|
+
// duplicate checks and reach here twice; the loser must fail with an explicit
|
|
125
|
+
// DUPLICATE rather than a raw SqliteError. These DB constraints are what
|
|
126
|
+
// serialize the final registration — the guard turns the collision into a
|
|
127
|
+
// typed error instead of preventing it.
|
|
128
|
+
try {
|
|
129
|
+
stmt.run(id, data.name, data.path, data.enabled !== false ? 1 : 0, data.visible !== false ? 1 : 0, data.cloneUrl || null, data.normalizedCloneUrl || null, data.cloneSource, data.isEnvManaged ? 1 : 0, now, now);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
if (error instanceof Error && error.message.includes('UNIQUE constraint')) {
|
|
133
|
+
throw new RepositoryDbError(`A repository is already registered at path "${data.path}"` +
|
|
134
|
+
(data.normalizedCloneUrl ? ` or for URL "${data.normalizedCloneUrl}"` : ''), 'DUPLICATE', error);
|
|
135
|
+
}
|
|
136
|
+
throw new RepositoryDbError(`Failed to create repository: ${error instanceof Error ? error.message : 'Unknown error'}`, 'DB_ERROR', error instanceof Error ? error : undefined);
|
|
137
|
+
}
|
|
98
138
|
return {
|
|
99
139
|
id,
|
|
100
140
|
name: data.name,
|
|
@@ -142,6 +182,39 @@ function getRepositoryByPath(db, path) {
|
|
|
142
182
|
const row = stmt.get(path);
|
|
143
183
|
return row ? mapRepositoryRow(row) : null;
|
|
144
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Physically delete a repositories row by id.
|
|
187
|
+
*
|
|
188
|
+
* Issue #1350: before this, the only way to "remove" a repository was
|
|
189
|
+
* `disableRepository()` (enabled=0) — the row itself was never deleted. A row
|
|
190
|
+
* whose on-disk directory has been removed and that has no worktrees left
|
|
191
|
+
* ("ghost") therefore lingered forever and blocked re-cloning the same URL,
|
|
192
|
+
* with no removal path in the UI or API. This gives callers a real delete so a
|
|
193
|
+
* ghost can be cleared. Linkage of worktrees/child rows is by
|
|
194
|
+
* `worktrees.repository_path` (TEXT), not a FK to `repositories`, so deleting
|
|
195
|
+
* the row does not cascade — callers must confirm the row is a ghost first.
|
|
196
|
+
*
|
|
197
|
+
* @returns true if a row was deleted, false if no row matched the id.
|
|
198
|
+
*/
|
|
199
|
+
function deleteRepository(db, id) {
|
|
200
|
+
const result = db.prepare('DELETE FROM repositories WHERE id = ?').run(id);
|
|
201
|
+
return result.changes > 0;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Count the worktrees associated with a repository path.
|
|
205
|
+
*
|
|
206
|
+
* Repository ↔ worktree linkage is by matching `repositories.path` against
|
|
207
|
+
* `worktrees.repository_path` (TEXT) — see `getAllRepositoriesWithWorktreeCount`.
|
|
208
|
+
* Issue #1350 uses this to tell a recoverable "ghost" (directory gone AND zero
|
|
209
|
+
* worktrees) apart from a repository that still has worktrees registered, which
|
|
210
|
+
* must never be silently deleted.
|
|
211
|
+
*/
|
|
212
|
+
function countWorktreesByRepositoryPath(db, repositoryPath) {
|
|
213
|
+
const row = db
|
|
214
|
+
.prepare('SELECT COUNT(*) AS count FROM worktrees WHERE repository_path = ?')
|
|
215
|
+
.get(repositoryPath);
|
|
216
|
+
return Number(row.count) || 0;
|
|
217
|
+
}
|
|
145
218
|
/**
|
|
146
219
|
* Update repository
|
|
147
220
|
*
|
|
@@ -371,25 +444,40 @@ function registerAndFilterRepositories(db, repositoryPaths) {
|
|
|
371
444
|
* SF-002: SRP - disable logic encapsulated
|
|
372
445
|
*/
|
|
373
446
|
function disableRepository(db, repositoryPath) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if (repo) {
|
|
377
|
-
updateRepository(db, repo.id, { enabled: false });
|
|
447
|
+
if (disableExistingRepository(db, repositoryPath)) {
|
|
448
|
+
return;
|
|
378
449
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
createRepository(db, {
|
|
386
|
-
name: path_1.default.basename(resolvedPath),
|
|
387
|
-
path: resolvedPath,
|
|
388
|
-
cloneSource: 'local',
|
|
389
|
-
isEnvManaged: false,
|
|
390
|
-
enabled: false, // Explicit: do not rely on undefined -> 1 default
|
|
391
|
-
});
|
|
450
|
+
const resolvedPath = resolveRepositoryPath(repositoryPath);
|
|
451
|
+
// SEC-SF-004: Check disabled repository count limit before creating new record
|
|
452
|
+
const disabledCount = db.prepare('SELECT COUNT(*) as count FROM repositories WHERE enabled = 0').get();
|
|
453
|
+
if (disabledCount.count >= exports.MAX_DISABLED_REPOSITORIES) {
|
|
454
|
+
throw new Error('Disabled repository limit exceeded');
|
|
392
455
|
}
|
|
456
|
+
createRepository(db, {
|
|
457
|
+
name: path_1.default.basename(resolvedPath),
|
|
458
|
+
path: resolvedPath,
|
|
459
|
+
cloneSource: 'local',
|
|
460
|
+
isEnvManaged: false,
|
|
461
|
+
enabled: false, // Explicit: do not rely on undefined -> 1 default
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Disable a repository only when it is already registered (enabled=0).
|
|
466
|
+
*
|
|
467
|
+
* Unlike disableRepository(), this never creates a record, so callers that may be
|
|
468
|
+
* handed a path that was never registered do not leave a ghost `enabled=0` row behind.
|
|
469
|
+
*
|
|
470
|
+
* Issue #1346
|
|
471
|
+
*
|
|
472
|
+
* @returns true if a registered repository was disabled, false if none was registered
|
|
473
|
+
*/
|
|
474
|
+
function disableExistingRepository(db, repositoryPath) {
|
|
475
|
+
const resolvedPath = resolveRepositoryPath(repositoryPath);
|
|
476
|
+
const repo = getRepositoryByPath(db, resolvedPath);
|
|
477
|
+
if (!repo)
|
|
478
|
+
return false;
|
|
479
|
+
updateRepository(db, repo.id, { enabled: false });
|
|
480
|
+
return true;
|
|
393
481
|
}
|
|
394
482
|
/**
|
|
395
483
|
* Get paths of excluded (enabled=0) repositories
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.removeAgentInstance = exports.addAgentInstance = exports.setAgentInstances = exports.countAgentInstances = exports.getAgentInstance = exports.getAgentInstances = exports.deleteSessionState = exports.clearInProgressMessageId = exports.setInProgressMessageId = exports.updateSessionState = exports.getSessionState = exports.getMessagesByDateRange = exports.ACTIVE_FILTER = exports.markPendingPromptsAsAnswered = exports.updatePromptData = exports.getMessageById = exports.recomputeLastUserMessage = exports.clearLastUserMessage = exports.updateLastUserMessage = exports.deleteMessagesByInstance = exports.deleteMessagesByCliTool = exports.deleteMessageById = exports.deleteAllMessages = exports.getLastMessage = exports.getLastUserMessage = exports.getMessages = exports.updateMessageContent = exports.createMessage = exports.getLastAssistantMessageAt = exports.deleteWorktreesByIds = exports.deleteRepositoryWorktrees = exports.migrateWorktreeIdPreservingChildren = exports.getWorktreesByRepository = exports.getWorktreeIdsByRepository = exports.getInitialBranch = exports.saveInitialBranch = exports.updateVibeLocalContextWindow = exports.updateVibeLocalModel = exports.updateSelectedAgents = exports.updateCliToolId = exports.updateStatus = exports.updateFavorite = exports.updateLastViewedAt = exports.updateWorktreeLink = exports.updateWorktreeDescription = exports.upsertWorktree = exports.getWorktreeById = exports.getRepositories = exports.getWorktrees = exports.initDatabase = void 0;
|
|
14
|
-
exports.
|
|
15
|
-
exports.deletePushSubscriptionByEndpoint = exports.updatePushSubscriptionPreferences = exports.getPushSubscriptionsForKind = exports.getAllPushSubscriptions = exports.getPushSubscriptionByEndpoint = exports.upsertPushSubscription = exports.deleteAssistantSessionState = exports.updateAssistantSessionState = exports.getAssistantSessionState = exports.listRunningAssistantExecutions = exports.getRunningAssistantExecutionByConversation = void 0;
|
|
14
|
+
exports.getAssistantExecutionById = exports.updateAssistantExecution = exports.createAssistantExecution = exports.archiveAssistantMessagesFrom = exports.archiveAllAssistantMessages = exports.getAssistantMessageById = exports.getAssistantMessages = exports.updateAssistantMessageStatus = exports.createAssistantMessage = exports.updateAssistantConversation = exports.createAssistantConversation = exports.getAssistantConversationByRepositoryAndCliTool = exports.getAssistantConversationById = exports.updateDailyReportContent = exports.saveDailyReport = exports.getDailyReport = exports.recoverStuckSendingTimers = exports.clearTimerHistory = exports.cleanupOldTimers = exports.getPendingTimerCountByWorktree = exports.cancelTimersByWorktree = exports.cancelTimer = exports.updateTimerStatus = exports.getPendingTimers = exports.getTimerById = exports.getTimersByWorktree = exports.createTimer = exports.WORKTREE_TODO_STATUSES = exports.isWorktreeTodoStatus = exports.reorderWorktreeTodos = exports.deleteWorktreeTodo = exports.updateWorktreeTodo = exports.createWorktreeTodo = exports.getWorktreeTodoById = exports.getTodosByWorktreeId = exports.deleteTodo = exports.updateTodo = exports.createTodo = exports.getTodoById = exports.getAllTodos = exports.getTodosByRepositoryId = exports.MemoDbError = exports.reorderMemos = exports.deleteMemo = exports.updateMemo = exports.createMemo = exports.getMemoById = exports.getMemosByWorktreeId = exports.InvalidAgentInstanceError = exports.AgentInstanceLimitError = void 0;
|
|
15
|
+
exports.deletePushSubscriptionByEndpoint = exports.updatePushSubscriptionPreferences = exports.getPushSubscriptionsForKind = exports.getAllPushSubscriptions = exports.getPushSubscriptionByEndpoint = exports.upsertPushSubscription = exports.deleteAssistantSessionState = exports.updateAssistantSessionState = exports.getAssistantSessionState = exports.listRunningAssistantExecutions = exports.getRunningAssistantExecutionByConversation = exports.getLatestAssistantExecutionByConversation = void 0;
|
|
16
16
|
// init-db
|
|
17
17
|
var init_db_1 = require("./init-db");
|
|
18
18
|
Object.defineProperty(exports, "initDatabase", { enumerable: true, get: function () { return init_db_1.initDatabase; } });
|
|
@@ -83,6 +83,7 @@ Object.defineProperty(exports, "createMemo", { enumerable: true, get: function (
|
|
|
83
83
|
Object.defineProperty(exports, "updateMemo", { enumerable: true, get: function () { return memo_db_1.updateMemo; } });
|
|
84
84
|
Object.defineProperty(exports, "deleteMemo", { enumerable: true, get: function () { return memo_db_1.deleteMemo; } });
|
|
85
85
|
Object.defineProperty(exports, "reorderMemos", { enumerable: true, get: function () { return memo_db_1.reorderMemos; } });
|
|
86
|
+
Object.defineProperty(exports, "MemoDbError", { enumerable: true, get: function () { return memo_db_1.MemoDbError; } });
|
|
86
87
|
// todo-db (repository-scoped Home ToDo widget)
|
|
87
88
|
var todo_db_1 = require("./todo-db");
|
|
88
89
|
Object.defineProperty(exports, "getTodosByRepositoryId", { enumerable: true, get: function () { return todo_db_1.getTodosByRepositoryId; } });
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* Issue #479: Extracted from db.ts for single-responsibility separation
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MemoDbError = void 0;
|
|
9
10
|
exports.getMemosByWorktreeId = getMemosByWorktreeId;
|
|
10
11
|
exports.getMemoById = getMemoById;
|
|
11
12
|
exports.createMemo = createMemo;
|
|
@@ -13,6 +14,26 @@ exports.updateMemo = updateMemo;
|
|
|
13
14
|
exports.deleteMemo = deleteMemo;
|
|
14
15
|
exports.reorderMemos = reorderMemos;
|
|
15
16
|
const crypto_1 = require("crypto");
|
|
17
|
+
/**
|
|
18
|
+
* Database error for memo operations.
|
|
19
|
+
*
|
|
20
|
+
* Issue #1351: `createMemo` writes to a table with a
|
|
21
|
+
* `UNIQUE(worktree_id, position)` constraint. Converting the driver's opaque
|
|
22
|
+
* "UNIQUE constraint failed" message into a typed, coded error lets API callers
|
|
23
|
+
* map the collision to an explicit 409 instead of a generic 500. Mirrors
|
|
24
|
+
* `ExternalAppDbError` in `src/lib/external-apps/db.ts`.
|
|
25
|
+
*/
|
|
26
|
+
class MemoDbError extends Error {
|
|
27
|
+
code;
|
|
28
|
+
cause;
|
|
29
|
+
constructor(message, code, cause) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.code = code;
|
|
32
|
+
this.cause = cause;
|
|
33
|
+
this.name = 'MemoDbError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.MemoDbError = MemoDbError;
|
|
16
37
|
/**
|
|
17
38
|
* Map database row to WorktreeMemo model
|
|
18
39
|
*/
|
|
@@ -73,7 +94,17 @@ function createMemo(db, worktreeId, options) {
|
|
|
73
94
|
INSERT INTO worktree_memos (id, worktree_id, title, content, position, created_at, updated_at)
|
|
74
95
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
75
96
|
`);
|
|
76
|
-
|
|
97
|
+
try {
|
|
98
|
+
stmt.run(id, worktreeId, title, content, options.position, now, now);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
// UNIQUE(worktree_id, position) violation -> typed DUPLICATE error (Issue #1351).
|
|
102
|
+
// Other failures (e.g. FOREIGN KEY) are re-thrown unchanged.
|
|
103
|
+
if (error instanceof Error && error.message.includes('UNIQUE constraint')) {
|
|
104
|
+
throw new MemoDbError(`Memo position ${options.position} is already in use for worktree "${worktreeId}"`, 'DUPLICATE_POSITION', error);
|
|
105
|
+
}
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
77
108
|
return {
|
|
78
109
|
id,
|
|
79
110
|
worktreeId,
|
|
@@ -26,6 +26,7 @@ const v39_worktree_todo_detail_1 = require("./v39-worktree-todo-detail");
|
|
|
26
26
|
const v40_timer_error_1 = require("./v40-timer-error");
|
|
27
27
|
const v41_push_subscriptions_1 = require("./v41-push-subscriptions");
|
|
28
28
|
const v42_push_subscription_locale_1 = require("./v42-push-subscription-locale");
|
|
29
|
+
const v43_remove_cm_root_dir_ghost_repository_1 = require("./v43-remove-cm-root-dir-ghost-repository");
|
|
29
30
|
/**
|
|
30
31
|
* Complete ordered list of all migrations.
|
|
31
32
|
* Used internally by the barrel file (db-migrations.ts); NOT exported from the barrel (DR2-004).
|
|
@@ -55,4 +56,5 @@ exports.migrations = [
|
|
|
55
56
|
...v40_timer_error_1.v40_migrations,
|
|
56
57
|
...v41_push_subscriptions_1.v41_migrations,
|
|
57
58
|
...v42_push_subscription_locale_1.v42_migrations,
|
|
59
|
+
...v43_remove_cm_root_dir_ghost_repository_1.v43_migrations,
|
|
58
60
|
];
|
|
@@ -17,7 +17,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
17
17
|
* Current schema version
|
|
18
18
|
* Increment this when adding new migrations
|
|
19
19
|
*/
|
|
20
|
-
exports.CURRENT_SCHEMA_VERSION =
|
|
20
|
+
exports.CURRENT_SCHEMA_VERSION = 43;
|
|
21
21
|
/**
|
|
22
22
|
* Get current schema version from database
|
|
23
23
|
*/
|
|
@@ -56,6 +56,16 @@ function runMigrations(db, migrations) {
|
|
|
56
56
|
// Get current version
|
|
57
57
|
const currentVersion = getCurrentVersion(db);
|
|
58
58
|
console.log(`Current schema version: ${currentVersion}`);
|
|
59
|
+
// Issue #1353: refuse a database written by a newer build.
|
|
60
|
+
// Migrations only move forward, so this build has no definition for the
|
|
61
|
+
// schema it is looking at: queries still written against renamed/dropped
|
|
62
|
+
// columns would fail at runtime, long after startup reported success.
|
|
63
|
+
// The check sits after the version read but before any migration writes.
|
|
64
|
+
if (currentVersion > exports.CURRENT_SCHEMA_VERSION) {
|
|
65
|
+
throw new Error(`This database (schema v${currentVersion}) was created by a newer version of CommandMate ` +
|
|
66
|
+
`(this build supports up to v${exports.CURRENT_SCHEMA_VERSION}). ` +
|
|
67
|
+
`Please update: commandmate update`);
|
|
68
|
+
}
|
|
59
69
|
// Find pending migrations
|
|
60
70
|
const pendingMigrations = migrations.filter(migration => migration.version > currentVersion);
|
|
61
71
|
if (pendingMigrations.length === 0) {
|