agents-inc 0.152.1 → 0.153.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 (440) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +31 -35
  3. package/dist/{chunk-LDP5ASDM.js → chunk-2HC2SNRP.js} +2 -15
  4. package/dist/chunk-2HC2SNRP.js.map +1 -0
  5. package/dist/{chunk-WKTHWQKM.js → chunk-35VOK7XE.js} +1338 -2573
  6. package/dist/chunk-35VOK7XE.js.map +1 -0
  7. package/dist/{chunk-SX5H6TSC.js → chunk-4VYALFQZ.js} +11 -8
  8. package/dist/chunk-4VYALFQZ.js.map +1 -0
  9. package/dist/{chunk-KXYVJGJP.js → chunk-6CNRMCFM.js} +3 -2
  10. package/dist/{chunk-KXYVJGJP.js.map → chunk-6CNRMCFM.js.map} +1 -1
  11. package/dist/{chunk-LZ52XEPR.js → chunk-ACKC577F.js} +7 -6
  12. package/dist/chunk-ACKC577F.js.map +1 -0
  13. package/dist/{chunk-XHUODHZ4.js → chunk-BMGBA6HJ.js} +22 -49
  14. package/dist/chunk-BMGBA6HJ.js.map +1 -0
  15. package/dist/{chunk-FVDKAVOL.js → chunk-EFU6P3B7.js} +18 -51
  16. package/dist/chunk-EFU6P3B7.js.map +1 -0
  17. package/dist/{chunk-STMHDOZD.js → chunk-F7Z5I6GU.js} +12 -9
  18. package/dist/chunk-F7Z5I6GU.js.map +1 -0
  19. package/dist/{chunk-E5X6RJ4E.js → chunk-FIHTAFST.js} +29 -26
  20. package/dist/chunk-FIHTAFST.js.map +1 -0
  21. package/dist/{chunk-QZZJFYUQ.js → chunk-FRWKCE6R.js} +3 -3
  22. package/dist/chunk-FRWKCE6R.js.map +1 -0
  23. package/dist/{chunk-5UWKOOIS.js → chunk-HEBPKK5L.js} +129 -195
  24. package/dist/chunk-HEBPKK5L.js.map +1 -0
  25. package/dist/{chunk-MJ2KHG24.js → chunk-IO4VEW5U.js} +6 -6
  26. package/dist/{chunk-MJ2KHG24.js.map → chunk-IO4VEW5U.js.map} +1 -1
  27. package/dist/{chunk-TUPYW2IQ.js → chunk-JC7DBPRD.js} +9 -12
  28. package/dist/chunk-JC7DBPRD.js.map +1 -0
  29. package/dist/{chunk-5GUOIJSG.js → chunk-JFAUQDZM.js} +3 -15
  30. package/dist/chunk-JFAUQDZM.js.map +1 -0
  31. package/dist/{chunk-ZL7PFNHN.js → chunk-K3O3YQYG.js} +2 -2
  32. package/dist/{chunk-SKQWRUPX.js → chunk-K7PJDWER.js} +59 -33
  33. package/dist/chunk-K7PJDWER.js.map +1 -0
  34. package/dist/{chunk-MVR3SYMN.js → chunk-KET3EVGX.js} +4 -3
  35. package/dist/{chunk-MVR3SYMN.js.map → chunk-KET3EVGX.js.map} +1 -1
  36. package/dist/{chunk-MWG4VU64.js → chunk-M5HSTNYU.js} +50 -56
  37. package/dist/chunk-M5HSTNYU.js.map +1 -0
  38. package/dist/{chunk-TJJPWUMA.js → chunk-NSJ2S7R5.js} +3 -2
  39. package/dist/{chunk-TJJPWUMA.js.map → chunk-NSJ2S7R5.js.map} +1 -1
  40. package/dist/{chunk-IHUY4M22.js → chunk-NXGMM5YN.js} +4 -4
  41. package/dist/chunk-NXQAY5U7.js +18441 -0
  42. package/dist/chunk-NXQAY5U7.js.map +1 -0
  43. package/dist/{chunk-Q2KG7UV3.js → chunk-OJJLYHM3.js} +2 -1
  44. package/dist/{chunk-Q2KG7UV3.js.map → chunk-OJJLYHM3.js.map} +1 -1
  45. package/dist/{chunk-PZIZNMHK.js → chunk-ORJ5Y222.js} +159 -138
  46. package/dist/chunk-ORJ5Y222.js.map +1 -0
  47. package/dist/{chunk-NR3OZGL4.js → chunk-OZXAJNLA.js} +2 -1
  48. package/dist/{chunk-NR3OZGL4.js.map → chunk-OZXAJNLA.js.map} +1 -1
  49. package/dist/{chunk-MM7CTTAV.js → chunk-Q5FLW4JG.js} +2 -2
  50. package/dist/{chunk-MM7CTTAV.js.map → chunk-Q5FLW4JG.js.map} +1 -1
  51. package/dist/{chunk-GRVKW3CC.js → chunk-R4SEU3DF.js} +3 -2
  52. package/dist/{chunk-GRVKW3CC.js.map → chunk-R4SEU3DF.js.map} +1 -1
  53. package/dist/{chunk-76ADG7LQ.js → chunk-R54KIGN2.js} +8 -22
  54. package/dist/chunk-R54KIGN2.js.map +1 -0
  55. package/dist/{chunk-SBHBBZKF.js → chunk-REKOWTIB.js} +25 -120
  56. package/dist/chunk-REKOWTIB.js.map +1 -0
  57. package/dist/chunk-TY6CAOL7.js +40 -0
  58. package/dist/chunk-TY6CAOL7.js.map +1 -0
  59. package/dist/{chunk-BNSRA6HL.js → chunk-U2DNAHFE.js} +39 -176
  60. package/dist/chunk-U2DNAHFE.js.map +1 -0
  61. package/dist/{chunk-PMM2MYMA.js → chunk-U2YSGBHA.js} +624 -349
  62. package/dist/chunk-U2YSGBHA.js.map +1 -0
  63. package/dist/{chunk-DTSG5XZB.js → chunk-V3ENMW7G.js} +3 -3
  64. package/dist/{chunk-L7SZXUBJ.js → chunk-VECFAKM5.js} +7 -6
  65. package/dist/{chunk-L7SZXUBJ.js.map → chunk-VECFAKM5.js.map} +1 -1
  66. package/dist/chunk-VGEBYCQZ.js +59 -0
  67. package/dist/chunk-VGEBYCQZ.js.map +1 -0
  68. package/dist/chunk-VZRO7RYT.js +3694 -0
  69. package/dist/chunk-VZRO7RYT.js.map +1 -0
  70. package/dist/{chunk-LASI35KT.js → chunk-WDAO3RUY.js} +14 -28
  71. package/dist/chunk-WDAO3RUY.js.map +1 -0
  72. package/dist/{chunk-MQ7FLIYS.js → chunk-WG6V6VJV.js} +3 -2
  73. package/dist/{chunk-MQ7FLIYS.js.map → chunk-WG6V6VJV.js.map} +1 -1
  74. package/dist/chunk-X5XJ6WKO.js +284 -0
  75. package/dist/chunk-X5XJ6WKO.js.map +1 -0
  76. package/dist/{chunk-RNJWAKMO.js → chunk-XGMOXMS4.js} +9 -8
  77. package/dist/chunk-XGMOXMS4.js.map +1 -0
  78. package/dist/{chunk-IUQBOCSU.js → chunk-ZBPEFQ4G.js} +2 -1
  79. package/dist/{chunk-IUQBOCSU.js.map → chunk-ZBPEFQ4G.js.map} +1 -1
  80. package/dist/{chunk-QRDTLVXG.js → chunk-ZNDLUWWD.js} +9 -22
  81. package/dist/chunk-ZNDLUWWD.js.map +1 -0
  82. package/dist/commands/build/marketplace.js +114 -35
  83. package/dist/commands/build/marketplace.js.map +1 -1
  84. package/dist/commands/build/plugins.js +9 -10
  85. package/dist/commands/build/plugins.js.map +1 -1
  86. package/dist/commands/compile.js +97 -70
  87. package/dist/commands/compile.js.map +1 -1
  88. package/dist/commands/doctor.js +793 -64
  89. package/dist/commands/doctor.js.map +1 -1
  90. package/dist/commands/edit.js +169 -208
  91. package/dist/commands/edit.js.map +1 -1
  92. package/dist/commands/eject.js +24 -39
  93. package/dist/commands/eject.js.map +1 -1
  94. package/dist/commands/init.js +41 -46
  95. package/dist/commands/list.js +10 -12
  96. package/dist/commands/list.js.map +1 -1
  97. package/dist/commands/search.js +20 -81
  98. package/dist/commands/search.js.map +1 -1
  99. package/dist/commands/uninstall.js +25 -31
  100. package/dist/commands/uninstall.js.map +1 -1
  101. package/dist/commands/update.js +82 -332
  102. package/dist/commands/update.js.map +1 -1
  103. package/dist/components/common/confirm.js +1 -1
  104. package/dist/components/common/prompt-confirm.js +1 -1
  105. package/dist/components/common/select-list.js +2 -2
  106. package/dist/components/common/spinner.js +1 -1
  107. package/dist/components/wizard/category-grid.js +5 -6
  108. package/dist/components/wizard/checkbox-grid.js +5 -6
  109. package/dist/components/wizard/domain-selection.js +12 -13
  110. package/dist/components/wizard/run-wizard-session.js +30 -36
  111. package/dist/components/wizard/scroll-affordance.js +2 -2
  112. package/dist/components/wizard/skill-agent-summary.js +7 -7
  113. package/dist/components/wizard/source-grid.js +6 -11
  114. package/dist/components/wizard/stack-selection.js +9 -9
  115. package/dist/components/wizard/step-agents.js +12 -12
  116. package/dist/components/wizard/step-build.js +10 -11
  117. package/dist/components/wizard/step-confirm.js +11 -11
  118. package/dist/components/wizard/step-sources.js +11 -17
  119. package/dist/components/wizard/step-stack.js +10 -10
  120. package/dist/components/wizard/summary-panel.js +10 -10
  121. package/dist/components/wizard/toast.js +2 -2
  122. package/dist/components/wizard/wizard-layout.js +15 -16
  123. package/dist/components/wizard/wizard-tabs.js +6 -12
  124. package/dist/components/wizard/wizard.js +29 -35
  125. package/dist/config-exports.js +1 -1
  126. package/dist/copy-local-skills-KF2RAVD3.js +14 -0
  127. package/dist/hooks/init.js +49 -48
  128. package/dist/hooks/init.js.map +1 -1
  129. package/dist/index.js +3 -1
  130. package/dist/index.js.map +1 -1
  131. package/dist/load-agent-defs-DGXGBU3Q.js +15 -0
  132. package/dist/{loader-5JP4S7CJ.js → loader-4U7UCE2Y.js} +7 -5
  133. package/dist/recompile-project-agents-CJVBAWDJ.js +20 -0
  134. package/dist/{source-loader-MZYCPL2S.js → source-loader-ZNSYJJCI.js} +6 -6
  135. package/dist/src/agents/developer/ai-developer/identity.md +4 -4
  136. package/dist/src/agents/developer/ai-developer/playbook.md +1 -1
  137. package/dist/src/agents/developer/api-developer/identity.md +4 -4
  138. package/dist/src/agents/developer/api-developer/metadata.yaml +1 -1
  139. package/dist/src/agents/developer/cli-developer/identity.md +4 -4
  140. package/dist/src/agents/developer/web-developer/identity.md +2 -2
  141. package/dist/src/agents/developer/web-developer/metadata.yaml +1 -1
  142. package/dist/src/agents/meta/agent-summoner/identity.md +4 -5
  143. package/dist/src/agents/meta/agent-summoner/output.md +2 -2
  144. package/dist/src/agents/meta/agent-summoner/playbook.md +15 -16
  145. package/dist/src/agents/meta/codex-keeper/identity.md +4 -4
  146. package/dist/src/agents/meta/codex-keeper/playbook.md +1 -1
  147. package/dist/src/agents/meta/convention-keeper/identity.md +1 -1
  148. package/dist/src/agents/meta/skill-summoner/critical-reminders.md +0 -34
  149. package/dist/src/agents/meta/skill-summoner/critical-requirements.md +27 -3
  150. package/dist/src/agents/meta/skill-summoner/identity.md +2 -2
  151. package/{src/agents/planning/web-pm → dist/src/agents/planning/pm}/critical-reminders.md +10 -7
  152. package/dist/src/agents/planning/{web-pm → pm}/critical-requirements.md +8 -4
  153. package/dist/src/agents/planning/pm/identity.md +47 -0
  154. package/dist/src/agents/planning/pm/metadata.yaml +12 -0
  155. package/dist/src/agents/planning/{web-pm → pm}/output.md +7 -90
  156. package/dist/src/agents/planning/pm/playbook.md +185 -0
  157. package/dist/src/agents/researcher/ai-researcher/critical-reminders.md +58 -0
  158. package/dist/src/agents/researcher/ai-researcher/critical-requirements.md +40 -0
  159. package/dist/src/agents/researcher/ai-researcher/identity.md +86 -0
  160. package/dist/src/agents/researcher/ai-researcher/metadata.yaml +10 -0
  161. package/dist/src/agents/researcher/ai-researcher/output.md +363 -0
  162. package/dist/src/agents/researcher/ai-researcher/playbook.md +545 -0
  163. package/dist/src/agents/researcher/api-researcher/critical-reminders.md +16 -0
  164. package/dist/src/agents/researcher/api-researcher/identity.md +7 -7
  165. package/dist/src/agents/researcher/cli-researcher/critical-reminders.md +50 -0
  166. package/dist/src/agents/researcher/cli-researcher/critical-requirements.md +36 -0
  167. package/dist/src/agents/researcher/cli-researcher/identity.md +87 -0
  168. package/dist/src/agents/researcher/cli-researcher/metadata.yaml +10 -0
  169. package/dist/src/agents/researcher/cli-researcher/output.md +343 -0
  170. package/dist/src/agents/researcher/cli-researcher/playbook.md +370 -0
  171. package/dist/src/agents/researcher/web-researcher/identity.md +5 -6
  172. package/dist/src/agents/reviewer/reviewer/critical-reminders.md +29 -0
  173. package/dist/src/agents/reviewer/reviewer/critical-requirements.md +31 -0
  174. package/dist/src/agents/reviewer/reviewer/identity.md +41 -0
  175. package/dist/src/agents/reviewer/reviewer/metadata.yaml +12 -0
  176. package/dist/src/agents/reviewer/reviewer/output.md +202 -0
  177. package/dist/src/agents/reviewer/reviewer/playbook.md +141 -0
  178. package/dist/src/agents/tester/ai-tester/critical-reminders.md +48 -0
  179. package/dist/src/agents/tester/ai-tester/critical-requirements.md +49 -0
  180. package/dist/src/agents/tester/ai-tester/identity.md +62 -0
  181. package/dist/src/agents/tester/ai-tester/metadata.yaml +12 -0
  182. package/dist/src/agents/tester/ai-tester/output.md +375 -0
  183. package/dist/src/agents/tester/ai-tester/playbook.md +789 -0
  184. package/dist/src/agents/tester/api-tester/identity.md +3 -3
  185. package/dist/src/agents/tester/cli-tester/critical-reminders.md +3 -3
  186. package/dist/src/agents/tester/cli-tester/critical-requirements.md +2 -2
  187. package/dist/src/agents/tester/cli-tester/identity.md +3 -3
  188. package/dist/src/agents/tester/cli-tester/output.md +4 -4
  189. package/dist/src/agents/tester/cli-tester/playbook.md +3 -3
  190. package/dist/src/agents/tester/web-tester/identity.md +3 -3
  191. package/dist/stores/wizard-store.js +8 -6
  192. package/package.json +13 -2
  193. package/src/agents/developer/ai-developer/identity.md +4 -4
  194. package/src/agents/developer/ai-developer/playbook.md +1 -1
  195. package/src/agents/developer/api-developer/identity.md +4 -4
  196. package/src/agents/developer/api-developer/metadata.yaml +1 -1
  197. package/src/agents/developer/cli-developer/identity.md +4 -4
  198. package/src/agents/developer/web-developer/identity.md +2 -2
  199. package/src/agents/developer/web-developer/metadata.yaml +1 -1
  200. package/src/agents/meta/agent-summoner/identity.md +4 -5
  201. package/src/agents/meta/agent-summoner/output.md +2 -2
  202. package/src/agents/meta/agent-summoner/playbook.md +15 -16
  203. package/src/agents/meta/codex-keeper/identity.md +4 -4
  204. package/src/agents/meta/codex-keeper/playbook.md +1 -1
  205. package/src/agents/meta/convention-keeper/identity.md +1 -1
  206. package/src/agents/meta/skill-summoner/critical-reminders.md +0 -34
  207. package/src/agents/meta/skill-summoner/critical-requirements.md +27 -3
  208. package/src/agents/meta/skill-summoner/identity.md +2 -2
  209. package/{dist/src/agents/planning/web-pm → src/agents/planning/pm}/critical-reminders.md +10 -7
  210. package/src/agents/planning/{web-pm → pm}/critical-requirements.md +8 -4
  211. package/src/agents/planning/pm/identity.md +47 -0
  212. package/src/agents/planning/pm/metadata.yaml +12 -0
  213. package/src/agents/planning/{web-pm → pm}/output.md +7 -90
  214. package/src/agents/planning/pm/playbook.md +185 -0
  215. package/src/agents/researcher/ai-researcher/critical-reminders.md +58 -0
  216. package/src/agents/researcher/ai-researcher/critical-requirements.md +40 -0
  217. package/src/agents/researcher/ai-researcher/identity.md +86 -0
  218. package/src/agents/researcher/ai-researcher/metadata.yaml +10 -0
  219. package/src/agents/researcher/ai-researcher/output.md +363 -0
  220. package/src/agents/researcher/ai-researcher/playbook.md +545 -0
  221. package/src/agents/researcher/api-researcher/critical-reminders.md +16 -0
  222. package/src/agents/researcher/api-researcher/identity.md +7 -7
  223. package/src/agents/researcher/cli-researcher/critical-reminders.md +50 -0
  224. package/src/agents/researcher/cli-researcher/critical-requirements.md +36 -0
  225. package/src/agents/researcher/cli-researcher/identity.md +87 -0
  226. package/src/agents/researcher/cli-researcher/metadata.yaml +10 -0
  227. package/src/agents/researcher/cli-researcher/output.md +343 -0
  228. package/src/agents/researcher/cli-researcher/playbook.md +370 -0
  229. package/src/agents/researcher/web-researcher/identity.md +5 -6
  230. package/src/agents/reviewer/reviewer/critical-reminders.md +29 -0
  231. package/src/agents/reviewer/reviewer/critical-requirements.md +31 -0
  232. package/src/agents/reviewer/reviewer/identity.md +41 -0
  233. package/src/agents/reviewer/reviewer/metadata.yaml +12 -0
  234. package/src/agents/reviewer/reviewer/output.md +202 -0
  235. package/src/agents/reviewer/reviewer/playbook.md +141 -0
  236. package/src/agents/tester/ai-tester/critical-reminders.md +48 -0
  237. package/src/agents/tester/ai-tester/critical-requirements.md +49 -0
  238. package/src/agents/tester/ai-tester/identity.md +62 -0
  239. package/src/agents/tester/ai-tester/metadata.yaml +12 -0
  240. package/src/agents/tester/ai-tester/output.md +375 -0
  241. package/src/agents/tester/ai-tester/playbook.md +789 -0
  242. package/src/agents/tester/api-tester/identity.md +3 -3
  243. package/src/agents/tester/cli-tester/critical-reminders.md +3 -3
  244. package/src/agents/tester/cli-tester/critical-requirements.md +2 -2
  245. package/src/agents/tester/cli-tester/identity.md +3 -3
  246. package/src/agents/tester/cli-tester/output.md +4 -4
  247. package/src/agents/tester/cli-tester/playbook.md +3 -3
  248. package/src/agents/tester/web-tester/identity.md +3 -3
  249. package/src/schemas/metadata.schema.json +31 -2
  250. package/src/schemas/project-config.schema.json +61 -15
  251. package/src/schemas/project-source-config.schema.json +0 -47
  252. package/dist/chunk-5GUOIJSG.js.map +0 -1
  253. package/dist/chunk-5UWKOOIS.js.map +0 -1
  254. package/dist/chunk-76ADG7LQ.js.map +0 -1
  255. package/dist/chunk-BNSRA6HL.js.map +0 -1
  256. package/dist/chunk-E5X6RJ4E.js.map +0 -1
  257. package/dist/chunk-EEPELKOM.js +0 -5938
  258. package/dist/chunk-EEPELKOM.js.map +0 -1
  259. package/dist/chunk-F7T5AFFN.js +0 -20
  260. package/dist/chunk-F7T5AFFN.js.map +0 -1
  261. package/dist/chunk-FVDKAVOL.js.map +0 -1
  262. package/dist/chunk-KFB5CRXZ.js +0 -377
  263. package/dist/chunk-KFB5CRXZ.js.map +0 -1
  264. package/dist/chunk-KR65TPKC.js +0 -664
  265. package/dist/chunk-KR65TPKC.js.map +0 -1
  266. package/dist/chunk-LASI35KT.js.map +0 -1
  267. package/dist/chunk-LDP5ASDM.js.map +0 -1
  268. package/dist/chunk-LZ52XEPR.js.map +0 -1
  269. package/dist/chunk-M7HO7NBK.js +0 -88
  270. package/dist/chunk-M7HO7NBK.js.map +0 -1
  271. package/dist/chunk-MWG4VU64.js.map +0 -1
  272. package/dist/chunk-ODNDXQH2.js +0 -77
  273. package/dist/chunk-ODNDXQH2.js.map +0 -1
  274. package/dist/chunk-P44SXVH3.js +0 -80
  275. package/dist/chunk-P44SXVH3.js.map +0 -1
  276. package/dist/chunk-PMM2MYMA.js.map +0 -1
  277. package/dist/chunk-PZIZNMHK.js.map +0 -1
  278. package/dist/chunk-Q45ZU6HD.js +0 -37
  279. package/dist/chunk-Q45ZU6HD.js.map +0 -1
  280. package/dist/chunk-QRDTLVXG.js.map +0 -1
  281. package/dist/chunk-QZZJFYUQ.js.map +0 -1
  282. package/dist/chunk-R5NOI2LP.js +0 -170
  283. package/dist/chunk-R5NOI2LP.js.map +0 -1
  284. package/dist/chunk-RNJWAKMO.js.map +0 -1
  285. package/dist/chunk-SBHBBZKF.js.map +0 -1
  286. package/dist/chunk-SKQWRUPX.js.map +0 -1
  287. package/dist/chunk-STMHDOZD.js.map +0 -1
  288. package/dist/chunk-SX5H6TSC.js.map +0 -1
  289. package/dist/chunk-TUPYW2IQ.js.map +0 -1
  290. package/dist/chunk-UBEDZ4FD.js +0 -4198
  291. package/dist/chunk-UBEDZ4FD.js.map +0 -1
  292. package/dist/chunk-VY6MNOXL.js +0 -20
  293. package/dist/chunk-VY6MNOXL.js.map +0 -1
  294. package/dist/chunk-WBCPLH66.js +0 -42
  295. package/dist/chunk-WBCPLH66.js.map +0 -1
  296. package/dist/chunk-WKTHWQKM.js.map +0 -1
  297. package/dist/chunk-XHUODHZ4.js.map +0 -1
  298. package/dist/chunk-ZPPHXXAP.js +0 -252
  299. package/dist/chunk-ZPPHXXAP.js.map +0 -1
  300. package/dist/commands/import/skill.js +0 -344
  301. package/dist/commands/import/skill.js.map +0 -1
  302. package/dist/commands/new/agent.js +0 -300
  303. package/dist/commands/new/agent.js.map +0 -1
  304. package/dist/commands/new/marketplace.js +0 -310
  305. package/dist/commands/new/marketplace.js.map +0 -1
  306. package/dist/commands/new/skill.js +0 -26
  307. package/dist/commands/validate.js +0 -575
  308. package/dist/commands/validate.js.map +0 -1
  309. package/dist/components/wizard/search-modal.js +0 -13
  310. package/dist/components/wizard/selection-card.js +0 -9
  311. package/dist/components/wizard/step-settings.js +0 -18
  312. package/dist/copy-local-skills-6EMVN7RB.js +0 -14
  313. package/dist/load-agent-defs-BWOUVEAR.js +0 -15
  314. package/dist/load-agent-defs-BWOUVEAR.js.map +0 -1
  315. package/dist/loader-5JP4S7CJ.js.map +0 -1
  316. package/dist/recompile-project-agents-6DL45TDI.js +0 -19
  317. package/dist/recompile-project-agents-6DL45TDI.js.map +0 -1
  318. package/dist/source-loader-MZYCPL2S.js.map +0 -1
  319. package/dist/src/agents/developer/web-architecture/critical-reminders.md +0 -48
  320. package/dist/src/agents/developer/web-architecture/critical-requirements.md +0 -65
  321. package/dist/src/agents/developer/web-architecture/identity.md +0 -64
  322. package/dist/src/agents/developer/web-architecture/metadata.yaml +0 -12
  323. package/dist/src/agents/developer/web-architecture/output.md +0 -449
  324. package/dist/src/agents/developer/web-architecture/playbook.md +0 -481
  325. package/dist/src/agents/pattern/pattern-scout/critical-reminders.md +0 -71
  326. package/dist/src/agents/pattern/pattern-scout/critical-requirements.md +0 -31
  327. package/dist/src/agents/pattern/pattern-scout/identity.md +0 -25
  328. package/dist/src/agents/pattern/pattern-scout/metadata.yaml +0 -10
  329. package/dist/src/agents/pattern/pattern-scout/output.md +0 -290
  330. package/dist/src/agents/pattern/pattern-scout/playbook.md +0 -1806
  331. package/dist/src/agents/pattern/web-pattern-critique/critical-reminders.md +0 -30
  332. package/dist/src/agents/pattern/web-pattern-critique/critical-requirements.md +0 -28
  333. package/dist/src/agents/pattern/web-pattern-critique/identity.md +0 -41
  334. package/dist/src/agents/pattern/web-pattern-critique/metadata.yaml +0 -12
  335. package/dist/src/agents/pattern/web-pattern-critique/output.md +0 -314
  336. package/dist/src/agents/pattern/web-pattern-critique/playbook.md +0 -572
  337. package/dist/src/agents/planning/api-pm/critical-reminders.md +0 -48
  338. package/dist/src/agents/planning/api-pm/critical-requirements.md +0 -41
  339. package/dist/src/agents/planning/api-pm/identity.md +0 -39
  340. package/dist/src/agents/planning/api-pm/metadata.yaml +0 -12
  341. package/dist/src/agents/planning/api-pm/output.md +0 -475
  342. package/dist/src/agents/planning/api-pm/playbook.md +0 -129
  343. package/dist/src/agents/planning/web-pm/identity.md +0 -26
  344. package/dist/src/agents/planning/web-pm/metadata.yaml +0 -12
  345. package/dist/src/agents/planning/web-pm/playbook.md +0 -318
  346. package/dist/src/agents/reviewer/ai-reviewer/critical-reminders.md +0 -40
  347. package/dist/src/agents/reviewer/ai-reviewer/critical-requirements.md +0 -37
  348. package/dist/src/agents/reviewer/ai-reviewer/identity.md +0 -51
  349. package/dist/src/agents/reviewer/ai-reviewer/metadata.yaml +0 -10
  350. package/dist/src/agents/reviewer/ai-reviewer/output.md +0 -395
  351. package/dist/src/agents/reviewer/ai-reviewer/playbook.md +0 -90
  352. package/dist/src/agents/reviewer/api-reviewer/critical-reminders.md +0 -31
  353. package/dist/src/agents/reviewer/api-reviewer/critical-requirements.md +0 -27
  354. package/dist/src/agents/reviewer/api-reviewer/identity.md +0 -51
  355. package/dist/src/agents/reviewer/api-reviewer/metadata.yaml +0 -12
  356. package/dist/src/agents/reviewer/api-reviewer/output.md +0 -343
  357. package/dist/src/agents/reviewer/api-reviewer/playbook.md +0 -288
  358. package/dist/src/agents/reviewer/cli-reviewer/critical-reminders.md +0 -33
  359. package/dist/src/agents/reviewer/cli-reviewer/critical-requirements.md +0 -30
  360. package/dist/src/agents/reviewer/cli-reviewer/identity.md +0 -44
  361. package/dist/src/agents/reviewer/cli-reviewer/metadata.yaml +0 -12
  362. package/dist/src/agents/reviewer/cli-reviewer/output.md +0 -414
  363. package/dist/src/agents/reviewer/cli-reviewer/playbook.md +0 -218
  364. package/dist/src/agents/reviewer/infra-reviewer/critical-reminders.md +0 -38
  365. package/dist/src/agents/reviewer/infra-reviewer/critical-requirements.md +0 -38
  366. package/dist/src/agents/reviewer/infra-reviewer/identity.md +0 -53
  367. package/dist/src/agents/reviewer/infra-reviewer/metadata.yaml +0 -10
  368. package/dist/src/agents/reviewer/infra-reviewer/output.md +0 -364
  369. package/dist/src/agents/reviewer/infra-reviewer/playbook.md +0 -161
  370. package/dist/src/agents/reviewer/web-reviewer/critical-reminders.md +0 -31
  371. package/dist/src/agents/reviewer/web-reviewer/critical-requirements.md +0 -26
  372. package/dist/src/agents/reviewer/web-reviewer/identity.md +0 -40
  373. package/dist/src/agents/reviewer/web-reviewer/metadata.yaml +0 -12
  374. package/dist/src/agents/reviewer/web-reviewer/output.md +0 -333
  375. package/dist/src/agents/reviewer/web-reviewer/playbook.md +0 -156
  376. package/src/agents/developer/web-architecture/critical-reminders.md +0 -48
  377. package/src/agents/developer/web-architecture/critical-requirements.md +0 -65
  378. package/src/agents/developer/web-architecture/identity.md +0 -64
  379. package/src/agents/developer/web-architecture/metadata.yaml +0 -12
  380. package/src/agents/developer/web-architecture/output.md +0 -449
  381. package/src/agents/developer/web-architecture/playbook.md +0 -481
  382. package/src/agents/pattern/pattern-scout/critical-reminders.md +0 -71
  383. package/src/agents/pattern/pattern-scout/critical-requirements.md +0 -31
  384. package/src/agents/pattern/pattern-scout/identity.md +0 -25
  385. package/src/agents/pattern/pattern-scout/metadata.yaml +0 -10
  386. package/src/agents/pattern/pattern-scout/output.md +0 -290
  387. package/src/agents/pattern/pattern-scout/playbook.md +0 -1806
  388. package/src/agents/pattern/web-pattern-critique/critical-reminders.md +0 -30
  389. package/src/agents/pattern/web-pattern-critique/critical-requirements.md +0 -28
  390. package/src/agents/pattern/web-pattern-critique/identity.md +0 -41
  391. package/src/agents/pattern/web-pattern-critique/metadata.yaml +0 -12
  392. package/src/agents/pattern/web-pattern-critique/output.md +0 -314
  393. package/src/agents/pattern/web-pattern-critique/playbook.md +0 -572
  394. package/src/agents/planning/api-pm/critical-reminders.md +0 -48
  395. package/src/agents/planning/api-pm/critical-requirements.md +0 -41
  396. package/src/agents/planning/api-pm/identity.md +0 -39
  397. package/src/agents/planning/api-pm/metadata.yaml +0 -12
  398. package/src/agents/planning/api-pm/output.md +0 -475
  399. package/src/agents/planning/api-pm/playbook.md +0 -129
  400. package/src/agents/planning/web-pm/identity.md +0 -26
  401. package/src/agents/planning/web-pm/metadata.yaml +0 -12
  402. package/src/agents/planning/web-pm/playbook.md +0 -318
  403. package/src/agents/reviewer/ai-reviewer/critical-reminders.md +0 -40
  404. package/src/agents/reviewer/ai-reviewer/critical-requirements.md +0 -37
  405. package/src/agents/reviewer/ai-reviewer/identity.md +0 -51
  406. package/src/agents/reviewer/ai-reviewer/metadata.yaml +0 -10
  407. package/src/agents/reviewer/ai-reviewer/output.md +0 -395
  408. package/src/agents/reviewer/ai-reviewer/playbook.md +0 -90
  409. package/src/agents/reviewer/api-reviewer/critical-reminders.md +0 -31
  410. package/src/agents/reviewer/api-reviewer/critical-requirements.md +0 -27
  411. package/src/agents/reviewer/api-reviewer/identity.md +0 -51
  412. package/src/agents/reviewer/api-reviewer/metadata.yaml +0 -12
  413. package/src/agents/reviewer/api-reviewer/output.md +0 -343
  414. package/src/agents/reviewer/api-reviewer/playbook.md +0 -288
  415. package/src/agents/reviewer/cli-reviewer/critical-reminders.md +0 -33
  416. package/src/agents/reviewer/cli-reviewer/critical-requirements.md +0 -30
  417. package/src/agents/reviewer/cli-reviewer/identity.md +0 -44
  418. package/src/agents/reviewer/cli-reviewer/metadata.yaml +0 -12
  419. package/src/agents/reviewer/cli-reviewer/output.md +0 -414
  420. package/src/agents/reviewer/cli-reviewer/playbook.md +0 -218
  421. package/src/agents/reviewer/infra-reviewer/critical-reminders.md +0 -38
  422. package/src/agents/reviewer/infra-reviewer/critical-requirements.md +0 -38
  423. package/src/agents/reviewer/infra-reviewer/identity.md +0 -53
  424. package/src/agents/reviewer/infra-reviewer/metadata.yaml +0 -10
  425. package/src/agents/reviewer/infra-reviewer/output.md +0 -364
  426. package/src/agents/reviewer/infra-reviewer/playbook.md +0 -161
  427. package/src/agents/reviewer/web-reviewer/critical-reminders.md +0 -31
  428. package/src/agents/reviewer/web-reviewer/critical-requirements.md +0 -26
  429. package/src/agents/reviewer/web-reviewer/identity.md +0 -40
  430. package/src/agents/reviewer/web-reviewer/metadata.yaml +0 -12
  431. package/src/agents/reviewer/web-reviewer/output.md +0 -333
  432. package/src/agents/reviewer/web-reviewer/playbook.md +0 -156
  433. /package/dist/{chunk-ZL7PFNHN.js.map → chunk-K3O3YQYG.js.map} +0 -0
  434. /package/dist/{chunk-IHUY4M22.js.map → chunk-NXGMM5YN.js.map} +0 -0
  435. /package/dist/{chunk-DTSG5XZB.js.map → chunk-V3ENMW7G.js.map} +0 -0
  436. /package/dist/{commands/new/skill.js.map → copy-local-skills-KF2RAVD3.js.map} +0 -0
  437. /package/dist/{components/wizard/search-modal.js.map → load-agent-defs-DGXGBU3Q.js.map} +0 -0
  438. /package/dist/{components/wizard/selection-card.js.map → loader-4U7UCE2Y.js.map} +0 -0
  439. /package/dist/{components/wizard/step-settings.js.map → recompile-project-agents-CJVBAWDJ.js.map} +0 -0
  440. /package/dist/{copy-local-skills-6EMVN7RB.js.map → source-loader-ZNSYJJCI.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/edit.tsx"],"sourcesContent":["import path from \"path\";\n\nimport chalk from \"chalk\";\nimport { Flags } from \"@oclif/core\";\nimport { render } from \"../components/render.js\";\n\nimport { difference, indexBy } from \"remeda\";\n\nimport { BaseCommand, type SourceRefreshFlags } from \"../base-command.js\";\nimport { type WizardResultV2 } from \"../components/wizard/wizard.js\";\nimport { runWizardSession } from \"../components/wizard/run-wizard-session.js\";\nimport {\n CLI_INVOKE_COMMAND,\n CLI_COLORS,\n EDIT_PROJECT_SETUP_FLAG,\n EJECT_SOURCE,\n formatSourceDisplayName,\n} from \"../consts.js\";\nimport {\n detectProject,\n loadSource,\n copyLocalSkills,\n installPluginSkills,\n pluginInstallFailureError,\n uninstallPluginSkills,\n loadAgentDefs,\n type AgentDefs,\n writeProjectConfig,\n type ConfigWriteResult,\n compileAgentsAllScopes,\n discoverInstalledSkills,\n} from \"../lib/operations/index.js\";\nimport { Spinner } from \"../components/common/spinner.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n type Installation,\n detectMigrations,\n executeMigration,\n isHomeDirectory,\n installBaseDir,\n resolveInstallPaths,\n} from \"../lib/installation/index.js\";\nimport {\n applyMigratedGlobalSources,\n mutateGlobal,\n type GateReport,\n} from \"../lib/config-gate/index.js\";\nimport { matrix, getSkillById, getSkillDisplayName } from \"../lib/matrix/matrix-provider\";\nimport { activeAgentScopeMap, isActiveAt } from \"../lib/configuration/scope-predicates.js\";\nimport type { SourceLoadResult } from \"../lib/loading/index.js\";\nimport {\n discoverAllPluginSkills,\n buildMarketplacePluginRef,\n toClaudePluginScope,\n} from \"../lib/plugins/index.js\";\nimport { deleteLocalSkill, migrateLocalSkillScope } from \"../lib/skills/index.js\";\nimport type {\n SkillId,\n SkillConfig,\n AgentName,\n AgentScopeConfig,\n ProjectConfig,\n SkillScope,\n} from \"../types/index.js\";\nimport { claudePluginInstall, claudePluginUninstall } from \"../utils/exec.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { remove } from \"../utils/fs.js\";\nimport { type StartupMessage } from \"../utils/logger.js\";\nimport { ERROR_MESSAGES, STATUS_MESSAGES } from \"../utils/messages.js\";\nimport { formatScopeTag } from \"../lib/wizard/index.js\";\nimport { typedKeys } from \"../utils/typed-object.js\";\n\n/** A scope transition (`from` → `to`) for a re-scoped skill or agent. */\ntype ScopeChange = { from: SkillScope; to: SkillScope };\n\n/**\n * Dual-scope add/remove: the project half of a [P][G] pair was toggled while the\n * global half persists. Reported as a project-scope addition/removal; a\n * scope-change arrow line would falsely claim the global install moved.\n */\nfunction formatDualScopeTransition(displayName: string, to: SkillScope): string {\n const isAdd = to === \"project\";\n const prefix = isAdd ? \"+\" : \"-\";\n const color = isAdd ? CLI_COLORS.SUCCESS : CLI_COLORS.ERROR;\n return chalk.hex(color)(` ${prefix} ${displayName} [P]`);\n}\n\n/** @internal Re-exported for testing — the transform itself lives inside the gate. */\nexport { applyMigratedGlobalSources };\n\ntype EditContext = {\n installation: Installation;\n projectConfig: ProjectConfig | null;\n projectDir: string;\n sourceResult: SourceLoadResult;\n startupMessages: StartupMessage[];\n currentSkillIds: SkillId[];\n};\n\nexport default class Edit extends BaseCommand {\n static summary = \"Edit skills in the plugin\";\n static description = \"Modify the currently installed skills via interactive wizard\";\n\n static examples = [\n {\n description: \"Open the edit wizard\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Edit with a custom source\",\n command: \"<%= config.bin %> <%= command.id %> --source github:org/marketplace\",\n },\n {\n description: \"Force refresh skills from remote\",\n command: \"<%= config.bin %> <%= command.id %> --refresh\",\n },\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n refresh: Flags.boolean({\n description: \"Force refresh from remote sources\",\n default: false,\n }),\n [EDIT_PROJECT_SETUP_FLAG]: Flags.boolean({\n description: \"Internal: this run continues an `init` project setup\",\n default: false,\n hidden: true,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Edit);\n const cwd = process.cwd();\n\n const { unmount, clear: clearSpinner } = render(\n <Spinner label={STATUS_MESSAGES.LOADING_SKILLS} />,\n );\n const context = await this.loadContext(flags);\n clearSpinner();\n unmount();\n\n const result = await this.runEditWizard(context, cwd);\n if (!result) this.error(\"Cancelled\", { exit: EXIT_CODES.CANCELLED });\n\n this.reportValidationErrors(result);\n\n // Filter excluded entries ONCE — downstream methods receive only active entries\n const activeNewSkills = result.skills.filter((s) => !s.excluded);\n const activeNewAgents = result.agentConfigs.filter((a) => !a.excluded);\n const activeOldSkills = (context.projectConfig?.skills ?? []).filter((s) => !s.excluded);\n const activeOldAgents = (context.projectConfig?.agents ?? []).filter((a) => !a.excluded);\n\n const filteredResult: WizardResultV2 = {\n ...result,\n skills: activeNewSkills,\n agentConfigs: activeNewAgents,\n };\n const filteredOldConfig: ProjectConfig | null = context.projectConfig\n ? { ...context.projectConfig, skills: activeOldSkills, agents: activeOldAgents }\n : null;\n\n const changes = detectConfigChanges(filteredOldConfig, filteredResult, {\n newSkills: result.skills,\n oldSkills: context.projectConfig?.skills ?? [],\n newAgents: result.agentConfigs,\n oldAgents: context.projectConfig?.agents ?? [],\n });\n // `cc init` inside a project means \"set this project up\", so the project must be\n // materialised — `<project>/.claude-src/config.ts` + `config-types.ts` written and the\n // path registered in the global `projects[]` — even when the wizard produced no roster\n // change. At the home root there is no project to set up: the global install is what the\n // dashboard was shown for, so a no-change pass there stays an inspection, as does every\n // bare `cc edit`.\n const isProjectSetup = flags[EDIT_PROJECT_SETUP_FLAG] && !isHomeDirectory(cwd);\n\n if (!hasAnyChanges(changes)) {\n this.log(chalk.hex(CLI_COLORS.NEUTRAL)(\"No changes made.\"));\n if (!isProjectSetup) return;\n await this.writeConfigAndCompile(result, context, flags, cwd);\n this.logCompletionSummary(changes);\n return;\n }\n\n this.logChangeSummary(changes, filteredResult.skills, filteredOldConfig?.skills ?? []);\n const migratedSkillIds = await this.applyMigrations(\n changes,\n filteredResult,\n activeOldSkills,\n context,\n cwd,\n );\n await this.recordGlobalSourceMigrations(migratedSkillIds, filteredResult.skills, cwd, context);\n await this.applyScopeChanges(changes, filteredResult, context, cwd);\n await this.applySourceChanges(changes, activeOldSkills, cwd, migratedSkillIds);\n await this.applyPluginChanges(changes, filteredResult, activeOldSkills, context, cwd);\n await this.copyNewLocalSkills(changes, filteredResult, context, cwd);\n await this.removeDeletedLocalSkills(changes, activeOldSkills, cwd);\n await this.writeConfigAndCompile(result, context, flags, cwd);\n await this.cleanupStaleAgentFiles(changes, activeOldAgents, cwd);\n this.logCompletionSummary(changes);\n }\n\n private async loadContext(flags: SourceRefreshFlags): Promise<EditContext> {\n const detected = await detectProject();\n if (!detected) {\n this.error(ERROR_MESSAGES.NO_INSTALLATION, {\n exit: EXIT_CODES.ERROR,\n });\n }\n const { installation, config: projectConfig } = detected;\n\n // Use installation.projectDir for reads (loading config, discovering installed skills).\n // Use cwd for writes (config saves, plugin installs, scope migrations, recompilation output)\n // and for the global-scope check (determining whether editing from global context).\n const projectDir = installation.projectDir;\n\n let sourceResult: SourceLoadResult;\n let startupMessages: StartupMessage[] = [];\n try {\n const loaded = await loadSource({\n sourceFlag: flags.source,\n projectDir,\n forceRefresh: flags.refresh,\n captureStartupMessages: true,\n });\n sourceResult = loaded.sourceResult;\n startupMessages = loaded.startupMessages;\n\n const sourceInfo = sourceResult.isLocal ? \"local\" : sourceResult.sourceConfig.sourceOrigin;\n startupMessages.push({\n level: \"info\",\n text: `Loaded ${Object.keys(matrix.skills).length} skills (${sourceInfo})`,\n });\n } catch (error) {\n this.handleError(error);\n }\n\n let currentSkillIds: SkillId[];\n try {\n const discoveredSkills = await discoverAllPluginSkills(projectDir);\n const pluginSkillIds = typedKeys(discoveredSkills);\n\n // Merge plugin-discovered skills with config skills (catches local skills and\n // global-scoped plugins that discoverAllPluginSkills doesn't find).\n // Exclude skills marked as excluded — they should not appear as selected in the build step.\n // They are still preserved in skillConfigs via installedSkillConfigs for info panel/confirm step.\n const excludedConfigIds = new Set(\n projectConfig?.skills?.filter((s) => s.excluded).map((s) => s.id) ?? [],\n );\n const configSkillIds =\n projectConfig?.skills?.filter((s) => !s.excluded).map((s) => s.id) ?? [];\n const filteredPluginSkillIds = pluginSkillIds.filter((id) => !excludedConfigIds.has(id));\n const mergedIds = new Set<SkillId>([...filteredPluginSkillIds, ...configSkillIds]);\n currentSkillIds = [...mergedIds];\n\n startupMessages.push({\n level: \"info\",\n text: `Found ${currentSkillIds.length} installed skills`,\n });\n } catch (error) {\n this.handleError(error);\n }\n\n return {\n installation,\n projectConfig,\n projectDir,\n sourceResult,\n startupMessages,\n currentSkillIds,\n };\n }\n\n private async runEditWizard(context: EditContext, cwd: string): Promise<WizardResultV2 | null> {\n const { projectConfig, projectDir, currentSkillIds } = context;\n\n return runWizardSession({\n hydrate: {\n initialStep: \"build\",\n initialDomains: projectConfig?.domains,\n initialAgents: projectConfig?.selectedAgents,\n installedSkillIds: currentSkillIds,\n installedSkillConfigs: projectConfig?.skills,\n installedAgentConfigs: projectConfig?.agents,\n isEditingFromGlobalScope: isHomeDirectory(cwd),\n },\n props: {\n version: this.config.version,\n initialAgents: projectConfig?.selectedAgents,\n installedSkillIds: currentSkillIds,\n projectDir,\n startupMessages: context.startupMessages,\n },\n onCancel: () => this.log(\"\\nEdit cancelled\"),\n clearTerminal: () => this.clearTerminal(),\n });\n }\n\n /**\n * Records, in the GLOBAL config, the install-mode migrations this run already performed\n * under `$HOME`.\n *\n * A project-context edit otherwise never writes global config (commit 403df46, \"never\n * modify global config from project-level operations\"), and `authoritativeScope: \"owned\"`\n * enforces that for the roster — an inherited global-active entry is read-only, so\n * `mergeGlobalConfigs` preserves it verbatim. That protection is correct for selection and\n * scope, but `executeMigration` resolves each skill's paths from ITS OWN scope: switching a\n * global-scoped skill's source has already copied it under `$HOME` (or deleted it) and\n * added/removed its user-scope plugin registration by the time the config is written.\n * Leaving the global config alone there protects nothing — it only makes the recorded\n * source contradict the filesystem and the plugin registry.\n *\n * So authority follows the work actually performed, and no further: only ids\n * `executeMigration` acted on this run are rewritten, and only their `source` field. Global\n * entries this session merely displayed, re-scoped or deselected are untouched, as are\n * `marketplace`, `stack`, `agents` and every other registered project's view of them.\n * Refusing the switch instead is not an option — driving a global-scope migration from a\n * project directory is a supported flow (`scope-aware-local-copy` lifecycle tests).\n *\n * Runs BEFORE `writeConfigAndCompile`, so the global config written here is the one\n * the wizard write reloads, keeps (existing wins in `mergeGlobalConfigs`) and inlines\n * into the project config — both files then tell the same story. That second write\n * classifies as a no-op against what this one left on disk, so the fan-out below\n * happens once.\n *\n * The migrated `source` decides the reference form a compiled agent emits, so every\n * OTHER registered project's config and agents are stale until this write fans out —\n * which is why it goes through the gate rather than straight to the file.\n */\n private async recordGlobalSourceMigrations(\n migratedSkillIds: Set<SkillId>,\n newSkills: SkillConfig[],\n cwd: string,\n context: EditContext,\n ): Promise<void> {\n // A global-context edit writes the whole global config from the wizard result already.\n if (isHomeDirectory(cwd)) return;\n\n const migratedSources = new Map(\n newSkills\n .filter((s) => migratedSkillIds.has(s.id) && isActiveAt(s, \"global\"))\n .map((s) => [s.id, s.source] as const),\n );\n if (migratedSources.size === 0) return;\n\n try {\n const report = await mutateGlobal(\n { kind: \"migrate-skill-sources\", sources: migratedSources },\n {\n loadMatrix: async () => context.sourceResult.matrix,\n loadAgents: async () => (await loadAgentDefs({ projectDir: cwd })).agents,\n },\n );\n this.reportPropagatedRecompile(report);\n } catch (error) {\n this.warn(`Could not record global source change: ${getErrorMessage(error)}`);\n }\n }\n\n private reportValidationErrors(result: WizardResultV2): void {\n if (result.validation.errors.length > 0) {\n for (const err of result.validation.errors) {\n this.warn(err.message);\n }\n }\n }\n\n private logChangeSummary(\n changes: ConfigChanges,\n newSkills: SkillConfig[],\n oldSkills: SkillConfig[],\n ): void {\n const {\n addedSkills,\n removedSkills,\n addedAgents,\n removedAgents,\n sourceChanges,\n scopeChanges,\n agentScopeChanges,\n dualScopeSkillTransitions,\n dualScopeAgentTransitions,\n } = changes;\n\n this.log(`\\n${chalk.hex(CLI_COLORS.WHITE).bold(\"Changes:\")}`);\n for (const skillId of addedSkills) {\n const scope = newSkills.find((s) => s.id === skillId)?.scope;\n const scopeLabel = scope ? ` ${formatScopeTag(scope)}` : \"\";\n this.log(\n chalk.hex(CLI_COLORS.SUCCESS)(` + ${getSkillById(skillId).displayName}${scopeLabel}`),\n );\n }\n for (const skillId of removedSkills) {\n const scope = oldSkills.find((s) => s.id === skillId)?.scope;\n const scopeLabel = scope ? ` ${formatScopeTag(scope)}` : \"\";\n this.log(chalk.hex(CLI_COLORS.ERROR)(` - ${getSkillDisplayName(skillId)}${scopeLabel}`));\n }\n for (const agentName of addedAgents) {\n this.log(\n chalk.hex(CLI_COLORS.SUCCESS)(` + ${agentName}`) +\n chalk.hex(CLI_COLORS.NEUTRAL)(\" (agent)\"),\n );\n }\n for (const agentName of removedAgents) {\n this.log(\n chalk.hex(CLI_COLORS.ERROR)(` - ${agentName}`) + chalk.hex(CLI_COLORS.NEUTRAL)(\" (agent)\"),\n );\n }\n for (const [skillId, change] of sourceChanges) {\n const displayName = getSkillDisplayName(skillId);\n const fromLabel = formatSourceDisplayName(change.from);\n const toLabel = formatSourceDisplayName(change.to);\n this.log(\n chalk.hex(CLI_COLORS.WARNING)(` ~ ${displayName}`) +\n chalk.hex(CLI_COLORS.NEUTRAL)(` (${fromLabel} \\u2192 ${toLabel})`),\n );\n }\n for (const [skillId, change] of scopeChanges) {\n const displayName = getSkillDisplayName(skillId);\n\n if (dualScopeSkillTransitions.has(skillId)) {\n this.log(formatDualScopeTransition(displayName, change.to));\n continue;\n }\n\n const fromLabel = formatScopeTag(change.from);\n const toLabel = formatScopeTag(change.to);\n const isGlobalToProject = change.from === \"global\" && change.to === \"project\";\n const prefix = isGlobalToProject ? \"+\" : \"~\";\n const color = isGlobalToProject ? CLI_COLORS.SUCCESS : CLI_COLORS.WARNING;\n this.log(\n chalk.hex(color)(` ${prefix} ${displayName}`) +\n chalk.hex(CLI_COLORS.NEUTRAL)(` (${fromLabel} \\u2192 ${toLabel})`),\n );\n }\n for (const [agentName, change] of agentScopeChanges) {\n // Dual-scope add/remove for agents \\u2014 mirrors the skill path above.\n if (dualScopeAgentTransitions.has(agentName)) {\n this.log(\n formatDualScopeTransition(agentName, change.to) +\n chalk.hex(CLI_COLORS.NEUTRAL)(\" (agent)\"),\n );\n continue;\n }\n\n const fromLabel = formatScopeTag(change.from);\n const toLabel = formatScopeTag(change.to);\n this.log(\n chalk.hex(CLI_COLORS.WARNING)(` ~ ${agentName}`) +\n chalk.hex(CLI_COLORS.NEUTRAL)(` (${fromLabel} \\u2192 ${toLabel})`),\n );\n }\n this.log(\"\");\n }\n\n private async applyMigrations(\n _changes: ConfigChanges,\n filteredResult: WizardResultV2,\n activeOldSkills: SkillConfig[],\n context: EditContext,\n cwd: string,\n ): Promise<Set<SkillId>> {\n const migrationPlan = detectMigrations(activeOldSkills, filteredResult.skills);\n const hasMigrations = migrationPlan.toEject.length > 0 || migrationPlan.toPlugin.length > 0;\n\n if (hasMigrations) {\n if (migrationPlan.toEject.length > 0) {\n this.log(\n chalk.hex(CLI_COLORS.NEUTRAL)(\n `Switching ${migrationPlan.toEject.length} skill(s) to eject`,\n ),\n );\n }\n if (migrationPlan.toPlugin.length > 0) {\n this.log(\n chalk.hex(CLI_COLORS.NEUTRAL)(\n `Switching ${migrationPlan.toPlugin.length} skill(s) to plugin`,\n ),\n );\n // Installing a plugin needs the marketplace REGISTERED and up to date with the\n // Claude CLI — the same precondition `applyPluginChanges` and `applyScopeChanges`\n // establish. Without it `claude plugin install` rejects every ref against a stale\n // local copy. Runs before `executeMigration` so an unresolvable marketplace exits\n // while the ejected working copies are still intact. Eject-side plugin uninstalls\n // are diagnostic-only, so only plugin-install work demands this.\n await this.requireMarketplaceOrExit(context.sourceResult, \"migrate skills to plugin mode\");\n }\n\n const migrationResult = await executeMigration(migrationPlan, cwd, context.sourceResult);\n\n for (const warning of migrationResult.warnings) {\n this.warn(warning);\n }\n for (const item of migrationResult.failedPluginInstalls) {\n this.warn(`Failed to install plugin ${item.id}: ${item.error}`);\n }\n\n // Plugin install intent is inviolable — a migration whose plugin could not be\n // installed must not reach `recordGlobalSourceMigrations` or\n // `writeConfigAndCompile`, either of which would persist a marketplace `source`\n // for a skill with no plugin registration. Same guard as the newly-added-skill\n // path in `applyPluginChanges`.\n if (migrationResult.failedPluginInstalls.length > 0) {\n this.error(pluginInstallFailureError(migrationResult.failedPluginInstalls.length), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n return new Set([\n ...migrationPlan.toEject.map((m) => m.id),\n ...migrationPlan.toPlugin.map((m) => m.id),\n ]);\n }\n\n private async applyScopeChanges(\n changes: ConfigChanges,\n filteredResult: WizardResultV2,\n context: EditContext,\n cwd: string,\n ): Promise<void> {\n const { scopeChanges } = changes;\n\n // Handle scope migrations (P->G or G->P) for eject-mode skills\n for (const [skillId, change] of scopeChanges) {\n const skillConfig = filteredResult.skills.find((s) => s.id === skillId);\n if (skillConfig?.source === EJECT_SOURCE) {\n await migrateLocalSkillScope(skillId, change.from, cwd);\n }\n }\n\n // Plugin scope migrations require a marketplace.\n // Compute eligible migrations first; only resolve/demand marketplace when there are any.\n const hasPluginScopeChanges = [...scopeChanges.keys()].some((skillId) => {\n const skillConfig = filteredResult.skills.find((s) => s.id === skillId);\n return skillConfig && skillConfig.source !== EJECT_SOURCE;\n });\n if (!hasPluginScopeChanges) return;\n\n const marketplace = await this.requireMarketplaceOrExit(\n context.sourceResult,\n \"migrate plugin skill scopes\",\n );\n\n const pluginScopeResult = await migratePluginSkillScopes(\n scopeChanges,\n filteredResult.skills,\n marketplace,\n cwd,\n );\n for (const item of pluginScopeResult.failed) {\n this.warn(`Failed to migrate plugin scope for ${item.id}: ${item.error}`);\n }\n }\n\n private async applySourceChanges(\n changes: ConfigChanges,\n activeOldSkills: SkillConfig[],\n cwd: string,\n migratedSkillIds: Set<SkillId>,\n ): Promise<void> {\n const { sourceChanges } = changes;\n\n // Handle remaining non-migration source changes (e.g., marketplace A -> marketplace B)\n for (const [skillId, change] of sourceChanges) {\n // Skip skills already handled by mode migration\n if (migratedSkillIds.has(skillId)) {\n continue;\n }\n if (change.from === EJECT_SOURCE) {\n const oldSkill = activeOldSkills.find((s) => s.id === skillId);\n const deleteDir = installBaseDir(cwd, oldSkill?.scope);\n await deleteLocalSkill(deleteDir, skillId);\n }\n }\n }\n\n private async applyPluginChanges(\n changes: ConfigChanges,\n filteredResult: WizardResultV2,\n activeOldSkills: SkillConfig[],\n context: EditContext,\n cwd: string,\n ): Promise<void> {\n const { addedSkills, removedSkills } = changes;\n\n // Compute plugin-intent lists per-skill (ungated) — per-skill `source` drives install mode.\n const addedPluginSkills = filteredResult.skills.filter(\n (s) => addedSkills.includes(s.id) && s.source !== EJECT_SOURCE,\n );\n const removedPluginSkills = removedSkills.filter(\n (id) => activeOldSkills.find((s) => s.id === id)?.source !== EJECT_SOURCE,\n );\n\n if (addedPluginSkills.length === 0 && removedPluginSkills.length === 0) return;\n\n const marketplace = await this.requireMarketplaceOrExit(\n context.sourceResult,\n \"install or uninstall plugin skills\",\n );\n\n if (addedPluginSkills.length > 0) {\n const pluginResult = await installPluginSkills(addedPluginSkills, marketplace, cwd);\n if (pluginResult.installed.length > 0) {\n this.log(\n chalk.hex(CLI_COLORS.NEUTRAL)(`Installed ${pluginResult.installed.length} plugin(s)`),\n );\n }\n for (const item of pluginResult.failed) {\n this.warn(`Failed to install plugin ${item.id}: ${item.error}`);\n }\n\n // Plugin install intent is inviolable — if any skill failed to install,\n // hard-error BEFORE `writeConfigAndCompile` writes config.ts with orphan\n // entries claiming the skill is installed. Matches the\n // no-plugin-to-eject-fallback rule.\n if (pluginResult.failed.length > 0) {\n this.error(pluginInstallFailureError(pluginResult.failed.length), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n if (removedPluginSkills.length > 0) {\n const uninstallResult = await uninstallPluginSkills(\n removedPluginSkills,\n activeOldSkills,\n marketplace,\n cwd,\n );\n if (uninstallResult.uninstalled.length > 0) {\n this.log(\n chalk.hex(CLI_COLORS.NEUTRAL)(`Removed ${uninstallResult.uninstalled.length} plugin(s)`),\n );\n }\n for (const item of uninstallResult.failed) {\n this.warn(`Failed to uninstall plugin ${item.id}: ${item.error}`);\n }\n }\n }\n\n private async copyNewLocalSkills(\n changes: ConfigChanges,\n filteredResult: WizardResultV2,\n context: EditContext,\n cwd: string,\n ): Promise<void> {\n const { addedSkills } = changes;\n\n // Copy newly added local-source skills to .claude/skills/ (split by scope)\n const addedLocalSkills = filteredResult.skills.filter(\n (s) => addedSkills.includes(s.id) && s.source === EJECT_SOURCE,\n );\n\n if (addedLocalSkills.length > 0) {\n const copyResult = await copyLocalSkills(addedLocalSkills, cwd, context.sourceResult);\n this.log(chalk.hex(CLI_COLORS.NEUTRAL)(`Copied ${copyResult.totalCopied} local skill(s)`));\n }\n }\n\n private async removeDeletedLocalSkills(\n changes: ConfigChanges,\n activeOldSkills: SkillConfig[],\n cwd: string,\n ): Promise<void> {\n const { removedSkills } = changes;\n\n // A fully-deselected eject-mode skill is a genuine uninstall — its copied directory under\n // .claude/skills/<id>/ must be removed from the scope it was installed at (D-233). Plugin\n // removals are handled by applyPluginChanges; source-change (eject->marketplace) deletions by\n // applySourceChanges. deleteLocalSkill is a no-op when the directory is absent.\n for (const skillId of removedSkills) {\n const oldSkill = activeOldSkills.find((s) => s.id === skillId);\n if (oldSkill?.source !== EJECT_SOURCE) continue;\n\n const deleteDir = installBaseDir(cwd, oldSkill.scope);\n await deleteLocalSkill(deleteDir, skillId);\n }\n }\n\n private async writeConfigAndCompile(\n result: WizardResultV2,\n context: EditContext,\n flags: SourceRefreshFlags,\n cwd: string,\n ): Promise<void> {\n // Load agent definitions — needed for both config-types.ts and recompilation\n let agentDefsResult: AgentDefs;\n try {\n agentDefsResult = await loadAgentDefs({\n forceRefresh: flags.refresh,\n });\n } catch (error) {\n this.handleError(error);\n }\n\n // Persist wizard result to config.ts and config-types.ts (split by scope when in project context)\n let configResult: ConfigWriteResult | undefined;\n try {\n configResult = await writeProjectConfig({\n wizardResult: result,\n sourceResult: context.sourceResult,\n projectDir: cwd,\n sourceFlag: flags.source,\n agents: agentDefsResult.agents,\n // A full `cc edit` pass is authoritative over the roster it owns, so deselected entries\n // are removed rather than union-preserved (D-233 Scenario C). Global-context edit owns\n // the entire config (\"all\"); a project edit owns only project-scoped entries and its own\n // tombstones (\"owned\"), never inherited global-active entries.\n authoritativeScope: isHomeDirectory(cwd) ? \"all\" : \"owned\",\n });\n } catch (error) {\n this.warn(`Could not update config: ${getErrorMessage(error)}`);\n }\n\n try {\n const agentScopeMap = activeAgentScopeMap(result.agentConfigs);\n const { allSkills } = await discoverInstalledSkills(cwd);\n const compilationResult = await compileAgentsAllScopes({\n projectDir: cwd,\n sourcePath: agentDefsResult.sourcePath,\n skills: allSkills,\n agentScopeMap,\n });\n\n if (compilationResult.failed.length > 0) {\n this.log(\n chalk.hex(CLI_COLORS.NEUTRAL)(`Recompiled ${compilationResult.compiled.length} agents`) +\n chalk.hex(CLI_COLORS.WARNING)(` (${compilationResult.failed.length} failed)`),\n );\n for (const warning of compilationResult.warnings) {\n this.warn(warning);\n }\n } else if (compilationResult.compiled.length > 0) {\n this.log(\n chalk.hex(CLI_COLORS.NEUTRAL)(`Recompiled ${compilationResult.compiled.length} agents`),\n );\n } else {\n this.log(chalk.hex(CLI_COLORS.NEUTRAL)(\"No agents to recompile\"));\n }\n } catch (error) {\n this.warn(`Agent recompilation failed: ${getErrorMessage(error)}`);\n this.log(`You can manually recompile with '${CLI_INVOKE_COMMAND} compile'.`);\n }\n\n if (configResult) {\n this.reportPropagatedRecompile(configResult.propagation);\n }\n }\n\n /**\n * Renders the recompile the gated write already performed on every OTHER\n * registered project this run's global change was propagated into.\n */\n private reportPropagatedRecompile(propagation: GateReport): void {\n if (propagation.propagated.updated.length === 0) return;\n\n const { recompiledCount, failedCount, warnings } = propagation.recompile;\n for (const warning of warnings) {\n this.warn(warning);\n }\n\n const summary = chalk.hex(CLI_COLORS.NEUTRAL)(\n `Recompiled agents in ${recompiledCount} registered project(s)`,\n );\n this.log(\n failedCount > 0\n ? summary + chalk.hex(CLI_COLORS.WARNING)(` (${failedCount} failed)`)\n : summary,\n );\n }\n\n private async cleanupStaleAgentFiles(\n changes: ConfigChanges,\n oldAgents: AgentScopeConfig[],\n cwd: string,\n ): Promise<void> {\n const { agentScopeChanges, removedAgents } = changes;\n\n // Clean up old agent .md files after scope changes.\n // Recompilation wrote the new file to the correct scope directory;\n // now delete the stale copy from the old scope directory.\n // Only clean up for P→G direction. G→P is an override — the global\n // installation stays untouched; the project copy overrides it.\n for (const [agentName, change] of agentScopeChanges) {\n if (change.from === \"global\") continue;\n\n const oldAgentPath = path.join(\n resolveInstallPaths(cwd, \"project\").agentsDir,\n `${agentName}.md`,\n );\n try {\n await remove(oldAgentPath);\n } catch (error) {\n this.warn(`Could not remove old agent file ${oldAgentPath}: ${getErrorMessage(error)}`);\n }\n }\n\n // Deselected agents are a genuine uninstall — recompilation never rewrites their .md, so\n // delete the compiled file from the scope it was installed at (D-233). remove() is a no-op\n // when the file is absent.\n for (const agentName of removedAgents) {\n const oldScope = oldAgents.find((a) => a.name === agentName)?.scope ?? \"project\";\n const agentPath = path.join(resolveInstallPaths(cwd, oldScope).agentsDir, `${agentName}.md`);\n try {\n await remove(agentPath);\n } catch (error) {\n this.warn(`Could not remove agent file ${agentPath}: ${getErrorMessage(error)}`);\n }\n }\n }\n\n private logCompletionSummary(_changes: ConfigChanges): void {\n this.log(`\\n${chalk.hex(CLI_COLORS.SUCCESS)(\"\\u2713 Done\")}\\n`);\n }\n}\n\n/** @internal Exported for testing */\nexport type ConfigChanges = {\n addedSkills: SkillId[];\n removedSkills: SkillId[];\n addedAgents: AgentName[];\n removedAgents: AgentName[];\n sourceChanges: Map<SkillId, { from: string; to: string }>;\n scopeChanges: Map<SkillId, ScopeChange>;\n agentScopeChanges: Map<AgentName, ScopeChange>;\n /**\n * Skill ids whose `scopeChanges` entry is a dual-scope add/remove — the project\n * half of a `[P][G]` pair was toggled while the global half persists — NOT a true\n * single-entry migration. The disk-side scope work still flows through\n * `scopeChanges`; this set only steers the completion-summary display so a\n * dual-scope addition is not misreported as a `[G] → [P]` migration.\n */\n dualScopeSkillTransitions: Set<SkillId>;\n /** Agent equivalent of `dualScopeSkillTransitions`. */\n dualScopeAgentTransitions: Set<AgentName>;\n};\n\n/** Full (tombstone-inclusive) entry lists used to classify dual-scope transitions. */\ntype FullScopeEntries = {\n newSkills: SkillConfig[];\n oldSkills: SkillConfig[];\n newAgents: AgentScopeConfig[];\n oldAgents: AgentScopeConfig[];\n};\n\n/**\n * @internal Exported for testing\n *\n * `oldConfig` / `wizardResult` carry the ACTIVE (tombstone-filtered) entries used\n * for add/remove/source/scope diffing. `fullEntries`, when provided, carries the\n * unfiltered lists (including excluded tombstones) used ONLY to tell a genuine\n * scope migration apart from a dual-scope add/remove. When omitted, every scope\n * change is treated as a migration (the pre-dual-scope behaviour).\n */\nexport function detectConfigChanges(\n oldConfig: ProjectConfig | null,\n wizardResult: WizardResultV2,\n fullEntries?: FullScopeEntries,\n): ConfigChanges {\n const oldSkillIds = oldConfig?.skills?.map((s) => s.id) ?? [];\n const newSkillIds = wizardResult.skills.map((s) => s.id);\n const oldAgentNames = oldConfig?.agents?.map((a) => a.name) ?? [];\n const newAgentNames = wizardResult.agentConfigs.map((a) => a.name);\n\n const oldSkillsById = indexBy(oldConfig?.skills ?? [], (s) => s.id);\n const oldAgentsByName = indexBy(oldConfig?.agents ?? [], (a) => a.name);\n\n const scopeChanges = detectPropertyChanges(\n wizardResult.skills,\n oldSkillsById,\n (s) => s.id,\n (s) => s.scope,\n );\n const agentScopeChanges = detectPropertyChanges(\n wizardResult.agentConfigs,\n oldAgentsByName,\n (a) => a.name,\n (a) => a.scope,\n );\n\n return {\n addedSkills: difference(newSkillIds, oldSkillIds),\n removedSkills: difference(oldSkillIds, newSkillIds),\n addedAgents: difference(newAgentNames, oldAgentNames),\n removedAgents: difference(oldAgentNames, newAgentNames),\n sourceChanges: detectPropertyChanges(\n wizardResult.skills,\n oldSkillsById,\n (s) => s.id,\n (s) => s.source,\n ),\n scopeChanges,\n agentScopeChanges,\n dualScopeSkillTransitions: detectDualScopeTransitions(\n scopeChanges,\n fullEntries?.newSkills ?? [],\n fullEntries?.oldSkills ?? [],\n (s) => s.id,\n ),\n dualScopeAgentTransitions: detectDualScopeTransitions(\n agentScopeChanges,\n fullEntries?.newAgents ?? [],\n fullEntries?.oldAgents ?? [],\n (a) => a.name,\n ),\n };\n}\n\nfunction detectPropertyChanges<T, K extends string, V>(\n newItems: T[],\n oldByKey: Record<string, T>,\n getKey: (item: T) => K,\n getValue: (item: T) => V,\n): Map<K, { from: V; to: V }> {\n const changes = new Map<K, { from: V; to: V }>();\n for (const item of newItems) {\n const key = getKey(item);\n const old = oldByKey[key];\n if (old && getValue(old) !== getValue(item)) {\n changes.set(key, { from: getValue(old), to: getValue(item) });\n }\n }\n return changes;\n}\n\n/**\n * A scope change is a dual-scope transition (not a migration) when the canonical\n * dual-scope tombstone — an excluded global entry — sits alongside it:\n * - G→P add: the NEW state keeps a global tombstone, so the global install\n * survives and the project half was merely added.\n * - P→G remove: the OLD state held a global tombstone, so the pair was already\n * dual-scope and the project half was merely removed.\n * Either way the item occupied both scopes, so `[X] → [Y]` would misdescribe it.\n */\nfunction detectDualScopeTransitions<\n K extends string,\n T extends { scope: SkillScope; excluded?: boolean },\n>(scopeChanges: Map<K, ScopeChange>, fullNew: T[], fullOld: T[], getKey: (item: T) => K): Set<K> {\n const hasGlobalTombstone = (items: T[], key: K): boolean =>\n items.some((item) => getKey(item) === key && item.scope === \"global\" && item.excluded === true);\n\n const result = new Set<K>();\n for (const [key, change] of scopeChanges) {\n if (change.from === \"global\" && change.to === \"project\" && hasGlobalTombstone(fullNew, key)) {\n result.add(key);\n } else if (\n change.from === \"project\" &&\n change.to === \"global\" &&\n hasGlobalTombstone(fullOld, key)\n ) {\n result.add(key);\n }\n }\n return result;\n}\n\nfunction hasAnyChanges(changes: ConfigChanges): boolean {\n return (\n changes.addedSkills.length > 0 ||\n changes.removedSkills.length > 0 ||\n changes.addedAgents.length > 0 ||\n changes.removedAgents.length > 0 ||\n changes.sourceChanges.size > 0 ||\n changes.scopeChanges.size > 0 ||\n changes.agentScopeChanges.size > 0\n );\n}\n\n/** @internal Exported for testing */\nexport type PluginScopeMigrationResult = {\n migrated: SkillId[];\n failed: Array<{ id: SkillId; error: string }>;\n};\n\n/** @internal Exported for testing */\nexport async function migratePluginSkillScopes(\n scopeChanges: Map<SkillId, ScopeChange>,\n skills: Pick<SkillConfig, \"id\" | \"source\">[],\n marketplace: string,\n projectDir: string,\n): Promise<PluginScopeMigrationResult> {\n const migrated: SkillId[] = [];\n const failed: PluginScopeMigrationResult[\"failed\"] = [];\n\n for (const [skillId, change] of scopeChanges) {\n const skillConfig = skills.find((s) => s.id === skillId);\n if (!skillConfig || skillConfig.source === EJECT_SOURCE) {\n continue;\n }\n\n const newPluginScope = toClaudePluginScope(change.to);\n const pluginRef = buildMarketplacePluginRef(skillId, marketplace);\n\n try {\n // global→project: keep the global registration, just add project scope.\n // The global plugin must remain for other projects.\n // project→global: uninstall the project-scope registration, install global.\n if (change.from === \"project\") {\n await claudePluginUninstall(pluginRef, \"project\", projectDir);\n }\n await claudePluginInstall(pluginRef, newPluginScope, projectDir);\n migrated.push(skillId);\n } catch (error) {\n failed.push({ id: skillId, error: getErrorMessage(error) });\n }\n }\n\n return { migrated, failed };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/edit.tsx"],"sourcesContent":["import path from \"path\";\n\nimport chalk from \"chalk\";\nimport { Flags } from \"@oclif/core\";\nimport { render } from \"../components/render.js\";\n\nimport { difference, indexBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { type WizardResultV2 } from \"../components/wizard/wizard.js\";\nimport { runWizardSession } from \"../components/wizard/run-wizard-session.js\";\nimport {\n CLI_INVOKE_COMMAND,\n CLI_COLORS,\n EDIT_PROJECT_SETUP_FLAG,\n EJECT_SOURCE,\n formatSourceDisplayName,\n} from \"../consts.js\";\nimport {\n detectProject,\n loadSource,\n copyLocalSkills,\n uninstallPluginSkills,\n loadAgentDefs,\n type AgentDefs,\n writeProjectConfig,\n type ConfigWriteResult,\n compileAgentsAllScopes,\n discoverInstalledSkills,\n} from \"../lib/operations/index.js\";\nimport { Spinner } from \"../components/common/spinner.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n type Installation,\n detectMigrations,\n executeMigration,\n isHomeDirectory,\n installBaseDir,\n resolveInstallPaths,\n INSTALL_MODE_DESCRIPTIONS,\n} from \"../lib/installation/index.js\";\nimport { applyMigratedGlobalSources, mutateGlobal } from \"../lib/config-gate/index.js\";\nimport { matrix, getSkillById, getSkillDisplayName } from \"../lib/matrix/matrix-provider\";\nimport {\n activeAgentNames,\n activeAgentScopeMap,\n isActiveAt,\n} from \"../lib/configuration/scope-predicates.js\";\nimport type { SourceLoadResult } from \"../lib/loading/index.js\";\nimport {\n discoverAllPluginSkills,\n buildMarketplacePluginRef,\n toClaudePluginScope,\n} from \"../lib/plugins/index.js\";\nimport {\n deleteLocalSkill,\n migrateLocalSkillScope,\n unresolvedSkillRemovalReasons,\n} from \"../lib/skills/index.js\";\nimport type {\n SkillId,\n SkillConfig,\n AgentName,\n AgentScopeConfig,\n ProjectConfig,\n SkillScope,\n} from \"../types/index.js\";\nimport { claudePluginInstall, claudePluginUninstall } from \"../utils/exec.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { remove } from \"../utils/fs.js\";\nimport { type StartupMessage } from \"../utils/logger.js\";\nimport {\n ERROR_MESSAGES,\n INFO_MESSAGES,\n STATUS_MESSAGES,\n recompileSummary,\n} from \"../utils/messages.js\";\nimport { formatScopeTag } from \"../lib/wizard/index.js\";\nimport { typedKeys } from \"../utils/typed-object.js\";\n\n/** A scope transition (`from` → `to`) for a re-scoped skill or agent. */\ntype ScopeChange = { from: SkillScope; to: SkillScope };\n\n/**\n * The noun `edit`'s recompile summary counts in. `edit` recompiles every scope this\n * context owns in one pass, so it has no scope word to qualify with — `compile`,\n * which runs one scope at a time, does.\n */\nconst RECOMPILE_SUBJECT = \"agents\";\n\n/**\n * Dual-scope add/remove: the project half of a [P][G] pair was toggled while the\n * global half persists. Reported as a project-scope addition/removal; a\n * scope-change arrow line would falsely claim the global install moved.\n */\nfunction formatDualScopeTransition(displayName: string, to: SkillScope): string {\n const isAdd = to === \"project\";\n const prefix = isAdd ? \"+\" : \"-\";\n const color = isAdd ? CLI_COLORS.SUCCESS : CLI_COLORS.ERROR;\n return chalk.hex(color)(` ${prefix} ${displayName} [P]`);\n}\n\n/**\n * One re-scoped skill's line. A dual-scope toggle is the transition above rather than a\n * migration; a genuine `[G] → [P]` reads as an addition because the skill arrives in this\n * project, and every other direction is the amber `~` a move is written with.\n */\nfunction formatSkillScopeChangeLine(\n skillId: SkillId,\n change: ScopeChange,\n dualScopeSkillTransitions: ReadonlySet<SkillId>,\n): string {\n const displayName = getSkillDisplayName(skillId);\n if (dualScopeSkillTransitions.has(skillId)) {\n return formatDualScopeTransition(displayName, change.to);\n }\n\n const isGlobalToProject = change.from === \"global\" && change.to === \"project\";\n const prefix = isGlobalToProject ? \"+\" : \"~\";\n const color = isGlobalToProject ? CLI_COLORS.SUCCESS : CLI_COLORS.WARNING;\n return (\n chalk.hex(color)(` ${prefix} ${displayName}`) +\n chalk.hex(CLI_COLORS.NEUTRAL)(scopeArrow(change))\n );\n}\n\n/**\n * The agent mirror of the line above, with two differences preserved from how this summary has\n * always read: there is no `[G] → [P]`-reads-as-addition arm — an agent that moves is a move —\n * and only the dual-scope arm carries the `(agent)` suffix, since a `~` line names no skill it\n * could be confused with.\n */\nfunction formatAgentScopeChangeLine(\n agentName: AgentName,\n change: ScopeChange,\n dualScopeAgentTransitions: ReadonlySet<AgentName>,\n): string {\n const agentSuffix = chalk.hex(CLI_COLORS.NEUTRAL)(\" (agent)\");\n if (dualScopeAgentTransitions.has(agentName)) {\n return formatDualScopeTransition(agentName, change.to) + agentSuffix;\n }\n\n return (\n chalk.hex(CLI_COLORS.WARNING)(` ~ ${agentName}`) +\n chalk.hex(CLI_COLORS.NEUTRAL)(scopeArrow(change))\n );\n}\n\n/** The ` ([P] → [G])` half both lines above end with, in the tags the wizard writes scopes as. */\nfunction scopeArrow(change: ScopeChange): string {\n return ` (${formatScopeTag(change.from)} \\u2192 ${formatScopeTag(change.to)})`;\n}\n\n/**\n * The name this session's catalogue answers to — what a marketplace-dropped entry's removal\n * reason says the skill is not present in. The resolved marketplace where there is one,\n * otherwise the source string itself, which is what an installation pointed at a source that\n * never carried the skill has to be named by.\n */\nfunction loadedSourceLabel(sourceResult: SourceLoadResult): string {\n return sourceResult.marketplace ?? sourceResult.sourceConfig.source;\n}\n\n/** @internal Re-exported for testing — the transform itself lives inside the gate. */\nexport { applyMigratedGlobalSources };\n\ntype EditContext = {\n installation: Installation;\n projectConfig: ProjectConfig | null;\n projectDir: string;\n sourceResult: SourceLoadResult;\n startupMessages: StartupMessage[];\n currentSkillIds: SkillId[];\n};\n\nexport default class Edit extends BaseCommand {\n static summary = \"Edit skills in the plugin\";\n static description = \"Modify the currently installed skills via interactive wizard\";\n\n static examples = [\n {\n description: \"Open the edit wizard\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n ];\n\n static flags = {\n [EDIT_PROJECT_SETUP_FLAG]: Flags.boolean({\n description: \"Internal: this run continues an `init` project setup\",\n default: false,\n hidden: true,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Edit);\n const cwd = process.cwd();\n\n // Before anything renders: a config that cannot be read is recreated, not edited, and\n // refusing here is what keeps the refusal clean — past this point the wizard has already\n // copied skills and installed plugins by the time a config read fails.\n await this.ensureConfigReadable(cwd);\n\n const { unmount, clear: clearSpinner } = render(\n <Spinner label={STATUS_MESSAGES.LOADING_SKILLS} />,\n );\n const context = await this.loadContext();\n clearSpinner();\n unmount();\n\n // Still before anything renders, one layer below the config itself: an entry whose skill\n // IS installed and whose metadata.yaml describes it no longer would otherwise be dropped\n // from config.ts on the way out, over a file this refusal asks to be repaired instead.\n await this.ensureSavedSkillsReadable(\n context.projectConfig?.skills ?? [],\n context.sourceResult.matrix,\n context.projectDir,\n );\n\n const result = await this.runEditWizard(context, cwd);\n if (!result) this.error(\"Cancelled\", { exit: EXIT_CODES.CANCELLED });\n\n this.reportValidationErrors(result.validation);\n\n // Filter excluded entries ONCE — downstream methods receive only active entries\n const activeNewSkills = result.skills.filter((s) => !s.excluded);\n const activeNewAgents = result.agentConfigs.filter((a) => !a.excluded);\n const activeOldSkills = (context.projectConfig?.skills ?? []).filter((s) => !s.excluded);\n const activeOldAgents = (context.projectConfig?.agents ?? []).filter((a) => !a.excluded);\n\n const filteredResult: WizardResultV2 = {\n ...result,\n skills: activeNewSkills,\n agentConfigs: activeNewAgents,\n };\n const filteredOldConfig: ProjectConfig | null = context.projectConfig\n ? { ...context.projectConfig, skills: activeOldSkills, agents: activeOldAgents }\n : null;\n\n const changes = detectConfigChanges(filteredOldConfig, filteredResult, {\n newSkills: result.skills,\n oldSkills: context.projectConfig?.skills ?? [],\n newAgents: result.agentConfigs,\n oldAgents: context.projectConfig?.agents ?? [],\n });\n // `cc init` inside a project means \"set this project up\", so the project must be\n // materialised — `<project>/.claude-src/config.ts` + `config-types.ts` written and the\n // path registered in the global `projects[]` — even when the wizard produced no roster\n // change. At the home root there is no project to set up: the global install is what the\n // dashboard was shown for, so a no-change pass there stays an inspection, as does every\n // bare `cc edit`.\n const isProjectSetup = flags[EDIT_PROJECT_SETUP_FLAG] && !isHomeDirectory(cwd);\n\n if (!hasAnyChanges(changes)) {\n this.log(chalk.hex(CLI_COLORS.NEUTRAL)(\"No changes made.\"));\n if (!isProjectSetup) return;\n await this.writeConfigAndCompile(result, context, cwd);\n this.logCompletionSummary(changes);\n return;\n }\n\n const removalReasons = await unresolvedSkillRemovalReasons(\n result.unresolvableSkillIds,\n activeOldSkills,\n context.projectDir,\n loadedSourceLabel(context.sourceResult),\n );\n this.logChangeSummary(\n changes,\n filteredResult.skills,\n filteredOldConfig?.skills ?? [],\n removalReasons,\n );\n const migratedSkillIds = await this.applyMigrations(\n changes,\n filteredResult,\n activeOldSkills,\n context,\n cwd,\n );\n await this.recordGlobalSourceMigrations(migratedSkillIds, filteredResult.skills, cwd, context);\n await this.applyScopeChanges(changes, filteredResult, context, cwd);\n await this.applySourceChanges(changes, activeOldSkills, cwd, migratedSkillIds);\n await this.applyPluginChanges(changes, filteredResult, activeOldSkills, context, cwd);\n await this.copyNewLocalSkills(changes, filteredResult, context, cwd);\n await this.removeDeletedLocalSkills(changes, activeOldSkills, cwd);\n await this.writeConfigAndCompile(result, context, cwd);\n await this.cleanupStaleAgentFiles(changes, activeOldAgents, cwd);\n this.logCompletionSummary(changes);\n }\n\n private async loadContext(): Promise<EditContext> {\n const detected = await detectProject();\n if (!detected) {\n this.error(ERROR_MESSAGES.NO_INSTALLATION, {\n exit: EXIT_CODES.ERROR,\n });\n }\n const { installation, config: projectConfig } = detected;\n\n // Use installation.projectDir for reads (loading config, discovering installed skills).\n // Use cwd for writes (config saves, plugin installs, scope migrations, recompilation output)\n // and for the global-scope check (determining whether editing from global context).\n const projectDir = installation.projectDir;\n\n let sourceResult: SourceLoadResult;\n let startupMessages: StartupMessage[] = [];\n try {\n // No source is named here: `edit` reads the one the installation stored.\n const loaded = await loadSource({ projectDir, captureStartupMessages: true });\n sourceResult = loaded.sourceResult;\n startupMessages = loaded.startupMessages;\n\n const sourceInfo = sourceResult.isLocal ? \"local\" : sourceResult.sourceConfig.sourceOrigin;\n startupMessages.push({\n level: \"info\",\n text: `Loaded ${Object.keys(matrix.skills).length} skills (${sourceInfo})`,\n });\n } catch (error) {\n this.handleError(error);\n }\n\n let currentSkillIds: SkillId[];\n try {\n const discoveredSkills = await discoverAllPluginSkills(projectDir);\n const pluginSkillIds = typedKeys(discoveredSkills);\n\n // Merge plugin-discovered skills with config skills (catches local skills and\n // global-scoped plugins that discoverAllPluginSkills doesn't find).\n // Exclude skills marked as excluded — they should not appear as selected in the build step.\n // They are still preserved in skillConfigs via installedSkillConfigs for info panel/confirm step.\n const excludedConfigIds = new Set(\n projectConfig?.skills.filter((s) => s.excluded).map((s) => s.id) ?? [],\n );\n const configSkillIds =\n projectConfig?.skills.filter((s) => !s.excluded).map((s) => s.id) ?? [];\n const filteredPluginSkillIds = pluginSkillIds.filter((id) => !excludedConfigIds.has(id));\n const mergedIds = new Set<SkillId>([...filteredPluginSkillIds, ...configSkillIds]);\n currentSkillIds = [...mergedIds];\n\n startupMessages.push({\n level: \"info\",\n text: `Found ${currentSkillIds.length} installed skills`,\n });\n } catch (error) {\n this.handleError(error);\n }\n\n return {\n installation,\n projectConfig,\n projectDir,\n sourceResult,\n startupMessages,\n currentSkillIds,\n };\n }\n\n private async runEditWizard(context: EditContext, cwd: string): Promise<WizardResultV2 | null> {\n const { projectConfig, currentSkillIds } = context;\n const selectedAgents = projectConfig?.agents && activeAgentNames(projectConfig.agents);\n\n return runWizardSession({\n hydrate: {\n initialStep: \"build\",\n ...(projectConfig?.selectedDomains !== undefined && {\n initialDomains: projectConfig.selectedDomains,\n }),\n ...(selectedAgents !== undefined && { initialAgents: selectedAgents }),\n installedSkillIds: currentSkillIds,\n ...(projectConfig?.skills !== undefined && { installedSkillConfigs: projectConfig.skills }),\n ...(projectConfig?.agents !== undefined && { installedAgentConfigs: projectConfig.agents }),\n isEditingFromGlobalScope: isHomeDirectory(cwd),\n },\n props: {\n version: this.config.version,\n initialAgents: selectedAgents,\n installedSkillIds: currentSkillIds,\n startupMessages: context.startupMessages,\n },\n onCancel: () => this.log(\"\\nEdit cancelled\"),\n clearTerminal: () => this.clearTerminal(),\n });\n }\n\n /**\n * Records, in the GLOBAL config, the install-mode migrations this run already performed\n * under `$HOME`.\n *\n * A project-context edit otherwise never writes global config (commit 403df46, \"never\n * modify global config from project-level operations\"), and `authoritativeScope: \"owned\"`\n * enforces that for the roster — an inherited global-active entry is read-only, so\n * `mergeGlobalConfigs` preserves it verbatim. That protection is correct for selection and\n * scope, but `executeMigration` resolves each skill's paths from ITS OWN scope: switching a\n * global-scoped skill's source has already copied it under `$HOME` (or deleted it) and\n * added/removed its user-scope plugin registration by the time the config is written.\n * Leaving the global config alone there protects nothing — it only makes the recorded\n * source contradict the filesystem and the plugin registry.\n *\n * So authority follows the work actually performed, and no further: only ids\n * `executeMigration` acted on this run are rewritten, and only their `source` field. Global\n * entries this session merely displayed, re-scoped or deselected are untouched, as are\n * `marketplace`, `stack`, `agents` and every other registered project's view of them.\n * Refusing the switch instead is not an option — driving a global-scope migration from a\n * project directory is a supported flow (`scope-aware-local-copy` lifecycle tests).\n *\n * Runs BEFORE `writeConfigAndCompile`, so the global config written here is the one\n * the wizard write reloads, keeps (existing wins in `mergeGlobalConfigs`) and inlines\n * into the project config — both files then tell the same story. That second write\n * classifies as a no-op against what this one left on disk, so the fan-out below\n * happens once.\n *\n * The migrated `source` decides the reference form a compiled agent emits, so every\n * OTHER registered project's config and agents are stale until this write fans out —\n * which is why it goes through the gate rather than straight to the file.\n */\n private async recordGlobalSourceMigrations(\n migratedSkillIds: Set<SkillId>,\n newSkills: SkillConfig[],\n cwd: string,\n context: EditContext,\n ): Promise<void> {\n // A global-context edit writes the whole global config from the wizard result already.\n if (isHomeDirectory(cwd)) return;\n\n const migratedSources = new Map(\n newSkills\n .filter((s) => migratedSkillIds.has(s.id) && isActiveAt(s, \"global\"))\n .map((s) => [s.id, s.source] as const),\n );\n if (migratedSources.size === 0) return;\n\n try {\n const report = await mutateGlobal(\n { kind: \"migrate-skill-sources\", sources: migratedSources },\n {\n // The deps contract in config-gate/deps.ts declares\n // `() => Promise<MergedSkillsMatrix>`; this caller happens to have its\n // matrix in hand already.\n // eslint-disable-next-line @typescript-eslint/require-await -- deps contract\n loadMatrix: async () => context.sourceResult.matrix,\n loadAgents: async () => (await loadAgentDefs({ projectDir: cwd })).agents,\n },\n );\n this.reportPropagatedRecompile(report);\n } catch (error) {\n this.warn(`Could not record global source change: ${getErrorMessage(error)}`);\n }\n }\n\n private logChangeSummary(\n changes: ConfigChanges,\n newSkills: SkillConfig[],\n oldSkills: SkillConfig[],\n removalReasons: ReadonlyMap<SkillId, string>,\n ): void {\n const {\n addedSkills,\n removedSkills,\n addedAgents,\n removedAgents,\n sourceChanges,\n scopeChanges,\n agentScopeChanges,\n dualScopeSkillTransitions,\n dualScopeAgentTransitions,\n } = changes;\n\n this.log(`\\n${chalk.hex(CLI_COLORS.WHITE).bold(\"Changes:\")}`);\n for (const skillId of addedSkills) {\n const scope = newSkills.find((s) => s.id === skillId)?.scope;\n const scopeLabel = scope ? ` ${formatScopeTag(scope)}` : \"\";\n this.log(\n chalk.hex(CLI_COLORS.SUCCESS)(` + ${getSkillById(skillId).displayName}${scopeLabel}`),\n );\n }\n for (const skillId of removedSkills) {\n const scope = oldSkills.find((s) => s.id === skillId)?.scope;\n const scopeLabel = scope ? ` ${formatScopeTag(scope)}` : \"\";\n const reason = removalReasons.get(skillId);\n this.log(\n chalk.hex(CLI_COLORS.ERROR)(` - ${getSkillDisplayName(skillId)}${scopeLabel}`) +\n (reason ? chalk.hex(CLI_COLORS.NEUTRAL)(` (${reason})`) : \"\"),\n );\n }\n for (const agentName of addedAgents) {\n this.log(\n chalk.hex(CLI_COLORS.SUCCESS)(` + ${agentName}`) +\n chalk.hex(CLI_COLORS.NEUTRAL)(\" (agent)\"),\n );\n }\n for (const agentName of removedAgents) {\n this.log(\n chalk.hex(CLI_COLORS.ERROR)(` - ${agentName}`) + chalk.hex(CLI_COLORS.NEUTRAL)(\" (agent)\"),\n );\n }\n for (const [skillId, change] of sourceChanges) {\n const displayName = getSkillDisplayName(skillId);\n const fromLabel = formatSourceDisplayName(change.from);\n const toLabel = formatSourceDisplayName(change.to);\n this.log(\n chalk.hex(CLI_COLORS.WARNING)(` ~ ${displayName}`) +\n chalk.hex(CLI_COLORS.NEUTRAL)(` (${fromLabel} \\u2192 ${toLabel})`),\n );\n }\n for (const [skillId, change] of scopeChanges) {\n this.log(formatSkillScopeChangeLine(skillId, change, dualScopeSkillTransitions));\n }\n for (const [agentName, change] of agentScopeChanges) {\n this.log(formatAgentScopeChangeLine(agentName, change, dualScopeAgentTransitions));\n }\n this.log(\"\");\n }\n\n private async applyMigrations(\n _changes: ConfigChanges,\n filteredResult: WizardResultV2,\n activeOldSkills: SkillConfig[],\n context: EditContext,\n cwd: string,\n ): Promise<Set<SkillId>> {\n const migrationPlan = detectMigrations(activeOldSkills, filteredResult.skills);\n const migratedSkillIds = new Set([\n ...migrationPlan.toEject.map((m) => m.id),\n ...migrationPlan.toPlugin.map((m) => m.id),\n ]);\n if (migratedSkillIds.size === 0) return migratedSkillIds;\n\n if (migrationPlan.toEject.length > 0) {\n this.logModeSwitch(migrationPlan.toEject.length, INSTALL_MODE_DESCRIPTIONS.eject);\n }\n if (migrationPlan.toPlugin.length > 0) {\n this.logModeSwitch(migrationPlan.toPlugin.length, INSTALL_MODE_DESCRIPTIONS.plugin);\n // Installing a plugin needs the marketplace REGISTERED and up to date with the\n // Claude CLI — the same precondition `applyPluginChanges` and `applyScopeChanges`\n // establish. Without it `claude plugin install` rejects every ref against a stale\n // local copy. Runs before `executeMigration` so an unresolvable marketplace exits\n // while the ejected working copies are still intact. Eject-side plugin uninstalls\n // are diagnostic-only, so only plugin-install work demands this.\n await this.requireMarketplaceOrExit(context.sourceResult, \"migrate skills to plugin mode\");\n // The install itself happens inside `executeMigration`, which deletes each skill's\n // working copy the moment that skill's plugin is registered — so the banner is\n // announced here and the outcome reported below, through the same surface `init`\n // and the newly-added-skill path narrate an install with.\n this.announcePluginInstall();\n }\n\n const migrationResult = await executeMigration(migrationPlan, cwd, context.sourceResult);\n\n for (const warning of migrationResult.warnings) {\n this.warn(warning);\n }\n\n // Reports what was installed and hard-errors on any failure: a migration whose\n // plugin could not be installed must not reach `recordGlobalSourceMigrations` or\n // `writeConfigAndCompile`, either of which would persist a marketplace `source`\n // for a skill with no plugin registration.\n if (migrationPlan.toPlugin.length > 0) {\n this.reportPluginInstalls(migrationResult.pluginInstalls);\n }\n\n return migratedSkillIds;\n }\n\n /** Names what this run is switching, in the words `init` describes an install mode with. */\n private logModeSwitch(count: number, modeDescription: string): void {\n this.log(chalk.hex(CLI_COLORS.NEUTRAL)(`Switching ${count} skill(s) to ${modeDescription}`));\n }\n\n private async applyScopeChanges(\n changes: ConfigChanges,\n filteredResult: WizardResultV2,\n context: EditContext,\n cwd: string,\n ): Promise<void> {\n const { scopeChanges } = changes;\n\n // Handle scope migrations (P->G or G->P) for eject-mode skills\n for (const [skillId, change] of scopeChanges) {\n const skillConfig = filteredResult.skills.find((s) => s.id === skillId);\n if (skillConfig?.source === EJECT_SOURCE) {\n await migrateLocalSkillScope(skillId, change.from, cwd);\n }\n }\n\n // Plugin scope migrations require a marketplace.\n // Compute eligible migrations first; only resolve/demand marketplace when there are any.\n const hasPluginScopeChanges = [...scopeChanges.keys()].some((skillId) => {\n const skillConfig = filteredResult.skills.find((s) => s.id === skillId);\n return skillConfig && skillConfig.source !== EJECT_SOURCE;\n });\n if (!hasPluginScopeChanges) return;\n\n const marketplace = await this.requireMarketplaceOrExit(\n context.sourceResult,\n \"migrate plugin skill scopes\",\n );\n\n const pluginScopeResult = await migratePluginSkillScopes(\n scopeChanges,\n filteredResult.skills,\n marketplace,\n cwd,\n );\n for (const item of pluginScopeResult.failed) {\n this.warn(`Failed to migrate plugin scope for ${item.id}: ${item.error}`);\n }\n }\n\n private async applySourceChanges(\n changes: ConfigChanges,\n activeOldSkills: SkillConfig[],\n cwd: string,\n migratedSkillIds: Set<SkillId>,\n ): Promise<void> {\n const { sourceChanges } = changes;\n\n // Handle remaining non-migration source changes (e.g., marketplace A -> marketplace B)\n for (const [skillId, change] of sourceChanges) {\n // Skip skills already handled by mode migration\n if (migratedSkillIds.has(skillId)) {\n continue;\n }\n if (change.from === EJECT_SOURCE) {\n const oldSkill = activeOldSkills.find((s) => s.id === skillId);\n const deleteDir = installBaseDir(cwd, oldSkill?.scope);\n await deleteLocalSkill(deleteDir, skillId);\n }\n }\n }\n\n private async applyPluginChanges(\n changes: ConfigChanges,\n filteredResult: WizardResultV2,\n activeOldSkills: SkillConfig[],\n context: EditContext,\n cwd: string,\n ): Promise<void> {\n const { addedSkills, removedSkills } = changes;\n\n // Compute plugin-intent lists per-skill (ungated) — per-skill `source` drives install mode.\n const addedPluginSkills = filteredResult.skills.filter(\n (s) => addedSkills.includes(s.id) && s.source !== EJECT_SOURCE,\n );\n const removedPluginSkills = removedSkills.filter(\n (id) => activeOldSkills.find((s) => s.id === id)?.source !== EJECT_SOURCE,\n );\n\n if (addedPluginSkills.length === 0 && removedPluginSkills.length === 0) return;\n\n const marketplace = await this.requireMarketplaceOrExit(\n context.sourceResult,\n \"install or uninstall plugin skills\",\n );\n\n if (addedPluginSkills.length > 0) {\n await this.installPluginSkillsReported(addedPluginSkills, marketplace, cwd);\n }\n\n if (removedPluginSkills.length > 0) {\n const uninstallResult = await uninstallPluginSkills(\n removedPluginSkills,\n activeOldSkills,\n marketplace,\n cwd,\n );\n if (uninstallResult.uninstalled.length > 0) {\n this.log(\n chalk.hex(CLI_COLORS.NEUTRAL)(`Removed ${uninstallResult.uninstalled.length} plugin(s)`),\n );\n }\n for (const item of uninstallResult.failed) {\n this.warn(`Failed to uninstall plugin ${item.id}: ${item.error}`);\n }\n }\n }\n\n private async copyNewLocalSkills(\n changes: ConfigChanges,\n filteredResult: WizardResultV2,\n context: EditContext,\n cwd: string,\n ): Promise<void> {\n const { addedSkills } = changes;\n\n // Copy newly added local-source skills to .claude/skills/ (split by scope)\n const addedLocalSkills = filteredResult.skills.filter(\n (s) => addedSkills.includes(s.id) && s.source === EJECT_SOURCE,\n );\n\n if (addedLocalSkills.length > 0) {\n const copyResult = await copyLocalSkills(addedLocalSkills, cwd, context.sourceResult);\n this.log(chalk.hex(CLI_COLORS.NEUTRAL)(`Copied ${copyResult.totalCopied} local skill(s)`));\n }\n }\n\n private async removeDeletedLocalSkills(\n changes: ConfigChanges,\n activeOldSkills: SkillConfig[],\n cwd: string,\n ): Promise<void> {\n const { removedSkills } = changes;\n\n // A fully-deselected eject-mode skill is a genuine uninstall — its copied directory under\n // .claude/skills/<id>/ must be removed from the scope it was installed at (D-233). Plugin\n // removals are handled by applyPluginChanges; source-change (eject->marketplace) deletions by\n // applySourceChanges. deleteLocalSkill is a no-op when the directory is absent.\n for (const skillId of removedSkills) {\n const oldSkill = activeOldSkills.find((s) => s.id === skillId);\n if (oldSkill?.source !== EJECT_SOURCE) continue;\n\n const deleteDir = installBaseDir(cwd, oldSkill.scope);\n await deleteLocalSkill(deleteDir, skillId);\n }\n }\n\n private async writeConfigAndCompile(\n result: WizardResultV2,\n context: EditContext,\n cwd: string,\n ): Promise<void> {\n // Load agent definitions — needed for both config-types.ts and recompilation\n let agentDefsResult: AgentDefs;\n try {\n agentDefsResult = await loadAgentDefs({});\n } catch (error) {\n this.handleError(error);\n }\n\n // Persist wizard result to config.ts and config-types.ts (split by scope when in project context)\n let configResult: ConfigWriteResult | undefined;\n try {\n configResult = await writeProjectConfig({\n wizardResult: result,\n sourceResult: context.sourceResult,\n projectDir: cwd,\n agents: agentDefsResult.agents,\n // A full `cc edit` pass is authoritative over the roster it owns, so deselected entries\n // are removed rather than union-preserved (D-233 Scenario C). Global-context edit owns\n // the entire config (\"all\"); a project edit owns only project-scoped entries and its own\n // tombstones (\"owned\"), never inherited global-active entries.\n authoritativeScope: isHomeDirectory(cwd) ? \"all\" : \"owned\",\n });\n } catch (error) {\n this.warn(`Could not update config: ${getErrorMessage(error)}`);\n }\n\n try {\n const agentScopeMap = activeAgentScopeMap(result.agentConfigs);\n const { allSkills } = await discoverInstalledSkills(cwd);\n const compilationResult = await compileAgentsAllScopes({\n projectDir: cwd,\n sourcePath: agentDefsResult.sourcePath,\n skills: allSkills,\n agentScopeMap,\n });\n\n const { compiled, rewritten, failed, warnings } = compilationResult;\n const summary = recompileSummary(\n rewritten.length,\n compiled.length - rewritten.length,\n RECOMPILE_SUBJECT,\n );\n\n if (failed.length > 0) {\n this.log(\n chalk.hex(CLI_COLORS.NEUTRAL)(summary) +\n chalk.hex(CLI_COLORS.WARNING)(` (${failed.length} failed)`),\n );\n for (const warning of warnings) {\n this.warn(warning);\n }\n } else if (compiled.length > 0) {\n this.log(chalk.hex(CLI_COLORS.NEUTRAL)(summary));\n } else {\n this.log(chalk.hex(CLI_COLORS.NEUTRAL)(INFO_MESSAGES.NO_AGENTS_TO_RECOMPILE));\n }\n } catch (error) {\n this.warn(`Agent recompilation failed: ${getErrorMessage(error)}`);\n this.log(`You can manually recompile with '${CLI_INVOKE_COMMAND} compile'.`);\n }\n\n if (configResult) {\n this.reportPropagatedRecompile(configResult.propagation);\n }\n }\n\n private async cleanupStaleAgentFiles(\n changes: ConfigChanges,\n oldAgents: AgentScopeConfig[],\n cwd: string,\n ): Promise<void> {\n const { agentScopeChanges, removedAgents } = changes;\n\n // Clean up old agent .md files after scope changes.\n // Recompilation wrote the new file to the correct scope directory;\n // now delete the stale copy from the old scope directory.\n // Only clean up for P→G direction. G→P is an override — the global\n // installation stays untouched; the project copy overrides it.\n for (const [agentName, change] of agentScopeChanges) {\n if (change.from === \"global\") continue;\n\n const oldAgentPath = path.join(\n resolveInstallPaths(cwd, \"project\").agentsDir,\n `${agentName}.md`,\n );\n try {\n await remove(oldAgentPath);\n } catch (error) {\n this.warn(`Could not remove old agent file ${oldAgentPath}: ${getErrorMessage(error)}`);\n }\n }\n\n // Deselected agents are a genuine uninstall — recompilation never rewrites their .md, so\n // delete the compiled file from the scope it was installed at (D-233). remove() is a no-op\n // when the file is absent.\n for (const agentName of removedAgents) {\n const oldScope = oldAgents.find((a) => a.name === agentName)?.scope ?? \"project\";\n const agentPath = path.join(resolveInstallPaths(cwd, oldScope).agentsDir, `${agentName}.md`);\n try {\n await remove(agentPath);\n } catch (error) {\n this.warn(`Could not remove agent file ${agentPath}: ${getErrorMessage(error)}`);\n }\n }\n }\n\n private logCompletionSummary(_changes: ConfigChanges): void {\n this.log(`\\n${chalk.hex(CLI_COLORS.SUCCESS)(\"\\u2713 Done\")}\\n`);\n }\n}\n\n/** @internal Exported for testing */\nexport type ConfigChanges = {\n addedSkills: SkillId[];\n removedSkills: SkillId[];\n addedAgents: AgentName[];\n removedAgents: AgentName[];\n sourceChanges: Map<SkillId, { from: string; to: string }>;\n scopeChanges: Map<SkillId, ScopeChange>;\n agentScopeChanges: Map<AgentName, ScopeChange>;\n /**\n * Skill ids whose `scopeChanges` entry is a dual-scope add/remove — the project\n * half of a `[P][G]` pair was toggled while the global half persists — NOT a true\n * single-entry migration. The disk-side scope work still flows through\n * `scopeChanges`; this set only steers the completion-summary display so a\n * dual-scope addition is not misreported as a `[G] → [P]` migration.\n */\n dualScopeSkillTransitions: Set<SkillId>;\n /** Agent equivalent of `dualScopeSkillTransitions`. */\n dualScopeAgentTransitions: Set<AgentName>;\n};\n\n/** Full (tombstone-inclusive) entry lists used to classify dual-scope transitions. */\ntype FullScopeEntries = {\n newSkills: SkillConfig[];\n oldSkills: SkillConfig[];\n newAgents: AgentScopeConfig[];\n oldAgents: AgentScopeConfig[];\n};\n\n/**\n * @internal Exported for testing\n *\n * `oldConfig` / `wizardResult` carry the ACTIVE (tombstone-filtered) entries used\n * for add/remove/source/scope diffing. `fullEntries`, when provided, carries the\n * unfiltered lists (including excluded tombstones) used ONLY to tell a genuine\n * scope migration apart from a dual-scope add/remove. When omitted, every scope\n * change is treated as a migration (the pre-dual-scope behaviour).\n */\nexport function detectConfigChanges(\n oldConfig: ProjectConfig | null,\n wizardResult: WizardResultV2,\n fullEntries?: FullScopeEntries,\n): ConfigChanges {\n const oldSkillIds = oldConfig?.skills.map((s) => s.id) ?? [];\n const newSkillIds = wizardResult.skills.map((s) => s.id);\n const oldAgentNames = oldConfig?.agents.map((a) => a.name) ?? [];\n const newAgentNames = wizardResult.agentConfigs.map((a) => a.name);\n\n const oldSkillsById = indexBy(oldConfig?.skills ?? [], (s) => s.id);\n const oldAgentsByName = indexBy(oldConfig?.agents ?? [], (a) => a.name);\n\n const scopeChanges = detectPropertyChanges(\n wizardResult.skills,\n oldSkillsById,\n (s) => s.id,\n (s) => s.scope,\n );\n const agentScopeChanges = detectPropertyChanges(\n wizardResult.agentConfigs,\n oldAgentsByName,\n (a) => a.name,\n (a) => a.scope,\n );\n\n return {\n addedSkills: difference(newSkillIds, oldSkillIds),\n removedSkills: difference(oldSkillIds, newSkillIds),\n addedAgents: difference(newAgentNames, oldAgentNames),\n removedAgents: difference(oldAgentNames, newAgentNames),\n sourceChanges: detectPropertyChanges(\n wizardResult.skills,\n oldSkillsById,\n (s) => s.id,\n (s) => s.source,\n ),\n scopeChanges,\n agentScopeChanges,\n dualScopeSkillTransitions: detectDualScopeTransitions(\n scopeChanges,\n fullEntries?.newSkills ?? [],\n fullEntries?.oldSkills ?? [],\n (s) => s.id,\n ),\n dualScopeAgentTransitions: detectDualScopeTransitions(\n agentScopeChanges,\n fullEntries?.newAgents ?? [],\n fullEntries?.oldAgents ?? [],\n (a) => a.name,\n ),\n };\n}\n\nfunction detectPropertyChanges<T, K extends string, V>(\n newItems: T[],\n oldByKey: Record<string, T>,\n getKey: (item: T) => K,\n getValue: (item: T) => V,\n): Map<K, { from: V; to: V }> {\n const changes = new Map<K, { from: V; to: V }>();\n for (const item of newItems) {\n const key = getKey(item);\n const old = oldByKey[key];\n if (old && getValue(old) !== getValue(item)) {\n changes.set(key, { from: getValue(old), to: getValue(item) });\n }\n }\n return changes;\n}\n\n/**\n * A scope change is a dual-scope transition (not a migration) when the canonical\n * dual-scope tombstone — an excluded global entry — sits alongside it:\n * - G→P add: the NEW state keeps a global tombstone, so the global install\n * survives and the project half was merely added.\n * - P→G remove: the OLD state held a global tombstone, so the pair was already\n * dual-scope and the project half was merely removed.\n * Either way the item occupied both scopes, so `[X] → [Y]` would misdescribe it.\n */\nfunction detectDualScopeTransitions<\n K extends string,\n T extends { scope: SkillScope; excluded?: boolean },\n>(scopeChanges: Map<K, ScopeChange>, fullNew: T[], fullOld: T[], getKey: (item: T) => K): Set<K> {\n const hasGlobalTombstone = (items: T[], key: K): boolean =>\n items.some((item) => getKey(item) === key && item.scope === \"global\" && item.excluded === true);\n\n const result = new Set<K>();\n for (const [key, change] of scopeChanges) {\n if (change.from === \"global\" && change.to === \"project\" && hasGlobalTombstone(fullNew, key)) {\n result.add(key);\n } else if (\n change.from === \"project\" &&\n change.to === \"global\" &&\n hasGlobalTombstone(fullOld, key)\n ) {\n result.add(key);\n }\n }\n return result;\n}\n\nfunction hasAnyChanges(changes: ConfigChanges): boolean {\n return (\n changes.addedSkills.length > 0 ||\n changes.removedSkills.length > 0 ||\n changes.addedAgents.length > 0 ||\n changes.removedAgents.length > 0 ||\n changes.sourceChanges.size > 0 ||\n changes.scopeChanges.size > 0 ||\n changes.agentScopeChanges.size > 0\n );\n}\n\n/** @internal Exported for testing */\nexport type PluginScopeMigrationResult = {\n migrated: SkillId[];\n failed: Array<{ id: SkillId; error: string }>;\n};\n\n/** @internal Exported for testing */\nexport async function migratePluginSkillScopes(\n scopeChanges: Map<SkillId, ScopeChange>,\n skills: Pick<SkillConfig, \"id\" | \"source\">[],\n marketplace: string,\n projectDir: string,\n): Promise<PluginScopeMigrationResult> {\n const migrated: SkillId[] = [];\n const failed: PluginScopeMigrationResult[\"failed\"] = [];\n\n for (const [skillId, change] of scopeChanges) {\n const skillConfig = skills.find((s) => s.id === skillId);\n if (!skillConfig || skillConfig.source === EJECT_SOURCE) {\n continue;\n }\n\n const newPluginScope = toClaudePluginScope(change.to);\n const pluginRef = buildMarketplacePluginRef(skillId, marketplace);\n\n try {\n // global→project: keep the global registration, just add project scope.\n // The global plugin must remain for other projects.\n // project→global: uninstall the project-scope registration, install global.\n if (change.from === \"project\") {\n await claudePluginUninstall(pluginRef, \"project\", projectDir);\n }\n await claudePluginInstall(pluginRef, newPluginScope, projectDir);\n migrated.push(skillId);\n } catch (error) {\n failed.push({ id: skillId, error: getErrorMessage(error) });\n }\n }\n\n return { migrated, failed };\n}\n"],"mappings":"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","names":[]}
