commandmate 0.11.4 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +406 -314
- package/.next/app-path-routes-manifest.json +35 -26
- package/.next/build-manifest.json +5 -5
- package/.next/prerender-manifest.json +15 -15
- 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_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.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 +35 -26
- 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 +3 -3
- package/.next/server/chunks/6065.js +1 -0
- package/.next/server/chunks/6130.js +1 -0
- package/.next/server/chunks/6283.js +1 -1
- 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/ZYti9g9gICKnjtmkfvvB2/_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-76295bf0184b101f.js → 6488-624d4b6d2d4cc236.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-7dd929bfc978742e.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/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/cli-tools/antigravity.js +8 -13
- package/dist/server/src/lib/cli-tools/codex.js +8 -14
- package/dist/server/src/lib/cli-tools/copilot.js +12 -13
- package/dist/server/src/lib/cli-tools/gemini.js +8 -13
- package/dist/server/src/lib/cli-tools/opencode.js +8 -13
- package/dist/server/src/lib/cli-tools/submit-verified-sender.js +174 -0
- package/dist/server/src/lib/cli-tools/vibe-local.js +12 -17
- 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/session-key-sender.js +11 -9
- 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/0_lnKsT0DH-MnHhnV5n-l/_buildManifest.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-9a4ce51e697baac6.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/dist/server/src/lib/pasted-text-helper.js +0 -58
- /package/.next/static/{0_lnKsT0DH-MnHhnV5n-l → ZYti9g9gICKnjtmkfvvB2}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Deleting exactly the files CommandMate wrote, and nothing else (Issue #1236)
|
|
4
|
+
*
|
|
5
|
+
* The delete half of the plan/apply pair, and the only module in the codebase
|
|
6
|
+
* that removes Skill payload from a repository. #1235's install could rely on a
|
|
7
|
+
* single atomic rename for its safety argument; deletion has no such primitive,
|
|
8
|
+
* so the argument here is built from four rules instead:
|
|
9
|
+
*
|
|
10
|
+
* - **Zero-delete on ambiguity.** The whole install root is re-assessed before
|
|
11
|
+
* the first `unlink`. One modified, unknown, missing or irregular path and the
|
|
12
|
+
* operation stops having deleted nothing. There is no partial uninstall —
|
|
13
|
+
* "removed seven of eight files" is a corrupted Skill reported as a success.
|
|
14
|
+
* - **The destination is derived, never received.** The install root comes from
|
|
15
|
+
* the server-resolved worktree path plus a Skill ID re-checked against
|
|
16
|
+
* {@link SKILL_ID_PATTERN}, using #1233's resolver — the same derivation
|
|
17
|
+
* install uses, because a delete that resolved its target differently from the
|
|
18
|
+
* write that created it would eventually resolve it somewhere else entirely.
|
|
19
|
+
* - **Nothing is followed.** Every path component from the install root down is
|
|
20
|
+
* `lstat`ed immediately before the file it leads to is unlinked, so a symlink
|
|
21
|
+
* swapped in after the scan is refused rather than traversed. `unlink` itself
|
|
22
|
+
* never follows its final component, so the directory chain is the exposure.
|
|
23
|
+
* - **Directories go only when empty.** `rmdir(2)` is used, never a recursive
|
|
24
|
+
* remove, and only on directories the receipt's own file list implies. An
|
|
25
|
+
* empty directory the user made is not ours to collect.
|
|
26
|
+
*
|
|
27
|
+
* The receipt is deleted **last**. Until it is gone the directory still explains
|
|
28
|
+
* itself: a crash mid-delete leaves a worktree that #1234 reconciliation — and a
|
|
29
|
+
* human reading `.commandmate-receipt.json` — can still make sense of.
|
|
30
|
+
*
|
|
31
|
+
* @module lib/skills/uninstall-apply
|
|
32
|
+
*/
|
|
33
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
34
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
35
|
+
};
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.SkillUninstallError = exports.SKILL_UNINSTALL_ERROR_STATUS = exports.SkillUninstallErrorCode = void 0;
|
|
38
|
+
exports.isSkillUninstallError = isSkillUninstallError;
|
|
39
|
+
exports.resolveSkillUninstallTarget = resolveSkillUninstallTarget;
|
|
40
|
+
exports.resolveSkillUninstallTargetFor = resolveSkillUninstallTargetFor;
|
|
41
|
+
exports.assertSkillUninstallAncestors = assertSkillUninstallAncestors;
|
|
42
|
+
exports.removeReceiptOwnedFile = removeReceiptOwnedFile;
|
|
43
|
+
exports.applySkillUninstall = applySkillUninstall;
|
|
44
|
+
exports.hasRemovedSkillPayload = hasRemovedSkillPayload;
|
|
45
|
+
const fs_1 = require("fs");
|
|
46
|
+
const path_1 = __importDefault(require("path"));
|
|
47
|
+
const constants_1 = require("../../lib/skills/constants");
|
|
48
|
+
const integrity_1 = require("../../lib/skills/integrity");
|
|
49
|
+
const install_plan_1 = require("../../lib/skills/install-plan");
|
|
50
|
+
const preview_diff_1 = require("../../lib/skills/preview-diff");
|
|
51
|
+
const uninstall_plan_1 = require("../../lib/skills/uninstall-plan");
|
|
52
|
+
// =============================================================================
|
|
53
|
+
// Errors
|
|
54
|
+
// =============================================================================
|
|
55
|
+
/** Client-safe reasons an uninstall refused to delete or could not finish. */
|
|
56
|
+
exports.SkillUninstallErrorCode = {
|
|
57
|
+
/** The install root could not be derived safely from the worktree and Skill ID. */
|
|
58
|
+
TARGET_UNSAFE: 'SKILL_UNINSTALL_TARGET_UNSAFE',
|
|
59
|
+
/** An ancestor of the install root is a symlink or is not a directory. */
|
|
60
|
+
ANCESTOR_UNSAFE: 'SKILL_UNINSTALL_ANCESTOR_UNSAFE',
|
|
61
|
+
/** There is nothing to uninstall at the target. */
|
|
62
|
+
NOT_INSTALLED: 'SKILL_UNINSTALL_NOT_INSTALLED',
|
|
63
|
+
/** At least one path is not provably managed and unchanged. Nothing was deleted. */
|
|
64
|
+
BLOCKED: 'SKILL_UNINSTALL_BLOCKED',
|
|
65
|
+
/** The install root changed between the plan and this apply. Nothing was deleted. */
|
|
66
|
+
DRIFT: 'SKILL_UNINSTALL_DRIFT',
|
|
67
|
+
/** A file changed between the re-assessment and its own delete. */
|
|
68
|
+
FILE_CHANGED: 'SKILL_UNINSTALL_FILE_CHANGED',
|
|
69
|
+
/** A path or one of its ancestors is not what it was when it was scanned. */
|
|
70
|
+
PATH_UNSAFE: 'SKILL_UNINSTALL_PATH_UNSAFE',
|
|
71
|
+
/** The delete syscall itself failed. */
|
|
72
|
+
DELETE_FAILED: 'SKILL_UNINSTALL_DELETE_FAILED',
|
|
73
|
+
};
|
|
74
|
+
/** HTTP status each reason maps to, so every caller answers alike. */
|
|
75
|
+
exports.SKILL_UNINSTALL_ERROR_STATUS = {
|
|
76
|
+
[exports.SkillUninstallErrorCode.TARGET_UNSAFE]: 400,
|
|
77
|
+
[exports.SkillUninstallErrorCode.ANCESTOR_UNSAFE]: 409,
|
|
78
|
+
[exports.SkillUninstallErrorCode.NOT_INSTALLED]: 404,
|
|
79
|
+
[exports.SkillUninstallErrorCode.BLOCKED]: 409,
|
|
80
|
+
[exports.SkillUninstallErrorCode.DRIFT]: 409,
|
|
81
|
+
[exports.SkillUninstallErrorCode.FILE_CHANGED]: 409,
|
|
82
|
+
[exports.SkillUninstallErrorCode.PATH_UNSAFE]: 409,
|
|
83
|
+
[exports.SkillUninstallErrorCode.DELETE_FAILED]: 500,
|
|
84
|
+
};
|
|
85
|
+
/** An uninstall rejection. The message is built from the code — never from a path. */
|
|
86
|
+
class SkillUninstallError extends Error {
|
|
87
|
+
code;
|
|
88
|
+
detail;
|
|
89
|
+
blockers;
|
|
90
|
+
constructor(code, detail,
|
|
91
|
+
/** Repository-relative paths that blocked the operation, for UX-07. */
|
|
92
|
+
blockers = []) {
|
|
93
|
+
super(`Skill uninstall rejected: ${code}`);
|
|
94
|
+
this.code = code;
|
|
95
|
+
this.detail = detail;
|
|
96
|
+
this.blockers = blockers;
|
|
97
|
+
this.name = 'SkillUninstallError';
|
|
98
|
+
}
|
|
99
|
+
get status() {
|
|
100
|
+
return exports.SKILL_UNINSTALL_ERROR_STATUS[this.code];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
exports.SkillUninstallError = SkillUninstallError;
|
|
104
|
+
function isSkillUninstallError(value) {
|
|
105
|
+
return value instanceof SkillUninstallError;
|
|
106
|
+
}
|
|
107
|
+
function fail(code, detail, blockers = []) {
|
|
108
|
+
throw new SkillUninstallError(code, detail, blockers);
|
|
109
|
+
}
|
|
110
|
+
// =============================================================================
|
|
111
|
+
// Path safety
|
|
112
|
+
// =============================================================================
|
|
113
|
+
/**
|
|
114
|
+
* Absolute install root for a validated Skill ID inside a server-resolved worktree.
|
|
115
|
+
*
|
|
116
|
+
* Delegates to #1233's resolver — the same one {@link resolveSkillInstallTarget}
|
|
117
|
+
* uses — and re-checks the ID grammar here as well, because `path.join`
|
|
118
|
+
* normalizes `..` away and a containment check alone would accept an ID that
|
|
119
|
+
* walked out of the Skills directory.
|
|
120
|
+
*/
|
|
121
|
+
function resolveSkillUninstallTarget(worktreePath, skillId) {
|
|
122
|
+
return resolveSkillUninstallTargetFor(worktreePath, constants_1.SKILL_INSTALL_ROOT_PREFIX, skillId);
|
|
123
|
+
}
|
|
124
|
+
/** Absolute install root for a Skill ID under one root prefix (#1460). */
|
|
125
|
+
function resolveSkillUninstallTargetFor(worktreePath, rootPrefix, skillId) {
|
|
126
|
+
if (!constants_1.SKILL_ID_PATTERN.test(skillId) || skillId.length > constants_1.SKILL_ID_MAX_LENGTH) {
|
|
127
|
+
fail(exports.SkillUninstallErrorCode.TARGET_UNSAFE, { reason: 'skill-id' });
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
return (0, preview_diff_1.resolveSkillInstallRootFor)(worktreePath, rootPrefix, skillId);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return fail(exports.SkillUninstallErrorCode.TARGET_UNSAFE, { reason: 'install-root' });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Prove no ancestor of the install root was swapped for a link.
|
|
138
|
+
*
|
|
139
|
+
* `lstat` at every level from the worktree down. `realpath` alone would silently
|
|
140
|
+
* *follow* a swapped ancestor and delete under whatever it pointed at, which is
|
|
141
|
+
* precisely the failure this whole module exists to make unrepresentable.
|
|
142
|
+
*/
|
|
143
|
+
function assertSkillUninstallAncestors(worktreeRealPath, worktreePath, rootPrefix = constants_1.SKILL_INSTALL_ROOT_PREFIX) {
|
|
144
|
+
let resolved;
|
|
145
|
+
try {
|
|
146
|
+
resolved = (0, fs_1.realpathSync)(worktreePath);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return fail(exports.SkillUninstallErrorCode.ANCESTOR_UNSAFE, { reason: 'worktree-unresolvable' });
|
|
150
|
+
}
|
|
151
|
+
if (resolved !== worktreeRealPath) {
|
|
152
|
+
fail(exports.SkillUninstallErrorCode.ANCESTOR_UNSAFE, { reason: 'worktree-identity' });
|
|
153
|
+
}
|
|
154
|
+
let walked = worktreeRealPath;
|
|
155
|
+
for (const segment of rootPrefix.split('/')) {
|
|
156
|
+
walked = path_1.default.join(walked, segment);
|
|
157
|
+
let stats;
|
|
158
|
+
try {
|
|
159
|
+
stats = (0, fs_1.lstatSync)(walked);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Absent is fine: there is then nothing under it to delete.
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (stats.isSymbolicLink() || !stats.isDirectory()) {
|
|
166
|
+
fail(exports.SkillUninstallErrorCode.ANCESTOR_UNSAFE, { reason: 'not-a-directory' });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Reject a receipt-recorded path that is not a plain relative path.
|
|
172
|
+
*
|
|
173
|
+
* The receipt is a file inside a repository, so it is data the user could have
|
|
174
|
+
* edited even though CommandMate wrote it. Its `files` entries name what gets
|
|
175
|
+
* unlinked, and are therefore validated here rather than trusted.
|
|
176
|
+
*/
|
|
177
|
+
function assertSafeRelativePath(relativePath) {
|
|
178
|
+
if (relativePath.length === 0 ||
|
|
179
|
+
relativePath.includes('\0') ||
|
|
180
|
+
relativePath.includes('\\') ||
|
|
181
|
+
path_1.default.posix.isAbsolute(relativePath) ||
|
|
182
|
+
path_1.default.win32.isAbsolute(relativePath)) {
|
|
183
|
+
fail(exports.SkillUninstallErrorCode.PATH_UNSAFE, { reason: 'grammar' });
|
|
184
|
+
}
|
|
185
|
+
for (const segment of relativePath.split('/')) {
|
|
186
|
+
if (segment === '' || segment === '.' || segment === '..') {
|
|
187
|
+
fail(exports.SkillUninstallErrorCode.PATH_UNSAFE, { reason: 'segment' });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* `lstat` every directory from the install root down to the file's parent.
|
|
193
|
+
*
|
|
194
|
+
* Run immediately before each `unlink`, not once per operation: the exclusive
|
|
195
|
+
* lock keeps CommandMate out, but nothing stops the user's own tooling from
|
|
196
|
+
* replacing a directory with a link while the deletes are running.
|
|
197
|
+
*/
|
|
198
|
+
function assertDirectoryChainIsReal(installRootAbs, relativePath) {
|
|
199
|
+
let walked = installRootAbs;
|
|
200
|
+
const segments = relativePath.split('/').slice(0, -1);
|
|
201
|
+
for (let index = 0; index <= segments.length; index += 1) {
|
|
202
|
+
if (index > 0)
|
|
203
|
+
walked = path_1.default.join(walked, segments[index - 1]);
|
|
204
|
+
let stats;
|
|
205
|
+
try {
|
|
206
|
+
stats = (0, fs_1.lstatSync)(walked);
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return fail(exports.SkillUninstallErrorCode.PATH_UNSAFE, { reason: 'ancestor-missing' });
|
|
210
|
+
}
|
|
211
|
+
if (stats.isSymbolicLink() || !stats.isDirectory()) {
|
|
212
|
+
fail(exports.SkillUninstallErrorCode.PATH_UNSAFE, { reason: 'ancestor-not-a-directory' });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Delete one receipt-owned file, having just proved it is still that file.
|
|
218
|
+
*
|
|
219
|
+
* The digest is re-read here even though the assessment already checked it, for
|
|
220
|
+
* the same reason install re-reads what it wrote: the assessment is evidence
|
|
221
|
+
* about a moment that has passed, and the only claim worth making about a delete
|
|
222
|
+
* is one established immediately before the syscall.
|
|
223
|
+
*
|
|
224
|
+
* @internal Exported for the guard tests; callers use {@link applySkillUninstall}.
|
|
225
|
+
* @throws SkillUninstallError — the file was not deleted in every case.
|
|
226
|
+
*/
|
|
227
|
+
function removeReceiptOwnedFile(installRootAbs, relativePath, expected) {
|
|
228
|
+
assertSafeRelativePath(relativePath);
|
|
229
|
+
assertDirectoryChainIsReal(installRootAbs, relativePath);
|
|
230
|
+
const absolute = path_1.default.join(installRootAbs, relativePath);
|
|
231
|
+
if (path_1.default.relative(installRootAbs, absolute) !== relativePath.split('/').join(path_1.default.sep)) {
|
|
232
|
+
fail(exports.SkillUninstallErrorCode.PATH_UNSAFE, { reason: 'containment' });
|
|
233
|
+
}
|
|
234
|
+
let stats;
|
|
235
|
+
try {
|
|
236
|
+
stats = (0, fs_1.lstatSync)(absolute);
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return fail(exports.SkillUninstallErrorCode.FILE_CHANGED, { reason: 'vanished' });
|
|
240
|
+
}
|
|
241
|
+
if (stats.isSymbolicLink() || !stats.isFile()) {
|
|
242
|
+
fail(exports.SkillUninstallErrorCode.PATH_UNSAFE, { reason: 'not-a-regular-file' });
|
|
243
|
+
}
|
|
244
|
+
// A hard link means the same inode is reachable from somewhere we did not
|
|
245
|
+
// scan, so the receipt cannot claim sole ownership of this content.
|
|
246
|
+
if (stats.nlink !== 1) {
|
|
247
|
+
fail(exports.SkillUninstallErrorCode.PATH_UNSAFE, { reason: 'hard-linked' });
|
|
248
|
+
}
|
|
249
|
+
if (((stats.mode & 0o111) !== 0) !== expected.executable) {
|
|
250
|
+
fail(exports.SkillUninstallErrorCode.FILE_CHANGED, { reason: 'mode' });
|
|
251
|
+
}
|
|
252
|
+
let bytes;
|
|
253
|
+
try {
|
|
254
|
+
bytes = (0, fs_1.readFileSync)(absolute);
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
return fail(exports.SkillUninstallErrorCode.FILE_CHANGED, { reason: 'unreadable' });
|
|
258
|
+
}
|
|
259
|
+
if (!(0, integrity_1.digestMatches)((0, integrity_1.computeSha256Hex)(bytes), expected.sha256)) {
|
|
260
|
+
fail(exports.SkillUninstallErrorCode.FILE_CHANGED, { reason: 'digest' });
|
|
261
|
+
}
|
|
262
|
+
try {
|
|
263
|
+
(0, fs_1.unlinkSync)(absolute);
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
return fail(exports.SkillUninstallErrorCode.DELETE_FAILED, { reason: 'unlink' });
|
|
267
|
+
}
|
|
268
|
+
return bytes.byteLength;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Remove a directory only if it is empty.
|
|
272
|
+
*
|
|
273
|
+
* `rmdir(2)` refuses a non-empty directory, so the emptiness check and the
|
|
274
|
+
* removal are one indivisible step rather than a scan followed by a delete that
|
|
275
|
+
* could act on a directory something was written into meanwhile.
|
|
276
|
+
*
|
|
277
|
+
* @returns whether the directory was removed
|
|
278
|
+
*/
|
|
279
|
+
function removeIfEmpty(directoryAbs) {
|
|
280
|
+
let stats;
|
|
281
|
+
try {
|
|
282
|
+
stats = (0, fs_1.lstatSync)(directoryAbs);
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
if (stats.isSymbolicLink() || !stats.isDirectory())
|
|
288
|
+
return false;
|
|
289
|
+
try {
|
|
290
|
+
(0, fs_1.rmdirSync)(directoryAbs);
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Directories the receipt's file list implies, deepest first.
|
|
299
|
+
*
|
|
300
|
+
* Derived from the receipt rather than from a directory walk on purpose: an
|
|
301
|
+
* empty directory the user created inside the install root is not something the
|
|
302
|
+
* install put there, and collecting it would be a deletion nobody asked for.
|
|
303
|
+
*/
|
|
304
|
+
function directoriesImpliedByReceipt(relativePaths) {
|
|
305
|
+
const directories = new Set();
|
|
306
|
+
for (const relative of relativePaths) {
|
|
307
|
+
const segments = relative.split('/').slice(0, -1);
|
|
308
|
+
let walked = '';
|
|
309
|
+
for (const segment of segments) {
|
|
310
|
+
walked = walked === '' ? segment : `${walked}/${segment}`;
|
|
311
|
+
directories.add(walked);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return [...directories].sort((a, b) => b.split('/').length - a.split('/').length || (a < b ? 1 : -1));
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Verify and delete one Skill install.
|
|
318
|
+
*
|
|
319
|
+
* Everything before {@link SkillUninstallApplyInput.onCommitPoint} is a read:
|
|
320
|
+
* on any rejection the worktree is byte-for-byte what it was. After it, files
|
|
321
|
+
* are gone and a failure is reported as *committed, reconciling* — the receipt
|
|
322
|
+
* survives until last precisely so that state remains explainable.
|
|
323
|
+
*
|
|
324
|
+
* @throws SkillUninstallError
|
|
325
|
+
*/
|
|
326
|
+
function applySkillUninstall(input) {
|
|
327
|
+
// The primary root anchors the plan: its receipt names every root, and its
|
|
328
|
+
// tree hash and receipt digest are what the plan bound the token to.
|
|
329
|
+
const primaryAbs = resolveSkillUninstallTarget(input.worktreePath, input.skillId);
|
|
330
|
+
assertSkillUninstallAncestors(input.worktreeRealPath, input.worktreePath);
|
|
331
|
+
const primary = (0, uninstall_plan_1.assessSkillUninstall)(primaryAbs, input.skillId, {
|
|
332
|
+
existing: (0, preview_diff_1.readExistingSkillTree)(primaryAbs),
|
|
333
|
+
});
|
|
334
|
+
if (!primary.present) {
|
|
335
|
+
fail(exports.SkillUninstallErrorCode.NOT_INSTALLED, undefined, primary.blockers);
|
|
336
|
+
}
|
|
337
|
+
if (!primary.removable || primary.receipt === null) {
|
|
338
|
+
fail(exports.SkillUninstallErrorCode.BLOCKED, undefined, primary.blockers);
|
|
339
|
+
}
|
|
340
|
+
if (primary.currentTreeHash !== input.expectedTreeHash) {
|
|
341
|
+
fail(exports.SkillUninstallErrorCode.DRIFT, { reason: 'tree-hash' });
|
|
342
|
+
}
|
|
343
|
+
const receipt = primary.receipt;
|
|
344
|
+
const receiptDigest = primary.receiptDigest;
|
|
345
|
+
if (receiptDigest === null || !(0, integrity_1.digestMatches)(receiptDigest, input.expectedReceiptDigest)) {
|
|
346
|
+
fail(exports.SkillUninstallErrorCode.DRIFT, { reason: 'receipt-digest' });
|
|
347
|
+
}
|
|
348
|
+
// Resolve and assess every recorded root before deleting anything (#1460). An
|
|
349
|
+
// absent root is already gone and skipped; any present root that is not
|
|
350
|
+
// provably managed-and-unchanged blocks the whole operation, so "zero-delete
|
|
351
|
+
// on ambiguity" holds across roots, not just within one.
|
|
352
|
+
const installRoots = (0, install_plan_1.receiptInstallRoots)(receipt);
|
|
353
|
+
const planned = [];
|
|
354
|
+
for (const rootRel of installRoots) {
|
|
355
|
+
const rootPrefix = rootRel.slice(0, Math.max(0, rootRel.length - input.skillId.length - 1));
|
|
356
|
+
const abs = rootPrefix === constants_1.SKILL_INSTALL_ROOT_PREFIX
|
|
357
|
+
? primaryAbs
|
|
358
|
+
: resolveSkillUninstallTargetFor(input.worktreePath, rootPrefix, input.skillId);
|
|
359
|
+
assertSkillUninstallAncestors(input.worktreeRealPath, input.worktreePath, rootPrefix);
|
|
360
|
+
const assessment = rootPrefix === constants_1.SKILL_INSTALL_ROOT_PREFIX
|
|
361
|
+
? primary
|
|
362
|
+
: (0, uninstall_plan_1.assessSkillUninstall)(abs, input.skillId, {
|
|
363
|
+
existing: (0, preview_diff_1.readExistingSkillTree)(abs),
|
|
364
|
+
rootPrefix,
|
|
365
|
+
});
|
|
366
|
+
// A recorded root already removed is not an error: convergence may have
|
|
367
|
+
// deleted it, or a legacy single-root receipt never wrote it.
|
|
368
|
+
if (!assessment.present)
|
|
369
|
+
continue;
|
|
370
|
+
if (!assessment.removable || assessment.receipt === null) {
|
|
371
|
+
fail(exports.SkillUninstallErrorCode.BLOCKED, undefined, assessment.blockers);
|
|
372
|
+
}
|
|
373
|
+
// Every root holds the byte-identical payload, so each must match the same
|
|
374
|
+
// tree hash and receipt digest the plan bound; anything else is drift.
|
|
375
|
+
if (assessment.currentTreeHash !== input.expectedTreeHash) {
|
|
376
|
+
fail(exports.SkillUninstallErrorCode.DRIFT, { reason: 'tree-hash' });
|
|
377
|
+
}
|
|
378
|
+
if (assessment.receiptDigest === null ||
|
|
379
|
+
!(0, integrity_1.digestMatches)(assessment.receiptDigest, input.expectedReceiptDigest)) {
|
|
380
|
+
fail(exports.SkillUninstallErrorCode.DRIFT, { reason: 'receipt-digest' });
|
|
381
|
+
}
|
|
382
|
+
planned.push({ abs, assessment });
|
|
383
|
+
}
|
|
384
|
+
input.onCommitPoint?.();
|
|
385
|
+
const removedFiles = [];
|
|
386
|
+
const removedDirectories = [];
|
|
387
|
+
const retained = [];
|
|
388
|
+
let allFullyRemoved = true;
|
|
389
|
+
let primaryReceiptRemoved = false;
|
|
390
|
+
for (const { abs, assessment } of planned) {
|
|
391
|
+
const removed = deleteSkillInstallRoot(abs, assessment, receiptDigest);
|
|
392
|
+
removedFiles.push(...removed.removedFiles);
|
|
393
|
+
removedDirectories.push(...removed.removedDirectories);
|
|
394
|
+
retained.push(...removed.retained);
|
|
395
|
+
if (!removed.fullyRemoved)
|
|
396
|
+
allFullyRemoved = false;
|
|
397
|
+
if (abs === primaryAbs)
|
|
398
|
+
primaryReceiptRemoved = removed.receiptRemoved;
|
|
399
|
+
}
|
|
400
|
+
return {
|
|
401
|
+
installRoot: primary.installRoot,
|
|
402
|
+
installRoots,
|
|
403
|
+
version: receipt.version,
|
|
404
|
+
removedFiles,
|
|
405
|
+
removedDirectories,
|
|
406
|
+
retained,
|
|
407
|
+
receiptRemoved: primaryReceiptRemoved,
|
|
408
|
+
fullyRemoved: allFullyRemoved,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
/** Delete every managed file in one root, receipt last. All checks already passed. */
|
|
412
|
+
function deleteSkillInstallRoot(installRootAbs, assessment, receiptDigest) {
|
|
413
|
+
const payload = assessment.entries.filter((entry) => entry.disposition === 'remove' && !entry.generated);
|
|
414
|
+
const removedFiles = [];
|
|
415
|
+
for (const entry of payload) {
|
|
416
|
+
const size = removeReceiptOwnedFile(installRootAbs, entry.relativePath, {
|
|
417
|
+
sha256: entry.recordedSha256,
|
|
418
|
+
executable: entry.executable,
|
|
419
|
+
});
|
|
420
|
+
removedFiles.push({ path: entry.path, sha256: entry.recordedSha256, size });
|
|
421
|
+
}
|
|
422
|
+
const removedDirectories = [];
|
|
423
|
+
for (const relative of directoriesImpliedByReceipt(payload.map((entry) => entry.relativePath))) {
|
|
424
|
+
if (removeIfEmpty(path_1.default.join(installRootAbs, relative))) {
|
|
425
|
+
removedDirectories.push(`${assessment.installRoot}/${relative}`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
// Last, so that up to this point the directory still says what it is.
|
|
429
|
+
const receiptEntry = assessment.entries.find((entry) => entry.generated);
|
|
430
|
+
if (receiptEntry) {
|
|
431
|
+
const size = removeReceiptOwnedFile(installRootAbs, install_plan_1.SKILL_RECEIPT_FILENAME, {
|
|
432
|
+
sha256: receiptDigest,
|
|
433
|
+
executable: false,
|
|
434
|
+
});
|
|
435
|
+
removedFiles.push({
|
|
436
|
+
path: `${assessment.installRoot}/${install_plan_1.SKILL_RECEIPT_FILENAME}`,
|
|
437
|
+
sha256: receiptDigest,
|
|
438
|
+
size,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
const fullyRemoved = removeIfEmpty(installRootAbs);
|
|
442
|
+
const retained = fullyRemoved ? [] : listRetainedPaths(installRootAbs, assessment.installRoot);
|
|
443
|
+
return {
|
|
444
|
+
removedFiles,
|
|
445
|
+
removedDirectories,
|
|
446
|
+
retained,
|
|
447
|
+
receiptRemoved: receiptEntry !== undefined,
|
|
448
|
+
fullyRemoved,
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Name what is still inside the install root.
|
|
453
|
+
*
|
|
454
|
+
* Only reached when the root would not collect, which after a fail-closed
|
|
455
|
+
* assessment means something appeared during the delete. The user is told the
|
|
456
|
+
* paths rather than that "uninstall partially failed" (UX-07).
|
|
457
|
+
*/
|
|
458
|
+
function listRetainedPaths(installRootAbs, installRoot) {
|
|
459
|
+
let entries;
|
|
460
|
+
try {
|
|
461
|
+
entries = (0, fs_1.readdirSync)(installRootAbs);
|
|
462
|
+
}
|
|
463
|
+
catch {
|
|
464
|
+
return [];
|
|
465
|
+
}
|
|
466
|
+
return entries.map((name) => ({
|
|
467
|
+
path: `${installRoot}/${name}`,
|
|
468
|
+
reason: 'SKILL_UNINSTALL_UNMANAGED_FILE',
|
|
469
|
+
messageKey: 'skills.uninstall.reason.unmanagedFile',
|
|
470
|
+
}));
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Whether the payload a committed uninstall removed is really gone.
|
|
474
|
+
*
|
|
475
|
+
* The uninstall counterpart of `hasCommittedSkillPayload`: #1234's reconciler
|
|
476
|
+
* asks whether the filesystem side of an operation landed, and for a delete
|
|
477
|
+
* that means the receipt no longer names this install.
|
|
478
|
+
*/
|
|
479
|
+
function hasRemovedSkillPayload(worktreePath, skillId, receiptDigest) {
|
|
480
|
+
let installRootAbs;
|
|
481
|
+
try {
|
|
482
|
+
installRootAbs = resolveSkillUninstallTarget(worktreePath, skillId);
|
|
483
|
+
}
|
|
484
|
+
catch {
|
|
485
|
+
return true;
|
|
486
|
+
}
|
|
487
|
+
let bytes;
|
|
488
|
+
try {
|
|
489
|
+
bytes = (0, fs_1.readFileSync)(path_1.default.join(installRootAbs, install_plan_1.SKILL_RECEIPT_FILENAME));
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
return true;
|
|
493
|
+
}
|
|
494
|
+
return receiptDigest !== null && !(0, integrity_1.digestMatches)((0, integrity_1.computeSha256Hex)(bytes), receiptDigest);
|
|
495
|
+
}
|