commandmate 0.11.4 → 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.
Files changed (591) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +395 -303
  3. package/.next/app-path-routes-manifest.json +31 -22
  4. package/.next/build-manifest.json +5 -5
  5. package/.next/prerender-manifest.json +12 -12
  6. package/.next/react-loadable-manifest.json +8 -6
  7. package/.next/required-server-files.json +1 -1
  8. package/.next/routes-manifest.json +66 -0
  9. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  10. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  12. package/.next/server/app/api/app/update-check/route.js +1 -1
  13. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  18. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  24. package/.next/server/app/api/daily-summary/route.js +1 -1
  25. package/.next/server/app/api/daily-summary/route.js.nft.json +1 -1
  26. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  27. package/.next/server/app/api/daily-summary/status/route.js +1 -1
  28. package/.next/server/app/api/daily-summary/status/route.js.nft.json +1 -1
  29. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  30. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/push/subscriptions/route.js +1 -1
  36. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js +1 -1
  40. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/repositories/[id]/todos/route.js +1 -1
  42. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  47. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  48. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  51. package/.next/server/app/api/skills/[id]/route.js +1 -0
  52. package/.next/server/app/api/skills/[id]/route.js.nft.json +1 -0
  53. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -0
  54. package/.next/server/app/api/skills/route.js +1 -0
  55. package/.next/server/app/api/skills/route.js.nft.json +1 -0
  56. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -0
  57. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  58. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/todos/route.js +1 -1
  61. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  64. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -1
  65. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  66. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +1 -1
  67. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  69. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
  70. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +1 -1
  72. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  73. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js +1 -1
  75. package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js.nft.json +1 -1
  76. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js +1 -1
  78. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js.nft.json +1 -1
  79. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/worktrees/[id]/git/branches/route.js +1 -1
  81. package/.next/server/app/api/worktrees/[id]/git/branches/route.js.nft.json +1 -1
  82. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/worktrees/[id]/git/checkout/route.js +1 -1
  84. package/.next/server/app/api/worktrees/[id]/git/checkout/route.js.nft.json +1 -1
  85. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  86. package/.next/server/app/api/worktrees/[id]/git/commit/route.js +1 -1
  87. package/.next/server/app/api/worktrees/[id]/git/commit/route.js.nft.json +1 -1
  88. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/worktrees/[id]/git/diff/route.js +1 -1
  90. package/.next/server/app/api/worktrees/[id]/git/diff/route.js.nft.json +1 -1
  91. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/api/worktrees/[id]/git/fetch/route.js +1 -1
  93. package/.next/server/app/api/worktrees/[id]/git/fetch/route.js.nft.json +1 -1
  94. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/worktrees/[id]/git/log/route.js +1 -1
  96. package/.next/server/app/api/worktrees/[id]/git/log/route.js.nft.json +1 -1
  97. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/worktrees/[id]/git/pull/route.js +1 -1
  99. package/.next/server/app/api/worktrees/[id]/git/pull/route.js.nft.json +1 -1
  100. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/worktrees/[id]/git/push/route.js +1 -1
  102. package/.next/server/app/api/worktrees/[id]/git/push/route.js.nft.json +1 -1
  103. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/worktrees/[id]/git/reset/route.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/git/reset/route.js.nft.json +1 -1
  106. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/worktrees/[id]/git/revert/route.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/git/revert/route.js.nft.json +1 -1
  109. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js.nft.json +1 -1
  112. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  113. package/.next/server/app/api/worktrees/[id]/git/stage/route.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/git/stage/route.js.nft.json +1 -1
  115. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/git/staged/route.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/git/staged/route.js.nft.json +1 -1
  118. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  119. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js.nft.json +1 -1
  121. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js.nft.json +1 -1
  124. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js.nft.json +1 -1
  127. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js.nft.json +1 -1
  130. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/git/stash/route.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/git/stash/route.js.nft.json +1 -1
  133. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/git/status/route.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/git/status/route.js.nft.json +1 -1
  136. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/git/unstage/route.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/git/unstage/route.js.nft.json +1 -1
  139. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js.nft.json +1 -1
  142. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/logs/route.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/marp-render/route.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/memos/route.js +1 -1
  154. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/messages/route.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  161. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/schedules/route.js +1 -1
  167. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  170. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  171. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js +1 -0
  173. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js.nft.json +1 -0
  174. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -0
  175. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js +1 -0
  176. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js.nft.json +1 -0
  177. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -0
  178. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js +1 -0
  179. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js.nft.json +1 -0
  180. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -0
  181. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js +1 -0
  182. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js.nft.json +1 -0
  183. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -0
  184. package/.next/server/app/api/worktrees/[id]/skills/route.js +23 -0
  185. package/.next/server/app/api/worktrees/[id]/skills/route.js.nft.json +1 -0
  186. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -0
  187. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
  188. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +1 -1
  191. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/timers/history/route.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js +1 -1
  196. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  197. package/.next/server/app/api/worktrees/[id]/todos/route.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  199. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js +1 -1
  200. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/tree/route.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  203. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/viewed/route.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  206. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  207. package/.next/server/app/chat/page.js +2 -2
  208. package/.next/server/app/chat/page.js.nft.json +1 -1
  209. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  210. package/.next/server/app/login/page.js.nft.json +1 -1
  211. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  212. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  213. package/.next/server/app/more/page.js +2 -2
  214. package/.next/server/app/more/page.js.nft.json +1 -1
  215. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  216. package/.next/server/app/offline/page.js.nft.json +1 -1
  217. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  218. package/.next/server/app/page.js +1 -1
  219. package/.next/server/app/page.js.nft.json +1 -1
  220. package/.next/server/app/page_client-reference-manifest.js +1 -1
  221. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  222. package/.next/server/app/repositories/page.js +1 -1
  223. package/.next/server/app/repositories/page.js.nft.json +1 -1
  224. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  225. package/.next/server/app/review/page.js +1 -1
  226. package/.next/server/app/review/page.js.nft.json +1 -1
  227. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  228. package/.next/server/app/sessions/page.js +1 -1
  229. package/.next/server/app/sessions/page.js.nft.json +1 -1
  230. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  231. package/.next/server/app/skills/[skillId]/page.js +2 -0
  232. package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -0
  233. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -0
  234. package/.next/server/app/skills/page.js +2 -0
  235. package/.next/server/app/skills/page.js.nft.json +1 -0
  236. package/.next/server/app/skills/page_client-reference-manifest.js +1 -0
  237. package/.next/server/app/worktrees/[id]/files/[...path]/page.js +2 -2
  238. package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -1
  239. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  240. package/.next/server/app/worktrees/[id]/page.js +9 -9
  241. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  242. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  243. package/.next/server/app/worktrees/[id]/terminal/page.js +3 -3
  244. package/.next/server/app/worktrees/[id]/terminal/page.js.nft.json +1 -1
  245. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  246. package/.next/server/app-paths-manifest.json +31 -22
  247. package/.next/server/chunks/1117.js +1 -1
  248. package/.next/server/chunks/120.js +1 -0
  249. package/.next/server/chunks/1808.js +1 -0
  250. package/.next/server/chunks/186.js +1 -0
  251. package/.next/server/chunks/2119.js +1 -1
  252. package/.next/server/chunks/22.js +1 -0
  253. package/.next/server/chunks/2328.js +1 -0
  254. package/.next/server/chunks/2445.js +1 -1
  255. package/.next/server/chunks/3042.js +2 -0
  256. package/.next/server/chunks/3543.js +1 -1
  257. package/.next/server/chunks/3708.js +1 -0
  258. package/.next/server/chunks/3945.js +1 -1
  259. package/.next/server/chunks/5064.js +1 -0
  260. package/.next/server/chunks/5226.js +28 -0
  261. package/.next/server/chunks/5306.js +2 -0
  262. package/.next/server/chunks/5312.js +1 -0
  263. package/.next/server/chunks/5326.js +1 -0
  264. package/.next/server/chunks/5381.js +1 -1
  265. package/.next/server/chunks/5456.js +1 -0
  266. package/.next/server/chunks/5571.js +1 -1
  267. package/.next/server/chunks/5959.js +2 -2
  268. package/.next/server/chunks/6065.js +1 -0
  269. package/.next/server/chunks/6130.js +1 -0
  270. package/.next/server/chunks/6285.js +1 -1
  271. package/.next/server/chunks/646.js +6 -6
  272. package/.next/server/chunks/{9968.js → 7587.js} +1 -1
  273. package/.next/server/chunks/8584.js +1 -0
  274. package/.next/server/chunks/8681.js +1 -1
  275. package/.next/server/chunks/8807.js +950 -804
  276. package/.next/server/chunks/9123.js +1 -1
  277. package/.next/server/middleware-build-manifest.js +1 -1
  278. package/.next/server/middleware-manifest.json +5 -5
  279. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  280. package/.next/server/pages/500.html +1 -1
  281. package/.next/server/server-reference-manifest.json +1 -1
  282. package/.next/static/D-aoE4gWfuCUN0GqEPIX3/_buildManifest.js +1 -0
  283. package/.next/static/chunks/1668-7484081c45a44f89.js +1 -0
  284. package/.next/static/chunks/3418-7e47651340d940b0.js +1 -0
  285. package/.next/static/chunks/4027-0c529b322be7d4d8.js +1 -0
  286. package/.next/static/chunks/{4560-64b1461fd996127a.js → 4560-04e5aebcab96bfa1.js} +1 -1
  287. package/.next/static/chunks/6007-de36119357dcd418.js +1 -0
  288. package/.next/static/chunks/{6488-76295bf0184b101f.js → 6488-e257111ca7389d05.js} +1 -1
  289. package/.next/static/chunks/{8965-872d8de254196cec.js → 6497-dc26c6c6b0b15adf.js} +1 -1
  290. package/.next/static/chunks/790-d8e6acd26e03679c.js +1 -0
  291. package/.next/static/chunks/8361.4bf062be2d2962f4.js +1 -0
  292. package/.next/static/chunks/app/api/app/update/route-56dad0523d3c4a92.js +1 -0
  293. package/.next/static/chunks/app/api/app/update-check/route-56dad0523d3c4a92.js +1 -0
  294. package/.next/static/chunks/app/api/assistant/conversation/route-56dad0523d3c4a92.js +1 -0
  295. package/.next/static/chunks/app/api/assistant/current-output/route-56dad0523d3c4a92.js +1 -0
  296. package/.next/static/chunks/app/api/assistant/messages/route-56dad0523d3c4a92.js +1 -0
  297. package/.next/static/chunks/app/api/assistant/session/route-56dad0523d3c4a92.js +1 -0
  298. package/.next/static/chunks/app/api/assistant/start/route-56dad0523d3c4a92.js +1 -0
  299. package/.next/static/chunks/app/api/assistant/terminal/route-56dad0523d3c4a92.js +1 -0
  300. package/.next/static/chunks/app/api/assistant/tools/route-56dad0523d3c4a92.js +1 -0
  301. package/.next/static/chunks/app/api/auth/login/route-56dad0523d3c4a92.js +1 -0
  302. package/.next/static/chunks/app/api/auth/logout/route-56dad0523d3c4a92.js +1 -0
  303. package/.next/static/chunks/app/api/auth/status/route-56dad0523d3c4a92.js +1 -0
  304. package/.next/static/chunks/app/api/daily-summary/route-56dad0523d3c4a92.js +1 -0
  305. package/.next/static/chunks/app/api/daily-summary/status/route-56dad0523d3c4a92.js +1 -0
  306. package/.next/static/chunks/app/api/external-apps/[id]/health/route-56dad0523d3c4a92.js +1 -0
  307. package/.next/static/chunks/app/api/external-apps/[id]/route-56dad0523d3c4a92.js +1 -0
  308. package/.next/static/chunks/app/api/external-apps/route-56dad0523d3c4a92.js +1 -0
  309. package/.next/static/chunks/app/api/hooks/claude-done/route-56dad0523d3c4a92.js +1 -0
  310. package/.next/static/chunks/app/api/ollama/models/route-56dad0523d3c4a92.js +1 -0
  311. package/.next/static/chunks/app/api/push/subscriptions/route-56dad0523d3c4a92.js +1 -0
  312. package/.next/static/chunks/app/api/push/vapid/route-56dad0523d3c4a92.js +1 -0
  313. package/.next/static/chunks/app/api/repositories/[id]/route-56dad0523d3c4a92.js +1 -0
  314. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-56dad0523d3c4a92.js +1 -0
  315. package/.next/static/chunks/app/api/repositories/[id]/todos/route-56dad0523d3c4a92.js +1 -0
  316. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-56dad0523d3c4a92.js +1 -0
  317. package/.next/static/chunks/app/api/repositories/clone/route-56dad0523d3c4a92.js +1 -0
  318. package/.next/static/chunks/app/api/repositories/excluded/route-56dad0523d3c4a92.js +1 -0
  319. package/.next/static/chunks/app/api/repositories/restore/route-56dad0523d3c4a92.js +1 -0
  320. package/.next/static/chunks/app/api/repositories/route-56dad0523d3c4a92.js +1 -0
  321. package/.next/static/chunks/app/api/repositories/scan/route-56dad0523d3c4a92.js +1 -0
  322. package/.next/static/chunks/app/api/repositories/sync/route-56dad0523d3c4a92.js +1 -0
  323. package/.next/static/chunks/app/api/sidebar/group-order/route-56dad0523d3c4a92.js +1 -0
  324. package/.next/static/chunks/app/api/skills/[id]/route-56dad0523d3c4a92.js +1 -0
  325. package/.next/static/chunks/app/api/skills/route-56dad0523d3c4a92.js +1 -0
  326. package/.next/static/chunks/app/api/slash-commands/route-56dad0523d3c4a92.js +1 -0
  327. package/.next/static/chunks/app/api/templates/[id]/route-56dad0523d3c4a92.js +1 -0
  328. package/.next/static/chunks/app/api/templates/route-56dad0523d3c4a92.js +1 -0
  329. package/.next/static/chunks/app/api/todos/route-56dad0523d3c4a92.js +1 -0
  330. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-56dad0523d3c4a92.js +1 -0
  331. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-56dad0523d3c4a92.js +1 -0
  332. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-56dad0523d3c4a92.js +1 -0
  333. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-56dad0523d3c4a92.js +1 -0
  334. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-56dad0523d3c4a92.js +1 -0
  335. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-56dad0523d3c4a92.js +1 -0
  336. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-56dad0523d3c4a92.js +1 -0
  337. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-56dad0523d3c4a92.js +1 -0
  338. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-56dad0523d3c4a92.js +1 -0
  339. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-56dad0523d3c4a92.js +1 -0
  340. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-56dad0523d3c4a92.js +1 -0
  341. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-56dad0523d3c4a92.js +1 -0
  342. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-56dad0523d3c4a92.js +1 -0
  343. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-56dad0523d3c4a92.js +1 -0
  344. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-56dad0523d3c4a92.js +1 -0
  345. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-56dad0523d3c4a92.js +1 -0
  346. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-56dad0523d3c4a92.js +1 -0
  347. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-56dad0523d3c4a92.js +1 -0
  348. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-56dad0523d3c4a92.js +1 -0
  349. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-56dad0523d3c4a92.js +1 -0
  350. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-56dad0523d3c4a92.js +1 -0
  351. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-56dad0523d3c4a92.js +1 -0
  352. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-56dad0523d3c4a92.js +1 -0
  353. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-56dad0523d3c4a92.js +1 -0
  354. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-56dad0523d3c4a92.js +1 -0
  355. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-56dad0523d3c4a92.js +1 -0
  356. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-56dad0523d3c4a92.js +1 -0
  357. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-56dad0523d3c4a92.js +1 -0
  358. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-56dad0523d3c4a92.js +1 -0
  359. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-56dad0523d3c4a92.js +1 -0
  360. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-56dad0523d3c4a92.js +1 -0
  361. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-56dad0523d3c4a92.js +1 -0
  362. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-56dad0523d3c4a92.js +1 -0
  363. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-56dad0523d3c4a92.js +1 -0
  364. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-56dad0523d3c4a92.js +1 -0
  365. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-56dad0523d3c4a92.js +1 -0
  366. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-56dad0523d3c4a92.js +1 -0
  367. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-56dad0523d3c4a92.js +1 -0
  368. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-56dad0523d3c4a92.js +1 -0
  369. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-56dad0523d3c4a92.js +1 -0
  370. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-56dad0523d3c4a92.js +1 -0
  371. package/.next/static/chunks/app/api/worktrees/[id]/route-56dad0523d3c4a92.js +1 -0
  372. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-56dad0523d3c4a92.js +1 -0
  373. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-56dad0523d3c4a92.js +1 -0
  374. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-56dad0523d3c4a92.js +1 -0
  375. package/.next/static/chunks/app/api/worktrees/[id]/search/route-56dad0523d3c4a92.js +1 -0
  376. package/.next/static/chunks/app/api/worktrees/[id]/send/route-56dad0523d3c4a92.js +1 -0
  377. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-56dad0523d3c4a92.js +1 -0
  378. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-56dad0523d3c4a92.js +1 -0
  379. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-56dad0523d3c4a92.js +1 -0
  380. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-56dad0523d3c4a92.js +1 -0
  381. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-56dad0523d3c4a92.js +1 -0
  382. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-56dad0523d3c4a92.js +1 -0
  383. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-56dad0523d3c4a92.js +1 -0
  384. package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-56dad0523d3c4a92.js +1 -0
  385. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-56dad0523d3c4a92.js +1 -0
  386. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-56dad0523d3c4a92.js +1 -0
  387. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-56dad0523d3c4a92.js +1 -0
  388. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-56dad0523d3c4a92.js +1 -0
  389. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-56dad0523d3c4a92.js +1 -0
  390. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-56dad0523d3c4a92.js +1 -0
  391. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-56dad0523d3c4a92.js +1 -0
  392. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-56dad0523d3c4a92.js +1 -0
  393. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-56dad0523d3c4a92.js +1 -0
  394. package/.next/static/chunks/app/api/worktrees/route-56dad0523d3c4a92.js +1 -0
  395. package/.next/static/chunks/app/chat/{page-9ed2ffd98eb4ae18.js → page-9cf4ba62e21d9074.js} +1 -1
  396. package/.next/static/chunks/app/manifest.webmanifest/route-56dad0523d3c4a92.js +1 -0
  397. package/.next/static/chunks/app/more/{page-a496425bba427b48.js → page-082d4ae496f9a36e.js} +1 -1
  398. package/.next/static/chunks/app/{page-15bfd76bcf65842d.js → page-af457ca5876ed616.js} +1 -1
  399. package/.next/static/chunks/app/proxy/[...path]/route-56dad0523d3c4a92.js +1 -0
  400. package/.next/static/chunks/app/repositories/{page-d214522ab8792ce7.js → page-75f0d70452c6b6c0.js} +1 -1
  401. package/.next/static/chunks/app/review/{page-1dadf0b5d7129598.js → page-f431d630097c2e85.js} +1 -1
  402. package/.next/static/chunks/app/sessions/{page-96f007d986c5f327.js → page-20f07a99db64d2ca.js} +1 -1
  403. package/.next/static/chunks/app/skills/[skillId]/page-68ed5e9186efe56d.js +1 -0
  404. package/.next/static/chunks/app/skills/page-46242c428ee8bccf.js +1 -0
  405. package/.next/static/chunks/app/worktrees/[id]/page-bf811e793052c917.js +1 -0
  406. package/.next/static/chunks/app/worktrees/[id]/terminal/page-a75fe180a7233b2b.js +1 -0
  407. package/.next/static/chunks/webpack-0f9275e279c058eb.js +1 -0
  408. package/.next/static/css/b4bdb1f3457fe9a7.css +1 -0
  409. package/.next/trace +11 -10
  410. package/.next/types/app/api/skills/[id]/route.ts +347 -0
  411. package/.next/types/app/api/skills/route.ts +347 -0
  412. package/.next/types/app/api/worktrees/[id]/skills/[skillId]/install/route.ts +347 -0
  413. package/.next/types/app/api/worktrees/[id]/skills/[skillId]/plan/route.ts +347 -0
  414. package/.next/types/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.ts +347 -0
  415. package/.next/types/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.ts +347 -0
  416. package/.next/types/app/api/worktrees/[id]/skills/route.ts +347 -0
  417. package/.next/types/app/skills/[skillId]/page.ts +84 -0
  418. package/.next/types/app/skills/page.ts +84 -0
  419. package/.next/types/routes.d.ts +11 -2
  420. package/.next/types/validator.ts +81 -0
  421. package/dist/cli/commands/skill-format.d.ts +28 -0
  422. package/dist/cli/commands/skill-format.d.ts.map +1 -0
  423. package/dist/cli/commands/skill-format.js +163 -0
  424. package/dist/cli/commands/skill-guards.d.ts +53 -0
  425. package/dist/cli/commands/skill-guards.d.ts.map +1 -0
  426. package/dist/cli/commands/skill-guards.js +188 -0
  427. package/dist/cli/commands/skill.d.ts +24 -0
  428. package/dist/cli/commands/skill.d.ts.map +1 -0
  429. package/dist/cli/commands/skill.js +365 -0
  430. package/dist/cli/docs/agent-operations.d.ts +1 -1
  431. package/dist/cli/docs/agent-operations.d.ts.map +1 -1
  432. package/dist/cli/docs/agent-operations.js +36 -0
  433. package/dist/cli/program.d.ts.map +1 -1
  434. package/dist/cli/program.js +11 -0
  435. package/dist/cli/types/api-responses.d.ts +215 -0
  436. package/dist/cli/types/api-responses.d.ts.map +1 -1
  437. package/dist/cli/types/index.d.ts +60 -0
  438. package/dist/cli/types/index.d.ts.map +1 -1
  439. package/dist/cli/types/index.js +23 -1
  440. package/dist/cli/utils/api-client.d.ts +19 -1
  441. package/dist/cli/utils/api-client.d.ts.map +1 -1
  442. package/dist/cli/utils/api-client.js +41 -4
  443. package/dist/server/server.js +57 -0
  444. package/dist/server/src/config/activity-bar-config.js +2 -0
  445. package/dist/server/src/config/git-status-config.js +83 -0
  446. package/dist/server/src/config/skill-security-config.js +139 -0
  447. package/dist/server/src/lib/db/migrations/index.js +8 -0
  448. package/dist/server/src/lib/db/migrations/runner.js +1 -1
  449. package/dist/server/src/lib/db/migrations/v44-skill-operations.js +81 -0
  450. package/dist/server/src/lib/db/migrations/v45-skill-installations.js +59 -0
  451. package/dist/server/src/lib/db/migrations/v46-skill-installations-cascade.js +107 -0
  452. package/dist/server/src/lib/db/migrations/v47-skill-installations-roots.js +70 -0
  453. package/dist/server/src/lib/db/worktree-db.js +9 -4
  454. package/dist/server/src/lib/git/git-errors.js +336 -0
  455. package/dist/server/src/lib/git/git-exec.js +285 -0
  456. package/dist/server/src/lib/skills/compatibility.js +194 -0
  457. package/dist/server/src/lib/skills/constants.js +252 -0
  458. package/dist/server/src/lib/skills/errors.js +82 -0
  459. package/dist/server/src/lib/skills/index.js +91 -0
  460. package/dist/server/src/lib/skills/install-apply.js +670 -0
  461. package/dist/server/src/lib/skills/install-plan.js +582 -0
  462. package/dist/server/src/lib/skills/installed-state.js +127 -0
  463. package/dist/server/src/lib/skills/integrity.js +225 -0
  464. package/dist/server/src/lib/skills/json-schema.js +365 -0
  465. package/dist/server/src/lib/skills/operation-audit.js +120 -0
  466. package/dist/server/src/lib/skills/operation-journal.js +286 -0
  467. package/dist/server/src/lib/skills/operation-lock.js +339 -0
  468. package/dist/server/src/lib/skills/operation-reconciler.js +107 -0
  469. package/dist/server/src/lib/skills/operation-store.js +153 -0
  470. package/dist/server/src/lib/skills/package-reader.js +495 -0
  471. package/dist/server/src/lib/skills/package-validator.js +451 -0
  472. package/dist/server/src/lib/skills/preview-diff.js +627 -0
  473. package/dist/server/src/lib/skills/safe-yaml.js +593 -0
  474. package/dist/server/src/lib/skills/schema.js +1248 -0
  475. package/dist/server/src/lib/skills/semver.js +193 -0
  476. package/dist/server/src/lib/skills/snapshot-store.js +334 -0
  477. package/dist/server/src/lib/skills/startup-reconcile.js +138 -0
  478. package/dist/server/src/lib/skills/uninstall-apply.js +495 -0
  479. package/dist/server/src/lib/skills/uninstall-plan.js +479 -0
  480. package/dist/server/src/types/skills.js +17 -0
  481. package/package.json +1 -1
  482. package/.next/server/chunks/129.js +0 -1
  483. package/.next/server/chunks/2478.js +0 -1
  484. package/.next/server/chunks/9886.js +0 -1
  485. package/.next/static/0_lnKsT0DH-MnHhnV5n-l/_buildManifest.js +0 -1
  486. package/.next/static/chunks/3165-87bf884f7f3d15cf.js +0 -1
  487. package/.next/static/chunks/6416.6756b7ad06dd96f7.js +0 -1
  488. package/.next/static/chunks/8676.57260a06f6554e7e.js +0 -1
  489. package/.next/static/chunks/app/api/app/update/route-7536041a7a89616d.js +0 -1
  490. package/.next/static/chunks/app/api/app/update-check/route-7536041a7a89616d.js +0 -1
  491. package/.next/static/chunks/app/api/assistant/conversation/route-7536041a7a89616d.js +0 -1
  492. package/.next/static/chunks/app/api/assistant/current-output/route-7536041a7a89616d.js +0 -1
  493. package/.next/static/chunks/app/api/assistant/messages/route-7536041a7a89616d.js +0 -1
  494. package/.next/static/chunks/app/api/assistant/session/route-7536041a7a89616d.js +0 -1
  495. package/.next/static/chunks/app/api/assistant/start/route-7536041a7a89616d.js +0 -1
  496. package/.next/static/chunks/app/api/assistant/terminal/route-7536041a7a89616d.js +0 -1
  497. package/.next/static/chunks/app/api/assistant/tools/route-7536041a7a89616d.js +0 -1
  498. package/.next/static/chunks/app/api/auth/login/route-7536041a7a89616d.js +0 -1
  499. package/.next/static/chunks/app/api/auth/logout/route-7536041a7a89616d.js +0 -1
  500. package/.next/static/chunks/app/api/auth/status/route-7536041a7a89616d.js +0 -1
  501. package/.next/static/chunks/app/api/daily-summary/route-7536041a7a89616d.js +0 -1
  502. package/.next/static/chunks/app/api/daily-summary/status/route-7536041a7a89616d.js +0 -1
  503. package/.next/static/chunks/app/api/external-apps/[id]/health/route-7536041a7a89616d.js +0 -1
  504. package/.next/static/chunks/app/api/external-apps/[id]/route-7536041a7a89616d.js +0 -1
  505. package/.next/static/chunks/app/api/external-apps/route-7536041a7a89616d.js +0 -1
  506. package/.next/static/chunks/app/api/hooks/claude-done/route-7536041a7a89616d.js +0 -1
  507. package/.next/static/chunks/app/api/ollama/models/route-7536041a7a89616d.js +0 -1
  508. package/.next/static/chunks/app/api/push/subscriptions/route-7536041a7a89616d.js +0 -1
  509. package/.next/static/chunks/app/api/push/vapid/route-7536041a7a89616d.js +0 -1
  510. package/.next/static/chunks/app/api/repositories/[id]/route-7536041a7a89616d.js +0 -1
  511. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-7536041a7a89616d.js +0 -1
  512. package/.next/static/chunks/app/api/repositories/[id]/todos/route-7536041a7a89616d.js +0 -1
  513. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-7536041a7a89616d.js +0 -1
  514. package/.next/static/chunks/app/api/repositories/clone/route-7536041a7a89616d.js +0 -1
  515. package/.next/static/chunks/app/api/repositories/excluded/route-7536041a7a89616d.js +0 -1
  516. package/.next/static/chunks/app/api/repositories/restore/route-7536041a7a89616d.js +0 -1
  517. package/.next/static/chunks/app/api/repositories/route-7536041a7a89616d.js +0 -1
  518. package/.next/static/chunks/app/api/repositories/scan/route-7536041a7a89616d.js +0 -1
  519. package/.next/static/chunks/app/api/repositories/sync/route-7536041a7a89616d.js +0 -1
  520. package/.next/static/chunks/app/api/sidebar/group-order/route-7536041a7a89616d.js +0 -1
  521. package/.next/static/chunks/app/api/slash-commands/route-7536041a7a89616d.js +0 -1
  522. package/.next/static/chunks/app/api/templates/[id]/route-7536041a7a89616d.js +0 -1
  523. package/.next/static/chunks/app/api/templates/route-7536041a7a89616d.js +0 -1
  524. package/.next/static/chunks/app/api/todos/route-7536041a7a89616d.js +0 -1
  525. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-7536041a7a89616d.js +0 -1
  526. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-7536041a7a89616d.js +0 -1
  527. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-7536041a7a89616d.js +0 -1
  528. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-7536041a7a89616d.js +0 -1
  529. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-7536041a7a89616d.js +0 -1
  530. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-7536041a7a89616d.js +0 -1
  531. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-7536041a7a89616d.js +0 -1
  532. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-7536041a7a89616d.js +0 -1
  533. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-7536041a7a89616d.js +0 -1
  534. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-7536041a7a89616d.js +0 -1
  535. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-7536041a7a89616d.js +0 -1
  536. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-7536041a7a89616d.js +0 -1
  537. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-7536041a7a89616d.js +0 -1
  538. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-7536041a7a89616d.js +0 -1
  539. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-7536041a7a89616d.js +0 -1
  540. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-7536041a7a89616d.js +0 -1
  541. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-7536041a7a89616d.js +0 -1
  542. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-7536041a7a89616d.js +0 -1
  543. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-7536041a7a89616d.js +0 -1
  544. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-7536041a7a89616d.js +0 -1
  545. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-7536041a7a89616d.js +0 -1
  546. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-7536041a7a89616d.js +0 -1
  547. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-7536041a7a89616d.js +0 -1
  548. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-7536041a7a89616d.js +0 -1
  549. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-7536041a7a89616d.js +0 -1
  550. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-7536041a7a89616d.js +0 -1
  551. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-7536041a7a89616d.js +0 -1
  552. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-7536041a7a89616d.js +0 -1
  553. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-7536041a7a89616d.js +0 -1
  554. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-7536041a7a89616d.js +0 -1
  555. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-7536041a7a89616d.js +0 -1
  556. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-7536041a7a89616d.js +0 -1
  557. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-7536041a7a89616d.js +0 -1
  558. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-7536041a7a89616d.js +0 -1
  559. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-7536041a7a89616d.js +0 -1
  560. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-7536041a7a89616d.js +0 -1
  561. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-7536041a7a89616d.js +0 -1
  562. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-7536041a7a89616d.js +0 -1
  563. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-7536041a7a89616d.js +0 -1
  564. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-7536041a7a89616d.js +0 -1
  565. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-7536041a7a89616d.js +0 -1
  566. package/.next/static/chunks/app/api/worktrees/[id]/route-7536041a7a89616d.js +0 -1
  567. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-7536041a7a89616d.js +0 -1
  568. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-7536041a7a89616d.js +0 -1
  569. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-7536041a7a89616d.js +0 -1
  570. package/.next/static/chunks/app/api/worktrees/[id]/search/route-7536041a7a89616d.js +0 -1
  571. package/.next/static/chunks/app/api/worktrees/[id]/send/route-7536041a7a89616d.js +0 -1
  572. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-7536041a7a89616d.js +0 -1
  573. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-7536041a7a89616d.js +0 -1
  574. package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-7536041a7a89616d.js +0 -1
  575. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-7536041a7a89616d.js +0 -1
  576. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-7536041a7a89616d.js +0 -1
  577. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-7536041a7a89616d.js +0 -1
  578. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-7536041a7a89616d.js +0 -1
  579. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-7536041a7a89616d.js +0 -1
  580. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-7536041a7a89616d.js +0 -1
  581. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-7536041a7a89616d.js +0 -1
  582. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-7536041a7a89616d.js +0 -1
  583. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-7536041a7a89616d.js +0 -1
  584. package/.next/static/chunks/app/api/worktrees/route-7536041a7a89616d.js +0 -1
  585. package/.next/static/chunks/app/manifest.webmanifest/route-7536041a7a89616d.js +0 -1
  586. package/.next/static/chunks/app/proxy/[...path]/route-7536041a7a89616d.js +0 -1
  587. package/.next/static/chunks/app/worktrees/[id]/page-9a4ce51e697baac6.js +0 -1
  588. package/.next/static/chunks/app/worktrees/[id]/terminal/page-ed4590b024edd8d6.js +0 -1
  589. package/.next/static/chunks/webpack-2e3739a831868daa.js +0 -1
  590. package/.next/static/css/d7e2e8d1b8d69d36.css +0 -1
  591. /package/.next/static/{0_lnKsT0DH-MnHhnV5n-l → D-aoE4gWfuCUN0GqEPIX3}/_ssgManifest.js +0 -0