@@ -1,16 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  loadSource
4
- } from "../chunk-STMHDOZD.js";
5
- import "../chunk-SBHBBZKF.js";
6
- import "../chunk-IHUY4M22.js";
7
- import "../chunk-QZZJFYUQ.js";
8
- import "../chunk-E5X6RJ4E.js";
4
+ } from "../chunk-F7Z5I6GU.js";
5
+ import "../chunk-REKOWTIB.js";
6
+ import "../chunk-NXGMM5YN.js";
7
+ import "../chunk-FRWKCE6R.js";
8
+ import "../chunk-FIHTAFST.js";
9
9
  import {
10
10
  BaseCommand,
11
11
  EXIT_CODES
12
- } from "../chunk-KR65TPKC.js";
13
- import "../chunk-ZL7PFNHN.js";
12
+ } from "../chunk-X5XJ6WKO.js";
13
+ import "../chunk-TY6CAOL7.js";
14
+ import "../chunk-K3O3YQYG.js";
14
15
  import {
15
16
  copySkillsToLocalFlattened,
16
17
  ensureBlankPair,
@@ -21,17 +22,17 @@ import {
21
22
  mutateGlobal,
22
23
  resolveSource,
23
24
  writeProjectPartial
24
- } from "../chunk-EEPELKOM.js";
25
+ } from "../chunk-NXQAY5U7.js";
25
26
  import {
26
27
  copy,
27
28
  directoryExists,
28
29
  ensureDir,
29
30
  fileExists,
30
31
  listDirectories
31
- } from "../chunk-PMM2MYMA.js";
32
+ } from "../chunk-U2YSGBHA.js";
32
33
  import {
33
34
  matrix
34
- } from "../chunk-WKTHWQKM.js";
35
+ } from "../chunk-35VOK7XE.js";
35
36
  import {
36
37
  typedKeys
37
38
  } from "../chunk-VASLW636.js";
