commandmate 0.11.3 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +392 -300
- package/.next/app-path-routes-manifest.json +30 -21
- package/.next/build-manifest.json +5 -5
- package/.next/prerender-manifest.json +12 -12
- package/.next/react-loadable-manifest.json +8 -6
- package/.next/required-server-files.json +1 -1
- package/.next/routes-manifest.json +66 -0
- package/.next/server/app/_not-found/page.js.nft.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 +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/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_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js +1 -0
- package/.next/server/app/api/skills/[id]/route.js.nft.json +1 -0
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/skills/route.js +1 -0
- package/.next/server/app/api/skills/route.js.nft.json +1 -0
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -0
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route.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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +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]/install/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/route.js +23 -0
- package/.next/server/app/api/worktrees/[id]/skills/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.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.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]/viewed/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/chat/page.js +2 -2
- 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.js.nft.json +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.js.nft.json +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/skills/[skillId]/page.js +2 -0
- package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -0
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -0
- package/.next/server/app/skills/page.js +2 -0
- package/.next/server/app/skills/page.js.nft.json +1 -0
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -0
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js +2 -2
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +9 -9
- 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.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +30 -21
- package/.next/server/chunks/1117.js +1 -1
- package/.next/server/chunks/120.js +1 -0
- package/.next/server/chunks/1808.js +1 -0
- package/.next/server/chunks/186.js +1 -0
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/22.js +1 -0
- package/.next/server/chunks/2328.js +1 -0
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/3042.js +2 -0
- package/.next/server/chunks/3543.js +1 -1
- package/.next/server/chunks/3708.js +1 -0
- package/.next/server/chunks/3945.js +1 -1
- package/.next/server/chunks/5064.js +1 -0
- package/.next/server/chunks/5226.js +28 -0
- package/.next/server/chunks/5306.js +2 -0
- package/.next/server/chunks/5312.js +1 -0
- package/.next/server/chunks/5326.js +1 -0
- package/.next/server/chunks/5381.js +1 -1
- package/.next/server/chunks/5456.js +1 -0
- package/.next/server/chunks/5571.js +1 -1
- package/.next/server/chunks/5959.js +2 -2
- package/.next/server/chunks/6065.js +1 -0
- package/.next/server/chunks/6130.js +1 -0
- package/.next/server/chunks/6285.js +1 -1
- package/.next/server/chunks/646.js +6 -6
- package/.next/server/chunks/{9968.js → 7587.js} +1 -1
- package/.next/server/chunks/8584.js +1 -0
- package/.next/server/chunks/8681.js +1 -1
- package/.next/server/chunks/8807.js +950 -804
- package/.next/server/chunks/9123.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/D-aoE4gWfuCUN0GqEPIX3/_buildManifest.js +1 -0
- package/.next/static/chunks/1668-7484081c45a44f89.js +1 -0
- package/.next/static/chunks/3418-7e47651340d940b0.js +1 -0
- package/.next/static/chunks/4027-0c529b322be7d4d8.js +1 -0
- package/.next/static/chunks/{4560-64b1461fd996127a.js → 4560-04e5aebcab96bfa1.js} +1 -1
- package/.next/static/chunks/6007-de36119357dcd418.js +1 -0
- package/.next/static/chunks/{6488-8819e6905355caea.js → 6488-e257111ca7389d05.js} +1 -1
- package/.next/static/chunks/{8965-872d8de254196cec.js → 6497-dc26c6c6b0b15adf.js} +1 -1
- package/.next/static/chunks/790-d8e6acd26e03679c.js +1 -0
- package/.next/static/chunks/8361.4bf062be2d2962f4.js +1 -0
- package/.next/static/chunks/app/api/app/update/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/app/update-check/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/assistant/conversation/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/assistant/current-output/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/assistant/messages/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/assistant/session/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/assistant/start/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/assistant/terminal/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/assistant/tools/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/auth/login/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/auth/status/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/status/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/external-apps/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/hooks/claude-done/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/ollama/models/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/push/subscriptions/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/push/vapid/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/repositories/excluded/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/repositories/restore/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/repositories/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/repositories/scan/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/repositories/sync/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/sidebar/group-order/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/skills/[id]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/skills/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/slash-commands/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/templates/[id]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/templates/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/todos/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/chat/{page-9ed2ffd98eb4ae18.js → page-9cf4ba62e21d9074.js} +1 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/more/{page-a496425bba427b48.js → page-082d4ae496f9a36e.js} +1 -1
- package/.next/static/chunks/app/{page-15bfd76bcf65842d.js → page-af457ca5876ed616.js} +1 -1
- package/.next/static/chunks/app/proxy/[...path]/route-56dad0523d3c4a92.js +1 -0
- package/.next/static/chunks/app/repositories/{page-d214522ab8792ce7.js → page-75f0d70452c6b6c0.js} +1 -1
- package/.next/static/chunks/app/review/{page-1dadf0b5d7129598.js → page-f431d630097c2e85.js} +1 -1
- package/.next/static/chunks/app/sessions/{page-96f007d986c5f327.js → page-20f07a99db64d2ca.js} +1 -1
- package/.next/static/chunks/app/skills/[skillId]/page-68ed5e9186efe56d.js +1 -0
- package/.next/static/chunks/app/skills/page-46242c428ee8bccf.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-bf811e793052c917.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/terminal/page-a75fe180a7233b2b.js +1 -0
- package/.next/static/chunks/webpack-0f9275e279c058eb.js +1 -0
- package/.next/static/css/b4bdb1f3457fe9a7.css +1 -0
- package/.next/trace +11 -10
- package/.next/types/app/api/skills/[id]/route.ts +347 -0
- package/.next/types/app/api/skills/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/skills/[skillId]/install/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/skills/[skillId]/plan/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/skills/route.ts +347 -0
- package/.next/types/app/skills/[skillId]/page.ts +84 -0
- package/.next/types/app/skills/page.ts +84 -0
- package/.next/types/routes.d.ts +11 -2
- package/.next/types/validator.ts +81 -0
- package/dist/cli/commands/skill-format.d.ts +28 -0
- package/dist/cli/commands/skill-format.d.ts.map +1 -0
- package/dist/cli/commands/skill-format.js +163 -0
- package/dist/cli/commands/skill-guards.d.ts +53 -0
- package/dist/cli/commands/skill-guards.d.ts.map +1 -0
- package/dist/cli/commands/skill-guards.js +188 -0
- package/dist/cli/commands/skill.d.ts +24 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +365 -0
- package/dist/cli/docs/agent-operations.d.ts +1 -1
- package/dist/cli/docs/agent-operations.d.ts.map +1 -1
- package/dist/cli/docs/agent-operations.js +36 -0
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +11 -0
- package/dist/cli/types/api-responses.d.ts +215 -0
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/types/index.d.ts +60 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/types/index.js +23 -1
- package/dist/cli/utils/api-client.d.ts +19 -1
- package/dist/cli/utils/api-client.d.ts.map +1 -1
- package/dist/cli/utils/api-client.js +41 -4
- package/dist/cli/utils/npx-runner.d.ts +14 -0
- package/dist/cli/utils/npx-runner.d.ts.map +1 -1
- package/dist/cli/utils/npx-runner.js +20 -0
- package/dist/server/server.js +57 -0
- package/dist/server/src/config/activity-bar-config.js +2 -0
- package/dist/server/src/config/git-status-config.js +83 -0
- package/dist/server/src/config/skill-security-config.js +139 -0
- package/dist/server/src/lib/db/migrations/index.js +8 -0
- package/dist/server/src/lib/db/migrations/runner.js +1 -1
- package/dist/server/src/lib/db/migrations/v44-skill-operations.js +81 -0
- package/dist/server/src/lib/db/migrations/v45-skill-installations.js +59 -0
- package/dist/server/src/lib/db/migrations/v46-skill-installations-cascade.js +107 -0
- package/dist/server/src/lib/db/migrations/v47-skill-installations-roots.js +70 -0
- package/dist/server/src/lib/db/worktree-db.js +9 -4
- package/dist/server/src/lib/git/git-errors.js +336 -0
- package/dist/server/src/lib/git/git-exec.js +285 -0
- package/dist/server/src/lib/skills/compatibility.js +194 -0
- package/dist/server/src/lib/skills/constants.js +252 -0
- package/dist/server/src/lib/skills/errors.js +82 -0
- package/dist/server/src/lib/skills/index.js +91 -0
- package/dist/server/src/lib/skills/install-apply.js +670 -0
- package/dist/server/src/lib/skills/install-plan.js +582 -0
- package/dist/server/src/lib/skills/installed-state.js +127 -0
- package/dist/server/src/lib/skills/integrity.js +225 -0
- package/dist/server/src/lib/skills/json-schema.js +365 -0
- package/dist/server/src/lib/skills/operation-audit.js +120 -0
- package/dist/server/src/lib/skills/operation-journal.js +286 -0
- package/dist/server/src/lib/skills/operation-lock.js +339 -0
- package/dist/server/src/lib/skills/operation-reconciler.js +107 -0
- package/dist/server/src/lib/skills/operation-store.js +153 -0
- package/dist/server/src/lib/skills/package-reader.js +495 -0
- package/dist/server/src/lib/skills/package-validator.js +451 -0
- package/dist/server/src/lib/skills/preview-diff.js +627 -0
- package/dist/server/src/lib/skills/safe-yaml.js +593 -0
- package/dist/server/src/lib/skills/schema.js +1248 -0
- package/dist/server/src/lib/skills/semver.js +193 -0
- package/dist/server/src/lib/skills/snapshot-store.js +334 -0
- package/dist/server/src/lib/skills/startup-reconcile.js +138 -0
- package/dist/server/src/lib/skills/uninstall-apply.js +495 -0
- package/dist/server/src/lib/skills/uninstall-plan.js +479 -0
- package/dist/server/src/types/skills.js +17 -0
- package/package.json +1 -1
- package/.next/server/chunks/129.js +0 -1
- package/.next/server/chunks/2478.js +0 -1
- package/.next/server/chunks/9886.js +0 -1
- package/.next/static/chunks/3165-87bf884f7f3d15cf.js +0 -1
- package/.next/static/chunks/6416.6756b7ad06dd96f7.js +0 -1
- package/.next/static/chunks/8676.57260a06f6554e7e.js +0 -1
- package/.next/static/chunks/app/api/app/update/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/app/update-check/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/assistant/conversation/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/assistant/current-output/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/assistant/messages/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/assistant/session/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/assistant/start/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/assistant/terminal/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/assistant/tools/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/auth/login/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/auth/status/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/status/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/external-apps/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/hooks/claude-done/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/ollama/models/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/push/subscriptions/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/push/vapid/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/repositories/excluded/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/repositories/restore/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/repositories/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/repositories/scan/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/repositories/sync/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/sidebar/group-order/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/slash-commands/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/templates/[id]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/templates/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/todos/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/proxy/[...path]/route-7536041a7a89616d.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-6105a3470b279527.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/terminal/page-ed4590b024edd8d6.js +0 -1
- package/.next/static/chunks/webpack-2e3739a831868daa.js +0 -1
- package/.next/static/css/d7e2e8d1b8d69d36.css +0 -1
- package/.next/static/i8mdUwheg9j9sU_lI_ZSf/_buildManifest.js +0 -1
- /package/.next/static/{i8mdUwheg9j9sU_lI_ZSf → D-aoE4gWfuCUN0GqEPIX3}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SemVer 2.0 handling for the Skills distribution contract (Issue #1228)
|
|
4
|
+
*
|
|
5
|
+
* `src/lib/version-checker.ts` intentionally compares only `major.minor.patch`
|
|
6
|
+
* of CommandMate's own release tags and tolerates a `v` prefix. The Skill
|
|
7
|
+
* contract needs full SemVer 2.0 precedence (prerelease ordering, build
|
|
8
|
+
* metadata ignored) and rejects the `v` prefix, so it gets its own strict
|
|
9
|
+
* implementation instead of loosening the update-check semantics.
|
|
10
|
+
*
|
|
11
|
+
* The range grammar is deliberately a small, total subset of npm's: a
|
|
12
|
+
* space-separated AND list of comparators. `||`, `x`-ranges, `*` and hyphen
|
|
13
|
+
* ranges are rejected so a range always has one unambiguous reading.
|
|
14
|
+
*
|
|
15
|
+
* @module lib/skills/semver
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.VERSION_RANGE_MAX_COMPARATORS = exports.VERSION_RANGE_MAX_LENGTH = exports.SEMVER_MAX_LENGTH = exports.SEMVER_2_PATTERN = void 0;
|
|
19
|
+
exports.parseSemVer = parseSemVer;
|
|
20
|
+
exports.isValidSemVer = isValidSemVer;
|
|
21
|
+
exports.compareParsedSemVer = compareParsedSemVer;
|
|
22
|
+
exports.compareSemVer = compareSemVer;
|
|
23
|
+
exports.parseSkillVersionRange = parseSkillVersionRange;
|
|
24
|
+
exports.isValidSkillVersionRange = isValidSkillVersionRange;
|
|
25
|
+
exports.satisfiesSkillVersionRange = satisfiesSkillVersionRange;
|
|
26
|
+
/** Strict SemVer 2.0 grammar. No `v` prefix, no leading zeroes. */
|
|
27
|
+
exports.SEMVER_2_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
|
28
|
+
/** Maximum accepted length of a version string. */
|
|
29
|
+
exports.SEMVER_MAX_LENGTH = 64;
|
|
30
|
+
/** Maximum accepted length of a range expression. */
|
|
31
|
+
exports.VERSION_RANGE_MAX_LENGTH = 100;
|
|
32
|
+
/** Maximum number of comparators in one range. */
|
|
33
|
+
exports.VERSION_RANGE_MAX_COMPARATORS = 4;
|
|
34
|
+
/** Parse a strict SemVer 2.0 string. Returns null when invalid. */
|
|
35
|
+
function parseSemVer(version) {
|
|
36
|
+
if (typeof version !== 'string' || version.length > exports.SEMVER_MAX_LENGTH)
|
|
37
|
+
return null;
|
|
38
|
+
const match = exports.SEMVER_2_PATTERN.exec(version);
|
|
39
|
+
if (!match)
|
|
40
|
+
return null;
|
|
41
|
+
return {
|
|
42
|
+
major: Number(match[1]),
|
|
43
|
+
minor: Number(match[2]),
|
|
44
|
+
patch: Number(match[3]),
|
|
45
|
+
prerelease: match[4] ? match[4].split('.') : [],
|
|
46
|
+
build: match[5] ? match[5].split('.') : [],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** True when the string is a strict SemVer 2.0 version. */
|
|
50
|
+
function isValidSemVer(version) {
|
|
51
|
+
return parseSemVer(version) !== null;
|
|
52
|
+
}
|
|
53
|
+
function comparePrerelease(a, b) {
|
|
54
|
+
// A release outranks any prerelease of the same major.minor.patch.
|
|
55
|
+
if (a.length === 0 && b.length === 0)
|
|
56
|
+
return 0;
|
|
57
|
+
if (a.length === 0)
|
|
58
|
+
return 1;
|
|
59
|
+
if (b.length === 0)
|
|
60
|
+
return -1;
|
|
61
|
+
const len = Math.min(a.length, b.length);
|
|
62
|
+
for (let i = 0; i < len; i++) {
|
|
63
|
+
const left = a[i];
|
|
64
|
+
const right = b[i];
|
|
65
|
+
if (left === right)
|
|
66
|
+
continue;
|
|
67
|
+
const leftNumeric = /^\d+$/.test(left);
|
|
68
|
+
const rightNumeric = /^\d+$/.test(right);
|
|
69
|
+
if (leftNumeric && rightNumeric)
|
|
70
|
+
return Number(left) < Number(right) ? -1 : 1;
|
|
71
|
+
if (leftNumeric)
|
|
72
|
+
return -1;
|
|
73
|
+
if (rightNumeric)
|
|
74
|
+
return 1;
|
|
75
|
+
return left < right ? -1 : 1;
|
|
76
|
+
}
|
|
77
|
+
if (a.length === b.length)
|
|
78
|
+
return 0;
|
|
79
|
+
return a.length < b.length ? -1 : 1;
|
|
80
|
+
}
|
|
81
|
+
/** Compare two parsed versions by SemVer 2.0 precedence. Build metadata is ignored. */
|
|
82
|
+
function compareParsedSemVer(a, b) {
|
|
83
|
+
if (a.major !== b.major)
|
|
84
|
+
return a.major < b.major ? -1 : 1;
|
|
85
|
+
if (a.minor !== b.minor)
|
|
86
|
+
return a.minor < b.minor ? -1 : 1;
|
|
87
|
+
if (a.patch !== b.patch)
|
|
88
|
+
return a.patch < b.patch ? -1 : 1;
|
|
89
|
+
return comparePrerelease(a.prerelease, b.prerelease);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Compare two SemVer 2.0 strings.
|
|
93
|
+
*
|
|
94
|
+
* @returns -1, 0 or 1; null when either input is not valid SemVer 2.0.
|
|
95
|
+
*/
|
|
96
|
+
function compareSemVer(a, b) {
|
|
97
|
+
const left = parseSemVer(a);
|
|
98
|
+
const right = parseSemVer(b);
|
|
99
|
+
if (!left || !right)
|
|
100
|
+
return null;
|
|
101
|
+
return compareParsedSemVer(left, right);
|
|
102
|
+
}
|
|
103
|
+
function samePrecedenceTuple(a, b) {
|
|
104
|
+
return a.major === b.major && a.minor === b.minor && a.patch === b.patch;
|
|
105
|
+
}
|
|
106
|
+
function caretUpperBound(v) {
|
|
107
|
+
if (v.major > 0)
|
|
108
|
+
return { major: v.major + 1, minor: 0, patch: 0, prerelease: [], build: [] };
|
|
109
|
+
if (v.minor > 0)
|
|
110
|
+
return { major: 0, minor: v.minor + 1, patch: 0, prerelease: [], build: [] };
|
|
111
|
+
return { major: 0, minor: 0, patch: v.patch + 1, prerelease: [], build: [] };
|
|
112
|
+
}
|
|
113
|
+
function tildeUpperBound(v) {
|
|
114
|
+
return { major: v.major, minor: v.minor + 1, patch: 0, prerelease: [], build: [] };
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Parse a range into desugared comparators combined with AND.
|
|
118
|
+
*
|
|
119
|
+
* Accepted tokens: `x.y.z`, `=x.y.z`, `>x.y.z`, `>=x.y.z`, `<x.y.z`, `<=x.y.z`,
|
|
120
|
+
* `^x.y.z`, `~x.y.z`. Returns null for anything else.
|
|
121
|
+
*/
|
|
122
|
+
function parseSkillVersionRange(range) {
|
|
123
|
+
if (typeof range !== 'string')
|
|
124
|
+
return null;
|
|
125
|
+
const trimmed = range.trim();
|
|
126
|
+
if (trimmed.length === 0 || trimmed.length > exports.VERSION_RANGE_MAX_LENGTH)
|
|
127
|
+
return null;
|
|
128
|
+
if (trimmed.includes('||'))
|
|
129
|
+
return null;
|
|
130
|
+
const tokens = trimmed.split(/\s+/);
|
|
131
|
+
if (tokens.length > exports.VERSION_RANGE_MAX_COMPARATORS)
|
|
132
|
+
return null;
|
|
133
|
+
const comparators = [];
|
|
134
|
+
for (const token of tokens) {
|
|
135
|
+
const match = /^(>=|<=|>|<|=|\^|~)?(.+)$/.exec(token);
|
|
136
|
+
if (!match)
|
|
137
|
+
return null;
|
|
138
|
+
const operator = match[1] ?? '=';
|
|
139
|
+
const version = parseSemVer(match[2]);
|
|
140
|
+
if (!version)
|
|
141
|
+
return null;
|
|
142
|
+
if (operator === '^' || operator === '~') {
|
|
143
|
+
const upper = operator === '^' ? caretUpperBound(version) : tildeUpperBound(version);
|
|
144
|
+
comparators.push({ operator: '>=', version });
|
|
145
|
+
comparators.push({ operator: '<', version: upper });
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
comparators.push({ operator: operator, version });
|
|
149
|
+
}
|
|
150
|
+
if (comparators.length > exports.VERSION_RANGE_MAX_COMPARATORS * 2)
|
|
151
|
+
return null;
|
|
152
|
+
return comparators;
|
|
153
|
+
}
|
|
154
|
+
/** True when the range is expressible in the supported grammar. */
|
|
155
|
+
function isValidSkillVersionRange(range) {
|
|
156
|
+
return parseSkillVersionRange(range) !== null;
|
|
157
|
+
}
|
|
158
|
+
function satisfiesComparator(version, comparator) {
|
|
159
|
+
const cmp = compareParsedSemVer(version, comparator.version);
|
|
160
|
+
switch (comparator.operator) {
|
|
161
|
+
case '=':
|
|
162
|
+
return cmp === 0;
|
|
163
|
+
case '>':
|
|
164
|
+
return cmp > 0;
|
|
165
|
+
case '>=':
|
|
166
|
+
return cmp >= 0;
|
|
167
|
+
case '<':
|
|
168
|
+
return cmp < 0;
|
|
169
|
+
case '<=':
|
|
170
|
+
return cmp <= 0;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Test a version against a range.
|
|
175
|
+
*
|
|
176
|
+
* A prerelease version only satisfies a range when some comparator names the
|
|
177
|
+
* same `major.minor.patch` *and* itself carries a prerelease. Without this rule
|
|
178
|
+
* `>=1.0.0` would silently accept `2.0.0-alpha.1`.
|
|
179
|
+
*
|
|
180
|
+
* @returns false for an invalid version or an unparsable range (fail closed).
|
|
181
|
+
*/
|
|
182
|
+
function satisfiesSkillVersionRange(version, range) {
|
|
183
|
+
const parsed = parseSemVer(version);
|
|
184
|
+
const comparators = parseSkillVersionRange(range);
|
|
185
|
+
if (!parsed || !comparators)
|
|
186
|
+
return false;
|
|
187
|
+
if (parsed.prerelease.length > 0) {
|
|
188
|
+
const allowed = comparators.some((c) => c.version.prerelease.length > 0 && samePrecedenceTuple(parsed, c.version));
|
|
189
|
+
if (!allowed)
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
return comparators.every((c) => satisfiesComparator(parsed, c));
|
|
193
|
+
}
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Read-only snapshot store for verified Skill artifacts (Issue #1229)
|
|
4
|
+
*
|
|
5
|
+
* A snapshot is verified artifact bytes parked in the service-owned data root
|
|
6
|
+
* so a later step (#1230 extraction, #1231 install) can read them without
|
|
7
|
+
* re-downloading. Snapshots are addressed by an opaque ID: absolute paths never
|
|
8
|
+
* leave this module, because they identify the machine and the data root.
|
|
9
|
+
*
|
|
10
|
+
* Lifetime is reference-counted with a TTL backstop. A snapshot with live
|
|
11
|
+
* references is never swept, no matter how much quota pressure there is —
|
|
12
|
+
* failing the new download is correct, corrupting an in-progress install is
|
|
13
|
+
* not. Process restart drops every reference, so initialization treats whatever
|
|
14
|
+
* is on disk as orphaned and removes it.
|
|
15
|
+
*
|
|
16
|
+
* @module lib/skills/snapshot-store
|
|
17
|
+
*/
|
|
18
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.initSkillSnapshotStore = initSkillSnapshotStore;
|
|
23
|
+
exports.isSkillSnapshotStoreInitialized = isSkillSnapshotStoreInitialized;
|
|
24
|
+
exports.createSkillSnapshot = createSkillSnapshot;
|
|
25
|
+
exports.acquireSkillSnapshot = acquireSkillSnapshot;
|
|
26
|
+
exports.releaseSkillSnapshot = releaseSkillSnapshot;
|
|
27
|
+
exports.getSkillSnapshot = getSkillSnapshot;
|
|
28
|
+
exports.readSkillSnapshotBytes = readSkillSnapshotBytes;
|
|
29
|
+
exports.resolveSkillSnapshotPath = resolveSkillSnapshotPath;
|
|
30
|
+
exports.sweepSkillSnapshots = sweepSkillSnapshots;
|
|
31
|
+
exports.getSkillSnapshotUsage = getSkillSnapshotUsage;
|
|
32
|
+
exports.resetSkillSnapshotStoreForTesting = resetSkillSnapshotStoreForTesting;
|
|
33
|
+
const crypto_1 = require("crypto");
|
|
34
|
+
const fs_1 = require("fs");
|
|
35
|
+
const path_1 = __importDefault(require("path"));
|
|
36
|
+
const install_context_1 = require("../../cli/utils/install-context");
|
|
37
|
+
const skill_security_config_1 = require("../../config/skill-security-config");
|
|
38
|
+
const system_directories_1 = require("../../config/system-directories");
|
|
39
|
+
const skills_1 = require("../../lib/skills");
|
|
40
|
+
const integrity_1 = require("../../lib/skills/integrity");
|
|
41
|
+
const state = globalThis.__skillSnapshotStore ??
|
|
42
|
+
(globalThis.__skillSnapshotStore = { rootDir: null, records: new Map(), totalBytes: 0 });
|
|
43
|
+
const SNAPSHOT_FILE_SUFFIX = '.artifact';
|
|
44
|
+
// =============================================================================
|
|
45
|
+
// Initialization
|
|
46
|
+
// =============================================================================
|
|
47
|
+
function resolveDefaultRoot() {
|
|
48
|
+
return path_1.default.join((0, install_context_1.getConfigDir)(), 'data', skill_security_config_1.SKILL_SNAPSHOT_DIRNAME);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Prepare the snapshot root and drop anything left behind by a previous process.
|
|
52
|
+
*
|
|
53
|
+
* Repeated calls with the same root are no-ops so a warm store is not wiped by
|
|
54
|
+
* a second consumer initializing lazily.
|
|
55
|
+
*
|
|
56
|
+
* @param options.rootDir Override for tests and for callers that own their data root
|
|
57
|
+
* @returns The resolved snapshot root
|
|
58
|
+
* @throws SkillFetchError with `STORE_IO`
|
|
59
|
+
*/
|
|
60
|
+
function initSkillSnapshotStore(options = {}) {
|
|
61
|
+
const rootDir = path_1.default.resolve(options.rootDir ?? resolveDefaultRoot());
|
|
62
|
+
if ((0, system_directories_1.isSystemDirectory)(rootDir)) {
|
|
63
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.STORE_IO, { reason: 'system-directory' });
|
|
64
|
+
}
|
|
65
|
+
if (state.rootDir === rootDir)
|
|
66
|
+
return rootDir;
|
|
67
|
+
try {
|
|
68
|
+
(0, fs_1.mkdirSync)(rootDir, { recursive: true, mode: skill_security_config_1.SKILL_SNAPSHOT_DIR_MODE });
|
|
69
|
+
(0, fs_1.chmodSync)(rootDir, skill_security_config_1.SKILL_SNAPSHOT_DIR_MODE);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.STORE_IO, { reason: 'mkdir' });
|
|
73
|
+
}
|
|
74
|
+
state.rootDir = rootDir;
|
|
75
|
+
state.records.clear();
|
|
76
|
+
state.totalBytes = 0;
|
|
77
|
+
purgeOrphanFiles();
|
|
78
|
+
return rootDir;
|
|
79
|
+
}
|
|
80
|
+
function requireRoot() {
|
|
81
|
+
if (!state.rootDir)
|
|
82
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.STORE_UNINITIALIZED);
|
|
83
|
+
return state.rootDir;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Whether a data root has been resolved.
|
|
87
|
+
*
|
|
88
|
+
* For callers that may run before the first artifact download — the background
|
|
89
|
+
* sweeper starts with the process, the store only on first use — and must skip
|
|
90
|
+
* rather than treat an untouched store as an error.
|
|
91
|
+
*/
|
|
92
|
+
function isSkillSnapshotStoreInitialized() {
|
|
93
|
+
return state.rootDir !== null;
|
|
94
|
+
}
|
|
95
|
+
/** Remove every snapshot file the in-memory index does not account for. */
|
|
96
|
+
function purgeOrphanFiles() {
|
|
97
|
+
const rootDir = requireRoot();
|
|
98
|
+
const tracked = new Set([...state.records.values()].map((record) => record.filename));
|
|
99
|
+
let entries;
|
|
100
|
+
try {
|
|
101
|
+
entries = (0, fs_1.readdirSync)(rootDir);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.STORE_IO, { reason: 'readdir' });
|
|
105
|
+
}
|
|
106
|
+
for (const entry of entries) {
|
|
107
|
+
if (tracked.has(entry))
|
|
108
|
+
continue;
|
|
109
|
+
(0, fs_1.rmSync)(path_1.default.join(rootDir, entry), { force: true, recursive: true });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// =============================================================================
|
|
113
|
+
// Internals
|
|
114
|
+
// =============================================================================
|
|
115
|
+
function filePathOf(record) {
|
|
116
|
+
return path_1.default.join(requireRoot(), record.filename);
|
|
117
|
+
}
|
|
118
|
+
function removeRecord(record) {
|
|
119
|
+
(0, fs_1.rmSync)(filePathOf(record), { force: true });
|
|
120
|
+
state.records.delete(record.snapshotId);
|
|
121
|
+
state.totalBytes -= record.size;
|
|
122
|
+
}
|
|
123
|
+
function requireRecord(snapshotId) {
|
|
124
|
+
requireRoot();
|
|
125
|
+
if (!skill_security_config_1.SKILL_SNAPSHOT_ID_PATTERN.test(snapshotId)) {
|
|
126
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.SNAPSHOT_NOT_FOUND);
|
|
127
|
+
}
|
|
128
|
+
const record = state.records.get(snapshotId);
|
|
129
|
+
if (!record)
|
|
130
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.SNAPSHOT_NOT_FOUND);
|
|
131
|
+
if (record.refCount === 0 && Date.now() >= record.expiresAt) {
|
|
132
|
+
removeRecord(record);
|
|
133
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.SNAPSHOT_EXPIRED);
|
|
134
|
+
}
|
|
135
|
+
return record;
|
|
136
|
+
}
|
|
137
|
+
function toHandle(record) {
|
|
138
|
+
return {
|
|
139
|
+
snapshotId: record.snapshotId,
|
|
140
|
+
skillId: record.skillId,
|
|
141
|
+
version: record.version,
|
|
142
|
+
commit: record.commit,
|
|
143
|
+
sha256: record.sha256,
|
|
144
|
+
size: record.size,
|
|
145
|
+
expiresAt: record.expiresAt,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function touch(record, now) {
|
|
149
|
+
record.lastAccessedAt = now;
|
|
150
|
+
record.expiresAt = now + skill_security_config_1.SKILL_SNAPSHOT_TTL_MS;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Free space for an incoming snapshot by evicting unreferenced ones.
|
|
154
|
+
*
|
|
155
|
+
* Expired entries go first, then least-recently-used. Referenced snapshots are
|
|
156
|
+
* never candidates, so a full store rejects the newcomer instead.
|
|
157
|
+
*/
|
|
158
|
+
function makeRoomFor(size, now) {
|
|
159
|
+
const fits = () => state.totalBytes + size <= skill_security_config_1.SKILL_SNAPSHOT_TOTAL_QUOTA_BYTES &&
|
|
160
|
+
state.records.size < skill_security_config_1.SKILL_SNAPSHOT_MAX_COUNT;
|
|
161
|
+
if (fits())
|
|
162
|
+
return;
|
|
163
|
+
const candidates = [...state.records.values()]
|
|
164
|
+
.filter((record) => record.refCount === 0)
|
|
165
|
+
.sort((a, b) => {
|
|
166
|
+
const aExpired = now >= a.expiresAt ? 0 : 1;
|
|
167
|
+
const bExpired = now >= b.expiresAt ? 0 : 1;
|
|
168
|
+
if (aExpired !== bExpired)
|
|
169
|
+
return aExpired - bExpired;
|
|
170
|
+
return a.lastAccessedAt - b.lastAccessedAt;
|
|
171
|
+
});
|
|
172
|
+
for (const candidate of candidates) {
|
|
173
|
+
if (fits())
|
|
174
|
+
return;
|
|
175
|
+
removeRecord(candidate);
|
|
176
|
+
}
|
|
177
|
+
if (!fits()) {
|
|
178
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.QUOTA_EXCEEDED, {
|
|
179
|
+
requested: size,
|
|
180
|
+
limit: skill_security_config_1.SKILL_SNAPSHOT_TOTAL_QUOTA_BYTES,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// =============================================================================
|
|
185
|
+
// Public API
|
|
186
|
+
// =============================================================================
|
|
187
|
+
/**
|
|
188
|
+
* Store verified artifact bytes as a read-only snapshot with one reference held.
|
|
189
|
+
*
|
|
190
|
+
* The digest is recomputed here rather than trusted from the downloader: this
|
|
191
|
+
* is the last point before bytes become readable by another module, and bytes
|
|
192
|
+
* that do not match the Catalog must never become visible as a snapshot.
|
|
193
|
+
*
|
|
194
|
+
* Bytes already snapshotted under the same digest are shared: the existing
|
|
195
|
+
* snapshot gains a reference and no second copy is written.
|
|
196
|
+
*
|
|
197
|
+
* @throws SkillFetchError — `CHECKSUM_MISMATCH`, `QUOTA_EXCEEDED`, `STORE_IO`
|
|
198
|
+
*/
|
|
199
|
+
function createSkillSnapshot(input) {
|
|
200
|
+
const rootDir = requireRoot();
|
|
201
|
+
const now = Date.now();
|
|
202
|
+
const size = input.bytes.byteLength;
|
|
203
|
+
if (size <= 0 || size > skills_1.SKILL_ARTIFACT_MAX_SIZE) {
|
|
204
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.SIZE_LIMIT_EXCEEDED, {
|
|
205
|
+
limit: skills_1.SKILL_ARTIFACT_MAX_SIZE,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (!(0, integrity_1.digestMatches)(input.sha256, (0, integrity_1.computeSha256Hex)(input.bytes))) {
|
|
209
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.CHECKSUM_MISMATCH);
|
|
210
|
+
}
|
|
211
|
+
for (const record of state.records.values()) {
|
|
212
|
+
if (record.sha256 === input.sha256 && (0, fs_1.existsSync)(filePathOf(record))) {
|
|
213
|
+
record.refCount += 1;
|
|
214
|
+
touch(record, now);
|
|
215
|
+
return toHandle(record);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
makeRoomFor(size, now);
|
|
219
|
+
const snapshotId = (0, crypto_1.randomBytes)(skill_security_config_1.SKILL_SNAPSHOT_ID_BYTES).toString('hex');
|
|
220
|
+
const filename = `${snapshotId}${SNAPSHOT_FILE_SUFFIX}`;
|
|
221
|
+
const finalPath = path_1.default.join(rootDir, filename);
|
|
222
|
+
const stagingPath = `${finalPath}.tmp`;
|
|
223
|
+
try {
|
|
224
|
+
(0, fs_1.writeFileSync)(stagingPath, input.bytes, { mode: 0o600 });
|
|
225
|
+
(0, fs_1.chmodSync)(stagingPath, skill_security_config_1.SKILL_SNAPSHOT_FILE_MODE);
|
|
226
|
+
(0, fs_1.renameSync)(stagingPath, finalPath);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
(0, fs_1.rmSync)(stagingPath, { force: true });
|
|
230
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.STORE_IO, { reason: 'write' });
|
|
231
|
+
}
|
|
232
|
+
const record = {
|
|
233
|
+
snapshotId,
|
|
234
|
+
skillId: input.skillId,
|
|
235
|
+
version: input.version,
|
|
236
|
+
commit: input.commit,
|
|
237
|
+
sha256: input.sha256,
|
|
238
|
+
size,
|
|
239
|
+
expiresAt: now + skill_security_config_1.SKILL_SNAPSHOT_TTL_MS,
|
|
240
|
+
refCount: 1,
|
|
241
|
+
lastAccessedAt: now,
|
|
242
|
+
filename,
|
|
243
|
+
};
|
|
244
|
+
state.records.set(snapshotId, record);
|
|
245
|
+
state.totalBytes += size;
|
|
246
|
+
return toHandle(record);
|
|
247
|
+
}
|
|
248
|
+
/** Take an additional reference, extending the TTL. */
|
|
249
|
+
function acquireSkillSnapshot(snapshotId) {
|
|
250
|
+
const record = requireRecord(snapshotId);
|
|
251
|
+
record.refCount += 1;
|
|
252
|
+
touch(record, Date.now());
|
|
253
|
+
return toHandle(record);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Drop one reference.
|
|
257
|
+
*
|
|
258
|
+
* The bytes stay until the TTL elapses or quota pressure evicts them, so a
|
|
259
|
+
* retry right after a failed install does not have to re-download. Releasing an
|
|
260
|
+
* unknown ID is a no-op: cleanup paths must be safe to run twice.
|
|
261
|
+
*/
|
|
262
|
+
function releaseSkillSnapshot(snapshotId) {
|
|
263
|
+
const record = state.records.get(snapshotId);
|
|
264
|
+
if (!record)
|
|
265
|
+
return;
|
|
266
|
+
if (record.refCount > 0)
|
|
267
|
+
record.refCount -= 1;
|
|
268
|
+
if (record.refCount === 0)
|
|
269
|
+
record.lastAccessedAt = Date.now();
|
|
270
|
+
}
|
|
271
|
+
/** Read a snapshot's metadata without taking a reference. */
|
|
272
|
+
function getSkillSnapshot(snapshotId) {
|
|
273
|
+
return toHandle(requireRecord(snapshotId));
|
|
274
|
+
}
|
|
275
|
+
/** Read the snapshot bytes. */
|
|
276
|
+
function readSkillSnapshotBytes(snapshotId) {
|
|
277
|
+
const record = requireRecord(snapshotId);
|
|
278
|
+
try {
|
|
279
|
+
const bytes = (0, fs_1.readFileSync)(filePathOf(record));
|
|
280
|
+
record.lastAccessedAt = Date.now();
|
|
281
|
+
return bytes;
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
throw new integrity_1.SkillFetchError(integrity_1.SkillFetchErrorCode.STORE_IO, { reason: 'read' });
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Absolute path of a snapshot file.
|
|
289
|
+
*
|
|
290
|
+
* For modules that must hand a path to a streaming reader (#1230 extraction).
|
|
291
|
+
* The result identifies the machine's data root and must never reach an API
|
|
292
|
+
* response, a log line or an error message.
|
|
293
|
+
*
|
|
294
|
+
* @internal
|
|
295
|
+
*/
|
|
296
|
+
function resolveSkillSnapshotPath(snapshotId) {
|
|
297
|
+
return filePathOf(requireRecord(snapshotId));
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Remove expired, unreferenced snapshots and any untracked file in the root.
|
|
301
|
+
*
|
|
302
|
+
* @returns Number of snapshots removed
|
|
303
|
+
*/
|
|
304
|
+
function sweepSkillSnapshots(options = {}) {
|
|
305
|
+
requireRoot();
|
|
306
|
+
const now = options.now ?? Date.now();
|
|
307
|
+
let removed = 0;
|
|
308
|
+
for (const record of [...state.records.values()]) {
|
|
309
|
+
if (record.refCount === 0 && now >= record.expiresAt) {
|
|
310
|
+
removeRecord(record);
|
|
311
|
+
removed += 1;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
purgeOrphanFiles();
|
|
315
|
+
return removed;
|
|
316
|
+
}
|
|
317
|
+
/** Current disk usage in bytes, for quota assertions and diagnostics. */
|
|
318
|
+
function getSkillSnapshotUsage() {
|
|
319
|
+
return { totalBytes: state.totalBytes, count: state.records.size };
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Drop every snapshot and forget the root.
|
|
323
|
+
* @internal
|
|
324
|
+
*/
|
|
325
|
+
function resetSkillSnapshotStoreForTesting() {
|
|
326
|
+
if (state.rootDir && (0, fs_1.existsSync)(state.rootDir)) {
|
|
327
|
+
for (const record of [...state.records.values()]) {
|
|
328
|
+
(0, fs_1.rmSync)(path_1.default.join(state.rootDir, record.filename), { force: true });
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
state.rootDir = null;
|
|
332
|
+
state.records.clear();
|
|
333
|
+
state.totalBytes = 0;
|
|
334
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Startup wiring for Skill operation crash recovery (Issue #1428)
|
|
4
|
+
*
|
|
5
|
+
* #1234 built {@link reconcileSkillOperations} and left the concrete ports it
|
|
6
|
+
* needs — *is the payload on disk?* and *rebuild the index row* — to the layers
|
|
7
|
+
* that own the filesystem and the DB (#1235/#1236). This module is the assembly
|
|
8
|
+
* point those pieces were missing: it constructs the production ports and runs
|
|
9
|
+
* reconciliation, and it is the single function the server startup path calls so
|
|
10
|
+
* that a restart converges every interrupted install/uninstall on one answer.
|
|
11
|
+
*
|
|
12
|
+
* It is deliberately the *only* place the startup ports are assembled. The
|
|
13
|
+
* Phase 1 gap that shipped a never-invoked reconciler happened because the tests
|
|
14
|
+
* imported the library directly and never crossed the startup seam; this
|
|
15
|
+
* function is what both `server.ts` and its test now go through, so a future
|
|
16
|
+
* regression that unwires it fails a test rather than passing silently.
|
|
17
|
+
*
|
|
18
|
+
* Running here also garbage-collects the journal: terminal entries past their
|
|
19
|
+
* retention window are pruned, so the journal directory tracks the operations of
|
|
20
|
+
* one window rather than growing without bound.
|
|
21
|
+
*
|
|
22
|
+
* @module lib/skills/startup-reconcile
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.buildSkillReconcilerPorts = buildSkillReconcilerPorts;
|
|
26
|
+
exports.runSkillStartupReconciliation = runSkillStartupReconciliation;
|
|
27
|
+
const fs_1 = require("fs");
|
|
28
|
+
const path_1 = require("path");
|
|
29
|
+
const db_1 = require("../../lib/db");
|
|
30
|
+
const logger_1 = require("../../lib/logger");
|
|
31
|
+
const integrity_1 = require("../../lib/skills/integrity");
|
|
32
|
+
const install_plan_1 = require("../../lib/skills/install-plan");
|
|
33
|
+
const install_apply_1 = require("../../lib/skills/install-apply");
|
|
34
|
+
const uninstall_apply_1 = require("../../lib/skills/uninstall-apply");
|
|
35
|
+
const installed_state_1 = require("../../lib/skills/installed-state");
|
|
36
|
+
const operation_audit_1 = require("../../lib/skills/operation-audit");
|
|
37
|
+
const operation_journal_1 = require("../../lib/skills/operation-journal");
|
|
38
|
+
const operation_reconciler_1 = require("../../lib/skills/operation-reconciler");
|
|
39
|
+
const reconcileLogger = (0, logger_1.createLogger)('lib/skills/startup-reconcile');
|
|
40
|
+
/**
|
|
41
|
+
* Whether an operation's kind removes payload (uninstall) rather than adding it.
|
|
42
|
+
* `update` re-installs, so it shares the install-side probe and index write.
|
|
43
|
+
*/
|
|
44
|
+
function isRemovalOperation(entry) {
|
|
45
|
+
return entry.operation === 'uninstall';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build the reconciler ports against the real filesystem and database.
|
|
49
|
+
*
|
|
50
|
+
* The reconciler asks one filesystem question and performs one index write per
|
|
51
|
+
* entry; both dispatch on the operation kind because "did it land?" and "rebuild
|
|
52
|
+
* the row" mean opposite things for an install and an uninstall.
|
|
53
|
+
*/
|
|
54
|
+
function buildSkillReconcilerPorts(db, options = {}) {
|
|
55
|
+
const resolveWorktreePath = options.resolveWorktreePath ??
|
|
56
|
+
((worktreeId) => {
|
|
57
|
+
const worktree = (0, db_1.getWorktreeById)(db, worktreeId);
|
|
58
|
+
return worktree ? worktree.path : null;
|
|
59
|
+
});
|
|
60
|
+
return {
|
|
61
|
+
hasCommittedPayload: (entry) => {
|
|
62
|
+
const worktreePath = resolveWorktreePath(entry.target.worktreeId);
|
|
63
|
+
if (worktreePath === null) {
|
|
64
|
+
// The worktree is gone: an install could not have left payload behind,
|
|
65
|
+
// and an uninstall's payload is by definition no longer present.
|
|
66
|
+
return isRemovalOperation(entry);
|
|
67
|
+
}
|
|
68
|
+
return isRemovalOperation(entry)
|
|
69
|
+
? (0, uninstall_apply_1.hasRemovedSkillPayload)(worktreePath, entry.target.skillId, entry.receiptDigest)
|
|
70
|
+
: (0, install_apply_1.hasCommittedSkillPayload)(worktreePath, entry.target.skillId, entry.receiptDigest);
|
|
71
|
+
},
|
|
72
|
+
reindex: (entry) => {
|
|
73
|
+
if (isRemovalOperation(entry)) {
|
|
74
|
+
// The row is dropped by (worktree, skill); no path or receipt is needed,
|
|
75
|
+
// and the delete is idempotent so a replay after a partial pass is safe.
|
|
76
|
+
(0, installed_state_1.deleteSkillInstallation)(db, entry.target.worktreeId, entry.target.skillId);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const worktreePath = resolveWorktreePath(entry.target.worktreeId);
|
|
80
|
+
if (worktreePath === null) {
|
|
81
|
+
throw new Error('worktree path is unavailable for reindex');
|
|
82
|
+
}
|
|
83
|
+
// Converge any secondary root a partial multi-root install did not reach,
|
|
84
|
+
// copying the byte-identical payload forward from the committed primary
|
|
85
|
+
// (#1460). Best-effort: a root blocked by a user file must not stall the
|
|
86
|
+
// index write, which is what actually makes the install visible.
|
|
87
|
+
try {
|
|
88
|
+
(0, install_apply_1.completeSecondarySkillInstallRoots)(worktreePath, (0, fs_1.realpathSync)(worktreePath), entry.target.skillId);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
reconcileLogger.warn('skill-secondary-root-convergence-failed', {
|
|
92
|
+
operationId: entry.operationId,
|
|
93
|
+
error: error instanceof Error ? error.message : String(error),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// The index row is rebuilt from the receipt that actually landed rather
|
|
97
|
+
// than from the journal, which never carried the full receipt. The receipt
|
|
98
|
+
// on disk is the same artifact the user can see, so the row cannot drift
|
|
99
|
+
// from it.
|
|
100
|
+
const installRootAbs = (0, install_apply_1.resolveSkillInstallTarget)(worktreePath, entry.target.skillId);
|
|
101
|
+
const bytes = (0, fs_1.readFileSync)((0, path_1.join)(installRootAbs, install_plan_1.SKILL_RECEIPT_FILENAME));
|
|
102
|
+
const receipt = (0, install_plan_1.parseInstalledReceipt)(bytes);
|
|
103
|
+
if (receipt === null) {
|
|
104
|
+
throw new Error('receipt on disk is unreadable during reindex');
|
|
105
|
+
}
|
|
106
|
+
(0, installed_state_1.upsertSkillInstallation)(db, {
|
|
107
|
+
worktreeId: entry.target.worktreeId,
|
|
108
|
+
receipt,
|
|
109
|
+
receiptSha256: (0, integrity_1.computeSha256Hex)(bytes),
|
|
110
|
+
operationId: entry.operationId,
|
|
111
|
+
installedAt: entry.fsCommittedAt ?? options.now ?? Date.now(),
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
recordAudit: (input) => {
|
|
115
|
+
(0, operation_audit_1.recordSkillOperationAudit)(db, input);
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Converge interrupted Skill operations and collect expired journal entries.
|
|
121
|
+
*
|
|
122
|
+
* Called once at server startup, after migrations (the audit table is
|
|
123
|
+
* migration-owned) and before the server begins accepting requests. Returns the
|
|
124
|
+
* reconciliation report augmented with what retention pruned.
|
|
125
|
+
*/
|
|
126
|
+
function runSkillStartupReconciliation(db, options = {}) {
|
|
127
|
+
const ports = buildSkillReconcilerPorts(db, options);
|
|
128
|
+
const report = (0, operation_reconciler_1.reconcileSkillOperations)(ports, options);
|
|
129
|
+
// Pruning runs after convergence: an entry that just converged to SUCCEEDED
|
|
130
|
+
// has a fresh `updatedAt` and is well inside its window, so this pass only
|
|
131
|
+
// collects entries that were already terminal in an earlier one.
|
|
132
|
+
const prunedKeys = (0, operation_journal_1.pruneExpiredSkillOperationJournal)({
|
|
133
|
+
root: options.root,
|
|
134
|
+
now: options.now,
|
|
135
|
+
retentionMs: options.retentionMs,
|
|
136
|
+
});
|
|
137
|
+
return { ...report, prunedKeys, pruned: prunedKeys.length };
|
|
138
|
+
}
|