@@ -0,0 +1,670 @@
1
+ "use strict";
2
+ /**
3
+ * Atomic commit of a planned Skill install into one worktree (Issue #1235)
4
+ *
5
+ * The write half of the plan/apply pair. #1233 fixed *what* would be written —
6
+ * the exact payload bytes, the exact receipt bytes and the tree hash they add up
7
+ * to — and this module is the only place those bytes reach a repository.
8
+ *
9
+ * Four properties carry the safety argument:
10
+ *
11
+ * - **The destination is derived, never received.** The install root comes from
12
+ * a server-resolved worktree path plus a Skill ID re-checked against
13
+ * {@link SKILL_ID_PATTERN}. Re-checking the grammar rather than only the
14
+ * joined result is deliberate: `path.join` normalizes `..` away, so
15
+ * `.agents/skills/../x` and `.agents/x` compare equal and a containment check
16
+ * alone would accept an ID that walked out of the Skills directory.
17
+ * - **Every write is exclusive and does not follow links.** Files are created
18
+ * with `O_CREAT|O_EXCL|O_NOFOLLOW`, so a symlink or a file planted between the
19
+ * directory scan and the write cannot be written *through*; mode and digest
20
+ * are re-read afterwards, so a file that changed underneath us never reaches
21
+ * the receipt.
22
+ * - **The commit point is one rename.** Staging lives in the reserved
23
+ * `.agents/skills/.commandmate-staging/` namespace, on the same filesystem as
24
+ * the destination, so `rename(2)` is atomic. Before it lands the destination
25
+ * is proven absent: an existing directory — managed or hand-made — is refused,
26
+ * never merged into and never implicitly overwritten.
27
+ * - **Nothing is executed.** No script, hook, install step or archive-carried
28
+ * mode is ever run or honoured. Modes are assigned from the manifest's
29
+ * declared executable bit and nothing else.
30
+ *
31
+ * A failure *after* the rename is not a rollback. The payload exists, and the
32
+ * caller must report it as committed and hand the remainder to #1234
33
+ * reconciliation rather than claiming the worktree is unchanged.
34
+ *
35
+ * @module lib/skills/install-apply
36
+ */
37
+ var __importDefault = (this && this.__importDefault) || function (mod) {
38
+ return (mod && mod.__esModule) ? mod : { "default": mod };
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.SKILL_INSTALL_NEXT_ACTION_KEYS = exports.SKILL_INSTALL_RELOAD_MESSAGE_KEYS = exports.SkillInstallError = exports.SKILL_INSTALL_ERROR_STATUS = exports.SkillInstallErrorCode = exports.SKILL_INSTALL_OPERATION_ID_PATTERN = exports.SKILL_INSTALL_EXECUTABLE_MODE = exports.SKILL_INSTALL_FILE_MODE = exports.SKILL_INSTALL_DIR_MODE = void 0;
42
+ exports.isSkillInstallError = isSkillInstallError;
43
+ exports.buildSkillReloadGuidance = buildSkillReloadGuidance;
44
+ exports.resolveSkillInstallTarget = resolveSkillInstallTarget;
45
+ exports.resolveSkillInstallTargetFor = resolveSkillInstallTargetFor;
46
+ exports.inspectSkillDestination = inspectSkillDestination;
47
+ exports.hasCommittedSkillPayload = hasCommittedSkillPayload;
48
+ exports.writeSkillPayloadFile = writeSkillPayloadFile;
49
+ exports.applySkillInstall = applySkillInstall;
50
+ exports.completeSecondarySkillInstallRoots = completeSecondarySkillInstallRoots;
51
+ exports.cleanupSkillInstallStaging = cleanupSkillInstallStaging;
52
+ const fs_1 = require("fs");
53
+ const crypto_1 = require("crypto");
54
+ const path_1 = __importDefault(require("path"));
55
+ const constants_1 = require("../../lib/skills/constants");
56
+ const integrity_1 = require("../../lib/skills/integrity");
57
+ const operation_store_1 = require("../../lib/skills/operation-store");
58
+ const preview_diff_1 = require("../../lib/skills/preview-diff");
59
+ const install_plan_1 = require("../../lib/skills/install-plan");
60
+ // =============================================================================
61
+ // Modes and layout
62
+ // =============================================================================
63
+ /** Payload directories are owner-only, like the staging that produced them. */
64
+ exports.SKILL_INSTALL_DIR_MODE = 0o700;
65
+ /** Ordinary payload files. */
66
+ exports.SKILL_INSTALL_FILE_MODE = 0o600;
67
+ /** Files the manifest declared executable. Only the owner execute bit is added. */
68
+ exports.SKILL_INSTALL_EXECUTABLE_MODE = 0o700;
69
+ /**
70
+ * Grammar of the staging directory name.
71
+ *
72
+ * The name is a server-generated operation ID and never a client string, but it
73
+ * becomes a path segment, so it is checked rather than trusted.
74
+ */
75
+ exports.SKILL_INSTALL_OPERATION_ID_PATTERN = /^[0-9a-zA-Z-]{8,64}$/;
76
+ /** `O_NOFOLLOW` is POSIX-only; on platforms without it the flag is a no-op. */
77
+ const O_NOFOLLOW = fs_1.constants.O_NOFOLLOW ?? 0;
78
+ // =============================================================================
79
+ // Errors
80
+ // =============================================================================
81
+ /** Client-safe reasons an apply refused to write or could not finish. */
82
+ exports.SkillInstallErrorCode = {
83
+ /** The install root could not be derived safely from the worktree and Skill ID. */
84
+ TARGET_UNSAFE: 'SKILL_INSTALL_TARGET_UNSAFE',
85
+ /** An ancestor of the install root is a symlink or is not a directory. */
86
+ ANCESTOR_UNSAFE: 'SKILL_INSTALL_ANCESTOR_UNSAFE',
87
+ /** A CommandMate-managed install is already present. Updating is out of scope. */
88
+ DESTINATION_EXISTS: 'SKILL_INSTALL_DESTINATION_EXISTS',
89
+ /** Something CommandMate does not manage occupies the install root. */
90
+ DESTINATION_UNMANAGED: 'SKILL_INSTALL_DESTINATION_UNMANAGED',
91
+ /** Staging and destination are on different filesystems, so rename is not atomic. */
92
+ CROSS_DEVICE: 'SKILL_INSTALL_CROSS_DEVICE',
93
+ /** Staging could not be created or written. */
94
+ STAGING_IO: 'SKILL_INSTALL_STAGING_IO',
95
+ /** What landed in staging is not what the plan fixed. */
96
+ PAYLOAD_MISMATCH: 'SKILL_INSTALL_PAYLOAD_MISMATCH',
97
+ /** The atomic rename itself failed. Nothing was published. */
98
+ COMMIT_FAILED: 'SKILL_INSTALL_COMMIT_FAILED',
99
+ };
100
+ /** HTTP status each reason maps to, so every caller answers alike. */
101
+ exports.SKILL_INSTALL_ERROR_STATUS = {
102
+ [exports.SkillInstallErrorCode.TARGET_UNSAFE]: 400,
103
+ [exports.SkillInstallErrorCode.ANCESTOR_UNSAFE]: 409,
104
+ [exports.SkillInstallErrorCode.DESTINATION_EXISTS]: 409,
105
+ [exports.SkillInstallErrorCode.DESTINATION_UNMANAGED]: 409,
106
+ [exports.SkillInstallErrorCode.CROSS_DEVICE]: 500,
107
+ [exports.SkillInstallErrorCode.STAGING_IO]: 500,
108
+ [exports.SkillInstallErrorCode.PAYLOAD_MISMATCH]: 500,
109
+ [exports.SkillInstallErrorCode.COMMIT_FAILED]: 500,
110
+ };
111
+ /** An apply rejection. The message is built from the code — never from a path. */
112
+ class SkillInstallError extends Error {
113
+ code;
114
+ detail;
115
+ constructor(code, detail) {
116
+ super(`Skill install rejected: ${code}`);
117
+ this.code = code;
118
+ this.detail = detail;
119
+ this.name = 'SkillInstallError';
120
+ }
121
+ get status() {
122
+ return exports.SKILL_INSTALL_ERROR_STATUS[this.code];
123
+ }
124
+ }
125
+ exports.SkillInstallError = SkillInstallError;
126
+ function isSkillInstallError(value) {
127
+ return value instanceof SkillInstallError;
128
+ }
129
+ function fail(code, detail) {
130
+ throw new SkillInstallError(code, detail);
131
+ }
132
+ // =============================================================================
133
+ // Reload guidance
134
+ // =============================================================================
135
+ /** i18n key per agent support level, so UI and CLI say the same thing (UX-01). */
136
+ exports.SKILL_INSTALL_RELOAD_MESSAGE_KEYS = {
137
+ native: 'skills.install.reload.native',
138
+ commandmate_runtime: 'skills.install.reload.commandmateRuntime',
139
+ unsupported: 'skills.install.reload.unsupported',
140
+ unknown: 'skills.install.reload.unknown',
141
+ };
142
+ /** i18n key for what the user should do next, per outcome (UX-07). */
143
+ exports.SKILL_INSTALL_NEXT_ACTION_KEYS = {
144
+ succeeded: 'skills.install.nextAction.succeeded',
145
+ committedReconciling: 'skills.install.nextAction.committedReconciling',
146
+ failed: 'skills.install.nextAction.failed',
147
+ };
148
+ /**
149
+ * Derive reload guidance from the receipt.
150
+ *
151
+ * The receipt is used rather than the Catalog because it is the record of what
152
+ * actually landed: guidance for a version other than the installed one would be
153
+ * worse than none.
154
+ */
155
+ function buildSkillReloadGuidance(receipt) {
156
+ return {
157
+ skillId: receipt.skill_id,
158
+ version: receipt.version,
159
+ installRoot: receipt.install_root,
160
+ agents: receipt.agent_compatibility.map((entry) => ({
161
+ agent: entry.agent,
162
+ support: entry.support,
163
+ messageKey: exports.SKILL_INSTALL_RELOAD_MESSAGE_KEYS[entry.support],
164
+ })),
165
+ };
166
+ }
167
+ // =============================================================================
168
+ // Path safety
169
+ // =============================================================================
170
+ /**
171
+ * Absolute install root for a validated Skill ID inside a server-resolved worktree.
172
+ *
173
+ * Delegates to #1233's resolver so plan and apply cannot disagree about where a
174
+ * Skill lives, and re-checks the ID here as well: this module must be safe to
175
+ * call without a plan, for instance from reconciliation.
176
+ */
177
+ function resolveSkillInstallTarget(worktreePath, skillId) {
178
+ return resolveSkillInstallTargetFor(worktreePath, constants_1.SKILL_INSTALL_ROOT_PREFIX, skillId);
179
+ }
180
+ /**
181
+ * Absolute install root for a validated Skill ID under one root prefix (#1460).
182
+ *
183
+ * The per-root generalization of {@link resolveSkillInstallTarget}: `.claude/skills`
184
+ * gets exactly the grammar re-check and containment rejection `.agents/skills`
185
+ * always had, so neither root can be walked out of by a crafted ID.
186
+ */
187
+ function resolveSkillInstallTargetFor(worktreePath, rootPrefix, skillId) {
188
+ if (!constants_1.SKILL_ID_PATTERN.test(skillId) || skillId.length > constants_1.SKILL_ID_MAX_LENGTH) {
189
+ fail(exports.SkillInstallErrorCode.TARGET_UNSAFE, { reason: 'skill-id' });
190
+ }
191
+ try {
192
+ return (0, preview_diff_1.resolveSkillInstallRootFor)(worktreePath, rootPrefix, skillId);
193
+ }
194
+ catch {
195
+ return fail(exports.SkillInstallErrorCode.TARGET_UNSAFE, { reason: 'install-root' });
196
+ }
197
+ }
198
+ /**
199
+ * Prove no ancestor of the install root was swapped for a link.
200
+ *
201
+ * `lstat` at every level from the worktree down: a symlink anywhere on the chain
202
+ * would let the rename publish the payload outside the registered worktree, and
203
+ * `realpath` alone would silently *follow* it instead of refusing.
204
+ */
205
+ function assertAncestorsAreRealDirectories(worktreeRealPath, worktreePath, rootPrefix = constants_1.SKILL_INSTALL_ROOT_PREFIX) {
206
+ let resolved;
207
+ try {
208
+ resolved = (0, fs_1.realpathSync)(worktreePath);
209
+ }
210
+ catch {
211
+ return fail(exports.SkillInstallErrorCode.ANCESTOR_UNSAFE, { reason: 'worktree-unresolvable' });
212
+ }
213
+ if (resolved !== worktreeRealPath) {
214
+ fail(exports.SkillInstallErrorCode.ANCESTOR_UNSAFE, { reason: 'worktree-identity' });
215
+ }
216
+ let walked = worktreeRealPath;
217
+ for (const segment of rootPrefix.split('/')) {
218
+ walked = path_1.default.join(walked, segment);
219
+ let stats;
220
+ try {
221
+ stats = (0, fs_1.lstatSync)(walked);
222
+ }
223
+ catch {
224
+ // Not yet created is fine; it is created below with a plain mkdir.
225
+ return;
226
+ }
227
+ if (stats.isSymbolicLink() || !stats.isDirectory()) {
228
+ fail(exports.SkillInstallErrorCode.ANCESTOR_UNSAFE, { reason: 'not-a-directory' });
229
+ }
230
+ }
231
+ }
232
+ /**
233
+ * Describe the install root without following anything.
234
+ *
235
+ * A non-directory at the install root (a file, a symlink) counts as present and
236
+ * unmanaged: it is not something an install may quietly replace.
237
+ */
238
+ function inspectSkillDestination(installRootAbs) {
239
+ let stats;
240
+ try {
241
+ stats = (0, fs_1.lstatSync)(installRootAbs);
242
+ }
243
+ catch {
244
+ return { present: false, managed: false, version: null };
245
+ }
246
+ if (stats.isSymbolicLink() || !stats.isDirectory()) {
247
+ return { present: true, managed: false, version: null };
248
+ }
249
+ try {
250
+ const receipt = (0, install_plan_1.parseInstalledReceipt)((0, fs_1.readFileSync)(path_1.default.join(installRootAbs, install_plan_1.SKILL_RECEIPT_FILENAME)));
251
+ if (receipt)
252
+ return { present: true, managed: true, version: receipt.version };
253
+ }
254
+ catch {
255
+ // No readable receipt: the directory exists but CommandMate did not write it.
256
+ }
257
+ return { present: true, managed: false, version: null };
258
+ }
259
+ /**
260
+ * Whether the payload a committed operation wrote is still on disk.
261
+ *
262
+ * The port #1234's reconciler needs: it decides between "converge forward" and
263
+ * "genuinely rolled back", and only the receipt digest can distinguish the
264
+ * install that committed from a different one that happens to share the path.
265
+ */
266
+ function hasCommittedSkillPayload(worktreePath, skillId, receiptDigest) {
267
+ let installRootAbs;
268
+ try {
269
+ installRootAbs = resolveSkillInstallTarget(worktreePath, skillId);
270
+ }
271
+ catch {
272
+ return false;
273
+ }
274
+ let bytes;
275
+ try {
276
+ bytes = (0, fs_1.readFileSync)(path_1.default.join(installRootAbs, install_plan_1.SKILL_RECEIPT_FILENAME));
277
+ }
278
+ catch {
279
+ return false;
280
+ }
281
+ if ((0, install_plan_1.parseInstalledReceipt)(bytes) === null)
282
+ return false;
283
+ return receiptDigest === null || (0, integrity_1.digestMatches)((0, integrity_1.computeSha256Hex)(bytes), receiptDigest);
284
+ }
285
+ // =============================================================================
286
+ // Staging
287
+ // =============================================================================
288
+ function makeDirectory(target, mode, recursive) {
289
+ try {
290
+ (0, fs_1.mkdirSync)(target, { mode, recursive });
291
+ }
292
+ catch {
293
+ fail(exports.SkillInstallErrorCode.STAGING_IO, { reason: 'mkdir' });
294
+ }
295
+ let stats;
296
+ try {
297
+ stats = (0, fs_1.lstatSync)(target);
298
+ }
299
+ catch {
300
+ return fail(exports.SkillInstallErrorCode.STAGING_IO, { reason: 'mkdir-verify' });
301
+ }
302
+ if (stats.isSymbolicLink() || !stats.isDirectory()) {
303
+ fail(exports.SkillInstallErrorCode.STAGING_IO, { reason: 'not-a-directory' });
304
+ }
305
+ }
306
+ /**
307
+ * Write one file and prove afterwards that it is the file we meant to write.
308
+ *
309
+ * `O_EXCL` means an existing path is never written to, and `O_NOFOLLOW` means a
310
+ * symlink planted at that path is refused rather than followed — together they
311
+ * make "the write landed somewhere else" unrepresentable. The post-write checks
312
+ * are not belt-and-braces either: `nlink !== 1` would mean the path was
313
+ * hard-linked elsewhere, and a digest read back through the same path is the
314
+ * only evidence that what a later reader sees matches the plan.
315
+ *
316
+ * @internal Exported for the guard tests; callers use {@link applySkillInstall}.
317
+ */
318
+ function writeSkillPayloadFile(target, bytes, executable) {
319
+ const mode = executable ? exports.SKILL_INSTALL_EXECUTABLE_MODE : exports.SKILL_INSTALL_FILE_MODE;
320
+ let fd;
321
+ try {
322
+ fd = (0, fs_1.openSync)(target, fs_1.constants.O_WRONLY | fs_1.constants.O_CREAT | fs_1.constants.O_EXCL | O_NOFOLLOW, mode);
323
+ }
324
+ catch {
325
+ return fail(exports.SkillInstallErrorCode.STAGING_IO, { reason: 'open' });
326
+ }
327
+ try {
328
+ let written = 0;
329
+ while (written < bytes.byteLength) {
330
+ written += (0, fs_1.writeSync)(fd, bytes, written, bytes.byteLength - written);
331
+ }
332
+ }
333
+ catch {
334
+ (0, fs_1.closeSync)(fd);
335
+ return fail(exports.SkillInstallErrorCode.STAGING_IO, { reason: 'write' });
336
+ }
337
+ (0, fs_1.closeSync)(fd);
338
+ const stats = (0, fs_1.lstatSync)(target);
339
+ if (!stats.isFile() || stats.nlink !== 1 || stats.size !== bytes.byteLength) {
340
+ fail(exports.SkillInstallErrorCode.STAGING_IO, { reason: 'verify-stat' });
341
+ }
342
+ if (((stats.mode & 0o111) !== 0) !== executable) {
343
+ fail(exports.SkillInstallErrorCode.STAGING_IO, { reason: 'verify-mode' });
344
+ }
345
+ if (!(0, integrity_1.digestMatches)((0, integrity_1.computeSha256Hex)((0, fs_1.readFileSync)(target)), (0, integrity_1.computeSha256Hex)(bytes))) {
346
+ fail(exports.SkillInstallErrorCode.PAYLOAD_MISMATCH, { reason: 'readback' });
347
+ }
348
+ }
349
+ /** Re-read a staged tree from disk, so verification never trusts its own inputs. */
350
+ function readStagedTree(stagingDir) {
351
+ const files = [];
352
+ const walk = (dirAbs, relPrefix) => {
353
+ for (const entry of (0, fs_1.readdirSync)(dirAbs, { withFileTypes: true })) {
354
+ const relative = relPrefix ? `${relPrefix}/${entry.name}` : entry.name;
355
+ const absolute = path_1.default.join(dirAbs, entry.name);
356
+ const stats = (0, fs_1.lstatSync)(absolute);
357
+ if (stats.isDirectory()) {
358
+ walk(absolute, relative);
359
+ continue;
360
+ }
361
+ if (!stats.isFile()) {
362
+ fail(exports.SkillInstallErrorCode.PAYLOAD_MISMATCH, { reason: 'irregular-staged-entry' });
363
+ }
364
+ files.push({
365
+ path: relative,
366
+ sha256: (0, integrity_1.computeSha256Hex)((0, fs_1.readFileSync)(absolute)),
367
+ executable: (stats.mode & 0o111) !== 0,
368
+ });
369
+ }
370
+ };
371
+ walk(stagingDir, '');
372
+ return files;
373
+ }
374
+ /**
375
+ * Stage, verify and atomically publish one Skill install.
376
+ *
377
+ * Everything before the `renameSync` is undoable and is undone on any failure:
378
+ * the staging directory is removed and the destination is untouched. Everything
379
+ * after it is not, which is why the rename is the last thing that happens and
380
+ * why the caller records `FS_COMMITTED` the moment this returns.
381
+ *
382
+ * @throws SkillInstallError — the destination was not modified in every case.
383
+ */
384
+ function applySkillInstall(input) {
385
+ if (!exports.SKILL_INSTALL_OPERATION_ID_PATTERN.test(input.operationId)) {
386
+ fail(exports.SkillInstallErrorCode.STAGING_IO, { reason: 'operation-id' });
387
+ }
388
+ const rootPrefixes = input.rootPrefixes && input.rootPrefixes.length > 0
389
+ ? [...input.rootPrefixes]
390
+ : [constants_1.SKILL_INSTALL_ROOT_PREFIX];
391
+ // The payload is identical across roots: read and digest-verify it once, then
392
+ // stage the same bytes into each root (#1460).
393
+ const payload = input.snapshot.files.map((file) => {
394
+ const bytes = input.snapshot.readFile(file.path);
395
+ if (!(0, integrity_1.digestMatches)((0, integrity_1.computeSha256Hex)(bytes), file.sha256)) {
396
+ fail(exports.SkillInstallErrorCode.PAYLOAD_MISMATCH, { reason: 'snapshot-digest' });
397
+ }
398
+ return { relativePath: file.path, bytes, executable: file.executable };
399
+ });
400
+ const directories = directoriesFor(input.snapshot.files.map((f) => f.path), input.snapshot.directories);
401
+ // Every destination is proven safe and absent *before* the primary commits, so
402
+ // a secondary that is already blocked cannot leave a committed primary behind.
403
+ for (const prefix of rootPrefixes) {
404
+ const abs = resolveSkillInstallTargetFor(input.worktreePath, prefix, input.skillId);
405
+ assertAncestorsAreRealDirectories(input.worktreeRealPath, input.worktreePath, prefix);
406
+ const destination = inspectSkillDestination(abs);
407
+ if (destination.present) {
408
+ fail(destination.managed
409
+ ? exports.SkillInstallErrorCode.DESTINATION_EXISTS
410
+ : exports.SkillInstallErrorCode.DESTINATION_UNMANAGED, destination.version ? { version: destination.version } : undefined);
411
+ }
412
+ }
413
+ const committedRoots = [];
414
+ const pendingRoots = [];
415
+ for (let index = 0; index < rootPrefixes.length; index += 1) {
416
+ const prefix = rootPrefixes[index];
417
+ try {
418
+ stageAndCommitSkillRoot({
419
+ worktreePath: input.worktreePath,
420
+ worktreeRealPath: input.worktreeRealPath,
421
+ rootPrefix: prefix,
422
+ skillId: input.skillId,
423
+ operationId: input.operationId,
424
+ payload,
425
+ directories,
426
+ receiptBytes: input.receiptBytes,
427
+ plannedTreeHash: input.plannedTreeHash,
428
+ });
429
+ committedRoots.push((0, preview_diff_1.skillInstallRootFor)(prefix, input.skillId));
430
+ }
431
+ catch (error) {
432
+ // The primary rename is the commit point. A failure there published
433
+ // nothing, so it rolls back cleanly and is rethrown. A failure at a
434
+ // secondary root leaves the primary committed: the operation is
435
+ // *committed, reconciling*, and the remaining roots are handed to #1234.
436
+ if (index === 0)
437
+ throw error;
438
+ for (let rest = index; rest < rootPrefixes.length; rest += 1) {
439
+ pendingRoots.push((0, preview_diff_1.skillInstallRootFor)(rootPrefixes[rest], input.skillId));
440
+ }
441
+ break;
442
+ }
443
+ }
444
+ const installRoots = rootPrefixes.map((prefix) => (0, preview_diff_1.skillInstallRootFor)(prefix, input.skillId));
445
+ const installRootRel = installRoots[0];
446
+ const receiptSha256 = (0, integrity_1.computeSha256Hex)(input.receiptBytes);
447
+ return {
448
+ installRoot: installRootRel,
449
+ installRoots,
450
+ committedRoots,
451
+ pendingRoots,
452
+ reconciling: pendingRoots.length > 0,
453
+ receiptPath: `${installRootRel}/${install_plan_1.SKILL_RECEIPT_FILENAME}`,
454
+ receiptSha256,
455
+ receiptSize: input.receiptBytes.byteLength,
456
+ files: input.snapshot.files.map((file) => ({
457
+ path: file.path,
458
+ sha256: file.sha256,
459
+ size: file.size,
460
+ executable: file.executable,
461
+ })),
462
+ treeHash: input.plannedTreeHash,
463
+ };
464
+ }
465
+ /** Sorted set of directories a payload implies, plus any the package declared. */
466
+ function directoriesFor(filePaths, declared = []) {
467
+ const directories = new Set(declared);
468
+ for (const filePath of filePaths) {
469
+ const parents = filePath.split('/').slice(0, -1);
470
+ let walked = '';
471
+ for (const segment of parents) {
472
+ walked = walked === '' ? segment : `${walked}/${segment}`;
473
+ directories.add(walked);
474
+ }
475
+ }
476
+ return [...directories].sort();
477
+ }
478
+ /**
479
+ * Stage the verified payload into one root and atomically publish it (#1460).
480
+ *
481
+ * The single-root commit #1235 built, lifted to take the root prefix as a
482
+ * parameter: staging lives under *that* root's reserved namespace so the rename
483
+ * stays on one filesystem, and every check — ancestor lstat walk, exclusive
484
+ * no-follow writes, tree-hash gate, destination-absent, same-filesystem — is
485
+ * applied per root. Throws {@link SkillInstallError} on any failure, having
486
+ * removed its own staging; the destination is untouched unless the rename ran.
487
+ */
488
+ function stageAndCommitSkillRoot(input) {
489
+ const installRootAbs = resolveSkillInstallTargetFor(input.worktreePath, input.rootPrefix, input.skillId);
490
+ assertAncestorsAreRealDirectories(input.worktreeRealPath, input.worktreePath, input.rootPrefix);
491
+ const destinationBefore = inspectSkillDestination(installRootAbs);
492
+ if (destinationBefore.present) {
493
+ fail(destinationBefore.managed
494
+ ? exports.SkillInstallErrorCode.DESTINATION_EXISTS
495
+ : exports.SkillInstallErrorCode.DESTINATION_UNMANAGED, destinationBefore.version ? { version: destinationBefore.version } : undefined);
496
+ }
497
+ const stagingRoot = (0, operation_store_1.getSkillInstallStagingRoot)(input.worktreePath, input.rootPrefix);
498
+ makeDirectory(path_1.default.dirname(stagingRoot), 0o755, true);
499
+ makeDirectory(stagingRoot, exports.SKILL_INSTALL_DIR_MODE, true);
500
+ // Not recursive: a staging directory that already exists means another
501
+ // operation is using this ID, and silently adopting it would merge two writes.
502
+ const stagingDir = path_1.default.join(stagingRoot, input.operationId);
503
+ makeDirectory(stagingDir, exports.SKILL_INSTALL_DIR_MODE, false);
504
+ try {
505
+ for (const directory of input.directories) {
506
+ makeDirectory(path_1.default.join(stagingDir, directory), exports.SKILL_INSTALL_DIR_MODE, false);
507
+ }
508
+ for (const file of input.payload) {
509
+ // The execute bit comes from the reconciled inventory, which is also what
510
+ // the plan hashed — never from the archive header, which is attacker data.
511
+ writeSkillPayloadFile(path_1.default.join(stagingDir, file.relativePath), file.bytes, file.executable);
512
+ }
513
+ // The receipt is written last and from the plan's own bytes: rebuilding it
514
+ // here would make the file the user previewed and the file on disk two
515
+ // different artifacts that merely ought to agree.
516
+ writeSkillPayloadFile(path_1.default.join(stagingDir, install_plan_1.SKILL_RECEIPT_FILENAME), input.receiptBytes, false);
517
+ const staged = readStagedTree(stagingDir);
518
+ const treeHash = (0, preview_diff_1.computeSkillTreeHash)(staged);
519
+ if (treeHash !== input.plannedTreeHash) {
520
+ fail(exports.SkillInstallErrorCode.PAYLOAD_MISMATCH, { reason: 'tree-hash' });
521
+ }
522
+ assertSameFilesystem(stagingDir, path_1.default.dirname(installRootAbs));
523
+ // Re-checked immediately before the rename rather than only at entry: the
524
+ // exclusive lock keeps CommandMate out, but nothing keeps the user's own
525
+ // editor from creating this directory while the payload was being staged.
526
+ assertAncestorsAreRealDirectories(input.worktreeRealPath, input.worktreePath, input.rootPrefix);
527
+ const destinationNow = inspectSkillDestination(installRootAbs);
528
+ if (destinationNow.present) {
529
+ fail(destinationNow.managed
530
+ ? exports.SkillInstallErrorCode.DESTINATION_EXISTS
531
+ : exports.SkillInstallErrorCode.DESTINATION_UNMANAGED);
532
+ }
533
+ try {
534
+ (0, fs_1.renameSync)(stagingDir, installRootAbs);
535
+ }
536
+ catch {
537
+ fail(exports.SkillInstallErrorCode.COMMIT_FAILED, { reason: 'rename' });
538
+ }
539
+ }
540
+ catch (error) {
541
+ (0, fs_1.rmSync)(stagingDir, { recursive: true, force: true });
542
+ pruneStagingRoot(stagingRoot);
543
+ throw error;
544
+ }
545
+ pruneStagingRoot(stagingRoot);
546
+ }
547
+ /**
548
+ * Converge a committed install's secondary roots forward from the primary (#1460).
549
+ *
550
+ * The reconciliation primitive for a partial multi-root install: when the
551
+ * primary `.agents/skills` root committed but a secondary rename did not, this
552
+ * reads the primary's own on-disk payload — proven byte-for-byte against the
553
+ * receipt inventory — and atomically writes it into every declared root that is
554
+ * still absent. A root already present (the correct managed copy, or a user's
555
+ * conflict) is left untouched, so convergence is forward-only and never
556
+ * overwrites. Idempotent: a second call after a partial pass completes the rest.
557
+ *
558
+ * @returns repository-relative roots this call wrote
559
+ */
560
+ function completeSecondarySkillInstallRoots(worktreePath, worktreeRealPath, skillId) {
561
+ const primaryAbs = resolveSkillInstallTarget(worktreePath, skillId);
562
+ const receiptBytes = (0, fs_1.readFileSync)(path_1.default.join(primaryAbs, install_plan_1.SKILL_RECEIPT_FILENAME));
563
+ const receipt = (0, install_plan_1.parseInstalledReceipt)(receiptBytes);
564
+ if (receipt === null) {
565
+ fail(exports.SkillInstallErrorCode.PAYLOAD_MISMATCH, { reason: 'primary-receipt-unreadable' });
566
+ }
567
+ // Read the primary payload from disk and prove it against the receipt before
568
+ // it is copied anywhere: a copy of a tampered primary must not propagate.
569
+ const payload = receipt.files.map((file) => {
570
+ const bytes = (0, fs_1.readFileSync)(path_1.default.join(primaryAbs, file.path));
571
+ if (!(0, integrity_1.digestMatches)((0, integrity_1.computeSha256Hex)(bytes), file.sha256)) {
572
+ fail(exports.SkillInstallErrorCode.PAYLOAD_MISMATCH, { reason: 'primary-file-digest' });
573
+ }
574
+ return { relativePath: file.path, bytes, executable: file.executable };
575
+ });
576
+ const directories = directoriesFor(receipt.files.map((file) => file.path));
577
+ const plannedTreeHash = (0, preview_diff_1.computeSkillTreeHash)([
578
+ ...receipt.files.map((file) => ({
579
+ path: file.path,
580
+ sha256: file.sha256,
581
+ executable: file.executable,
582
+ })),
583
+ { path: install_plan_1.SKILL_RECEIPT_FILENAME, sha256: (0, integrity_1.computeSha256Hex)(receiptBytes), executable: false },
584
+ ]);
585
+ const operationId = (0, crypto_1.randomBytes)(16).toString('hex');
586
+ const completed = [];
587
+ for (const rootRel of (0, install_plan_1.receiptInstallRoots)(receipt)) {
588
+ const prefix = rootRel.slice(0, Math.max(0, rootRel.length - skillId.length - 1));
589
+ const abs = resolveSkillInstallTargetFor(worktreePath, prefix, skillId);
590
+ // Present already: either the correct managed copy or a user conflict. Both
591
+ // are left alone — convergence only fills absent roots.
592
+ if (inspectSkillDestination(abs).present)
593
+ continue;
594
+ stageAndCommitSkillRoot({
595
+ worktreePath,
596
+ worktreeRealPath,
597
+ rootPrefix: prefix,
598
+ skillId,
599
+ operationId,
600
+ payload,
601
+ directories,
602
+ receiptBytes,
603
+ plannedTreeHash,
604
+ });
605
+ completed.push(rootRel);
606
+ }
607
+ return { completed };
608
+ }
609
+ /**
610
+ * Refuse to commit across a filesystem boundary.
611
+ *
612
+ * `rename(2)` is only atomic within one filesystem; across one it fails with
613
+ * EXDEV, and a caller that "helpfully" fell back to copy+delete would give up
614
+ * the single property the whole design rests on. Staging is placed inside the
615
+ * destination's own parent so this holds by construction — the check is here so
616
+ * a future change that moves staging elsewhere fails loudly.
617
+ */
618
+ function assertSameFilesystem(stagingDir, destinationParent) {
619
+ let stagingDev;
620
+ let destinationDev;
621
+ try {
622
+ stagingDev = (0, fs_1.lstatSync)(stagingDir).dev;
623
+ destinationDev = (0, fs_1.lstatSync)(destinationParent).dev;
624
+ }
625
+ catch {
626
+ return fail(exports.SkillInstallErrorCode.STAGING_IO, { reason: 'stat-device' });
627
+ }
628
+ if (stagingDev !== destinationDev) {
629
+ fail(exports.SkillInstallErrorCode.CROSS_DEVICE);
630
+ }
631
+ }
632
+ /** Remove the staging root once it is empty, so it does not linger in a worktree. */
633
+ function pruneStagingRoot(stagingRoot) {
634
+ try {
635
+ (0, fs_1.rmdirSync)(stagingRoot);
636
+ }
637
+ catch {
638
+ // Still in use by a concurrent operation, or already gone.
639
+ }
640
+ }
641
+ /**
642
+ * Drop staging directories left behind by a crashed process.
643
+ *
644
+ * Only entries whose name matches the operation-ID grammar are removed, so
645
+ * pointing this at a directory holding anything else cannot destroy content.
646
+ *
647
+ * @returns Number of staging directories removed
648
+ */
649
+ function cleanupSkillInstallStaging(worktreePath) {
650
+ let removed = 0;
651
+ // Each install root has its own staging namespace (#1460); clean all of them.
652
+ for (const rootPrefix of constants_1.SKILL_INSTALL_ROOT_PREFIXES) {
653
+ const stagingRoot = (0, operation_store_1.getSkillInstallStagingRoot)(worktreePath, rootPrefix);
654
+ let entries;
655
+ try {
656
+ entries = (0, fs_1.readdirSync)(stagingRoot);
657
+ }
658
+ catch {
659
+ continue;
660
+ }
661
+ for (const entry of entries) {
662
+ if (!exports.SKILL_INSTALL_OPERATION_ID_PATTERN.test(entry))
663
+ continue;
664
+ (0, fs_1.rmSync)(path_1.default.join(stagingRoot, entry), { recursive: true, force: true });
665
+ removed += 1;
666
+ }
667
+ pruneStagingRoot(stagingRoot);
668
+ }
669
+ return removed;
670
+ }