@@ -42,8 +43,8 @@ import {
42
43
  LOCAL_SKILLS_PATH,
43
44
  PROJECT_ROOT,
44
45
  STANDARD_FILES
45
- } from "../chunk-76ADG7LQ.js";
46
- import "../chunk-UBEDZ4FD.js";
46
+ } from "../chunk-R54KIGN2.js";
47
+ import "../chunk-VZRO7RYT.js";
47
48
 
48
49
  // src/cli/commands/eject.ts
49
50
  import { Args, Flags } from "@oclif/core";
@@ -55,7 +56,7 @@ function isEjectType(value) {
55
56
  }
56
57
  var Eject = class _Eject extends BaseCommand {
57
58
  static summary = "Eject skills, agent partials, or templates for local customization";
58
- static description = "Copy agent partials, templates, or skills to your project for customization. Agent partials and templates are always copied from the CLI. Skills are copied from the configured source (public marketplace by default).";
59
+ static description = "Copy agent partials, templates, or skills to your project for customization. Agent partials and templates are always copied from the CLI. Skills are copied from the source this installation is configured to read (the public marketplace by default).";
59
60
  static examples = [
60
61
  {
61
62
  description: "Eject agent partials for customization",
@@ -86,7 +87,6 @@ var Eject = class _Eject extends BaseCommand {
86
87
  })
87
88
  };
88
89
  static flags = {
89
- ...BaseCommand.baseFlags,
90
90
  force: Flags.boolean({
91
91
  char: "f",
92
92
  description: "Overwrite existing files",
@@ -95,10 +95,6 @@ var Eject = class _Eject extends BaseCommand {
95
95
  output: Flags.string({
96
96
  char: "o",
97
97
  description: "Output directory (default: .claude/ in current directory)"
98
- }),
99
- refresh: Flags.boolean({
100
- description: "Force refresh from remote source",
101
- default: false
102
98
  })
103
99
  };
104
100
  async run() {
@@ -107,10 +103,9 @@ var Eject = class _Eject extends BaseCommand {
107
103
  const ejectType = this.validateEjectType(args.type);
108
104
  const outputBase = await this.resolveOutputBase(flags, projectDir);
109
105
  this.printHeader(flags.output ? outputBase : void 0);
110
- const sourceResult = await this.loadSourceIfNeeded(ejectType, flags, projectDir);
106
+ const sourceResult = await this.loadSourceIfNeeded(ejectType, projectDir);
111
107
  await this.executeEject(ejectType, outputBase, flags, projectDir, sourceResult);
112
- await this.saveSourceIfFlagged(flags.source, projectDir);
113
- await this.ensureConfig(projectDir, flags.source, sourceResult);
108
+ await this.ensureConfig(projectDir, sourceResult);
114
109
  this.log("");
115
110
  this.logSuccess("Eject complete!");
116
111
  this.log("");
@@ -149,13 +144,9 @@ var Eject = class _Eject extends BaseCommand {
149
144
  this.log(`Output directory: ${outputBase}`);
150
145
  }
151
146
  }
152
- async loadSourceIfNeeded(ejectType, flags, projectDir) {
147
+ async loadSourceIfNeeded(ejectType, projectDir) {
153
148
  if (ejectType === "skills" || ejectType === "all") {
154
- const loaded = await loadSource({
155
- sourceFlag: flags.source,
156
- projectDir,
157
- forceRefresh: flags.refresh
158
- });
149
+ const loaded = await loadSource({ projectDir });
159
150
  return loaded.sourceResult;
160
151
  }
161
152
  return void 0;
@@ -189,16 +180,10 @@ var Eject = class _Eject extends BaseCommand {
189
180
  }
190
181
  }
191
182
  }
192
- async saveSourceIfFlagged(sourceFlag, projectDir) {
193
- if (!sourceFlag) return;
194
- await recordSource(projectDir, sourceFlag);
195
- this.log(`Source saved to ${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS}`);
196
- }
197
- async ensureConfig(projectDir, sourceFlag, sourceResult) {
183
+ async ensureConfig(projectDir, sourceResult) {
198
184
  const configResult = await ensureMinimalConfig({
199
185
  projectDir,
200
- sourceFlag,
201
- sourceResult
186
+ ...sourceResult !== void 0 && { sourceResult }
202
187
  });
203
188
  if (configResult.created) {
204
189
  this.logSuccess(`Created ${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS}`);
@@ -234,7 +219,7 @@ var Eject = class _Eject extends BaseCommand {
234
219
  sourceResult,
235
220
  matrix,
236
221
  directOutput,
237
- customOutputBase: directOutput ? outputBase : void 0
222
+ ...directOutput && { customOutputBase: outputBase }
238
223
  });
239
224
  if (result.skipped) {
240
225
  this.warn(result.skipReason);
@@ -335,14 +320,14 @@ async function ejectSkills(options) {
335
320
  };
336
321
  }
337
322
  async function ensureMinimalConfig(options) {
338
- const { projectDir, sourceFlag, sourceResult } = options;
323
+ const { projectDir, sourceResult } = options;
339
324
  const tsConfigPath = getProjectConfigPath(projectDir);
340
325
  if (await fileExists(tsConfigPath)) {
341
326
  return { configPath: tsConfigPath, created: false };
342
327
  }
343
- const resolvedConfig = sourceResult?.sourceConfig ?? await resolveSource(sourceFlag, projectDir);
328
+ const resolvedConfig = sourceResult?.sourceConfig ?? await resolveSource({ caller: "stored", projectDir });
344
329
  const existingProjectConfig = await loadProjectSourceConfig(projectDir);
345
- const source = sourceFlag || resolvedConfig.source || void 0;
330
+ const source = resolvedConfig.source || void 0;
346
331
  if (isHomeDirectory(projectDir)) {
347
332
  await ensureBlankPair();
348
333
  if (source) await recordSource(projectDir, source);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/eject.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport os from \"os\";\nimport { BaseCommand, type SourceRefreshFlags } from \"../base-command.js\";\nimport { copy, ensureDir, directoryExists, fileExists, listDirectories } from \"../utils/fs.js\";\nimport {\n CLAUDE_SRC_DIR,\n DEFAULT_BRANDING,\n DIRS,\n LOCAL_SKILLS_PATH,\n PROJECT_ROOT,\n STANDARD_FILES,\n} from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { loadSource } from \"../lib/operations/index.js\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport {\n resolveSource,\n loadProjectSourceConfig,\n getProjectConfigPath,\n} from \"../lib/configuration/index.js\";\nimport {\n ensureBlankPair,\n lazyGateDeps,\n mutateGlobal,\n writeProjectPartial,\n} from \"../lib/config-gate/index.js\";\nimport { isHomeDirectory } from \"../lib/installation/index.js\";\nimport { copySkillsToLocalFlattened, type CopiedSkill } from \"../lib/skills/index.js\";\nimport type { MergedSkillsMatrix, SkillId } from \"../types/index.js\";\nimport { typedKeys } from \"../utils/typed-object.js\";\n\nconst EJECT_TYPES = [\"agent-partials\", \"templates\", \"skills\", \"all\"] as const;\ntype EjectType = (typeof EJECT_TYPES)[number];\n\nfunction isEjectType(value: string): value is EjectType {\n return (EJECT_TYPES as readonly string[]).includes(value);\n}\n\nexport default class Eject extends BaseCommand {\n static summary = \"Eject skills, agent partials, or templates for local customization\";\n static description =\n \"Copy agent partials, templates, or skills to your project for customization. \" +\n \"Agent partials and templates are always copied from the CLI. \" +\n \"Skills are copied from the configured source (public marketplace by default).\";\n\n static examples = [\n {\n description: \"Eject agent partials for customization\",\n command: \"<%= config.bin %> <%= command.id %> agent-partials\",\n },\n {\n description: \"Eject only agent templates\",\n command: \"<%= config.bin %> <%= command.id %> templates\",\n },\n {\n description: \"Eject skills to local directory\",\n command: \"<%= config.bin %> <%= command.id %> skills\",\n },\n {\n description: \"Eject everything with force overwrite\",\n command: \"<%= config.bin %> <%= command.id %> all --force\",\n },\n {\n description: \"Eject to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> skills -o ./custom-dir\",\n },\n ];\n\n static args = {\n type: Args.string({\n description: \"What to eject: agent-partials, templates, skills, all\",\n required: false,\n options: [...EJECT_TYPES],\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing files\",\n default: false,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output directory (default: .claude/ in current directory)\",\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote source\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Eject);\n const projectDir = process.cwd();\n\n const ejectType = this.validateEjectType(args.type);\n const outputBase = await this.resolveOutputBase(flags, projectDir);\n\n this.printHeader(flags.output ? outputBase : undefined);\n\n const sourceResult = await this.loadSourceIfNeeded(ejectType, flags, projectDir);\n await this.executeEject(ejectType, outputBase, flags, projectDir, sourceResult);\n await this.saveSourceIfFlagged(flags.source, projectDir);\n await this.ensureConfig(projectDir, flags.source, sourceResult);\n\n this.log(\"\");\n this.logSuccess(\"Eject complete!\");\n this.log(\"\");\n }\n\n private validateEjectType(typeArg: string | undefined): EjectType {\n if (!typeArg) {\n this.error(\"Please specify what to eject: agent-partials, templates, skills, or all\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!isEjectType(typeArg)) {\n this.error(`Unknown eject type: ${typeArg}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n return typeArg;\n }\n\n private async resolveOutputBase(flags: { output?: string }, projectDir: string): Promise<string> {\n if (flags.output) {\n const expandedPath = flags.output.startsWith(\"~\")\n ? path.join(os.homedir(), flags.output.slice(1))\n : flags.output;\n const outputBase = path.resolve(projectDir, expandedPath);\n\n if (await fileExists(outputBase)) {\n this.error(`Output path exists as a file: ${outputBase}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n return outputBase;\n }\n\n return path.join(projectDir, CLAUDE_SRC_DIR);\n }\n\n private printHeader(outputBase?: string): void {\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Eject`);\n this.log(\"\");\n\n if (outputBase) {\n this.log(`Output directory: ${outputBase}`);\n }\n }\n\n private async loadSourceIfNeeded(\n ejectType: EjectType,\n flags: SourceRefreshFlags,\n projectDir: string,\n ): Promise<SourceLoadResult | undefined> {\n if (ejectType === \"skills\" || ejectType === \"all\") {\n const loaded = await loadSource({\n sourceFlag: flags.source,\n projectDir,\n forceRefresh: flags.refresh,\n });\n return loaded.sourceResult;\n }\n return undefined;\n }\n\n private async executeEject(\n ejectType: EjectType,\n outputBase: string,\n flags: { force: boolean; output?: string },\n projectDir: string,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n const directOutput = !!flags.output;\n\n switch (ejectType) {\n case \"agent-partials\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n break;\n case \"templates\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, true);\n break;\n case \"skills\":\n if (!sourceResult) {\n throw new Error(\"Source must be loaded for skills eject\");\n }\n await this.handleSkills(projectDir, flags.force, sourceResult, directOutput, outputBase);\n break;\n case \"all\":\n if (!sourceResult) {\n throw new Error(\"Source must be loaded for full eject\");\n }\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n await this.handleAgentPartials(outputBase, true, directOutput, true);\n await this.handleSkills(projectDir, flags.force, sourceResult, directOutput, outputBase);\n break;\n default: {\n const _exhaustive: never = ejectType;\n return _exhaustive;\n }\n }\n }\n\n private async saveSourceIfFlagged(\n sourceFlag: string | undefined,\n projectDir: string,\n ): Promise<void> {\n if (!sourceFlag) return;\n\n await recordSource(projectDir, sourceFlag);\n this.log(`Source saved to ${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS}`);\n }\n\n private async ensureConfig(\n projectDir: string,\n sourceFlag: string | undefined,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n const configResult = await ensureMinimalConfig({\n projectDir,\n sourceFlag,\n sourceResult,\n });\n if (configResult.created) {\n this.logSuccess(`Created ${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS}`);\n }\n }\n\n private async handleAgentPartials(\n outputBase: string,\n force: boolean,\n directOutput: boolean,\n templatesOnly: boolean,\n ): Promise<void> {\n const result = await ejectAgentPartials({\n outputBase,\n force,\n directOutput,\n templatesOnly,\n });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n if (result.templatesSkipped) {\n this.warn(\n \"Agent templates already exist — skipping templates, only ejecting agent partials.\",\n );\n }\n\n this.logSuccess(\n `${templatesOnly ? \"Agent templates\" : \"Agent partials\"} ejected to ${result.destDir}`,\n );\n this.log(\n templatesOnly\n ? \"You can now customize agent templates locally.\"\n : \"You can now customize templates, agent intro, workflow, and examples locally.\",\n );\n }\n\n private async handleSkills(\n projectDir: string,\n force: boolean,\n sourceResult: SourceLoadResult,\n directOutput: boolean,\n outputBase: string,\n ): Promise<void> {\n const result = await ejectSkills({\n projectDir,\n force,\n sourceResult,\n matrix,\n directOutput,\n customOutputBase: directOutput ? outputBase : undefined,\n });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n this.logSuccess(\n `${result.copiedSkills.length} skills ejected to ${result.destDir} from ${result.sourceLabel}`,\n );\n this.log(\"You can now customize skill content locally.\");\n }\n}\n\ntype EjectAgentPartialsOptions = {\n outputBase: string;\n force: boolean;\n /** When true, outputBase is used directly as the destination (no subdirectory nesting). */\n directOutput?: boolean;\n /** When true, ejects only the _templates directory instead of the full agents directory. */\n templatesOnly?: boolean;\n};\n\ntype EjectAgentPartialsResult =\n | {\n skipped: true;\n skipReason: string;\n templatesSkipped: false;\n }\n | {\n skipped: false;\n /** Destination directory that was written to. */\n destDir: string;\n /** Whether templates were skipped during a full agent-partials eject (existing templates preserved). */\n templatesSkipped: boolean;\n };\n\n/**\n * Copies agent partials or templates from the CLI source to a target directory.\n *\n * When `templatesOnly` is true, copies only the _templates subdirectory.\n * When false, copies the full agents directory (optionally skipping existing templates).\n *\n * Returns structured data — the command decides what to log.\n */\n/** Direct output writes to the base itself; otherwise agents/ (plus templates/ in templates-only mode). */\nfunction resolveEjectDestDir(\n outputBase: string,\n directOutput: boolean,\n templatesOnly: boolean,\n): string {\n if (directOutput) return outputBase;\n const agentsDir = path.join(outputBase, path.basename(DIRS.agents));\n return templatesOnly ? path.join(agentsDir, path.basename(DIRS.templates)) : agentsDir;\n}\n\nasync function ejectAgentPartials(\n options: EjectAgentPartialsOptions,\n): Promise<EjectAgentPartialsResult> {\n const { outputBase, force, directOutput = false, templatesOnly = false } = options;\n\n const sourceDir = templatesOnly\n ? path.join(PROJECT_ROOT, DIRS.templates)\n : path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(sourceDir))) {\n return {\n skipped: true,\n skipReason: templatesOnly\n ? \"No agent templates found in CLI.\"\n : \"No agent partials found in CLI.\",\n templatesSkipped: false,\n };\n }\n\n const destDir = resolveEjectDestDir(outputBase, directOutput, templatesOnly);\n\n const templatesBasename = path.basename(DIRS.templates);\n\n if ((await directoryExists(destDir)) && !force) {\n if (templatesOnly) {\n return {\n skipped: true,\n skipReason: `Agent templates already exist at ${destDir}. Use --force to overwrite.`,\n templatesSkipped: false,\n };\n }\n\n const hasTemplates = await directoryExists(path.join(destDir, templatesBasename));\n if ((await hasAgentPartialDirs(destDir)) && !hasTemplates) {\n return {\n skipped: true,\n skipReason: `Agent partials already exist at ${destDir}. Use --force to overwrite.`,\n templatesSkipped: false,\n };\n }\n }\n\n await ensureDir(destDir);\n\n const skipTemplates =\n !templatesOnly && !force && (await directoryExists(path.join(destDir, templatesBasename)));\n\n if (skipTemplates) {\n const sourceEntries = await listDirectories(sourceDir);\n const nonTemplateEntries = sourceEntries.filter((entry) => entry !== templatesBasename);\n for (const entry of nonTemplateEntries) {\n await copy(path.join(sourceDir, entry), path.join(destDir, entry));\n }\n } else {\n await copy(sourceDir, destDir);\n }\n\n return {\n skipped: false,\n destDir,\n templatesSkipped: skipTemplates,\n };\n}\n\ntype EjectSkillsOptions = {\n projectDir: string;\n force: boolean;\n sourceResult: SourceLoadResult;\n matrix: MergedSkillsMatrix;\n /** When true, uses customOutputBase as destination instead of LOCAL_SKILLS_PATH. */\n directOutput?: boolean;\n customOutputBase?: string;\n};\n\ntype EjectSkillsResult =\n | {\n skipped: true;\n skipReason: string;\n copiedSkills: [];\n }\n | {\n skipped: false;\n /** Array of skills that were copied. */\n copiedSkills: CopiedSkill[];\n /** Destination directory that was written to. */\n destDir: string;\n /** Label describing the source that skills were copied from. */\n sourceLabel: string;\n };\n\n/**\n * Copies non-local skills from source to a target directory.\n *\n * Filters out skills already marked as local, then copies the remaining skills\n * using copySkillsToLocalFlattened.\n *\n * Returns structured data — the command decides what to log.\n */\nasync function ejectSkills(options: EjectSkillsOptions): Promise<EjectSkillsResult> {\n const {\n projectDir,\n force,\n sourceResult,\n matrix,\n directOutput = false,\n customOutputBase,\n } = options;\n\n const destDir =\n directOutput && customOutputBase ? customOutputBase : path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if ((await directoryExists(destDir)) && !force) {\n return {\n skipped: true,\n skipReason: `Skills already exist at ${destDir}. Use --force to overwrite.`,\n copiedSkills: [],\n };\n }\n\n const skillIds = typedKeys<SkillId>(matrix.skills).filter(\n (skillId) => !matrix.skills[skillId]?.local,\n );\n\n if (skillIds.length === 0) {\n return {\n skipped: true,\n skipReason: \"No skills found in source to eject.\",\n copiedSkills: [],\n };\n }\n\n await ensureDir(destDir);\n\n const copiedSkills = await copySkillsToLocalFlattened(skillIds, destDir, sourceResult);\n\n const sourceLabel = sourceResult.isLocal\n ? sourceResult.sourcePath\n : sourceResult.marketplace || sourceResult.sourceConfig.source;\n\n return {\n skipped: false,\n copiedSkills,\n destDir,\n sourceLabel,\n };\n}\n\ntype EnsureMinimalConfigOptions = {\n projectDir: string;\n sourceFlag?: string;\n sourceResult?: SourceLoadResult;\n};\n\ntype EnsureMinimalConfigResult = {\n /** Path to the config file. */\n configPath: string;\n /** Whether a new config was created. */\n created: boolean;\n};\n\n/**\n * Ensures a minimal config.ts exists so `npx agents-inc compile` works after eject.\n *\n * If the config already exists, returns immediately with `created: false`.\n * Otherwise generates a minimal config from the resolved source and project metadata.\n *\n * Returns structured data — the command decides what to log.\n */\nasync function ensureMinimalConfig(\n options: EnsureMinimalConfigOptions,\n): Promise<EnsureMinimalConfigResult> {\n const { projectDir, sourceFlag, sourceResult } = options;\n\n const tsConfigPath = getProjectConfigPath(projectDir);\n\n if (await fileExists(tsConfigPath)) {\n return { configPath: tsConfigPath, created: false };\n }\n\n const resolvedConfig =\n sourceResult?.sourceConfig ?? (await resolveSource(sourceFlag, projectDir));\n const existingProjectConfig = await loadProjectSourceConfig(projectDir);\n const source = sourceFlag || resolvedConfig.source || undefined;\n\n // At the home directory the invented config IS the global manifest, and the\n // file it opens with `import type { ProjectConfig } from \"./config-types\"`\n // cannot resolve its own types without the sibling. The gate writes the pair.\n if (isHomeDirectory(projectDir)) {\n await ensureBlankPair();\n if (source) await recordSource(projectDir, source);\n return { configPath: tsConfigPath, created: true };\n }\n\n await writeProjectPartial(\n projectDir,\n {\n skills: [],\n agents: [],\n ...(source ? { source } : {}),\n ...(resolvedConfig.marketplace ? { marketplace: resolvedConfig.marketplace } : {}),\n ...(existingProjectConfig?.author ? { author: existingProjectConfig.author } : {}),\n ...(existingProjectConfig?.agentsSource\n ? { agentsSource: existingProjectConfig.agentsSource }\n : {}),\n },\n { fallbackName: path.basename(projectDir) },\n );\n\n return { configPath: tsConfigPath, created: true };\n}\n\n/**\n * Records `source` in whichever scope's config `projectDir` names. At the home\n * directory that config is the global manifest every project's generated types\n * import from, so the write goes through the gate: registered projects inline\n * the scalar and follow it.\n */\nasync function recordSource(projectDir: string, source: string): Promise<void> {\n if (isHomeDirectory(projectDir)) {\n await mutateGlobal(\n { kind: \"set-source\", source, fallbackName: path.basename(projectDir) },\n lazyGateDeps(projectDir),\n );\n return;\n }\n\n const existing = (await loadProjectSourceConfig(projectDir)) ?? {};\n await writeProjectPartial(\n projectDir,\n { ...existing, source },\n { fallbackName: path.basename(projectDir) },\n );\n}\n\n/** Checks whether the agents directory contains any agent subdirectories (not just _templates). */\nasync function hasAgentPartialDirs(agentsDir: string): Promise<boolean> {\n const subdirs = await listDirectories(agentsDir);\n const templatesBasename = path.basename(DIRS.templates);\n return subdirs.some((dir) => dir !== templatesBasename);\n}\n"],"mappings":"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","names":["matrix"]}
1
+ {"version":3,"sources":["../../src/cli/commands/eject.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport os from \"os\";\nimport { BaseCommand } from \"../base-command.js\";\nimport { copy, ensureDir, directoryExists, fileExists, listDirectories } from \"../utils/fs.js\";\nimport {\n CLAUDE_SRC_DIR,\n DEFAULT_BRANDING,\n DIRS,\n LOCAL_SKILLS_PATH,\n PROJECT_ROOT,\n STANDARD_FILES,\n} from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { loadSource } from \"../lib/operations/index.js\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport {\n resolveSource,\n loadProjectSourceConfig,\n getProjectConfigPath,\n} from \"../lib/configuration/index.js\";\nimport {\n ensureBlankPair,\n lazyGateDeps,\n mutateGlobal,\n writeProjectPartial,\n} from \"../lib/config-gate/index.js\";\nimport { isHomeDirectory } from \"../lib/installation/index.js\";\nimport { copySkillsToLocalFlattened, type CopiedSkill } from \"../lib/skills/index.js\";\nimport type { MergedSkillsMatrix, SkillId } from \"../types/index.js\";\nimport { typedKeys } from \"../utils/typed-object.js\";\n\nconst EJECT_TYPES = [\"agent-partials\", \"templates\", \"skills\", \"all\"] as const;\ntype EjectType = (typeof EJECT_TYPES)[number];\n\nfunction isEjectType(value: string): value is EjectType {\n return (EJECT_TYPES as readonly string[]).includes(value);\n}\n\nexport default class Eject extends BaseCommand {\n static summary = \"Eject skills, agent partials, or templates for local customization\";\n static description =\n \"Copy agent partials, templates, or skills to your project for customization. \" +\n \"Agent partials and templates are always copied from the CLI. \" +\n \"Skills are copied from the source this installation is configured to read \" +\n \"(the public marketplace by default).\";\n\n static examples = [\n {\n description: \"Eject agent partials for customization\",\n command: \"<%= config.bin %> <%= command.id %> agent-partials\",\n },\n {\n description: \"Eject only agent templates\",\n command: \"<%= config.bin %> <%= command.id %> templates\",\n },\n {\n description: \"Eject skills to local directory\",\n command: \"<%= config.bin %> <%= command.id %> skills\",\n },\n {\n description: \"Eject everything with force overwrite\",\n command: \"<%= config.bin %> <%= command.id %> all --force\",\n },\n {\n description: \"Eject to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> skills -o ./custom-dir\",\n },\n ];\n\n static args = {\n type: Args.string({\n description: \"What to eject: agent-partials, templates, skills, all\",\n required: false,\n options: [...EJECT_TYPES],\n }),\n };\n\n static flags = {\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing files\",\n default: false,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output directory (default: .claude/ in current directory)\",\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Eject);\n const projectDir = process.cwd();\n\n const ejectType = this.validateEjectType(args.type);\n const outputBase = await this.resolveOutputBase(flags, projectDir);\n\n this.printHeader(flags.output ? outputBase : undefined);\n\n const sourceResult = await this.loadSourceIfNeeded(ejectType, projectDir);\n await this.executeEject(ejectType, outputBase, flags, projectDir, sourceResult);\n await this.ensureConfig(projectDir, sourceResult);\n\n this.log(\"\");\n this.logSuccess(\"Eject complete!\");\n this.log(\"\");\n }\n\n private validateEjectType(typeArg: string | undefined): EjectType {\n if (!typeArg) {\n this.error(\"Please specify what to eject: agent-partials, templates, skills, or all\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!isEjectType(typeArg)) {\n this.error(`Unknown eject type: ${typeArg}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n return typeArg;\n }\n\n private async resolveOutputBase(\n flags: { output: string | undefined },\n projectDir: string,\n ): Promise<string> {\n if (flags.output) {\n const expandedPath = flags.output.startsWith(\"~\")\n ? path.join(os.homedir(), flags.output.slice(1))\n : flags.output;\n const outputBase = path.resolve(projectDir, expandedPath);\n\n if (await fileExists(outputBase)) {\n this.error(`Output path exists as a file: ${outputBase}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n return outputBase;\n }\n\n return path.join(projectDir, CLAUDE_SRC_DIR);\n }\n\n private printHeader(outputBase?: string): void {\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Eject`);\n this.log(\"\");\n\n if (outputBase) {\n this.log(`Output directory: ${outputBase}`);\n }\n }\n\n private async loadSourceIfNeeded(\n ejectType: EjectType,\n projectDir: string,\n ): Promise<SourceLoadResult | undefined> {\n if (ejectType === \"skills\" || ejectType === \"all\") {\n const loaded = await loadSource({ projectDir });\n return loaded.sourceResult;\n }\n return undefined;\n }\n\n private async executeEject(\n ejectType: EjectType,\n outputBase: string,\n flags: { force: boolean; output: string | undefined },\n projectDir: string,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n const directOutput = !!flags.output;\n\n switch (ejectType) {\n case \"agent-partials\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n break;\n case \"templates\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, true);\n break;\n case \"skills\":\n if (!sourceResult) {\n throw new Error(\"Source must be loaded for skills eject\");\n }\n await this.handleSkills(projectDir, flags.force, sourceResult, directOutput, outputBase);\n break;\n case \"all\":\n if (!sourceResult) {\n throw new Error(\"Source must be loaded for full eject\");\n }\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n await this.handleAgentPartials(outputBase, true, directOutput, true);\n await this.handleSkills(projectDir, flags.force, sourceResult, directOutput, outputBase);\n break;\n default: {\n const _exhaustive: never = ejectType;\n return _exhaustive;\n }\n }\n }\n\n private async ensureConfig(\n projectDir: string,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n const configResult = await ensureMinimalConfig({\n projectDir,\n ...(sourceResult !== undefined && { sourceResult }),\n });\n if (configResult.created) {\n this.logSuccess(`Created ${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS}`);\n }\n }\n\n private async handleAgentPartials(\n outputBase: string,\n force: boolean,\n directOutput: boolean,\n templatesOnly: boolean,\n ): Promise<void> {\n const result = await ejectAgentPartials({\n outputBase,\n force,\n directOutput,\n templatesOnly,\n });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n if (result.templatesSkipped) {\n this.warn(\n \"Agent templates already exist — skipping templates, only ejecting agent partials.\",\n );\n }\n\n this.logSuccess(\n `${templatesOnly ? \"Agent templates\" : \"Agent partials\"} ejected to ${result.destDir}`,\n );\n this.log(\n templatesOnly\n ? \"You can now customize agent templates locally.\"\n : \"You can now customize templates, agent intro, workflow, and examples locally.\",\n );\n }\n\n private async handleSkills(\n projectDir: string,\n force: boolean,\n sourceResult: SourceLoadResult,\n directOutput: boolean,\n outputBase: string,\n ): Promise<void> {\n const result = await ejectSkills({\n projectDir,\n force,\n sourceResult,\n matrix,\n directOutput,\n ...(directOutput && { customOutputBase: outputBase }),\n });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n this.logSuccess(\n `${result.copiedSkills.length} skills ejected to ${result.destDir} from ${result.sourceLabel}`,\n );\n this.log(\"You can now customize skill content locally.\");\n }\n}\n\ntype EjectAgentPartialsOptions = {\n outputBase: string;\n force: boolean;\n /** When true, outputBase is used directly as the destination (no subdirectory nesting). */\n directOutput?: boolean;\n /** When true, ejects only the _templates directory instead of the full agents directory. */\n templatesOnly?: boolean;\n};\n\ntype EjectAgentPartialsResult =\n | {\n skipped: true;\n skipReason: string;\n templatesSkipped: false;\n }\n | {\n skipped: false;\n /** Destination directory that was written to. */\n destDir: string;\n /** Whether templates were skipped during a full agent-partials eject (existing templates preserved). */\n templatesSkipped: boolean;\n };\n\n/**\n * Copies agent partials or templates from the CLI source to a target directory.\n *\n * When `templatesOnly` is true, copies only the _templates subdirectory.\n * When false, copies the full agents directory (optionally skipping existing templates).\n *\n * Returns structured data — the command decides what to log.\n */\n/** Direct output writes to the base itself; otherwise agents/ (plus templates/ in templates-only mode). */\nfunction resolveEjectDestDir(\n outputBase: string,\n directOutput: boolean,\n templatesOnly: boolean,\n): string {\n if (directOutput) return outputBase;\n const agentsDir = path.join(outputBase, path.basename(DIRS.agents));\n return templatesOnly ? path.join(agentsDir, path.basename(DIRS.templates)) : agentsDir;\n}\n\nasync function ejectAgentPartials(\n options: EjectAgentPartialsOptions,\n): Promise<EjectAgentPartialsResult> {\n const { outputBase, force, directOutput = false, templatesOnly = false } = options;\n\n const sourceDir = templatesOnly\n ? path.join(PROJECT_ROOT, DIRS.templates)\n : path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(sourceDir))) {\n return {\n skipped: true,\n skipReason: templatesOnly\n ? \"No agent templates found in CLI.\"\n : \"No agent partials found in CLI.\",\n templatesSkipped: false,\n };\n }\n\n const destDir = resolveEjectDestDir(outputBase, directOutput, templatesOnly);\n\n const templatesBasename = path.basename(DIRS.templates);\n\n if ((await directoryExists(destDir)) && !force) {\n if (templatesOnly) {\n return {\n skipped: true,\n skipReason: `Agent templates already exist at ${destDir}. Use --force to overwrite.`,\n templatesSkipped: false,\n };\n }\n\n const hasTemplates = await directoryExists(path.join(destDir, templatesBasename));\n if ((await hasAgentPartialDirs(destDir)) && !hasTemplates) {\n return {\n skipped: true,\n skipReason: `Agent partials already exist at ${destDir}. Use --force to overwrite.`,\n templatesSkipped: false,\n };\n }\n }\n\n await ensureDir(destDir);\n\n const skipTemplates =\n !templatesOnly && !force && (await directoryExists(path.join(destDir, templatesBasename)));\n\n if (skipTemplates) {\n const sourceEntries = await listDirectories(sourceDir);\n const nonTemplateEntries = sourceEntries.filter((entry) => entry !== templatesBasename);\n for (const entry of nonTemplateEntries) {\n await copy(path.join(sourceDir, entry), path.join(destDir, entry));\n }\n } else {\n await copy(sourceDir, destDir);\n }\n\n return {\n skipped: false,\n destDir,\n templatesSkipped: skipTemplates,\n };\n}\n\ntype EjectSkillsOptions = {\n projectDir: string;\n force: boolean;\n sourceResult: SourceLoadResult;\n matrix: MergedSkillsMatrix;\n /** When true, uses customOutputBase as destination instead of LOCAL_SKILLS_PATH. */\n directOutput?: boolean;\n customOutputBase?: string;\n};\n\ntype EjectSkillsResult =\n | {\n skipped: true;\n skipReason: string;\n copiedSkills: [];\n }\n | {\n skipped: false;\n /** Array of skills that were copied. */\n copiedSkills: CopiedSkill[];\n /** Destination directory that was written to. */\n destDir: string;\n /** Label describing the source that skills were copied from. */\n sourceLabel: string;\n };\n\n/**\n * Copies non-local skills from source to a target directory.\n *\n * Filters out skills already marked as local, then copies the remaining skills\n * using copySkillsToLocalFlattened.\n *\n * Returns structured data — the command decides what to log.\n */\nasync function ejectSkills(options: EjectSkillsOptions): Promise<EjectSkillsResult> {\n const {\n projectDir,\n force,\n sourceResult,\n matrix,\n directOutput = false,\n customOutputBase,\n } = options;\n\n const destDir =\n directOutput && customOutputBase ? customOutputBase : path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if ((await directoryExists(destDir)) && !force) {\n return {\n skipped: true,\n skipReason: `Skills already exist at ${destDir}. Use --force to overwrite.`,\n copiedSkills: [],\n };\n }\n\n const skillIds = typedKeys<SkillId>(matrix.skills).filter(\n (skillId) => !matrix.skills[skillId]?.local,\n );\n\n if (skillIds.length === 0) {\n return {\n skipped: true,\n skipReason: \"No skills found in source to eject.\",\n copiedSkills: [],\n };\n }\n\n await ensureDir(destDir);\n\n const copiedSkills = await copySkillsToLocalFlattened(skillIds, destDir, sourceResult);\n\n const sourceLabel = sourceResult.isLocal\n ? sourceResult.sourcePath\n : sourceResult.marketplace || sourceResult.sourceConfig.source;\n\n return {\n skipped: false,\n copiedSkills,\n destDir,\n sourceLabel,\n };\n}\n\ntype EnsureMinimalConfigOptions = {\n projectDir: string;\n sourceResult?: SourceLoadResult;\n};\n\ntype EnsureMinimalConfigResult = {\n /** Path to the config file. */\n configPath: string;\n /** Whether a new config was created. */\n created: boolean;\n};\n\n/**\n * Ensures a minimal config.ts exists so `npx agents-inc compile` works after eject.\n *\n * If the config already exists, returns immediately with `created: false`.\n * Otherwise generates a minimal config from the resolved source and project metadata.\n *\n * Returns structured data — the command decides what to log.\n */\nasync function ensureMinimalConfig(\n options: EnsureMinimalConfigOptions,\n): Promise<EnsureMinimalConfigResult> {\n const { projectDir, sourceResult } = options;\n\n const tsConfigPath = getProjectConfigPath(projectDir);\n\n if (await fileExists(tsConfigPath)) {\n return { configPath: tsConfigPath, created: false };\n }\n\n const resolvedConfig =\n sourceResult?.sourceConfig ?? (await resolveSource({ caller: \"stored\", projectDir }));\n const existingProjectConfig = await loadProjectSourceConfig(projectDir);\n const source = resolvedConfig.source || undefined;\n\n // At the home directory the invented config IS the global manifest, and the\n // file it opens with `import type { ProjectConfig } from \"./config-types\"`\n // cannot resolve its own types without the sibling. The gate writes the pair.\n if (isHomeDirectory(projectDir)) {\n await ensureBlankPair();\n if (source) await recordSource(projectDir, source);\n return { configPath: tsConfigPath, created: true };\n }\n\n await writeProjectPartial(\n projectDir,\n {\n skills: [],\n agents: [],\n ...(source ? { source } : {}),\n ...(resolvedConfig.marketplace ? { marketplace: resolvedConfig.marketplace } : {}),\n ...(existingProjectConfig?.author ? { author: existingProjectConfig.author } : {}),\n ...(existingProjectConfig?.agentsSource\n ? { agentsSource: existingProjectConfig.agentsSource }\n : {}),\n },\n { fallbackName: path.basename(projectDir) },\n );\n\n return { configPath: tsConfigPath, created: true };\n}\n\n/**\n * Records `source` in whichever scope's config `projectDir` names. At the home\n * directory that config is the global manifest every project's generated types\n * import from, so the write goes through the gate: registered projects inline\n * the scalar and follow it.\n */\nasync function recordSource(projectDir: string, source: string): Promise<void> {\n if (isHomeDirectory(projectDir)) {\n await mutateGlobal(\n { kind: \"set-source\", source, fallbackName: path.basename(projectDir) },\n lazyGateDeps(projectDir),\n );\n return;\n }\n\n const existing = (await loadProjectSourceConfig(projectDir)) ?? {};\n await writeProjectPartial(\n projectDir,\n { ...existing, source },\n { fallbackName: path.basename(projectDir) },\n );\n}\n\n/** Checks whether the agents directory contains any agent subdirectories (not just _templates). */\nasync function hasAgentPartialDirs(agentsDir: string): Promise<boolean> {\n const subdirs = await listDirectories(agentsDir);\n const templatesBasename = path.basename(DIRS.templates);\n return subdirs.some((dir) => dir !== templatesBasename);\n}\n"],"mappings":"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","names":["matrix"]}