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,495 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Strict tar.gz table reader for Skill packages (Issue #1230)
|
|
4
|
+
*
|
|
5
|
+
* Reads a verified artifact snapshot (#1229) into an in-memory entry table.
|
|
6
|
+
* Nothing is written to disk here and no archive library is used: a
|
|
7
|
+
* general-purpose extractor decides for itself what a symlink, a hardlink or a
|
|
8
|
+
* `..` component means, and those decisions are exactly the ones that have to
|
|
9
|
+
* be ours.
|
|
10
|
+
*
|
|
11
|
+
* The reader parses *every* entry before returning, so a package is judged as a
|
|
12
|
+
* whole. One forbidden entry rejects the package rather than being skipped,
|
|
13
|
+
* which is what stops a partially-trusted payload from reaching a consumer.
|
|
14
|
+
*
|
|
15
|
+
* Only `ustar` regular files and directories are accepted. Symlinks, hardlinks,
|
|
16
|
+
* devices, FIFOs, sockets, sparse/contiguous files and pax/GNU extension
|
|
17
|
+
* records are refused by type, before their content is looked at. Ownership,
|
|
18
|
+
* timestamps and permission metadata are read only to *reject* setuid/setgid/
|
|
19
|
+
* sticky entries; nothing from the archive is ever applied to the filesystem.
|
|
20
|
+
*
|
|
21
|
+
* @module lib/skills/package-reader
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.SkillPackageError = exports.SkillPackageErrorCode = exports.SKILL_PACKAGE_MAX_ENTRIES = exports.SKILL_PACKAGE_RATIO_FLOOR_BYTES = exports.SKILL_PACKAGE_MAX_COMPRESSION_RATIO = exports.SKILL_PACKAGE_MAX_DECOMPRESSED_BYTES = exports.TAR_BLOCK_SIZE = void 0;
|
|
25
|
+
exports.isSkillPackageError = isSkillPackageError;
|
|
26
|
+
exports.encodeEntryPathForError = encodeEntryPathForError;
|
|
27
|
+
exports.readSkillPackage = readSkillPackage;
|
|
28
|
+
const zlib_1 = require("zlib");
|
|
29
|
+
const skills_1 = require("../../lib/skills");
|
|
30
|
+
const integrity_1 = require("../../lib/skills/integrity");
|
|
31
|
+
// =============================================================================
|
|
32
|
+
// Limits
|
|
33
|
+
// =============================================================================
|
|
34
|
+
/** Fixed tar block size. */
|
|
35
|
+
exports.TAR_BLOCK_SIZE = 512;
|
|
36
|
+
/** Hard cap on the decompressed archive, independent of the compressed size. */
|
|
37
|
+
exports.SKILL_PACKAGE_MAX_DECOMPRESSED_BYTES = 64 * 1024 * 1024;
|
|
38
|
+
/** Maximum decompressed-to-compressed ratio tolerated above the floor below. */
|
|
39
|
+
exports.SKILL_PACKAGE_MAX_COMPRESSION_RATIO = 200;
|
|
40
|
+
/**
|
|
41
|
+
* Ratio checking starts here.
|
|
42
|
+
*
|
|
43
|
+
* Tar pads every entry to 512 bytes and those pad bytes are zeros, so a small
|
|
44
|
+
* legitimate package compresses at a ratio a bomb would also show. Below this
|
|
45
|
+
* size the absolute caps are the meaningful guard.
|
|
46
|
+
*/
|
|
47
|
+
exports.SKILL_PACKAGE_RATIO_FLOOR_BYTES = 1024 * 1024;
|
|
48
|
+
/** Maximum number of archive entries, directories included. */
|
|
49
|
+
exports.SKILL_PACKAGE_MAX_ENTRIES = 1000;
|
|
50
|
+
// =============================================================================
|
|
51
|
+
// Error vocabulary
|
|
52
|
+
// =============================================================================
|
|
53
|
+
/**
|
|
54
|
+
* Stable reason codes for a rejected package.
|
|
55
|
+
*
|
|
56
|
+
* Shared with `package-validator` so a caller sees one vocabulary from
|
|
57
|
+
* decompression through materialization.
|
|
58
|
+
*/
|
|
59
|
+
exports.SkillPackageErrorCode = {
|
|
60
|
+
/** Bytes are not a readable gzip/ustar stream. */
|
|
61
|
+
ARCHIVE_FORMAT: 'SKILL_PACKAGE_ARCHIVE_FORMAT',
|
|
62
|
+
/** Archive ends in the middle of an entry. */
|
|
63
|
+
ARCHIVE_TRUNCATED: 'SKILL_PACKAGE_ARCHIVE_TRUNCATED',
|
|
64
|
+
/** Entry is not a regular file or a directory. */
|
|
65
|
+
ENTRY_TYPE_FORBIDDEN: 'SKILL_PACKAGE_ENTRY_TYPE_FORBIDDEN',
|
|
66
|
+
/** Entry path escapes the package root or is otherwise unsafe. */
|
|
67
|
+
ENTRY_PATH_UNSAFE: 'SKILL_PACKAGE_ENTRY_PATH_UNSAFE',
|
|
68
|
+
/** The same path appears twice. */
|
|
69
|
+
ENTRY_DUPLICATE: 'SKILL_PACKAGE_ENTRY_DUPLICATE',
|
|
70
|
+
/** Two paths differ only by case or Unicode form. */
|
|
71
|
+
ENTRY_COLLISION: 'SKILL_PACKAGE_ENTRY_COLLISION',
|
|
72
|
+
/** Entry carries setuid, setgid or sticky bits. */
|
|
73
|
+
ENTRY_MODE_FORBIDDEN: 'SKILL_PACKAGE_ENTRY_MODE_FORBIDDEN',
|
|
74
|
+
/** Archive holds more entries than the contract allows. */
|
|
75
|
+
ENTRY_LIMIT_EXCEEDED: 'SKILL_PACKAGE_ENTRY_LIMIT_EXCEEDED',
|
|
76
|
+
/** A single file or the whole payload exceeds its size cap. */
|
|
77
|
+
SIZE_LIMIT_EXCEEDED: 'SKILL_PACKAGE_SIZE_LIMIT_EXCEEDED',
|
|
78
|
+
/** Decompression ratio is outside the tolerated band. */
|
|
79
|
+
COMPRESSION_RATIO_EXCEEDED: 'SKILL_PACKAGE_COMPRESSION_RATIO_EXCEEDED',
|
|
80
|
+
/** Root layout, required entries or the package root directory are wrong. */
|
|
81
|
+
LAYOUT_INVALID: 'SKILL_PACKAGE_LAYOUT_INVALID',
|
|
82
|
+
/** Manifest is absent, or a second manifest is smuggled in a subdirectory. */
|
|
83
|
+
MANIFEST_MISSING: 'SKILL_PACKAGE_MANIFEST_MISSING',
|
|
84
|
+
/** Manifest does not parse or does not satisfy the #1228 contract. */
|
|
85
|
+
MANIFEST_INVALID: 'SKILL_PACKAGE_MANIFEST_INVALID',
|
|
86
|
+
/** Manifest disagrees with the package or with the Catalog coordinates. */
|
|
87
|
+
MANIFEST_MISMATCH: 'SKILL_PACKAGE_MANIFEST_MISMATCH',
|
|
88
|
+
/** A payload file carries the executable bit without declaring it. */
|
|
89
|
+
UNDECLARED_EXECUTABLE: 'SKILL_PACKAGE_UNDECLARED_EXECUTABLE',
|
|
90
|
+
/** A payload file is a script without declaring it. */
|
|
91
|
+
UNDECLARED_SCRIPT: 'SKILL_PACKAGE_UNDECLARED_SCRIPT',
|
|
92
|
+
/** A payload file's digest differs from the declared one. */
|
|
93
|
+
DIGEST_MISMATCH: 'SKILL_PACKAGE_DIGEST_MISMATCH',
|
|
94
|
+
/** A payload file's size differs from the declared one. */
|
|
95
|
+
SIZE_MISMATCH: 'SKILL_PACKAGE_SIZE_MISMATCH',
|
|
96
|
+
/** SKILL.md frontmatter is missing or disagrees with the manifest. */
|
|
97
|
+
SKILL_MD_INVALID: 'SKILL_PACKAGE_SKILL_MD_INVALID',
|
|
98
|
+
/** Staging directory could not be created, written or verified. */
|
|
99
|
+
STAGING_IO: 'SKILL_PACKAGE_STAGING_IO',
|
|
100
|
+
/** Caller aborted before the package was complete. */
|
|
101
|
+
ABORTED: 'SKILL_PACKAGE_ABORTED',
|
|
102
|
+
};
|
|
103
|
+
const CATEGORIES = {
|
|
104
|
+
[exports.SkillPackageErrorCode.ARCHIVE_FORMAT]: 'archive',
|
|
105
|
+
[exports.SkillPackageErrorCode.ARCHIVE_TRUNCATED]: 'archive',
|
|
106
|
+
[exports.SkillPackageErrorCode.ENTRY_TYPE_FORBIDDEN]: 'path',
|
|
107
|
+
[exports.SkillPackageErrorCode.ENTRY_PATH_UNSAFE]: 'path',
|
|
108
|
+
[exports.SkillPackageErrorCode.ENTRY_DUPLICATE]: 'path',
|
|
109
|
+
[exports.SkillPackageErrorCode.ENTRY_COLLISION]: 'path',
|
|
110
|
+
[exports.SkillPackageErrorCode.ENTRY_MODE_FORBIDDEN]: 'path',
|
|
111
|
+
[exports.SkillPackageErrorCode.ENTRY_LIMIT_EXCEEDED]: 'limit',
|
|
112
|
+
[exports.SkillPackageErrorCode.SIZE_LIMIT_EXCEEDED]: 'limit',
|
|
113
|
+
[exports.SkillPackageErrorCode.COMPRESSION_RATIO_EXCEEDED]: 'limit',
|
|
114
|
+
[exports.SkillPackageErrorCode.LAYOUT_INVALID]: 'manifest',
|
|
115
|
+
[exports.SkillPackageErrorCode.MANIFEST_MISSING]: 'manifest',
|
|
116
|
+
[exports.SkillPackageErrorCode.MANIFEST_INVALID]: 'manifest',
|
|
117
|
+
[exports.SkillPackageErrorCode.MANIFEST_MISMATCH]: 'manifest',
|
|
118
|
+
[exports.SkillPackageErrorCode.UNDECLARED_EXECUTABLE]: 'manifest',
|
|
119
|
+
[exports.SkillPackageErrorCode.UNDECLARED_SCRIPT]: 'manifest',
|
|
120
|
+
[exports.SkillPackageErrorCode.DIGEST_MISMATCH]: 'integrity',
|
|
121
|
+
[exports.SkillPackageErrorCode.SIZE_MISMATCH]: 'integrity',
|
|
122
|
+
[exports.SkillPackageErrorCode.SKILL_MD_INVALID]: 'manifest',
|
|
123
|
+
[exports.SkillPackageErrorCode.STAGING_IO]: 'staging',
|
|
124
|
+
[exports.SkillPackageErrorCode.ABORTED]: 'staging',
|
|
125
|
+
};
|
|
126
|
+
const MESSAGES = {
|
|
127
|
+
[exports.SkillPackageErrorCode.ARCHIVE_FORMAT]: 'Skill package is not a readable tar.gz archive',
|
|
128
|
+
[exports.SkillPackageErrorCode.ARCHIVE_TRUNCATED]: 'Skill package archive is truncated',
|
|
129
|
+
[exports.SkillPackageErrorCode.ENTRY_TYPE_FORBIDDEN]: 'Skill package contains a forbidden entry type',
|
|
130
|
+
[exports.SkillPackageErrorCode.ENTRY_PATH_UNSAFE]: 'Skill package contains an unsafe entry path',
|
|
131
|
+
[exports.SkillPackageErrorCode.ENTRY_DUPLICATE]: 'Skill package declares the same entry twice',
|
|
132
|
+
[exports.SkillPackageErrorCode.ENTRY_COLLISION]: 'Skill package contains colliding entry paths',
|
|
133
|
+
[exports.SkillPackageErrorCode.ENTRY_MODE_FORBIDDEN]: 'Skill package entry carries forbidden mode bits',
|
|
134
|
+
[exports.SkillPackageErrorCode.ENTRY_LIMIT_EXCEEDED]: 'Skill package contains too many entries',
|
|
135
|
+
[exports.SkillPackageErrorCode.SIZE_LIMIT_EXCEEDED]: 'Skill package exceeds a size limit',
|
|
136
|
+
[exports.SkillPackageErrorCode.COMPRESSION_RATIO_EXCEEDED]: 'Skill package decompression ratio exceeds the limit',
|
|
137
|
+
[exports.SkillPackageErrorCode.LAYOUT_INVALID]: 'Skill package layout does not match the contract',
|
|
138
|
+
[exports.SkillPackageErrorCode.MANIFEST_MISSING]: 'Skill package manifest is missing or misplaced',
|
|
139
|
+
[exports.SkillPackageErrorCode.MANIFEST_INVALID]: 'Skill package manifest is not valid',
|
|
140
|
+
[exports.SkillPackageErrorCode.MANIFEST_MISMATCH]: 'Skill package manifest does not match the package',
|
|
141
|
+
[exports.SkillPackageErrorCode.UNDECLARED_EXECUTABLE]: 'Skill package contains an undeclared executable',
|
|
142
|
+
[exports.SkillPackageErrorCode.UNDECLARED_SCRIPT]: 'Skill package contains an undeclared script',
|
|
143
|
+
[exports.SkillPackageErrorCode.DIGEST_MISMATCH]: 'Skill package file digest does not match the manifest',
|
|
144
|
+
[exports.SkillPackageErrorCode.SIZE_MISMATCH]: 'Skill package file size does not match the manifest',
|
|
145
|
+
[exports.SkillPackageErrorCode.SKILL_MD_INVALID]: 'Skill package SKILL.md is missing or inconsistent',
|
|
146
|
+
[exports.SkillPackageErrorCode.STAGING_IO]: 'Skill package staging could not be prepared',
|
|
147
|
+
[exports.SkillPackageErrorCode.ABORTED]: 'Skill package processing was aborted',
|
|
148
|
+
};
|
|
149
|
+
/** A rejected Skill package. Safe to surface to API clients and logs. */
|
|
150
|
+
class SkillPackageError extends Error {
|
|
151
|
+
code;
|
|
152
|
+
category;
|
|
153
|
+
detail;
|
|
154
|
+
constructor(code, detail) {
|
|
155
|
+
super(MESSAGES[code]);
|
|
156
|
+
this.name = 'SkillPackageError';
|
|
157
|
+
this.code = code;
|
|
158
|
+
this.category = CATEGORIES[code];
|
|
159
|
+
if (detail)
|
|
160
|
+
this.detail = detail;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.SkillPackageError = SkillPackageError;
|
|
164
|
+
/** Narrow an unknown thrown value to a {@link SkillPackageError}. */
|
|
165
|
+
function isSkillPackageError(value) {
|
|
166
|
+
return value instanceof SkillPackageError;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Render an archive-supplied path so it is safe to put in an error detail.
|
|
170
|
+
*
|
|
171
|
+
* Percent-encodes everything outside a conservative allow-list and truncates,
|
|
172
|
+
* so a crafted entry name cannot inject control characters into a log line or
|
|
173
|
+
* smuggle markup into a UI. Machine-absolute paths never reach this function:
|
|
174
|
+
* only archive-relative names do.
|
|
175
|
+
*/
|
|
176
|
+
function encodeEntryPathForError(value) {
|
|
177
|
+
const encoded = value.replace(/[^A-Za-z0-9._/-]/g, (ch) => [...ch]
|
|
178
|
+
.map((c) => `%${c.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0')}`)
|
|
179
|
+
.join(''));
|
|
180
|
+
return encoded.length > 120 ? `${encoded.slice(0, 120)}…` : encoded;
|
|
181
|
+
}
|
|
182
|
+
function fail(code, detail) {
|
|
183
|
+
throw new SkillPackageError(code, detail);
|
|
184
|
+
}
|
|
185
|
+
// =============================================================================
|
|
186
|
+
// tar header decoding
|
|
187
|
+
// =============================================================================
|
|
188
|
+
/** A regular file is typeflag `0`; historic writers use NUL for the same thing. */
|
|
189
|
+
const TYPEFLAG_REGULAR = new Set(['0', '\u0000']);
|
|
190
|
+
const TYPEFLAG_DIRECTORY = '5';
|
|
191
|
+
/**
|
|
192
|
+
* Read a NUL-terminated text field.
|
|
193
|
+
*
|
|
194
|
+
* Bytes after the terminator must be NUL: a name that continues past its own
|
|
195
|
+
* terminator is a header hand-built to be read differently by two parsers. The
|
|
196
|
+
* decoded text must also round-trip, so an invalid UTF-8 name cannot slip
|
|
197
|
+
* through as replacement characters.
|
|
198
|
+
*/
|
|
199
|
+
function readField(block, offset, length) {
|
|
200
|
+
const slice = block.subarray(offset, offset + length);
|
|
201
|
+
let end = slice.indexOf(0);
|
|
202
|
+
if (end === -1)
|
|
203
|
+
end = slice.length;
|
|
204
|
+
for (let i = end; i < slice.length; i++) {
|
|
205
|
+
if (slice[i] !== 0)
|
|
206
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_FORMAT, { field: 'padding' });
|
|
207
|
+
}
|
|
208
|
+
const raw = Buffer.from(slice.subarray(0, end));
|
|
209
|
+
const text = raw.toString('utf8');
|
|
210
|
+
if (!Buffer.from(text, 'utf8').equals(raw)) {
|
|
211
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_FORMAT, { field: 'encoding' });
|
|
212
|
+
}
|
|
213
|
+
return text;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Read an octal numeric field.
|
|
217
|
+
*
|
|
218
|
+
* Only octal digits, spaces and NULs are accepted; writers disagree about which
|
|
219
|
+
* padding they use, but none of them needs another character. GNU base-256
|
|
220
|
+
* encoding (high bit set) is refused rather than decoded: every value this
|
|
221
|
+
* reader cares about is bounded well below the point where base-256 is needed,
|
|
222
|
+
* so its presence only ever means a hand-built header.
|
|
223
|
+
*/
|
|
224
|
+
function readOctal(block, offset, length) {
|
|
225
|
+
if ((block[offset] & 0x80) !== 0) {
|
|
226
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_FORMAT, { field: 'numeric-encoding' });
|
|
227
|
+
}
|
|
228
|
+
let digits = '';
|
|
229
|
+
for (let i = offset; i < offset + length; i++) {
|
|
230
|
+
const byte = block[i];
|
|
231
|
+
if (byte === 0 || byte === 0x20)
|
|
232
|
+
continue;
|
|
233
|
+
if (byte < 0x30 || byte > 0x37) {
|
|
234
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_FORMAT, { field: 'numeric' });
|
|
235
|
+
}
|
|
236
|
+
digits += String.fromCharCode(byte);
|
|
237
|
+
}
|
|
238
|
+
if (digits === '')
|
|
239
|
+
return 0;
|
|
240
|
+
const value = parseInt(digits, 8);
|
|
241
|
+
if (!Number.isSafeInteger(value)) {
|
|
242
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_FORMAT, { field: 'numeric-range' });
|
|
243
|
+
}
|
|
244
|
+
return value;
|
|
245
|
+
}
|
|
246
|
+
function isZeroBlock(block) {
|
|
247
|
+
for (let i = 0; i < block.length; i++)
|
|
248
|
+
if (block[i] !== 0)
|
|
249
|
+
return false;
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
/** Verify the header checksum, accepting both the unsigned and signed sums. */
|
|
253
|
+
function verifyChecksum(block, declared) {
|
|
254
|
+
let unsigned = 0;
|
|
255
|
+
let signed = 0;
|
|
256
|
+
for (let i = 0; i < exports.TAR_BLOCK_SIZE; i++) {
|
|
257
|
+
const byte = i >= 148 && i < 156 ? 0x20 : block[i];
|
|
258
|
+
unsigned += byte;
|
|
259
|
+
signed += byte > 127 ? byte - 256 : byte;
|
|
260
|
+
}
|
|
261
|
+
if (declared !== unsigned && declared !== signed) {
|
|
262
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_FORMAT, { field: 'checksum' });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/** Decode the whole tar stream into raw entries, rejecting every other type. */
|
|
266
|
+
function readTarEntries(tar) {
|
|
267
|
+
if (tar.byteLength === 0 || tar.byteLength % exports.TAR_BLOCK_SIZE !== 0) {
|
|
268
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_TRUNCATED, { field: 'alignment' });
|
|
269
|
+
}
|
|
270
|
+
const entries = [];
|
|
271
|
+
let offset = 0;
|
|
272
|
+
while (offset + exports.TAR_BLOCK_SIZE <= tar.byteLength) {
|
|
273
|
+
const header = tar.subarray(offset, offset + exports.TAR_BLOCK_SIZE);
|
|
274
|
+
if (isZeroBlock(header)) {
|
|
275
|
+
for (let i = offset; i < tar.byteLength; i++) {
|
|
276
|
+
if (tar[i] !== 0)
|
|
277
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_FORMAT, { field: 'trailer' });
|
|
278
|
+
}
|
|
279
|
+
return entries;
|
|
280
|
+
}
|
|
281
|
+
verifyChecksum(header, readOctal(header, 148, 8));
|
|
282
|
+
// POSIX writes `ustar\0`, GNU writes `ustar ` — both are the same format here.
|
|
283
|
+
if (readField(header, 257, 6).trim() !== 'ustar') {
|
|
284
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_FORMAT, { field: 'magic' });
|
|
285
|
+
}
|
|
286
|
+
const typeflag = readField(header, 156, 1) || '\u0000';
|
|
287
|
+
const isDirectory = typeflag === TYPEFLAG_DIRECTORY;
|
|
288
|
+
if (!isDirectory && !TYPEFLAG_REGULAR.has(typeflag)) {
|
|
289
|
+
fail(exports.SkillPackageErrorCode.ENTRY_TYPE_FORBIDDEN, { typeflag: encodeEntryPathForError(typeflag) });
|
|
290
|
+
}
|
|
291
|
+
if (readField(header, 157, 100) !== '') {
|
|
292
|
+
fail(exports.SkillPackageErrorCode.ENTRY_TYPE_FORBIDDEN, { typeflag: 'link' });
|
|
293
|
+
}
|
|
294
|
+
const mode = readOctal(header, 100, 8);
|
|
295
|
+
if ((mode & 0o7000) !== 0) {
|
|
296
|
+
fail(exports.SkillPackageErrorCode.ENTRY_MODE_FORBIDDEN, { bits: (mode & 0o7000).toString(8) });
|
|
297
|
+
}
|
|
298
|
+
const prefix = readField(header, 345, 155);
|
|
299
|
+
const name = readField(header, 0, 100);
|
|
300
|
+
const fullName = prefix === '' ? name : `${prefix}/${name}`;
|
|
301
|
+
const size = readOctal(header, 124, 12);
|
|
302
|
+
if (isDirectory && size !== 0) {
|
|
303
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_FORMAT, { field: 'directory-size' });
|
|
304
|
+
}
|
|
305
|
+
if (size > skills_1.SKILL_FILE_MAX_SIZE) {
|
|
306
|
+
fail(exports.SkillPackageErrorCode.SIZE_LIMIT_EXCEEDED, { limit: skills_1.SKILL_FILE_MAX_SIZE });
|
|
307
|
+
}
|
|
308
|
+
const contentStart = offset + exports.TAR_BLOCK_SIZE;
|
|
309
|
+
const contentEnd = contentStart + size;
|
|
310
|
+
if (contentEnd > tar.byteLength)
|
|
311
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_TRUNCATED);
|
|
312
|
+
entries.push({
|
|
313
|
+
name: fullName,
|
|
314
|
+
isDirectory,
|
|
315
|
+
mode,
|
|
316
|
+
size,
|
|
317
|
+
bytes: isDirectory ? new Uint8Array(0) : tar.subarray(contentStart, contentEnd),
|
|
318
|
+
});
|
|
319
|
+
if (entries.length > exports.SKILL_PACKAGE_MAX_ENTRIES) {
|
|
320
|
+
fail(exports.SkillPackageErrorCode.ENTRY_LIMIT_EXCEEDED, { limit: exports.SKILL_PACKAGE_MAX_ENTRIES });
|
|
321
|
+
}
|
|
322
|
+
offset = contentStart + Math.ceil(size / exports.TAR_BLOCK_SIZE) * exports.TAR_BLOCK_SIZE;
|
|
323
|
+
}
|
|
324
|
+
// A well-formed archive ends with zero blocks; running off the end does not.
|
|
325
|
+
return fail(exports.SkillPackageErrorCode.ARCHIVE_TRUNCATED, { field: 'trailer' });
|
|
326
|
+
}
|
|
327
|
+
// =============================================================================
|
|
328
|
+
// Path normalization
|
|
329
|
+
// =============================================================================
|
|
330
|
+
/**
|
|
331
|
+
* Reduce an archive name to the form the root resolver and the payload-path
|
|
332
|
+
* validator expect: no `./` prefix, no trailing slash, never empty.
|
|
333
|
+
*
|
|
334
|
+
* Everything else — traversal, absolute and drive paths, control characters,
|
|
335
|
+
* depth and length — is left to `validateSkillPayloadPath`, which runs on the
|
|
336
|
+
* final root-relative path. Checking here as well would only add a guard no
|
|
337
|
+
* test could distinguish from the real one.
|
|
338
|
+
*/
|
|
339
|
+
function normalizeRawName(raw) {
|
|
340
|
+
let value = raw;
|
|
341
|
+
if (value.startsWith('./'))
|
|
342
|
+
value = value.slice(2);
|
|
343
|
+
const trailingSlash = value.endsWith('/');
|
|
344
|
+
if (trailingSlash)
|
|
345
|
+
value = value.slice(0, -1);
|
|
346
|
+
if (value === '')
|
|
347
|
+
fail(exports.SkillPackageErrorCode.ENTRY_PATH_UNSAFE, { reason: 'empty' });
|
|
348
|
+
return { path: value, trailingSlash };
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Strip the single top-level directory a conventional tarball carries.
|
|
352
|
+
*
|
|
353
|
+
* Only `<skill-id>` and `<skill-id>-<version>` are accepted as that directory,
|
|
354
|
+
* so a package cannot install itself under a name the Catalog never named.
|
|
355
|
+
*/
|
|
356
|
+
function resolveRootName(paths, options) {
|
|
357
|
+
const allowed = [options.skillId, `${options.skillId}-${options.version}`];
|
|
358
|
+
const firstSegments = new Set(paths.map((p) => p.split('/')[0]));
|
|
359
|
+
if (firstSegments.size !== 1)
|
|
360
|
+
return null;
|
|
361
|
+
const candidate = [...firstSegments][0];
|
|
362
|
+
const hasNested = paths.some((p) => p.startsWith(`${candidate}/`));
|
|
363
|
+
if (!hasNested)
|
|
364
|
+
return null;
|
|
365
|
+
if (!allowed.includes(candidate)) {
|
|
366
|
+
fail(exports.SkillPackageErrorCode.LAYOUT_INVALID, {
|
|
367
|
+
reason: 'root-directory',
|
|
368
|
+
entry: encodeEntryPathForError(candidate),
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
return candidate;
|
|
372
|
+
}
|
|
373
|
+
// =============================================================================
|
|
374
|
+
// Public API
|
|
375
|
+
// =============================================================================
|
|
376
|
+
/**
|
|
377
|
+
* Decompress and parse a Skill package into a bounded entry table.
|
|
378
|
+
*
|
|
379
|
+
* The caller is expected to have verified the artifact digest already (#1229);
|
|
380
|
+
* this step answers the separate question of whether the bytes are a package
|
|
381
|
+
* this build is willing to look at.
|
|
382
|
+
*
|
|
383
|
+
* @param artifact Verified artifact bytes from the snapshot store
|
|
384
|
+
* @param options Catalog coordinates the package must belong to
|
|
385
|
+
* @throws SkillPackageError for every rejection
|
|
386
|
+
*/
|
|
387
|
+
function readSkillPackage(artifact, options) {
|
|
388
|
+
if (artifact.byteLength < 2 || artifact[0] !== 0x1f || artifact[1] !== 0x8b) {
|
|
389
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_FORMAT, { field: 'gzip-magic' });
|
|
390
|
+
}
|
|
391
|
+
let tar;
|
|
392
|
+
try {
|
|
393
|
+
tar = (0, zlib_1.gunzipSync)(artifact, { maxOutputLength: exports.SKILL_PACKAGE_MAX_DECOMPRESSED_BYTES });
|
|
394
|
+
}
|
|
395
|
+
catch (error) {
|
|
396
|
+
const code = error?.code;
|
|
397
|
+
if (code === 'ERR_BUFFER_TOO_LARGE') {
|
|
398
|
+
fail(exports.SkillPackageErrorCode.SIZE_LIMIT_EXCEEDED, {
|
|
399
|
+
limit: exports.SKILL_PACKAGE_MAX_DECOMPRESSED_BYTES,
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
fail(exports.SkillPackageErrorCode.ARCHIVE_FORMAT, { field: 'gzip' });
|
|
403
|
+
}
|
|
404
|
+
if (tar.byteLength > exports.SKILL_PACKAGE_RATIO_FLOOR_BYTES &&
|
|
405
|
+
tar.byteLength / artifact.byteLength > exports.SKILL_PACKAGE_MAX_COMPRESSION_RATIO) {
|
|
406
|
+
fail(exports.SkillPackageErrorCode.COMPRESSION_RATIO_EXCEEDED, {
|
|
407
|
+
limit: exports.SKILL_PACKAGE_MAX_COMPRESSION_RATIO,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
const raw = readTarEntries(tar);
|
|
411
|
+
const normalized = raw.map((entry) => ({ entry, ...normalizeRawName(entry.name) }));
|
|
412
|
+
const rootName = resolveRootName(normalized.map((item) => item.path), options);
|
|
413
|
+
const files = [];
|
|
414
|
+
const directories = [];
|
|
415
|
+
const byPath = new Map();
|
|
416
|
+
const byFold = new Map();
|
|
417
|
+
let payloadBytes = 0;
|
|
418
|
+
for (const item of normalized) {
|
|
419
|
+
let relative = item.path;
|
|
420
|
+
if (rootName !== null) {
|
|
421
|
+
if (relative === rootName)
|
|
422
|
+
continue;
|
|
423
|
+
relative = relative.slice(rootName.length + 1);
|
|
424
|
+
}
|
|
425
|
+
const isDirectory = item.entry.isDirectory || item.trailingSlash;
|
|
426
|
+
const pathResult = (0, skills_1.validateSkillPayloadPath)(relative, '/entry');
|
|
427
|
+
if (!pathResult.ok) {
|
|
428
|
+
fail(exports.SkillPackageErrorCode.ENTRY_PATH_UNSAFE, {
|
|
429
|
+
entry: encodeEntryPathForError(relative),
|
|
430
|
+
reason: pathResult.errors[0].message,
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
if (byPath.has(relative)) {
|
|
434
|
+
fail(exports.SkillPackageErrorCode.ENTRY_DUPLICATE, { entry: encodeEntryPathForError(relative) });
|
|
435
|
+
}
|
|
436
|
+
const folded = relative
|
|
437
|
+
.split('/')
|
|
438
|
+
.map((segment) => (0, skills_1.foldSkillIdForCollision)(segment))
|
|
439
|
+
.join('/');
|
|
440
|
+
const collidesWith = byFold.get(folded);
|
|
441
|
+
if (collidesWith !== undefined) {
|
|
442
|
+
fail(exports.SkillPackageErrorCode.ENTRY_COLLISION, { entry: encodeEntryPathForError(relative) });
|
|
443
|
+
}
|
|
444
|
+
byPath.set(relative, isDirectory);
|
|
445
|
+
byFold.set(folded, relative);
|
|
446
|
+
if (isDirectory) {
|
|
447
|
+
directories.push(relative);
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
payloadBytes += item.entry.size;
|
|
451
|
+
if (payloadBytes > exports.SKILL_PACKAGE_MAX_DECOMPRESSED_BYTES) {
|
|
452
|
+
fail(exports.SkillPackageErrorCode.SIZE_LIMIT_EXCEEDED, {
|
|
453
|
+
limit: exports.SKILL_PACKAGE_MAX_DECOMPRESSED_BYTES,
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
const bytes = new Uint8Array(item.entry.bytes);
|
|
457
|
+
files.push({
|
|
458
|
+
path: relative,
|
|
459
|
+
size: item.entry.size,
|
|
460
|
+
sha256: (0, integrity_1.computeSha256Hex)(bytes),
|
|
461
|
+
executable: (item.entry.mode & 0o111) !== 0,
|
|
462
|
+
bytes,
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
const payloadCount = files.filter((file) => file.path !== skills_1.SKILL_MANIFEST_FILENAME).length;
|
|
466
|
+
if (payloadCount > skills_1.SKILL_FILES_MAX_COUNT) {
|
|
467
|
+
fail(exports.SkillPackageErrorCode.ENTRY_LIMIT_EXCEEDED, { limit: skills_1.SKILL_FILES_MAX_COUNT });
|
|
468
|
+
}
|
|
469
|
+
// A file entry may not also be claimed as a directory by another entry.
|
|
470
|
+
for (const directory of directories) {
|
|
471
|
+
if (files.some((file) => file.path === directory)) {
|
|
472
|
+
fail(exports.SkillPackageErrorCode.ENTRY_DUPLICATE, { entry: encodeEntryPathForError(directory) });
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
for (const file of files) {
|
|
476
|
+
const parents = file.path.split('/').slice(0, -1);
|
|
477
|
+
let walked = '';
|
|
478
|
+
for (const segment of parents) {
|
|
479
|
+
walked = walked === '' ? segment : `${walked}/${segment}`;
|
|
480
|
+
if (files.some((other) => other.path === walked)) {
|
|
481
|
+
fail(exports.SkillPackageErrorCode.ENTRY_PATH_UNSAFE, {
|
|
482
|
+
entry: encodeEntryPathForError(file.path),
|
|
483
|
+
reason: 'parent-is-file',
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return {
|
|
489
|
+
rootName,
|
|
490
|
+
files,
|
|
491
|
+
directories,
|
|
492
|
+
compressedSize: artifact.byteLength,
|
|
493
|
+
decompressedSize: tar.byteLength,
|
|
494
|
+
};
|
|
495
|
+
}
|