agents-inc 0.151.0 → 0.152.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 (253) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/{chunk-YA4QQKKE.js → chunk-5GUOIJSG.js} +3 -7
  3. package/dist/{chunk-YA4QQKKE.js.map → chunk-5GUOIJSG.js.map} +1 -1
  4. package/dist/{chunk-44LLPS2N.js → chunk-5UWKOOIS.js} +6 -26
  5. package/dist/chunk-5UWKOOIS.js.map +1 -0
  6. package/dist/{chunk-O5ASLZ2K.js → chunk-76ADG7LQ.js} +1 -5
  7. package/dist/{chunk-O5ASLZ2K.js.map → chunk-76ADG7LQ.js.map} +1 -1
  8. package/dist/{chunk-WK4J2CHH.js → chunk-BNSRA6HL.js} +13 -18
  9. package/dist/{chunk-WK4J2CHH.js.map → chunk-BNSRA6HL.js.map} +1 -1
  10. package/dist/{chunk-FYPUUYSG.js → chunk-DTSG5XZB.js} +3 -7
  11. package/dist/{chunk-FYPUUYSG.js.map → chunk-DTSG5XZB.js.map} +1 -1
  12. package/dist/{chunk-NGLQ5W7U.js → chunk-E5X6RJ4E.js} +5 -15
  13. package/dist/chunk-E5X6RJ4E.js.map +1 -0
  14. package/dist/{chunk-TVHRMRD3.js → chunk-EEPELKOM.js} +4008 -4084
  15. package/dist/chunk-EEPELKOM.js.map +1 -0
  16. package/dist/{chunk-NIKUMXE7.js → chunk-F7T5AFFN.js} +1 -5
  17. package/dist/{chunk-NIKUMXE7.js.map → chunk-F7T5AFFN.js.map} +1 -1
  18. package/dist/{chunk-LAXAQ3PZ.js → chunk-FVDKAVOL.js} +10 -14
  19. package/dist/{chunk-LAXAQ3PZ.js.map → chunk-FVDKAVOL.js.map} +1 -1
  20. package/dist/{chunk-BNE4HHIH.js → chunk-GRVKW3CC.js} +2 -6
  21. package/dist/{chunk-BNE4HHIH.js.map → chunk-GRVKW3CC.js.map} +1 -1
  22. package/dist/{chunk-3XFUQ6OL.js → chunk-IHUY4M22.js} +4 -8
  23. package/dist/{chunk-3XFUQ6OL.js.map → chunk-IHUY4M22.js.map} +1 -1
  24. package/dist/{chunk-OZZGXBCN.js → chunk-IUQBOCSU.js} +1 -5
  25. package/dist/{chunk-OZZGXBCN.js.map → chunk-IUQBOCSU.js.map} +1 -1
  26. package/dist/{chunk-LYYXX2W5.js → chunk-J27W6TXS.js} +4 -6
  27. package/dist/{chunk-LYYXX2W5.js.map → chunk-J27W6TXS.js.map} +1 -1
  28. package/dist/chunk-JFLVEFFP.js +16 -0
  29. package/dist/chunk-JFLVEFFP.js.map +1 -0
  30. package/dist/{chunk-PV2HNW4I.js → chunk-KFB5CRXZ.js} +7 -12
  31. package/dist/{chunk-PV2HNW4I.js.map → chunk-KFB5CRXZ.js.map} +1 -1
  32. package/dist/{chunk-SYUOXSPU.js → chunk-KR65TPKC.js} +168 -14
  33. package/dist/chunk-KR65TPKC.js.map +1 -0
  34. package/dist/{chunk-KOPEM3Q7.js → chunk-KXYVJGJP.js} +2 -6
  35. package/dist/{chunk-KOPEM3Q7.js.map → chunk-KXYVJGJP.js.map} +1 -1
  36. package/dist/{chunk-TYJLR32W.js → chunk-L7SZXUBJ.js} +9 -14
  37. package/dist/{chunk-TYJLR32W.js.map → chunk-L7SZXUBJ.js.map} +1 -1
  38. package/dist/{chunk-NHCGC6DG.js → chunk-LASI35KT.js} +4 -9
  39. package/dist/{chunk-NHCGC6DG.js.map → chunk-LASI35KT.js.map} +1 -1
  40. package/dist/{chunk-VG2TVBFN.js → chunk-LDP5ASDM.js} +2 -6
  41. package/dist/{chunk-VG2TVBFN.js.map → chunk-LDP5ASDM.js.map} +1 -1
  42. package/dist/{chunk-5V2O6C3T.js → chunk-LZ52XEPR.js} +4 -8
  43. package/dist/{chunk-5V2O6C3T.js.map → chunk-LZ52XEPR.js.map} +1 -1
  44. package/dist/{chunk-WFWCZEMS.js → chunk-M7HO7NBK.js} +4 -8
  45. package/dist/{chunk-WFWCZEMS.js.map → chunk-M7HO7NBK.js.map} +1 -1
  46. package/dist/{chunk-XA57SX4T.js → chunk-MJ2KHG24.js} +4 -8
  47. package/dist/{chunk-XA57SX4T.js.map → chunk-MJ2KHG24.js.map} +1 -1
  48. package/dist/{chunk-DAG2ULNF.js → chunk-MM7CTTAV.js} +2 -6
  49. package/dist/chunk-MM7CTTAV.js.map +1 -0
  50. package/dist/{chunk-UFURYGD3.js → chunk-MQ7FLIYS.js} +2 -6
  51. package/dist/{chunk-UFURYGD3.js.map → chunk-MQ7FLIYS.js.map} +1 -1
  52. package/dist/{chunk-SI5FOARI.js → chunk-MVR3SYMN.js} +6 -8
  53. package/dist/chunk-MVR3SYMN.js.map +1 -0
  54. package/dist/{chunk-UTFN6UJS.js → chunk-MWG4VU64.js} +12 -17
  55. package/dist/{chunk-UTFN6UJS.js.map → chunk-MWG4VU64.js.map} +1 -1
  56. package/dist/{chunk-ES3NJZON.js → chunk-NR3OZGL4.js} +1 -5
  57. package/dist/{chunk-ES3NJZON.js.map → chunk-NR3OZGL4.js.map} +1 -1
  58. package/dist/{chunk-GYG5SE2D.js → chunk-ODNDXQH2.js} +2 -6
  59. package/dist/{chunk-GYG5SE2D.js.map → chunk-ODNDXQH2.js.map} +1 -1
  60. package/dist/{chunk-2RSNKBXC.js → chunk-P44SXVH3.js} +6 -10
  61. package/dist/{chunk-2RSNKBXC.js.map → chunk-P44SXVH3.js.map} +1 -1
  62. package/dist/{chunk-3LIU2ZEF.js → chunk-PMM2MYMA.js} +3 -16
  63. package/dist/{chunk-3LIU2ZEF.js.map → chunk-PMM2MYMA.js.map} +1 -1
  64. package/dist/{chunk-QTFQEYDA.js → chunk-PZIZNMHK.js} +24 -36
  65. package/dist/chunk-PZIZNMHK.js.map +1 -0
  66. package/dist/{chunk-C55DN7GE.js → chunk-Q2KG7UV3.js} +3 -5
  67. package/dist/chunk-Q2KG7UV3.js.map +1 -0
  68. package/dist/{chunk-QQLRX4KI.js → chunk-Q45ZU6HD.js} +2 -6
  69. package/dist/{chunk-QQLRX4KI.js.map → chunk-Q45ZU6HD.js.map} +1 -1
  70. package/dist/{chunk-6RBQBOBS.js → chunk-QRDTLVXG.js} +9 -14
  71. package/dist/{chunk-6RBQBOBS.js.map → chunk-QRDTLVXG.js.map} +1 -1
  72. package/dist/{chunk-YBVA7GPW.js → chunk-QZZJFYUQ.js} +3 -7
  73. package/dist/{chunk-YBVA7GPW.js.map → chunk-QZZJFYUQ.js.map} +1 -1
  74. package/dist/{chunk-OJIESW5B.js → chunk-R5NOI2LP.js} +13 -17
  75. package/dist/{chunk-OJIESW5B.js.map → chunk-R5NOI2LP.js.map} +1 -1
  76. package/dist/{chunk-DUVWGO6E.js → chunk-RNJWAKMO.js} +3 -7
  77. package/dist/{chunk-DUVWGO6E.js.map → chunk-RNJWAKMO.js.map} +1 -1
  78. package/dist/{chunk-4R6PGHQQ.js → chunk-SBHBBZKF.js} +7 -23
  79. package/dist/chunk-SBHBBZKF.js.map +1 -0
  80. package/dist/{chunk-NM3EDGB5.js → chunk-SKQWRUPX.js} +10 -14
  81. package/dist/{chunk-NM3EDGB5.js.map → chunk-SKQWRUPX.js.map} +1 -1
  82. package/dist/{chunk-Y4CXDA3I.js → chunk-STMHDOZD.js} +4 -21
  83. package/dist/chunk-STMHDOZD.js.map +1 -0
  84. package/dist/{chunk-SHHOMVWC.js → chunk-SX5H6TSC.js} +7 -11
  85. package/dist/chunk-SX5H6TSC.js.map +1 -0
  86. package/dist/{chunk-RBHYLCUB.js → chunk-TJJPWUMA.js} +2 -6
  87. package/dist/{chunk-RBHYLCUB.js.map → chunk-TJJPWUMA.js.map} +1 -1
  88. package/dist/{chunk-IOJR5TOY.js → chunk-TSIU7DME.js} +1 -5
  89. package/dist/{chunk-IOJR5TOY.js.map → chunk-TSIU7DME.js.map} +1 -1
  90. package/dist/{chunk-EVXG3X6G.js → chunk-TUPYW2IQ.js} +3 -7
  91. package/dist/{chunk-EVXG3X6G.js.map → chunk-TUPYW2IQ.js.map} +1 -1
  92. package/dist/{chunk-YU2VGX5R.js → chunk-UBEDZ4FD.js} +1 -8
  93. package/dist/{chunk-YU2VGX5R.js.map → chunk-UBEDZ4FD.js.map} +1 -1
  94. package/dist/{chunk-VEP23B5W.js → chunk-VASLW636.js} +1 -5
  95. package/dist/{chunk-VEP23B5W.js.map → chunk-VASLW636.js.map} +1 -1
  96. package/dist/{chunk-PG4G4IIK.js → chunk-VY6MNOXL.js} +2 -6
  97. package/dist/{chunk-PG4G4IIK.js.map → chunk-VY6MNOXL.js.map} +1 -1
  98. package/dist/{chunk-IHO75PMZ.js → chunk-WBCPLH66.js} +15 -13
  99. package/dist/chunk-WBCPLH66.js.map +1 -0
  100. package/dist/{chunk-DG2NGZ7S.js → chunk-WKTHWQKM.js} +2 -7
  101. package/dist/{chunk-DG2NGZ7S.js.map → chunk-WKTHWQKM.js.map} +1 -1
  102. package/dist/{chunk-EZ7STXUV.js → chunk-XHUODHZ4.js} +19 -25
  103. package/dist/{chunk-EZ7STXUV.js.map → chunk-XHUODHZ4.js.map} +1 -1
  104. package/dist/{chunk-KIR7VYQD.js → chunk-XVAQG2CV.js} +1 -5
  105. package/dist/{chunk-KIR7VYQD.js.map → chunk-XVAQG2CV.js.map} +1 -1
  106. package/dist/{chunk-P3PN5SVI.js → chunk-ZL7PFNHN.js} +2 -6
  107. package/dist/{chunk-P3PN5SVI.js.map → chunk-ZL7PFNHN.js.map} +1 -1
  108. package/dist/{chunk-3YGUHWLR.js → chunk-ZPPHXXAP.js} +9 -15
  109. package/dist/{chunk-3YGUHWLR.js.map → chunk-ZPPHXXAP.js.map} +1 -1
  110. package/dist/commands/build/marketplace.js +10 -15
  111. package/dist/commands/build/marketplace.js.map +1 -1
  112. package/dist/commands/build/plugins.js +9 -14
  113. package/dist/commands/build/plugins.js.map +1 -1
  114. package/dist/commands/compile.js +14 -19
  115. package/dist/commands/compile.js.map +1 -1
  116. package/dist/commands/doctor.js +13 -18
  117. package/dist/commands/doctor.js.map +1 -1
  118. package/dist/commands/edit.js +51 -55
  119. package/dist/commands/edit.js.map +1 -1
  120. package/dist/commands/eject.js +13 -18
  121. package/dist/commands/eject.js.map +1 -1
  122. package/dist/commands/import/skill.js +9 -14
  123. package/dist/commands/import/skill.js.map +1 -1
  124. package/dist/commands/init.js +50 -51
  125. package/dist/commands/list.js +14 -16
  126. package/dist/commands/list.js.map +1 -1
  127. package/dist/commands/new/agent.js +12 -16
  128. package/dist/commands/new/agent.js.map +1 -1
  129. package/dist/commands/new/marketplace.js +15 -20
  130. package/dist/commands/new/marketplace.js.map +1 -1
  131. package/dist/commands/new/skill.js +11 -13
  132. package/dist/commands/search.js +14 -19
  133. package/dist/commands/search.js.map +1 -1
  134. package/dist/commands/uninstall.js +17 -21
  135. package/dist/commands/uninstall.js.map +1 -1
  136. package/dist/commands/update.js +17 -21
  137. package/dist/commands/update.js.map +1 -1
  138. package/dist/commands/validate.js +10 -16
  139. package/dist/commands/validate.js.map +1 -1
  140. package/dist/components/common/confirm.js +1 -2
  141. package/dist/components/common/prompt-confirm.js +2 -2
  142. package/dist/components/common/select-list.js +3 -4
  143. package/dist/components/common/spinner.js +1 -2
  144. package/dist/components/wizard/category-grid.js +8 -9
  145. package/dist/components/wizard/checkbox-grid.js +6 -7
  146. package/dist/components/wizard/domain-selection.js +14 -15
  147. package/dist/components/wizard/run-wizard-session.js +40 -40
  148. package/dist/components/wizard/scroll-affordance.js +2 -3
  149. package/dist/components/wizard/search-modal.js +6 -7
  150. package/dist/components/wizard/selection-card.js +2 -3
  151. package/dist/components/wizard/skill-agent-summary.js +8 -9
  152. package/dist/components/wizard/source-grid.js +13 -14
  153. package/dist/components/wizard/stack-selection.js +12 -13
  154. package/dist/components/wizard/step-agents.js +14 -15
  155. package/dist/components/wizard/step-build.js +14 -15
  156. package/dist/components/wizard/step-confirm.js +13 -14
  157. package/dist/components/wizard/step-settings.js +11 -12
  158. package/dist/components/wizard/step-sources.js +20 -21
  159. package/dist/components/wizard/step-stack.js +13 -14
  160. package/dist/components/wizard/summary-panel.js +12 -13
  161. package/dist/components/wizard/toast.js +2 -3
  162. package/dist/components/wizard/wizard-layout.js +18 -19
  163. package/dist/components/wizard/wizard-tabs.js +8 -9
  164. package/dist/components/wizard/wizard.js +38 -39
  165. package/dist/config-exports.js +1 -7
  166. package/dist/config-exports.js.map +1 -1
  167. package/dist/copy-local-skills-6EMVN7RB.js +14 -0
  168. package/dist/hooks/init.js +50 -54
  169. package/dist/hooks/init.js.map +1 -1
  170. package/dist/index.js +0 -4
  171. package/dist/index.js.map +1 -1
  172. package/dist/load-agent-defs-BWOUVEAR.js +15 -0
  173. package/dist/{loader-E2ERJYVA.js → loader-5JP4S7CJ.js} +4 -5
  174. package/dist/recompile-project-agents-6DL45TDI.js +19 -0
  175. package/dist/{source-loader-5UNRU7EZ.js → source-loader-MZYCPL2S.js} +7 -8
  176. package/dist/stores/wizard-store.js +7 -8
  177. package/package.json +15 -14
  178. package/dist/chunk-44LLPS2N.js.map +0 -1
  179. package/dist/chunk-4R6PGHQQ.js.map +0 -1
  180. package/dist/chunk-7QIHKQL5.js +0 -181
  181. package/dist/chunk-7QIHKQL5.js.map +0 -1
  182. package/dist/chunk-C55DN7GE.js.map +0 -1
  183. package/dist/chunk-DAG2ULNF.js.map +0 -1
  184. package/dist/chunk-DIBCRIMR.js +0 -36
  185. package/dist/chunk-DIBCRIMR.js.map +0 -1
  186. package/dist/chunk-EKWAUOQB.js +0 -96
  187. package/dist/chunk-EKWAUOQB.js.map +0 -1
  188. package/dist/chunk-I3XKEGHM.js +0 -16383
  189. package/dist/chunk-I3XKEGHM.js.map +0 -1
  190. package/dist/chunk-IHO75PMZ.js.map +0 -1
  191. package/dist/chunk-K3OU6TGX.js +0 -77
  192. package/dist/chunk-K3OU6TGX.js.map +0 -1
  193. package/dist/chunk-KSZ6PCY4.js +0 -43
  194. package/dist/chunk-KSZ6PCY4.js.map +0 -1
  195. package/dist/chunk-NGLQ5W7U.js.map +0 -1
  196. package/dist/chunk-P56WJ5FA.js +0 -50
  197. package/dist/chunk-P56WJ5FA.js.map +0 -1
  198. package/dist/chunk-QTFQEYDA.js.map +0 -1
  199. package/dist/chunk-SHHOMVWC.js.map +0 -1
  200. package/dist/chunk-SI5FOARI.js.map +0 -1
  201. package/dist/chunk-SYUOXSPU.js.map +0 -1
  202. package/dist/chunk-THKIOI32.js +0 -939
  203. package/dist/chunk-THKIOI32.js.map +0 -1
  204. package/dist/chunk-TVHRMRD3.js.map +0 -1
  205. package/dist/chunk-V7QOSGQA.js +0 -298
  206. package/dist/chunk-V7QOSGQA.js.map +0 -1
  207. package/dist/chunk-Y4CXDA3I.js.map +0 -1
  208. package/dist/components/common/confirm.test.js +0 -203
  209. package/dist/components/common/confirm.test.js.map +0 -1
  210. package/dist/components/wizard/category-grid.test.js +0 -1253
  211. package/dist/components/wizard/category-grid.test.js.map +0 -1
  212. package/dist/components/wizard/checkbox-grid.test.js +0 -264
  213. package/dist/components/wizard/checkbox-grid.test.js.map +0 -1
  214. package/dist/components/wizard/search-modal.test.js +0 -212
  215. package/dist/components/wizard/search-modal.test.js.map +0 -1
  216. package/dist/components/wizard/source-grid.test.js +0 -1094
  217. package/dist/components/wizard/source-grid.test.js.map +0 -1
  218. package/dist/components/wizard/step-agents.test.js +0 -204
  219. package/dist/components/wizard/step-agents.test.js.map +0 -1
  220. package/dist/components/wizard/step-build.test.js +0 -552
  221. package/dist/components/wizard/step-build.test.js.map +0 -1
  222. package/dist/components/wizard/step-confirm.test.js +0 -744
  223. package/dist/components/wizard/step-confirm.test.js.map +0 -1
  224. package/dist/components/wizard/step-settings.test.js +0 -244
  225. package/dist/components/wizard/step-settings.test.js.map +0 -1
  226. package/dist/components/wizard/step-sources.test.js +0 -155
  227. package/dist/components/wizard/step-sources.test.js.map +0 -1
  228. package/dist/components/wizard/step-stack.test.js +0 -262
  229. package/dist/components/wizard/step-stack.test.js.map +0 -1
  230. package/dist/components/wizard/summary-panel.test.js +0 -317
  231. package/dist/components/wizard/summary-panel.test.js.map +0 -1
  232. package/dist/components/wizard/wizard-layout.test.js +0 -200
  233. package/dist/components/wizard/wizard-layout.test.js.map +0 -1
  234. package/dist/components/wizard/wizard-tabs.test.js +0 -290
  235. package/dist/components/wizard/wizard-tabs.test.js.map +0 -1
  236. package/dist/copy-local-skills-UPA2GUZV.js +0 -15
  237. package/dist/dist-VNJNNJK7.js +0 -550
  238. package/dist/dist-VNJNNJK7.js.map +0 -1
  239. package/dist/load-agent-defs-SB4XAOVB.js +0 -16
  240. package/dist/magic-string.es-5TV73NJD.js +0 -1316
  241. package/dist/magic-string.es-5TV73NJD.js.map +0 -1
  242. package/dist/recompile-project-agents-U4ZY2GDX.js +0 -20
  243. package/dist/source-manager-3O54SIIB.js +0 -18
  244. package/dist/source-manager-3O54SIIB.js.map +0 -1
  245. package/dist/stores/d227-same-scope-tombstone-duplicate.test.js +0 -118
  246. package/dist/stores/d227-same-scope-tombstone-duplicate.test.js.map +0 -1
  247. package/dist/stores/wizard-store.test.js +0 -3053
  248. package/dist/stores/wizard-store.test.js.map +0 -1
  249. /package/dist/{copy-local-skills-UPA2GUZV.js.map → copy-local-skills-6EMVN7RB.js.map} +0 -0
  250. /package/dist/{load-agent-defs-SB4XAOVB.js.map → load-agent-defs-BWOUVEAR.js.map} +0 -0
  251. /package/dist/{loader-E2ERJYVA.js.map → loader-5JP4S7CJ.js.map} +0 -0
  252. /package/dist/{recompile-project-agents-U4ZY2GDX.js.map → recompile-project-agents-6DL45TDI.js.map} +0 -0
  253. /package/dist/{source-loader-5UNRU7EZ.js.map → source-loader-MZYCPL2S.js.map} +0 -0
@@ -5,19 +5,17 @@ import {
5
5
  generateSkillMd,
6
6
  resolveAuthorOrDefault,
7
7
  scaffoldSkillFiles
8
- } from "../../chunk-PV2HNW4I.js";
9
- import "../../chunk-PG4G4IIK.js";
10
- import "../../chunk-IHO75PMZ.js";
11
- import "../../chunk-7QIHKQL5.js";
12
- import "../../chunk-SYUOXSPU.js";
13
- import "../../chunk-P3PN5SVI.js";
14
- import "../../chunk-TVHRMRD3.js";
15
- import "../../chunk-3LIU2ZEF.js";
16
- import "../../chunk-DG2NGZ7S.js";
17
- import "../../chunk-VEP23B5W.js";
18
- import "../../chunk-O5ASLZ2K.js";
19
- import "../../chunk-YU2VGX5R.js";
20
- import "../../chunk-P56WJ5FA.js";
8
+ } from "../../chunk-KFB5CRXZ.js";
9
+ import "../../chunk-VY6MNOXL.js";
10
+ import "../../chunk-WBCPLH66.js";
11
+ import "../../chunk-KR65TPKC.js";
12
+ import "../../chunk-ZL7PFNHN.js";
13
+ import "../../chunk-EEPELKOM.js";
14
+ import "../../chunk-PMM2MYMA.js";
15
+ import "../../chunk-WKTHWQKM.js";
16
+ import "../../chunk-VASLW636.js";
17
+ import "../../chunk-76ADG7LQ.js";
18
+ import "../../chunk-UBEDZ4FD.js";
21
19
  export {
22
20
  NewSkill as default,
23
21
  generateMetadataYaml,
@@ -1,46 +1,41 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  STATUS_MESSAGES
4
- } from "../chunk-GYG5SE2D.js";
4
+ } from "../chunk-ODNDXQH2.js";
5
5
  import {
6
6
  loadSource
7
- } from "../chunk-Y4CXDA3I.js";
8
- import "../chunk-4R6PGHQQ.js";
9
- import "../chunk-3XFUQ6OL.js";
10
- import "../chunk-YBVA7GPW.js";
11
- import "../chunk-NGLQ5W7U.js";
7
+ } from "../chunk-STMHDOZD.js";
8
+ import "../chunk-SBHBBZKF.js";
9
+ import "../chunk-IHUY4M22.js";
10
+ import "../chunk-QZZJFYUQ.js";
11
+ import "../chunk-E5X6RJ4E.js";
12
12
  import {
13
13
  BaseCommand
14
- } from "../chunk-7QIHKQL5.js";
15
- import "../chunk-SYUOXSPU.js";
16
- import "../chunk-P3PN5SVI.js";
14
+ } from "../chunk-KR65TPKC.js";
15
+ import "../chunk-ZL7PFNHN.js";
17
16
  import {
18
17
  IMPORT_DEFAULTS,
19
18
  fetchFromSource,
20
19
  resolveAllSources,
21
20
  truncateText
22
- } from "../chunk-TVHRMRD3.js";
21
+ } from "../chunk-EEPELKOM.js";
23
22
  import {
24
23
  fileExists,
25
24
  listDirectories,
26
25
  parseFrontmatter,
27
26
  readFile
28
- } from "../chunk-3LIU2ZEF.js";
29
- import "../chunk-DG2NGZ7S.js";
27
+ } from "../chunk-PMM2MYMA.js";
28
+ import "../chunk-WKTHWQKM.js";
30
29
  import {
31
30
  typedValues
32
- } from "../chunk-VEP23B5W.js";
31
+ } from "../chunk-VASLW636.js";
33
32
  import {
34
33
  DEFAULT_SKILLS_SUBDIR,
35
34
  STANDARD_FILES
36
- } from "../chunk-O5ASLZ2K.js";
37
- import "../chunk-YU2VGX5R.js";
38
- import {
39
- init_esm_shims
40
- } from "../chunk-P56WJ5FA.js";
35
+ } from "../chunk-76ADG7LQ.js";
36
+ import "../chunk-UBEDZ4FD.js";
41
37
 
42
38
  // src/cli/commands/search.ts
43
- init_esm_shims();
44
39
  import { Args } from "@oclif/core";
45
40
  import { printTable } from "@oclif/table";
46
41
  import path from "path";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/search.ts"],"sourcesContent":["import { Args } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { DEFAULT_SKILLS_SUBDIR, STANDARD_FILES } from \"../consts.js\";\nimport { resolveAllSources } from \"../lib/configuration/index.js\";\nimport { fetchFromSource, parseFrontmatter } from \"../lib/loading/index.js\";\nimport { IMPORT_DEFAULTS } from \"../lib/metadata-keys.js\";\nimport { loadSource } from \"../lib/operations/index.js\";\nimport type { SourceEntry } from \"../types/config.js\";\nimport type { ResolvedSkill, SkillSlug } from \"../types/index.js\";\nimport { fileExists, listDirectories, readFile } from \"../utils/fs.js\";\nimport { STATUS_MESSAGES } from \"../utils/messages.js\";\nimport { truncateText } from \"../utils/string.js\";\nimport { typedValues } from \"../utils/typed-object.js\";\n\nconst MAX_DESCRIPTION_WIDTH = 50;\nconst PRIMARY_SOURCE_NAME = \"marketplace\";\n\ntype SearchableSkill = ResolvedSkill & { sourceName: string };\n\nexport default class Search extends BaseCommand {\n static summary = \"Search the catalog of available skills across all registered sources\";\n static description =\n \"Read-only catalog browse. Searches every registered source (primary + extras) \" +\n \"by id, displayName, slug, description, or category. Use `import skill` to install.\";\n\n static examples = [\n {\n description: \"Search for React skills\",\n command: \"<%= config.bin %> search react\",\n },\n {\n description: \"Search by any keyword (matches id, name, description, category)\",\n command: \"<%= config.bin %> search state\",\n },\n ];\n\n static args = {\n query: Args.string({\n description: \"Search query (matches id, displayName, slug, description, category)\",\n required: true,\n }),\n };\n\n // Override parent baseFlags to drop --source (search is a zero-flag command)\n static baseFlags = {} as (typeof BaseCommand)[\"baseFlags\"];\n\n static flags = {};\n\n async run(): Promise<void> {\n const { args } = await this.parse(Search);\n await this.runSearch(args.query);\n }\n\n private async runSearch(query: string): Promise<void> {\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const projectDir = process.cwd();\n const allSkills = await loadSkillsFromAllSources(projectDir);\n\n const results = sortBy(\n allSkills.filter((skill) => matchesQuery(skill, query)),\n (r) => r.displayName.toLowerCase(),\n );\n\n this.log(\"\");\n if (results.length === 0) {\n this.warn(`No skills found matching \"${query}\"`);\n return;\n }\n\n this.logInfo(\n `Found ${results.length} skill${results.length === 1 ? \"\" : \"s\"} matching \"${query}\"`,\n );\n this.log(\"\");\n\n printTable({\n data: results.map((skill) => ({\n id: skill.displayName,\n source: skill.sourceName,\n category: skill.category,\n description: truncateText(skill.description, MAX_DESCRIPTION_WIDTH),\n })),\n columns: [\n { key: \"id\", name: \"ID\" },\n { key: \"source\", name: \"Source\" },\n { key: \"category\", name: \"Category\" },\n { key: \"description\", name: \"Description\" },\n ],\n headerOptions: { bold: true },\n });\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n\nasync function loadSkillsFromAllSources(projectDir: string): Promise<SearchableSkill[]> {\n const { sourceResult } = await loadSource({ projectDir });\n const { matrix } = sourceResult;\n\n const primarySkills: SearchableSkill[] = typedValues(matrix.skills).map((skill) => ({\n ...skill,\n sourceName: PRIMARY_SOURCE_NAME,\n }));\n\n const { extras } = await resolveAllSources(projectDir);\n\n const extraSkillArrays = await Promise.all(extras.map(fetchSkillsFromExternalSource));\n\n return [...primarySkills, ...extraSkillArrays.flat()];\n}\n\nasync function fetchSkillsFromExternalSource(source: SourceEntry): Promise<SearchableSkill[]> {\n try {\n const result = await fetchFromSource(source.url, {});\n const skillsDir = path.join(result.path, DEFAULT_SKILLS_SUBDIR);\n\n if (!(await fileExists(skillsDir))) {\n return [];\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const loaded = await Promise.all(\n skillDirs.map((skillDir) => loadExternalSkill(skillsDir, skillDir, source.name)),\n );\n return loaded.filter((skill) => skill !== null);\n } catch {\n // Source unavailable, return empty\n return [];\n }\n}\n\n/** Loads one external skill dir as a SearchableSkill, or null when it has no valid SKILL.md. */\nasync function loadExternalSkill(\n skillsDir: string,\n skillDir: string,\n sourceName: string,\n): Promise<SearchableSkill | null> {\n const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);\n if (!(await fileExists(skillMdPath))) return null;\n\n const content = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(content, skillMdPath);\n if (!frontmatter) return null;\n\n return {\n id: frontmatter.name,\n description: frontmatter.description,\n // Boundary cast: directory name used as slug for third-party source skill\n slug: skillDir as SkillSlug,\n displayName: skillDir,\n // Boundary cast: external source skills have no real category; \"imported\" is a display-only placeholder\n category: IMPORT_DEFAULTS.CATEGORY,\n author: `@${sourceName}`,\n conflictsWith: [],\n isRecommended: false,\n requires: [],\n alternatives: [],\n discourages: [],\n compatibleWith: [],\n path: path.join(skillsDir, skillDir),\n sourceName,\n };\n}\n\nfunction matchesQuery(skill: ResolvedSkill, query: string): boolean {\n const lowerQuery = query.toLowerCase();\n return [skill.id, skill.displayName, skill.slug, skill.description, skill.category].some(\n (field) => field.toLowerCase().includes(lowerQuery),\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/search.ts"],"sourcesContent":["import { Args } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { DEFAULT_SKILLS_SUBDIR, STANDARD_FILES } from \"../consts.js\";\nimport { resolveAllSources } from \"../lib/configuration/index.js\";\nimport { fetchFromSource, parseFrontmatter } from \"../lib/loading/index.js\";\nimport { IMPORT_DEFAULTS } from \"../lib/metadata-keys.js\";\nimport { loadSource } from \"../lib/operations/index.js\";\nimport type { SourceEntry } from \"../types/config.js\";\nimport type { ResolvedSkill, SkillSlug } from \"../types/index.js\";\nimport { fileExists, listDirectories, readFile } from \"../utils/fs.js\";\nimport { STATUS_MESSAGES } from \"../utils/messages.js\";\nimport { truncateText } from \"../utils/string.js\";\nimport { typedValues } from \"../utils/typed-object.js\";\n\nconst MAX_DESCRIPTION_WIDTH = 50;\nconst PRIMARY_SOURCE_NAME = \"marketplace\";\n\ntype SearchableSkill = ResolvedSkill & { sourceName: string };\n\nexport default class Search extends BaseCommand {\n static summary = \"Search the catalog of available skills across all registered sources\";\n static description =\n \"Read-only catalog browse. Searches every registered source (primary + extras) \" +\n \"by id, displayName, slug, description, or category. Use `import skill` to install.\";\n\n static examples = [\n {\n description: \"Search for React skills\",\n command: \"<%= config.bin %> search react\",\n },\n {\n description: \"Search by any keyword (matches id, name, description, category)\",\n command: \"<%= config.bin %> search state\",\n },\n ];\n\n static args = {\n query: Args.string({\n description: \"Search query (matches id, displayName, slug, description, category)\",\n required: true,\n }),\n };\n\n // Override parent baseFlags to drop --source (search is a zero-flag command)\n static baseFlags = {} as (typeof BaseCommand)[\"baseFlags\"];\n\n static flags = {};\n\n async run(): Promise<void> {\n const { args } = await this.parse(Search);\n await this.runSearch(args.query);\n }\n\n private async runSearch(query: string): Promise<void> {\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const projectDir = process.cwd();\n const allSkills = await loadSkillsFromAllSources(projectDir);\n\n const results = sortBy(\n allSkills.filter((skill) => matchesQuery(skill, query)),\n (r) => r.displayName.toLowerCase(),\n );\n\n this.log(\"\");\n if (results.length === 0) {\n this.warn(`No skills found matching \"${query}\"`);\n return;\n }\n\n this.logInfo(\n `Found ${results.length} skill${results.length === 1 ? \"\" : \"s\"} matching \"${query}\"`,\n );\n this.log(\"\");\n\n printTable({\n data: results.map((skill) => ({\n id: skill.displayName,\n source: skill.sourceName,\n category: skill.category,\n description: truncateText(skill.description, MAX_DESCRIPTION_WIDTH),\n })),\n columns: [\n { key: \"id\", name: \"ID\" },\n { key: \"source\", name: \"Source\" },\n { key: \"category\", name: \"Category\" },\n { key: \"description\", name: \"Description\" },\n ],\n headerOptions: { bold: true },\n });\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n\nasync function loadSkillsFromAllSources(projectDir: string): Promise<SearchableSkill[]> {\n const { sourceResult } = await loadSource({ projectDir });\n const { matrix } = sourceResult;\n\n const primarySkills: SearchableSkill[] = typedValues(matrix.skills).map((skill) => ({\n ...skill,\n sourceName: PRIMARY_SOURCE_NAME,\n }));\n\n const { extras } = await resolveAllSources(projectDir);\n\n const extraSkillArrays = await Promise.all(extras.map(fetchSkillsFromExternalSource));\n\n return [...primarySkills, ...extraSkillArrays.flat()];\n}\n\nasync function fetchSkillsFromExternalSource(source: SourceEntry): Promise<SearchableSkill[]> {\n try {\n const result = await fetchFromSource(source.url, {});\n const skillsDir = path.join(result.path, DEFAULT_SKILLS_SUBDIR);\n\n if (!(await fileExists(skillsDir))) {\n return [];\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const loaded = await Promise.all(\n skillDirs.map((skillDir) => loadExternalSkill(skillsDir, skillDir, source.name)),\n );\n return loaded.filter((skill) => skill !== null);\n } catch {\n // Source unavailable, return empty\n return [];\n }\n}\n\n/** Loads one external skill dir as a SearchableSkill, or null when it has no valid SKILL.md. */\nasync function loadExternalSkill(\n skillsDir: string,\n skillDir: string,\n sourceName: string,\n): Promise<SearchableSkill | null> {\n const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);\n if (!(await fileExists(skillMdPath))) return null;\n\n const content = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(content, skillMdPath);\n if (!frontmatter) return null;\n\n return {\n id: frontmatter.name,\n description: frontmatter.description,\n // Boundary cast: directory name used as slug for third-party source skill\n slug: skillDir as SkillSlug,\n displayName: skillDir,\n // Boundary cast: external source skills have no real category; \"imported\" is a display-only placeholder\n category: IMPORT_DEFAULTS.CATEGORY,\n author: `@${sourceName}`,\n conflictsWith: [],\n isRecommended: false,\n requires: [],\n alternatives: [],\n discourages: [],\n compatibleWith: [],\n path: path.join(skillsDir, skillDir),\n sourceName,\n };\n}\n\nfunction matchesQuery(skill: ResolvedSkill, query: string): boolean {\n const lowerQuery = query.toLowerCase();\n return [skill.id, skill.displayName, skill.slug, skill.description, skill.category].some(\n (field) => field.toLowerCase().includes(lowerQuery),\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,32 +1,32 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Confirm
4
- } from "../chunk-ES3NJZON.js";
4
+ } from "../chunk-NR3OZGL4.js";
5
5
  import {
6
6
  promptConfirm
7
- } from "../chunk-C55DN7GE.js";
7
+ } from "../chunk-Q2KG7UV3.js";
8
8
  import {
9
9
  INFO_MESSAGES,
10
10
  SUCCESS_MESSAGES,
11
11
  registeredProjectUpdateSkipped,
12
12
  registeredProjectsUpdateFailed,
13
13
  registeredProjectsUpdated
14
- } from "../chunk-GYG5SE2D.js";
15
- import "../chunk-Y4CXDA3I.js";
16
- import "../chunk-4R6PGHQQ.js";
17
- import "../chunk-3XFUQ6OL.js";
14
+ } from "../chunk-ODNDXQH2.js";
15
+ import "../chunk-STMHDOZD.js";
16
+ import "../chunk-SBHBBZKF.js";
17
+ import "../chunk-IHUY4M22.js";
18
18
  import {
19
19
  loadAgentDefs
20
- } from "../chunk-YBVA7GPW.js";
20
+ } from "../chunk-QZZJFYUQ.js";
21
21
  import {
22
22
  listAgentMdFiles
23
- } from "../chunk-NGLQ5W7U.js";
23
+ } from "../chunk-E5X6RJ4E.js";
24
+ import "../chunk-JFLVEFFP.js";
24
25
  import {
25
26
  BaseCommand,
26
27
  EXIT_CODES
27
- } from "../chunk-7QIHKQL5.js";
28
- import "../chunk-SYUOXSPU.js";
29
- import "../chunk-P3PN5SVI.js";
28
+ } from "../chunk-KR65TPKC.js";
29
+ import "../chunk-ZL7PFNHN.js";
30
30
  import {
31
31
  ConfigLoadError,
32
32
  buildMarketplacePluginRef,
@@ -44,16 +44,16 @@ import {
44
44
  readForkedFromMetadata,
45
45
  resolveInstallPaths,
46
46
  toClaudePluginScope
47
- } from "../chunk-TVHRMRD3.js";
47
+ } from "../chunk-EEPELKOM.js";
48
48
  import {
49
49
  directoryExists,
50
50
  fileExists,
51
51
  getErrorMessage,
52
52
  listDirectories,
53
53
  remove
54
- } from "../chunk-3LIU2ZEF.js";
55
- import "../chunk-DG2NGZ7S.js";
56
- import "../chunk-VEP23B5W.js";
54
+ } from "../chunk-PMM2MYMA.js";
55
+ import "../chunk-WKTHWQKM.js";
56
+ import "../chunk-VASLW636.js";
57
57
  import {
58
58
  CLAUDE_DIR,
59
59
  CLAUDE_SRC_DIR,
@@ -61,14 +61,10 @@ import {
61
61
  DEFAULT_BRANDING,
62
62
  EJECT_SOURCE,
63
63
  STANDARD_FILES
64
- } from "../chunk-O5ASLZ2K.js";
65
- import "../chunk-YU2VGX5R.js";
66
- import {
67
- init_esm_shims
68
- } from "../chunk-P56WJ5FA.js";
64
+ } from "../chunk-76ADG7LQ.js";
65
+ import "../chunk-UBEDZ4FD.js";
69
66
 
70
67
  // src/cli/commands/uninstall.tsx
71
- init_esm_shims();
72
68
  import { partition } from "remeda";
73
69
  import path from "path";
74
70
  import { readdir } from "fs/promises";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\nimport { partition } from \"remeda\";\nimport path from \"path\";\nimport { readdir } from \"fs/promises\";\n\nimport { Flags } from \"@oclif/core\";\nimport { Box, Text, useApp } from \"ink\";\n\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm\";\nimport { promptConfirm } from \"../components/common/prompt-confirm.js\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { directoryExists, fileExists, listDirectories, remove } from \"../utils/fs\";\nimport { listAgentMdFiles } from \"../lib/agents\";\nimport { claudePluginUninstallBestEffort, isClaudeCLIAvailable } from \"../utils/exec\";\nimport {\n listPluginNames,\n getProjectPluginsDir,\n buildMarketplacePluginRef,\n parseMarketplacePluginRef,\n toClaudePluginScope,\n} from \"../lib/plugins/index\";\nimport { readForkedFromMetadata } from \"../lib/skills/index\";\nimport { isHomeDirectory, resolveInstallPaths } from \"../lib/installation/index\";\nimport { lazyGateDeps, mutateGlobal, propagateGlobalRemoval } from \"../lib/config-gate/index.js\";\nimport { loadSkillsMatrixFromSource } from \"../lib/loading\";\nimport { loadAgentDefs } from \"../lib/operations\";\nimport { ConfigLoadError, loadProjectConfigFromDir } from \"../lib/configuration/project-config\";\nimport {\n CLAUDE_DIR,\n CLAUDE_SRC_DIR,\n CLI_COLORS,\n DEFAULT_BRANDING,\n EJECT_SOURCE,\n STANDARD_FILES,\n} from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport {\n SUCCESS_MESSAGES,\n INFO_MESSAGES,\n registeredProjectsUpdated,\n registeredProjectUpdateSkipped,\n registeredProjectsUpdateFailed,\n} from \"../utils/messages\";\nimport type { AgentDefinition, AgentName, MergedSkillsMatrix, ProjectConfig } from \"../types/index\";\n\n/** A grouped section of the uninstall removal plan (header label + item lines). */\ntype RemovalPlanSection = {\n label: string;\n items: string[];\n};\n\n/**\n * Pure builder for the uninstall removal plan. The single source of the section\n * labels and item strings shared by printRemovalPlan (plain text) and the\n * UninstallConfirm Ink component — each renderer only adds its own\n * indentation/styling, so the emitted strings stay byte-identical.\n */\nfunction buildRemovalPlan(target: UninstallTarget): RemovalPlanSection[] {\n const sections: RemovalPlanSection[] = [];\n\n if (target.hasPlugins) {\n sections.push({ label: \"Plugins:\", items: [...target.cliPluginNames] });\n }\n\n if (target.hasLocalSkills || target.hasLocalAgents) {\n const items: string[] = [];\n if (target.hasLocalSkills) items.push(`${target.skillsDir}/ (matching sources)`);\n if (target.hasLocalAgents) items.push(`${target.agentsDir}/ (CLI-compiled)`);\n sections.push({ label: \"CLI-managed files:\", items });\n }\n\n // The CLI config manifest (config.ts + config-types.ts) is always removed.\n if (target.hasClaudeSrcConfig || target.hasClaudeSrcConfigTypes) {\n const items: string[] = [];\n if (target.hasClaudeSrcConfig) {\n items.push(`${target.claudeSrcDir}/${STANDARD_FILES.CONFIG_TS}`);\n }\n if (target.hasClaudeSrcConfigTypes) {\n items.push(`${target.claudeSrcDir}/${STANDARD_FILES.CONFIG_TYPES_TS}`);\n }\n sections.push({ label: \"Config:\", items });\n }\n\n return sections;\n}\n\ntype UninstallConfirmProps = {\n target: UninstallTarget;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UninstallConfirm: React.FC<UninstallConfirmProps> = ({ target, onConfirm, onCancel }) => {\n const { exit } = useApp();\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>The following will be removed:</Text>\n <Text> </Text>\n\n {buildRemovalPlan(target).map((section) => (\n <Box key={section.label} flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> {section.label}</Text>\n {section.items.map((item) => (\n <Text key={item} dimColor>\n {\" \"}\n {item}\n </Text>\n ))}\n </Box>\n ))}\n\n <Text> </Text>\n <Confirm\n message=\"Are you sure you want to uninstall?\"\n onConfirm={() => {\n onConfirm();\n exit();\n }}\n onCancel={() => {\n onCancel();\n exit();\n }}\n defaultValue={false}\n />\n </Box>\n );\n};\n\nexport default class Uninstall extends BaseCommand {\n static summary = `Remove ${DEFAULT_BRANDING.NAME} from this project`;\n\n static description = `Uninstall ${DEFAULT_BRANDING.NAME} from this project. Removes CLI-managed skills (matched by source), compiled agents, plugins, and the .claude-src/ config manifest (config.ts + config-types.ts). User-created content is preserved.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Uninstall);\n const projectDir = process.cwd();\n\n this.printHeader();\n\n const target = await detectUninstallTarget(projectDir, (reason) =>\n this.warn(\n `Could not read the project config — plugins and compiled agents it lists may be left behind: ${reason}`,\n ),\n );\n if (!hasAnythingToRemove(target)) {\n this.reportNothingToUninstall();\n return;\n }\n\n const confirmed = flags.yes ? this.printRemovalPlan(target) : await this.confirmRemoval(target);\n if (!confirmed) {\n this.log(\"\");\n this.log(\"Uninstall cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n await this.executeUninstall(target, projectDir);\n this.reportSuccess();\n }\n\n private printHeader(): void {\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Uninstall`);\n this.log(\"\");\n }\n\n private reportNothingToUninstall(): void {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n this.log(INFO_MESSAGES.NOT_INSTALLED);\n this.log(\"\");\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n }\n\n private printRemovalPlan(target: UninstallTarget): true {\n this.log(\"The following will be removed:\");\n this.log(\"\");\n\n for (const section of buildRemovalPlan(target)) {\n this.log(` ${section.label}`);\n for (const item of section.items) {\n this.log(` ${item}`);\n }\n }\n\n this.log(\"\");\n return true;\n }\n\n private async confirmRemoval(target: UninstallTarget): Promise<boolean> {\n const outcome = await promptConfirm(({ onConfirm, onCancel }) => (\n <UninstallConfirm target={target} onConfirm={onConfirm} onCancel={onCancel} />\n ));\n return outcome === \"confirmed\";\n }\n\n private async executeUninstall(target: UninstallTarget, projectDir: string): Promise<void> {\n const isGlobalUninstall = isHomeDirectory(projectDir);\n // Prepared BEFORE any removal: the projects[] registry and the source used\n // to regenerate each project's config-types.ts both live in the global\n // config this uninstall is about to delete.\n const propagation = isGlobalUninstall\n ? await this.prepareGlobalPropagation(target, projectDir)\n : null;\n\n if (target.hasPlugins) {\n this.log(\"Uninstalling plugins...\");\n\n try {\n const pluginResult = await uninstallPlugins(target, projectDir, (name) =>\n this.log(` Uninstalled plugin '${name}'`),\n );\n\n this.logSuccess(\n `Uninstalled ${pluginResult.totalUninstalled} ${pluginResult.totalUninstalled === 1 ? \"plugin\" : \"plugins\"}`,\n );\n } catch (error) {\n this.log(\"Plugin uninstall failed\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n try {\n await this.removeLocalFiles(target);\n } catch (error) {\n this.log(\"Failed to remove local files\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n if (isGlobalUninstall) {\n // The global manifest is gone — prune the inlined global-scoped entries the\n // registered projects still carry so they stop referencing removed content.\n if (propagation) {\n await this.updateRegisteredProjects(propagation);\n }\n return;\n }\n\n // Deregister this project from the global config's tracked projects so future\n // global edits stop propagating back into it. Best-effort by nature: a missing,\n // project-less, or corrupt global config (ConfigLoadError) must never fail the\n // uninstall — warn and move on.\n try {\n // Registration bookkeeping only: nothing inlines the `projects[]` list into a\n // project config, so this loads neither the matrix nor the agent definitions\n // and the uninstall stays offline.\n await mutateGlobal({ kind: \"deregister-project\", projectDir }, lazyGateDeps(projectDir));\n } catch (error) {\n this.warn(`Could not update the global project registry: ${getErrorMessage(error)}`);\n }\n }\n\n /**\n * Loads what updating registered projects needs (global config with its\n * projects[] registry, skills matrix, agent definitions) BEFORE the global\n * .claude-src manifest is deleted — source resolution reads that config.\n * Returns null when nothing is registered or loading fails; a load failure\n * warns and never aborts the uninstall.\n *\n * `skipExtraSources: true` is NOT a divergence from the wizard's full\n * multi-source load: extra-source loading only annotates each skill's\n * `availableSources`/`activeSource` for wizard UI tagging — it never adds\n * skills or categories to the matrix, and the config-types writer never reads\n * those annotations, so the regenerated project types are byte-identical\n * either way (pinned by the skipExtraSources parity test in\n * local-installer.test.ts). Skipping avoids fetching every registered extra\n * source (network on a cold cache, plus unreachable-remote warnings) during\n * an uninstall that must never hang or noise-fail on remote state.\n */\n private async prepareGlobalPropagation(\n target: UninstallTarget,\n projectDir: string,\n ): Promise<GlobalPropagationData | null> {\n const globalConfig = target.config;\n if (!globalConfig?.projects?.length) return null;\n\n try {\n const [sourceResult, agentDefs] = await Promise.all([\n loadSkillsMatrixFromSource({\n projectDir,\n skipExtraSources: true,\n matrixOnly: true,\n }),\n loadAgentDefs({ projectDir }),\n ]);\n return { globalConfig, matrix: sourceResult.matrix, agents: agentDefs.agents };\n } catch (error) {\n this.warn(registeredProjectsUpdateFailed(getErrorMessage(error)));\n return null;\n }\n }\n\n /**\n * Prunes the inlined global-scoped config entries from every registered\n * project and regenerates its config-types.ts. Runs AFTER the global manifest\n * removal so the regenerated project types fall back to the standalone form\n * instead of importing from the deleted global config-types.ts. Best-effort:\n * unreachable projects are warned and skipped, and no failure here may abort\n * the uninstall.\n */\n private async updateRegisteredProjects(propagation: GlobalPropagationData): Promise<void> {\n try {\n const report = await propagateGlobalRemoval(propagation.globalConfig, {\n matrix: propagation.matrix,\n agents: propagation.agents,\n });\n for (const skippedPath of report.propagated.skipped) {\n this.warn(registeredProjectUpdateSkipped(skippedPath));\n }\n if (report.propagated.updated.length === 0) return;\n\n this.logSuccess(registeredProjectsUpdated(report.propagated.updated.length));\n\n // The pruned projects' compiled agents were built from the global rows this\n // uninstall just removed, so the prune owes them a recompile too.\n const { recompiledCount, failedCount, warnings } = report.recompile;\n for (const warning of warnings) {\n this.warn(warning);\n }\n const failureSuffix = failedCount > 0 ? ` (${failedCount} failed)` : \"\";\n this.log(`Recompiled agents in ${recompiledCount} registered projects${failureSuffix}`);\n } catch (error) {\n this.warn(registeredProjectsUpdateFailed(getErrorMessage(error)));\n }\n }\n\n private reportSuccess(): void {\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} has been uninstalled.`);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);\n this.log(\"\");\n }\n\n private async removeLocalFiles(target: UninstallTarget): Promise<void> {\n const skillResult = await removeMatchingSkills(\n target,\n (dirName) => this.log(` Uninstalled skill '${dirName}'`),\n (dirName) => this.warn(`Skipping '${dirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`),\n );\n\n if (skillResult.removedCount > 0) {\n this.logSuccess(\n `Removed ${skillResult.removedCount} CLI-installed ${skillResult.removedCount === 1 ? \"skill\" : \"skills\"}`,\n );\n }\n\n const agentResult = await removeMatchingAgents(target, (agentName) =>\n this.log(` Uninstalled agent '${agentName}'`),\n );\n\n if (agentResult.removedCount > 0) {\n this.logSuccess(\n `Removed ${agentResult.removedCount} compiled ${agentResult.removedCount === 1 ? \"agent\" : \"agents\"}`,\n );\n }\n\n const cleanup = await cleanupEmptyDirs(target);\n\n if (cleanup.claudeSrcDirRemoved) {\n this.logSuccess(`Removed ${CLAUDE_SRC_DIR}/`);\n } else if (cleanup.claudeSrcManifestRemoved) {\n this.logSuccess(`Removed CLI config from ${CLAUDE_SRC_DIR}/`);\n }\n\n if (cleanup.claudeDirRemoved) {\n this.logSuccess(`Removed ${CLAUDE_DIR}/`);\n } else if (cleanup.claudeDirKept) {\n this.log(`Kept ${CLAUDE_DIR}/ (contains user content)`);\n }\n }\n}\n\n/** @internal Exported for testing */\nexport type UninstallTarget = {\n hasPlugins: boolean;\n pluginNames: string[];\n /** Plugin names filtered to only those installed by this CLI (matched against config skills) */\n cliPluginNames: string[];\n hasLocalSkills: boolean;\n hasLocalAgents: boolean;\n hasClaudeDir: boolean;\n /** Whether .claude-src/config.ts exists (the CLI config manifest). */\n hasClaudeSrcConfig: boolean;\n /** Whether .claude-src/config-types.ts exists (companion to config.ts). */\n hasClaudeSrcConfigTypes: boolean;\n pluginsDir: string;\n skillsDir: string;\n agentsDir: string;\n claudeDir: string;\n claudeSrcDir: string;\n /** Resolved project source config from .claude-src/config.ts */\n config: ProjectConfig | null;\n /** Agent names from the generated config (e.g., [\"web-developer\"]) */\n configuredAgents: AgentName[];\n};\n\n/**\n * Everything a global uninstall needs to update the registered projects after\n * the global manifest is removed — captured before removal because it is\n * sourced from the config being deleted.\n */\ntype GlobalPropagationData = {\n globalConfig: ProjectConfig;\n matrix: MergedSkillsMatrix;\n agents: Record<AgentName, AgentDefinition>;\n};\n\ntype SkillRemovalResult = {\n removedCount: number;\n skippedCount: number;\n removedNames: string[];\n skippedNames: string[];\n /** Whether the skills directory was cleaned up (empty after removal) */\n dirCleaned: boolean;\n};\n\ntype AgentRemovalResult = {\n removedCount: number;\n removedNames: string[];\n /** Whether the agents directory was cleaned up (empty after removal) */\n dirCleaned: boolean;\n};\n\ntype UninstallPluginsResult = {\n uninstalledNames: string[];\n totalUninstalled: number;\n};\n\ntype CleanupResult = {\n claudeDirRemoved: boolean;\n /** Whether config.ts/config-types.ts were removed from .claude-src/ */\n claudeSrcManifestRemoved: boolean;\n /** Whether the emptied .claude-src/ directory itself was removed */\n claudeSrcDirRemoved: boolean;\n /** Whether .claude/ still exists with user content after cleanup */\n claudeDirKept: boolean;\n};\n\nfunction hasAnythingToRemove(target: UninstallTarget): boolean {\n return (\n target.hasPlugins ||\n target.hasLocalSkills ||\n target.hasLocalAgents ||\n target.hasClaudeSrcConfig ||\n target.hasClaudeSrcConfigTypes\n );\n}\n\nfunction collectConfiguredAgents(config: Partial<ProjectConfig> | null): AgentName[] {\n if (!config?.agents) return [];\n return config.agents.map((a) => a.name);\n}\n\n/** @internal Exported for testing */\nexport function getCliInstalledPluginKeys(config: Partial<ProjectConfig> | null): Set<string> {\n if (!config?.skills) return new Set();\n const { marketplace } = config;\n return new Set(\n config.skills.flatMap((skill) => [\n // Primary key: skill.id@skill.source\n buildMarketplacePluginRef(skill.id, skill.source),\n // Marketplace variant for plugins installed via marketplace where\n // skill.source may differ (e.g., \"eject\" vs the marketplace name)\n ...(marketplace && skill.source !== marketplace && skill.source !== EJECT_SOURCE\n ? [buildMarketplacePluginRef(skill.id, marketplace)]\n : []),\n ]),\n );\n}\n\n/**\n * Loads the config that drives the removal plan. A config file that exists but\n * cannot be parsed (`ConfigLoadError`) is reported through `onLoadFailed` and\n * then treated exactly like a missing one — an unreadable config is precisely\n * when a user needs to uninstall, so it must never fail the run. Same posture as\n * the `deregisterProjectPath` call site. Only the plan degrades: the plugins and\n * compiled agents the config named can no longer be identified, while file\n * removal proceeds. Any other failure is a real fault and still propagates.\n */\nasync function loadUninstallConfig(\n projectDir: string,\n onLoadFailed: (reason: string) => void,\n): Promise<ProjectConfig | null> {\n try {\n const result = await loadProjectConfigFromDir(projectDir);\n return result?.config ?? null;\n } catch (error) {\n if (!(error instanceof ConfigLoadError)) throw error;\n onLoadFailed(getErrorMessage(error));\n return null;\n }\n}\n\n/**\n * Detects what's installed in a project directory for uninstallation.\n *\n * Checks for plugins, local skills, agents, config directories, and\n * resolves which plugins were installed by this CLI.\n */\nasync function detectUninstallTarget(\n projectDir: string,\n onConfigLoadFailed: (reason: string) => void,\n): Promise<UninstallTarget> {\n const pluginsDir = getProjectPluginsDir(projectDir);\n const { skillsDir, agentsDir } = resolveInstallPaths(projectDir);\n const claudeDir = path.join(projectDir, CLAUDE_DIR);\n const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);\n\n const claudeSrcConfigPath = path.join(claudeSrcDir, STANDARD_FILES.CONFIG_TS);\n const claudeSrcConfigTypesPath = path.join(claudeSrcDir, STANDARD_FILES.CONFIG_TYPES_TS);\n\n const [\n hasLocalSkills,\n hasLocalAgents,\n hasClaudeDir,\n hasClaudeSrcConfig,\n hasClaudeSrcConfigTypes,\n config,\n ] = await Promise.all([\n directoryExists(skillsDir),\n directoryExists(agentsDir),\n directoryExists(claudeDir),\n fileExists(claudeSrcConfigPath),\n fileExists(claudeSrcConfigTypesPath),\n loadUninstallConfig(projectDir, onConfigLoadFailed),\n ]);\n\n let pluginNames: string[] = [];\n try {\n pluginNames = await listPluginNames(projectDir);\n } catch {\n // Best-effort: plugin detection may fail\n }\n\n const activeConfig = config\n ? {\n ...config,\n skills: config.skills?.filter((s) => !s.excluded),\n agents: config.agents?.filter((a) => !a.excluded),\n }\n : null;\n const configuredAgents = collectConfiguredAgents(activeConfig);\n const cliInstalledKeys = getCliInstalledPluginKeys(activeConfig);\n const cliPluginNames = pluginNames.filter((name) => cliInstalledKeys.has(name));\n\n return {\n hasPlugins: cliPluginNames.length > 0,\n pluginNames,\n cliPluginNames,\n hasLocalSkills,\n hasLocalAgents,\n hasClaudeDir,\n hasClaudeSrcConfig,\n hasClaudeSrcConfigTypes,\n pluginsDir,\n skillsDir,\n agentsDir,\n claudeDir,\n claudeSrcDir,\n config,\n configuredAgents,\n };\n}\n\nfunction shouldRemoveSkill(forkedFrom: { source?: string } | null): boolean {\n return forkedFrom !== null;\n}\n\nasync function removeMatchingSkills(\n target: Pick<UninstallTarget, \"hasLocalSkills\" | \"skillsDir\">,\n onRemoved?: (dirName: string) => void,\n onSkipped?: (dirName: string) => void,\n): Promise<SkillRemovalResult> {\n if (!target.hasLocalSkills) {\n return {\n removedCount: 0,\n skippedCount: 0,\n removedNames: [],\n skippedNames: [],\n dirCleaned: false,\n };\n }\n\n const classified = await classifySkillDirs(target.skillsDir);\n const removedNames = await removeClassifiedSkills(\n classified.toRemove,\n target.skillsDir,\n onRemoved,\n );\n classified.toSkip.forEach((name) => onSkipped?.(name));\n const dirCleaned = await cleanupSkillsDir(target.skillsDir, classified.toSkip.length === 0);\n\n return {\n removedCount: removedNames.length,\n skippedCount: classified.toSkip.length,\n removedNames,\n skippedNames: classified.toSkip,\n dirCleaned,\n };\n}\n\nasync function classifySkillDirs(\n skillsDir: string,\n): Promise<{ toRemove: string[]; toSkip: string[] }> {\n const dirNames = await listDirectories(skillsDir);\n const entries = await Promise.all(\n dirNames.map(async (name) => ({\n name,\n forkedFrom: await readForkedFromMetadata(path.join(skillsDir, name)),\n })),\n );\n const [removable, skippable] = partition(entries, (entry) => shouldRemoveSkill(entry.forkedFrom));\n return { toRemove: removable.map((e) => e.name), toSkip: skippable.map((e) => e.name) };\n}\n\nasync function removeClassifiedSkills(\n names: string[],\n skillsDir: string,\n onRemoved?: (name: string) => void,\n): Promise<string[]> {\n for (const name of names) {\n await remove(path.join(skillsDir, name));\n onRemoved?.(name);\n }\n return names;\n}\n\nasync function cleanupSkillsDir(dir: string, allRemoved: boolean): Promise<boolean> {\n if (!allRemoved) return false;\n return removeDirIfEmpty(dir);\n}\n\n/** Removes `dir` when it exists and is empty; true when removed. */\nasync function removeDirIfEmpty(dir: string): Promise<boolean> {\n if (!(await directoryExists(dir))) return false;\n if (!(await isDirectoryEmpty(dir))) return false;\n await remove(dir);\n return true;\n}\n\n/**\n * Removes compiled agent .md files that are listed in the project config.\n *\n * A file is removed only when its basename matches a configured agent\n * (config.agents); agents absent from config are preserved. Cleans up the\n * agents directory if empty after removal.\n *\n * @param onRemoved - Called for each removed agent name (for logging)\n */\nasync function removeMatchingAgents(\n target: Pick<UninstallTarget, \"hasLocalAgents\" | \"agentsDir\" | \"configuredAgents\">,\n onRemoved?: (agentName: string) => void,\n): Promise<AgentRemovalResult> {\n if (!target.hasLocalAgents) {\n return { removedCount: 0, removedNames: [], dirCleaned: false };\n }\n\n if (target.configuredAgents.length === 0) {\n return { removedCount: 0, removedNames: [], dirCleaned: false };\n }\n\n const agentFiles = await listAgentFiles(target.agentsDir);\n const removedNames = agentFiles\n .map((agentFile) => agentFile.replace(/\\.md$/, \"\"))\n // Array<AgentName>.includes rejects a plain string; widen the configured\n // list to readonly string[] so the on-disk basename can be tested for\n // membership in config.agents.\n .filter((agentName) => (target.configuredAgents as readonly string[]).includes(agentName));\n\n for (const agentName of removedNames) {\n await remove(path.join(target.agentsDir, `${agentName}.md`));\n onRemoved?.(agentName);\n }\n\n const dirCleaned = await removeDirIfEmpty(target.agentsDir);\n\n return {\n removedCount: removedNames.length,\n removedNames,\n dirCleaned,\n };\n}\n\n/**\n * Uninstalls CLI-managed plugins by removing them from the Claude CLI\n * and deleting their local directories.\n *\n * Derives scope from per-skill config when available; falls back to project-level.\n *\n * @param onUninstalled - Called for each successfully uninstalled plugin name (for logging)\n * @internal Exported for testing\n */\nexport async function uninstallPlugins(\n target: Pick<UninstallTarget, \"hasPlugins\" | \"cliPluginNames\" | \"pluginsDir\" | \"config\">,\n projectDir: string,\n onUninstalled?: (pluginName: string) => void,\n): Promise<UninstallPluginsResult> {\n if (!target.hasPlugins) {\n return { uninstalledNames: [], totalUninstalled: 0 };\n }\n\n const cliAvailable = await isClaudeCLIAvailable();\n\n for (const pluginName of target.cliPluginNames) {\n if (cliAvailable) {\n // Derive primary scope from per-skill config; shared helper tries both scopes\n // to handle re-scoped plugins where the registry entry may be under the\n // original scope rather than the currently-configured one.\n const skillId = parseMarketplacePluginRef(pluginName);\n const skillConfig = target.config?.skills?.find((s) => s.id === skillId);\n const primaryScope = toClaudePluginScope(skillConfig?.scope);\n await claudePluginUninstallBestEffort(pluginName, primaryScope, projectDir);\n }\n\n const pluginPath = path.join(target.pluginsDir, pluginName);\n await remove(pluginPath);\n onUninstalled?.(pluginName);\n }\n\n // Every iteration either completes or throws (aborting the whole uninstall),\n // so reaching this return means every CLI-managed plugin was removed.\n return {\n uninstalledNames: target.cliPluginNames,\n totalUninstalled: target.cliPluginNames.length,\n };\n}\n\n/**\n * Removes the CLI config manifest (config.ts + config-types.ts) from .claude-src/,\n * then the .claude-src/ directory itself when it has nothing else left. User-owned\n * content in .claude-src/ (e.g. ejected templates) keeps the directory alive.\n */\nasync function removeConfigManifest(\n target: Pick<UninstallTarget, \"claudeSrcDir\" | \"hasClaudeSrcConfig\" | \"hasClaudeSrcConfigTypes\">,\n): Promise<{ manifestRemoved: boolean; dirRemoved: boolean }> {\n let manifestRemoved = false;\n\n if (target.hasClaudeSrcConfig) {\n await remove(path.join(target.claudeSrcDir, STANDARD_FILES.CONFIG_TS));\n manifestRemoved = true;\n }\n if (target.hasClaudeSrcConfigTypes) {\n await remove(path.join(target.claudeSrcDir, STANDARD_FILES.CONFIG_TYPES_TS));\n manifestRemoved = true;\n }\n\n const dirRemoved = manifestRemoved && (await removeDirIfEmpty(target.claudeSrcDir));\n return { manifestRemoved, dirRemoved };\n}\n\n/**\n * Removes the CLI config manifest and cleans up empty .claude/ and .claude-src/\n * directories after uninstall.\n *\n * The config manifest is always removed. The .claude-src/ and .claude/ directories\n * are removed only when they are empty after their CLI-managed contents are gone.\n */\nasync function cleanupEmptyDirs(\n target: Pick<\n UninstallTarget,\n \"hasClaudeDir\" | \"claudeDir\" | \"claudeSrcDir\" | \"hasClaudeSrcConfig\" | \"hasClaudeSrcConfigTypes\"\n >,\n): Promise<CleanupResult> {\n const manifest = await removeConfigManifest(target);\n\n const claudeDirRemoved = target.hasClaudeDir && (await removeDirIfEmpty(target.claudeDir));\n // Nothing else removes .claude itself, so \"kept\" is exactly \"present but not removed\".\n const claudeDirKept =\n !claudeDirRemoved && target.hasClaudeDir && (await directoryExists(target.claudeDir));\n\n return {\n claudeDirRemoved,\n claudeSrcManifestRemoved: manifest.manifestRemoved,\n claudeSrcDirRemoved: manifest.dirRemoved,\n claudeDirKept,\n };\n}\n\nasync function isDirectoryEmpty(dirPath: string): Promise<boolean> {\n try {\n const allEntries = await readdir(dirPath);\n return allEntries.length === 0;\n } catch {\n return true;\n }\n}\n\nasync function listAgentFiles(agentsDir: string): Promise<string[]> {\n try {\n return await listAgentMdFiles(agentsDir);\n } catch {\n return [];\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA,SAAS,iBAAiB;AAC1B,OAAO,UAAU;AACjB,SAAS,eAAe;AAExB,SAAS,aAAa;AACtB,SAAS,KAAK,MAAM,cAAc;AA4F5B,cAKI,YALJ;AAxCN,SAAS,iBAAiB,QAA+C;AACvE,QAAM,WAAiC,CAAC;AAExC,MAAI,OAAO,YAAY;AACrB,aAAS,KAAK,EAAE,OAAO,YAAY,OAAO,CAAC,GAAG,OAAO,cAAc,EAAE,CAAC;AAAA,EACxE;AAEA,MAAI,OAAO,kBAAkB,OAAO,gBAAgB;AAClD,UAAM,QAAkB,CAAC;AACzB,QAAI,OAAO,eAAgB,OAAM,KAAK,GAAG,OAAO,SAAS,sBAAsB;AAC/E,QAAI,OAAO,eAAgB,OAAM,KAAK,GAAG,OAAO,SAAS,kBAAkB;AAC3E,aAAS,KAAK,EAAE,OAAO,sBAAsB,MAAM,CAAC;AAAA,EACtD;AAGA,MAAI,OAAO,sBAAsB,OAAO,yBAAyB;AAC/D,UAAM,QAAkB,CAAC;AACzB,QAAI,OAAO,oBAAoB;AAC7B,YAAM,KAAK,GAAG,OAAO,YAAY,IAAI,eAAe,SAAS,EAAE;AAAA,IACjE;AACA,QAAI,OAAO,yBAAyB;AAClC,YAAM,KAAK,GAAG,OAAO,YAAY,IAAI,eAAe,eAAe,EAAE;AAAA,IACvE;AACA,aAAS,KAAK,EAAE,OAAO,WAAW,MAAM,CAAC;AAAA,EAC3C;AAEA,SAAO;AACT;AAQA,IAAM,mBAAoD,CAAC,EAAE,QAAQ,WAAW,SAAS,MAAM;AAC7F,QAAM,EAAE,KAAK,IAAI,OAAO;AAExB,SACE,qBAAC,OAAI,eAAc,UACjB;AAAA,wBAAC,QAAK,MAAI,MAAC,4CAA8B;AAAA,IACzC,oBAAC,QAAK,eAAC;AAAA,IAEN,iBAAiB,MAAM,EAAE,IAAI,CAAC,YAC7B,qBAAC,OAAwB,eAAc,UACrC;AAAA,2BAAC,QAAK,OAAO,WAAW,OAAO;AAAA;AAAA,QAAE,QAAQ;AAAA,SAAM;AAAA,MAC9C,QAAQ,MAAM,IAAI,CAAC,SAClB,qBAAC,QAAgB,UAAQ,MACtB;AAAA;AAAA,QACA;AAAA,WAFQ,IAGX,CACD;AAAA,SAPO,QAAQ,KAQlB,CACD;AAAA,IAED,oBAAC,QAAK,eAAC;AAAA,IACP;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,WAAW,MAAM;AACf,oBAAU;AACV,eAAK;AAAA,QACP;AAAA,QACA,UAAU,MAAM;AACd,mBAAS;AACT,eAAK;AAAA,QACP;AAAA,QACA,cAAc;AAAA;AAAA,IAChB;AAAA,KACF;AAEJ;AAEA,IAAqB,YAArB,MAAqB,mBAAkB,YAAY;AAAA,EACjD,OAAO,UAAU,UAAU,iBAAiB,IAAI;AAAA,EAEhD,OAAO,cAAc,aAAa,iBAAiB,IAAI;AAAA,EAEvD,OAAO,WAAW;AAAA,IAChB;AAAA,IACA;AAAA,EACF;AAAA,EAEA,OAAO,QAAQ;AAAA,IACb,GAAG,YAAY;AAAA,IACf,KAAK,MAAM,QAAQ;AAAA,MACjB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAqB;AACzB,UAAM,EAAE,MAAM,IAAI,MAAM,KAAK,MAAM,UAAS;AAC5C,UAAM,aAAa,QAAQ,IAAI;AAE/B,SAAK,YAAY;AAEjB,UAAM,SAAS,MAAM;AAAA,MAAsB;AAAA,MAAY,CAAC,WACtD,KAAK;AAAA,QACH,qGAAgG,MAAM;AAAA,MACxG;AAAA,IACF;AACA,QAAI,CAAC,oBAAoB,MAAM,GAAG;AAChC,WAAK,yBAAyB;AAC9B;AAAA,IACF;AAEA,UAAM,YAAY,MAAM,MAAM,KAAK,iBAAiB,MAAM,IAAI,MAAM,KAAK,eAAe,MAAM;AAC9F,QAAI,CAAC,WAAW;AACd,WAAK,IAAI,EAAE;AACX,WAAK,IAAI,qBAAqB;AAC9B,WAAK,KAAK,WAAW,SAAS;AAAA,IAChC;AAEA,UAAM,KAAK,iBAAiB,QAAQ,UAAU;AAC9C,SAAK,cAAc;AAAA,EACrB;AAAA,EAEQ,cAAoB;AAC1B,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,GAAG,iBAAiB,IAAI,YAAY;AAC7C,SAAK,IAAI,EAAE;AAAA,EACb;AAAA,EAEQ,2BAAiC;AACvC,SAAK,KAAK,uBAAuB;AACjC,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,cAAc,aAAa;AACpC,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,cAAc,eAAe;AAAA,EACxC;AAAA,EAEQ,iBAAiB,QAA+B;AACtD,SAAK,IAAI,gCAAgC;AACzC,SAAK,IAAI,EAAE;AAEX,eAAW,WAAW,iBAAiB,MAAM,GAAG;AAC9C,WAAK,IAAI,KAAK,QAAQ,KAAK,EAAE;AAC7B,iBAAW,QAAQ,QAAQ,OAAO;AAChC,aAAK,IAAI,OAAO,IAAI,EAAE;AAAA,MACxB;AAAA,IACF;AAEA,SAAK,IAAI,EAAE;AACX,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eAAe,QAA2C;AACtE,UAAM,UAAU,MAAM,cAAc,CAAC,EAAE,WAAW,SAAS,MACzD,oBAAC,oBAAiB,QAAgB,WAAsB,UAAoB,CAC7E;AACD,WAAO,YAAY;AAAA,EACrB;AAAA,EAEA,MAAc,iBAAiB,QAAyB,YAAmC;AACzF,UAAM,oBAAoB,gBAAgB,UAAU;AAIpD,UAAM,cAAc,oBAChB,MAAM,KAAK,yBAAyB,QAAQ,UAAU,IACtD;AAEJ,QAAI,OAAO,YAAY;AACrB,WAAK,IAAI,yBAAyB;AAElC,UAAI;AACF,cAAM,eAAe,MAAM;AAAA,UAAiB;AAAA,UAAQ;AAAA,UAAY,CAAC,SAC/D,KAAK,IAAI,yBAAyB,IAAI,GAAG;AAAA,QAC3C;AAEA,aAAK;AAAA,UACH,eAAe,aAAa,gBAAgB,IAAI,aAAa,qBAAqB,IAAI,WAAW,SAAS;AAAA,QAC5G;AAAA,MACF,SAAS,OAAO;AACd,aAAK,IAAI,yBAAyB;AAClC,aAAK,MAAM,gBAAgB,KAAK,GAAG;AAAA,UACjC,MAAM,WAAW;AAAA,QACnB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI;AACF,YAAM,KAAK,iBAAiB,MAAM;AAAA,IACpC,SAAS,OAAO;AACd,WAAK,IAAI,8BAA8B;AACvC,WAAK,MAAM,gBAAgB,KAAK,GAAG;AAAA,QACjC,MAAM,WAAW;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,QAAI,mBAAmB;AAGrB,UAAI,aAAa;AACf,cAAM,KAAK,yBAAyB,WAAW;AAAA,MACjD;AACA;AAAA,IACF;AAMA,QAAI;AAIF,YAAM,aAAa,EAAE,MAAM,sBAAsB,WAAW,GAAG,aAAa,UAAU,CAAC;AAAA,IACzF,SAAS,OAAO;AACd,WAAK,KAAK,iDAAiD,gBAAgB,KAAK,CAAC,EAAE;AAAA,IACrF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAc,yBACZ,QACA,YACuC;AACvC,UAAM,eAAe,OAAO;AAC5B,QAAI,CAAC,cAAc,UAAU,OAAQ,QAAO;AAE5C,QAAI;AACF,YAAM,CAAC,cAAc,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,QAClD,2BAA2B;AAAA,UACzB;AAAA,UACA,kBAAkB;AAAA,UAClB,YAAY;AAAA,QACd,CAAC;AAAA,QACD,cAAc,EAAE,WAAW,CAAC;AAAA,MAC9B,CAAC;AACD,aAAO,EAAE,cAAc,QAAQ,aAAa,QAAQ,QAAQ,UAAU,OAAO;AAAA,IAC/E,SAAS,OAAO;AACd,WAAK,KAAK,+BAA+B,gBAAgB,KAAK,CAAC,CAAC;AAChE,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,yBAAyB,aAAmD;AACxF,QAAI;AACF,YAAM,SAAS,MAAM,uBAAuB,YAAY,cAAc;AAAA,QACpE,QAAQ,YAAY;AAAA,QACpB,QAAQ,YAAY;AAAA,MACtB,CAAC;AACD,iBAAW,eAAe,OAAO,WAAW,SAAS;AACnD,aAAK,KAAK,+BAA+B,WAAW,CAAC;AAAA,MACvD;AACA,UAAI,OAAO,WAAW,QAAQ,WAAW,EAAG;AAE5C,WAAK,WAAW,0BAA0B,OAAO,WAAW,QAAQ,MAAM,CAAC;AAI3E,YAAM,EAAE,iBAAiB,aAAa,SAAS,IAAI,OAAO;AAC1D,iBAAW,WAAW,UAAU;AAC9B,aAAK,KAAK,OAAO;AAAA,MACnB;AACA,YAAM,gBAAgB,cAAc,IAAI,KAAK,WAAW,aAAa;AACrE,WAAK,IAAI,wBAAwB,eAAe,uBAAuB,aAAa,EAAE;AAAA,IACxF,SAAS,OAAO;AACd,WAAK,KAAK,+BAA+B,gBAAgB,KAAK,CAAC,CAAC;AAAA,IAClE;AAAA,EACF;AAAA,EAEQ,gBAAsB;AAC5B,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,GAAG,iBAAiB,IAAI,wBAAwB;AACzD,SAAK,IAAI,EAAE;AACX,SAAK,WAAW,iBAAiB,kBAAkB;AACnD,SAAK,IAAI,EAAE;AAAA,EACb;AAAA,EAEA,MAAc,iBAAiB,QAAwC;AACrE,UAAM,cAAc,MAAM;AAAA,MACxB;AAAA,MACA,CAAC,YAAY,KAAK,IAAI,wBAAwB,OAAO,GAAG;AAAA,MACxD,CAAC,YAAY,KAAK,KAAK,aAAa,OAAO,qBAAqB,iBAAiB,IAAI,MAAM;AAAA,IAC7F;AAEA,QAAI,YAAY,eAAe,GAAG;AAChC,WAAK;AAAA,QACH,WAAW,YAAY,YAAY,kBAAkB,YAAY,iBAAiB,IAAI,UAAU,QAAQ;AAAA,MAC1G;AAAA,IACF;AAEA,UAAM,cAAc,MAAM;AAAA,MAAqB;AAAA,MAAQ,CAAC,cACtD,KAAK,IAAI,wBAAwB,SAAS,GAAG;AAAA,IAC/C;AAEA,QAAI,YAAY,eAAe,GAAG;AAChC,WAAK;AAAA,QACH,WAAW,YAAY,YAAY,aAAa,YAAY,iBAAiB,IAAI,UAAU,QAAQ;AAAA,MACrG;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,iBAAiB,MAAM;AAE7C,QAAI,QAAQ,qBAAqB;AAC/B,WAAK,WAAW,WAAW,cAAc,GAAG;AAAA,IAC9C,WAAW,QAAQ,0BAA0B;AAC3C,WAAK,WAAW,2BAA2B,cAAc,GAAG;AAAA,IAC9D;AAEA,QAAI,QAAQ,kBAAkB;AAC5B,WAAK,WAAW,WAAW,UAAU,GAAG;AAAA,IAC1C,WAAW,QAAQ,eAAe;AAChC,WAAK,IAAI,QAAQ,UAAU,2BAA2B;AAAA,IACxD;AAAA,EACF;AACF;AAoEA,SAAS,oBAAoB,QAAkC;AAC7D,SACE,OAAO,cACP,OAAO,kBACP,OAAO,kBACP,OAAO,sBACP,OAAO;AAEX;AAEA,SAAS,wBAAwB,QAAoD;AACnF,MAAI,CAAC,QAAQ,OAAQ,QAAO,CAAC;AAC7B,SAAO,OAAO,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AACxC;AAGO,SAAS,0BAA0B,QAAoD;AAC5F,MAAI,CAAC,QAAQ,OAAQ,QAAO,oBAAI,IAAI;AACpC,QAAM,EAAE,YAAY,IAAI;AACxB,SAAO,IAAI;AAAA,IACT,OAAO,OAAO,QAAQ,CAAC,UAAU;AAAA;AAAA,MAE/B,0BAA0B,MAAM,IAAI,MAAM,MAAM;AAAA;AAAA;AAAA,MAGhD,GAAI,eAAe,MAAM,WAAW,eAAe,MAAM,WAAW,eAChE,CAAC,0BAA0B,MAAM,IAAI,WAAW,CAAC,IACjD,CAAC;AAAA,IACP,CAAC;AAAA,EACH;AACF;AAWA,eAAe,oBACb,YACA,cAC+B;AAC/B,MAAI;AACF,UAAM,SAAS,MAAM,yBAAyB,UAAU;AACxD,WAAO,QAAQ,UAAU;AAAA,EAC3B,SAAS,OAAO;AACd,QAAI,EAAE,iBAAiB,iBAAkB,OAAM;AAC/C,iBAAa,gBAAgB,KAAK,CAAC;AACnC,WAAO;AAAA,EACT;AACF;AAQA,eAAe,sBACb,YACA,oBAC0B;AAC1B,QAAM,aAAa,qBAAqB,UAAU;AAClD,QAAM,EAAE,WAAW,UAAU,IAAI,oBAAoB,UAAU;AAC/D,QAAM,YAAY,KAAK,KAAK,YAAY,UAAU;AAClD,QAAM,eAAe,KAAK,KAAK,YAAY,cAAc;AAEzD,QAAM,sBAAsB,KAAK,KAAK,cAAc,eAAe,SAAS;AAC5E,QAAM,2BAA2B,KAAK,KAAK,cAAc,eAAe,eAAe;AAEvF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,MAAM,QAAQ,IAAI;AAAA,IACpB,gBAAgB,SAAS;AAAA,IACzB,gBAAgB,SAAS;AAAA,IACzB,gBAAgB,SAAS;AAAA,IACzB,WAAW,mBAAmB;AAAA,IAC9B,WAAW,wBAAwB;AAAA,IACnC,oBAAoB,YAAY,kBAAkB;AAAA,EACpD,CAAC;AAED,MAAI,cAAwB,CAAC;AAC7B,MAAI;AACF,kBAAc,MAAM,gBAAgB,UAAU;AAAA,EAChD,QAAQ;AAAA,EAER;AAEA,QAAM,eAAe,SACjB;AAAA,IACE,GAAG;AAAA,IACH,QAAQ,OAAO,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ;AAAA,IAChD,QAAQ,OAAO,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ;AAAA,EAClD,IACA;AACJ,QAAM,mBAAmB,wBAAwB,YAAY;AAC7D,QAAM,mBAAmB,0BAA0B,YAAY;AAC/D,QAAM,iBAAiB,YAAY,OAAO,CAAC,SAAS,iBAAiB,IAAI,IAAI,CAAC;AAE9E,SAAO;AAAA,IACL,YAAY,eAAe,SAAS;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,YAAiD;AAC1E,SAAO,eAAe;AACxB;AAEA,eAAe,qBACb,QACA,WACA,WAC6B;AAC7B,MAAI,CAAC,OAAO,gBAAgB;AAC1B,WAAO;AAAA,MACL,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc,CAAC;AAAA,MACf,cAAc,CAAC;AAAA,MACf,YAAY;AAAA,IACd;AAAA,EACF;AAEA,QAAM,aAAa,MAAM,kBAAkB,OAAO,SAAS;AAC3D,QAAM,eAAe,MAAM;AAAA,IACzB,WAAW;AAAA,IACX,OAAO;AAAA,IACP;AAAA,EACF;AACA,aAAW,OAAO,QAAQ,CAAC,SAAS,YAAY,IAAI,CAAC;AACrD,QAAM,aAAa,MAAM,iBAAiB,OAAO,WAAW,WAAW,OAAO,WAAW,CAAC;AAE1F,SAAO;AAAA,IACL,cAAc,aAAa;AAAA,IAC3B,cAAc,WAAW,OAAO;AAAA,IAChC;AAAA,IACA,cAAc,WAAW;AAAA,IACzB;AAAA,EACF;AACF;AAEA,eAAe,kBACb,WACmD;AACnD,QAAM,WAAW,MAAM,gBAAgB,SAAS;AAChD,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,SAAS,IAAI,OAAO,UAAU;AAAA,MAC5B;AAAA,MACA,YAAY,MAAM,uBAAuB,KAAK,KAAK,WAAW,IAAI,CAAC;AAAA,IACrE,EAAE;AAAA,EACJ;AACA,QAAM,CAAC,WAAW,SAAS,IAAI,UAAU,SAAS,CAAC,UAAU,kBAAkB,MAAM,UAAU,CAAC;AAChG,SAAO,EAAE,UAAU,UAAU,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,QAAQ,UAAU,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;AACxF;AAEA,eAAe,uBACb,OACA,WACA,WACmB;AACnB,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,KAAK,KAAK,WAAW,IAAI,CAAC;AACvC,gBAAY,IAAI;AAAA,EAClB;AACA,SAAO;AACT;AAEA,eAAe,iBAAiB,KAAa,YAAuC;AAClF,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,iBAAiB,GAAG;AAC7B;AAGA,eAAe,iBAAiB,KAA+B;AAC7D,MAAI,CAAE,MAAM,gBAAgB,GAAG,EAAI,QAAO;AAC1C,MAAI,CAAE,MAAM,iBAAiB,GAAG,EAAI,QAAO;AAC3C,QAAM,OAAO,GAAG;AAChB,SAAO;AACT;AAWA,eAAe,qBACb,QACA,WAC6B;AAC7B,MAAI,CAAC,OAAO,gBAAgB;AAC1B,WAAO,EAAE,cAAc,GAAG,cAAc,CAAC,GAAG,YAAY,MAAM;AAAA,EAChE;AAEA,MAAI,OAAO,iBAAiB,WAAW,GAAG;AACxC,WAAO,EAAE,cAAc,GAAG,cAAc,CAAC,GAAG,YAAY,MAAM;AAAA,EAChE;AAEA,QAAM,aAAa,MAAM,eAAe,OAAO,SAAS;AACxD,QAAM,eAAe,WAClB,IAAI,CAAC,cAAc,UAAU,QAAQ,SAAS,EAAE,CAAC,EAIjD,OAAO,CAAC,cAAe,OAAO,iBAAuC,SAAS,SAAS,CAAC;AAE3F,aAAW,aAAa,cAAc;AACpC,UAAM,OAAO,KAAK,KAAK,OAAO,WAAW,GAAG,SAAS,KAAK,CAAC;AAC3D,gBAAY,SAAS;AAAA,EACvB;AAEA,QAAM,aAAa,MAAM,iBAAiB,OAAO,SAAS;AAE1D,SAAO;AAAA,IACL,cAAc,aAAa;AAAA,IAC3B;AAAA,IACA;AAAA,EACF;AACF;AAWA,eAAsB,iBACpB,QACA,YACA,eACiC;AACjC,MAAI,CAAC,OAAO,YAAY;AACtB,WAAO,EAAE,kBAAkB,CAAC,GAAG,kBAAkB,EAAE;AAAA,EACrD;AAEA,QAAM,eAAe,MAAM,qBAAqB;AAEhD,aAAW,cAAc,OAAO,gBAAgB;AAC9C,QAAI,cAAc;AAIhB,YAAM,UAAU,0BAA0B,UAAU;AACpD,YAAM,cAAc,OAAO,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO;AACvE,YAAM,eAAe,oBAAoB,aAAa,KAAK;AAC3D,YAAM,gCAAgC,YAAY,cAAc,UAAU;AAAA,IAC5E;AAEA,UAAM,aAAa,KAAK,KAAK,OAAO,YAAY,UAAU;AAC1D,UAAM,OAAO,UAAU;AACvB,oBAAgB,UAAU;AAAA,EAC5B;AAIA,SAAO;AAAA,IACL,kBAAkB,OAAO;AAAA,IACzB,kBAAkB,OAAO,eAAe;AAAA,EAC1C;AACF;AAOA,eAAe,qBACb,QAC4D;AAC5D,MAAI,kBAAkB;AAEtB,MAAI,OAAO,oBAAoB;AAC7B,UAAM,OAAO,KAAK,KAAK,OAAO,cAAc,eAAe,SAAS,CAAC;AACrE,sBAAkB;AAAA,EACpB;AACA,MAAI,OAAO,yBAAyB;AAClC,UAAM,OAAO,KAAK,KAAK,OAAO,cAAc,eAAe,eAAe,CAAC;AAC3E,sBAAkB;AAAA,EACpB;AAEA,QAAM,aAAa,mBAAoB,MAAM,iBAAiB,OAAO,YAAY;AACjF,SAAO,EAAE,iBAAiB,WAAW;AACvC;AASA,eAAe,iBACb,QAIwB;AACxB,QAAM,WAAW,MAAM,qBAAqB,MAAM;AAElD,QAAM,mBAAmB,OAAO,gBAAiB,MAAM,iBAAiB,OAAO,SAAS;AAExF,QAAM,gBACJ,CAAC,oBAAoB,OAAO,gBAAiB,MAAM,gBAAgB,OAAO,SAAS;AAErF,SAAO;AAAA,IACL;AAAA,IACA,0BAA0B,SAAS;AAAA,IACnC,qBAAqB,SAAS;AAAA,IAC9B;AAAA,EACF;AACF;AAEA,eAAe,iBAAiB,SAAmC;AACjE,MAAI;AACF,UAAM,aAAa,MAAM,QAAQ,OAAO;AACxC,WAAO,WAAW,WAAW;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,eAAe,WAAsC;AAClE,MAAI;AACF,WAAO,MAAM,iBAAiB,SAAS;AAAA,EACzC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\nimport { partition } from \"remeda\";\nimport path from \"path\";\nimport { readdir } from \"fs/promises\";\n\nimport { Flags } from \"@oclif/core\";\nimport { Box, Text, useApp } from \"ink\";\n\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm\";\nimport { promptConfirm } from \"../components/common/prompt-confirm.js\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { directoryExists, fileExists, listDirectories, remove } from \"../utils/fs\";\nimport { listAgentMdFiles } from \"../lib/agents\";\nimport { claudePluginUninstallBestEffort, isClaudeCLIAvailable } from \"../utils/exec\";\nimport {\n listPluginNames,\n getProjectPluginsDir,\n buildMarketplacePluginRef,\n parseMarketplacePluginRef,\n toClaudePluginScope,\n} from \"../lib/plugins/index\";\nimport { readForkedFromMetadata } from \"../lib/skills/index\";\nimport { isHomeDirectory, resolveInstallPaths } from \"../lib/installation/index\";\nimport { lazyGateDeps, mutateGlobal, propagateGlobalRemoval } from \"../lib/config-gate/index.js\";\nimport { loadSkillsMatrixFromSource } from \"../lib/loading\";\nimport { loadAgentDefs } from \"../lib/operations\";\nimport { ConfigLoadError, loadProjectConfigFromDir } from \"../lib/configuration/project-config\";\nimport {\n CLAUDE_DIR,\n CLAUDE_SRC_DIR,\n CLI_COLORS,\n DEFAULT_BRANDING,\n EJECT_SOURCE,\n STANDARD_FILES,\n} from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport {\n SUCCESS_MESSAGES,\n INFO_MESSAGES,\n registeredProjectsUpdated,\n registeredProjectUpdateSkipped,\n registeredProjectsUpdateFailed,\n} from \"../utils/messages\";\nimport type { AgentDefinition, AgentName, MergedSkillsMatrix, ProjectConfig } from \"../types/index\";\n\n/** A grouped section of the uninstall removal plan (header label + item lines). */\ntype RemovalPlanSection = {\n label: string;\n items: string[];\n};\n\n/**\n * Pure builder for the uninstall removal plan. The single source of the section\n * labels and item strings shared by printRemovalPlan (plain text) and the\n * UninstallConfirm Ink component — each renderer only adds its own\n * indentation/styling, so the emitted strings stay byte-identical.\n */\nfunction buildRemovalPlan(target: UninstallTarget): RemovalPlanSection[] {\n const sections: RemovalPlanSection[] = [];\n\n if (target.hasPlugins) {\n sections.push({ label: \"Plugins:\", items: [...target.cliPluginNames] });\n }\n\n if (target.hasLocalSkills || target.hasLocalAgents) {\n const items: string[] = [];\n if (target.hasLocalSkills) items.push(`${target.skillsDir}/ (matching sources)`);\n if (target.hasLocalAgents) items.push(`${target.agentsDir}/ (CLI-compiled)`);\n sections.push({ label: \"CLI-managed files:\", items });\n }\n\n // The CLI config manifest (config.ts + config-types.ts) is always removed.\n if (target.hasClaudeSrcConfig || target.hasClaudeSrcConfigTypes) {\n const items: string[] = [];\n if (target.hasClaudeSrcConfig) {\n items.push(`${target.claudeSrcDir}/${STANDARD_FILES.CONFIG_TS}`);\n }\n if (target.hasClaudeSrcConfigTypes) {\n items.push(`${target.claudeSrcDir}/${STANDARD_FILES.CONFIG_TYPES_TS}`);\n }\n sections.push({ label: \"Config:\", items });\n }\n\n return sections;\n}\n\ntype UninstallConfirmProps = {\n target: UninstallTarget;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UninstallConfirm: React.FC<UninstallConfirmProps> = ({ target, onConfirm, onCancel }) => {\n const { exit } = useApp();\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>The following will be removed:</Text>\n <Text> </Text>\n\n {buildRemovalPlan(target).map((section) => (\n <Box key={section.label} flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> {section.label}</Text>\n {section.items.map((item) => (\n <Text key={item} dimColor>\n {\" \"}\n {item}\n </Text>\n ))}\n </Box>\n ))}\n\n <Text> </Text>\n <Confirm\n message=\"Are you sure you want to uninstall?\"\n onConfirm={() => {\n onConfirm();\n exit();\n }}\n onCancel={() => {\n onCancel();\n exit();\n }}\n defaultValue={false}\n />\n </Box>\n );\n};\n\nexport default class Uninstall extends BaseCommand {\n static summary = `Remove ${DEFAULT_BRANDING.NAME} from this project`;\n\n static description = `Uninstall ${DEFAULT_BRANDING.NAME} from this project. Removes CLI-managed skills (matched by source), compiled agents, plugins, and the .claude-src/ config manifest (config.ts + config-types.ts). User-created content is preserved.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Uninstall);\n const projectDir = process.cwd();\n\n this.printHeader();\n\n const target = await detectUninstallTarget(projectDir, (reason) =>\n this.warn(\n `Could not read the project config — plugins and compiled agents it lists may be left behind: ${reason}`,\n ),\n );\n if (!hasAnythingToRemove(target)) {\n this.reportNothingToUninstall();\n return;\n }\n\n const confirmed = flags.yes ? this.printRemovalPlan(target) : await this.confirmRemoval(target);\n if (!confirmed) {\n this.log(\"\");\n this.log(\"Uninstall cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n await this.executeUninstall(target, projectDir);\n this.reportSuccess();\n }\n\n private printHeader(): void {\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Uninstall`);\n this.log(\"\");\n }\n\n private reportNothingToUninstall(): void {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n this.log(INFO_MESSAGES.NOT_INSTALLED);\n this.log(\"\");\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n }\n\n private printRemovalPlan(target: UninstallTarget): true {\n this.log(\"The following will be removed:\");\n this.log(\"\");\n\n for (const section of buildRemovalPlan(target)) {\n this.log(` ${section.label}`);\n for (const item of section.items) {\n this.log(` ${item}`);\n }\n }\n\n this.log(\"\");\n return true;\n }\n\n private async confirmRemoval(target: UninstallTarget): Promise<boolean> {\n const outcome = await promptConfirm(({ onConfirm, onCancel }) => (\n <UninstallConfirm target={target} onConfirm={onConfirm} onCancel={onCancel} />\n ));\n return outcome === \"confirmed\";\n }\n\n private async executeUninstall(target: UninstallTarget, projectDir: string): Promise<void> {\n const isGlobalUninstall = isHomeDirectory(projectDir);\n // Prepared BEFORE any removal: the projects[] registry and the source used\n // to regenerate each project's config-types.ts both live in the global\n // config this uninstall is about to delete.\n const propagation = isGlobalUninstall\n ? await this.prepareGlobalPropagation(target, projectDir)\n : null;\n\n if (target.hasPlugins) {\n this.log(\"Uninstalling plugins...\");\n\n try {\n const pluginResult = await uninstallPlugins(target, projectDir, (name) =>\n this.log(` Uninstalled plugin '${name}'`),\n );\n\n this.logSuccess(\n `Uninstalled ${pluginResult.totalUninstalled} ${pluginResult.totalUninstalled === 1 ? \"plugin\" : \"plugins\"}`,\n );\n } catch (error) {\n this.log(\"Plugin uninstall failed\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n try {\n await this.removeLocalFiles(target);\n } catch (error) {\n this.log(\"Failed to remove local files\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n if (isGlobalUninstall) {\n // The global manifest is gone — prune the inlined global-scoped entries the\n // registered projects still carry so they stop referencing removed content.\n if (propagation) {\n await this.updateRegisteredProjects(propagation);\n }\n return;\n }\n\n // Deregister this project from the global config's tracked projects so future\n // global edits stop propagating back into it. Best-effort by nature: a missing,\n // project-less, or corrupt global config (ConfigLoadError) must never fail the\n // uninstall — warn and move on.\n try {\n // Registration bookkeeping only: nothing inlines the `projects[]` list into a\n // project config, so this loads neither the matrix nor the agent definitions\n // and the uninstall stays offline.\n await mutateGlobal({ kind: \"deregister-project\", projectDir }, lazyGateDeps(projectDir));\n } catch (error) {\n this.warn(`Could not update the global project registry: ${getErrorMessage(error)}`);\n }\n }\n\n /**\n * Loads what updating registered projects needs (global config with its\n * projects[] registry, skills matrix, agent definitions) BEFORE the global\n * .claude-src manifest is deleted — source resolution reads that config.\n * Returns null when nothing is registered or loading fails; a load failure\n * warns and never aborts the uninstall.\n *\n * `skipExtraSources: true` is NOT a divergence from the wizard's full\n * multi-source load: extra-source loading only annotates each skill's\n * `availableSources`/`activeSource` for wizard UI tagging — it never adds\n * skills or categories to the matrix, and the config-types writer never reads\n * those annotations, so the regenerated project types are byte-identical\n * either way (pinned by the skipExtraSources parity test in\n * local-installer.test.ts). Skipping avoids fetching every registered extra\n * source (network on a cold cache, plus unreachable-remote warnings) during\n * an uninstall that must never hang or noise-fail on remote state.\n */\n private async prepareGlobalPropagation(\n target: UninstallTarget,\n projectDir: string,\n ): Promise<GlobalPropagationData | null> {\n const globalConfig = target.config;\n if (!globalConfig?.projects?.length) return null;\n\n try {\n const [sourceResult, agentDefs] = await Promise.all([\n loadSkillsMatrixFromSource({\n projectDir,\n skipExtraSources: true,\n matrixOnly: true,\n }),\n loadAgentDefs({ projectDir }),\n ]);\n return { globalConfig, matrix: sourceResult.matrix, agents: agentDefs.agents };\n } catch (error) {\n this.warn(registeredProjectsUpdateFailed(getErrorMessage(error)));\n return null;\n }\n }\n\n /**\n * Prunes the inlined global-scoped config entries from every registered\n * project and regenerates its config-types.ts. Runs AFTER the global manifest\n * removal so the regenerated project types fall back to the standalone form\n * instead of importing from the deleted global config-types.ts. Best-effort:\n * unreachable projects are warned and skipped, and no failure here may abort\n * the uninstall.\n */\n private async updateRegisteredProjects(propagation: GlobalPropagationData): Promise<void> {\n try {\n const report = await propagateGlobalRemoval(propagation.globalConfig, {\n matrix: propagation.matrix,\n agents: propagation.agents,\n });\n for (const skippedPath of report.propagated.skipped) {\n this.warn(registeredProjectUpdateSkipped(skippedPath));\n }\n if (report.propagated.updated.length === 0) return;\n\n this.logSuccess(registeredProjectsUpdated(report.propagated.updated.length));\n\n // The pruned projects' compiled agents were built from the global rows this\n // uninstall just removed, so the prune owes them a recompile too.\n const { recompiledCount, failedCount, warnings } = report.recompile;\n for (const warning of warnings) {\n this.warn(warning);\n }\n const failureSuffix = failedCount > 0 ? ` (${failedCount} failed)` : \"\";\n this.log(`Recompiled agents in ${recompiledCount} registered projects${failureSuffix}`);\n } catch (error) {\n this.warn(registeredProjectsUpdateFailed(getErrorMessage(error)));\n }\n }\n\n private reportSuccess(): void {\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} has been uninstalled.`);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);\n this.log(\"\");\n }\n\n private async removeLocalFiles(target: UninstallTarget): Promise<void> {\n const skillResult = await removeMatchingSkills(\n target,\n (dirName) => this.log(` Uninstalled skill '${dirName}'`),\n (dirName) => this.warn(`Skipping '${dirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`),\n );\n\n if (skillResult.removedCount > 0) {\n this.logSuccess(\n `Removed ${skillResult.removedCount} CLI-installed ${skillResult.removedCount === 1 ? \"skill\" : \"skills\"}`,\n );\n }\n\n const agentResult = await removeMatchingAgents(target, (agentName) =>\n this.log(` Uninstalled agent '${agentName}'`),\n );\n\n if (agentResult.removedCount > 0) {\n this.logSuccess(\n `Removed ${agentResult.removedCount} compiled ${agentResult.removedCount === 1 ? \"agent\" : \"agents\"}`,\n );\n }\n\n const cleanup = await cleanupEmptyDirs(target);\n\n if (cleanup.claudeSrcDirRemoved) {\n this.logSuccess(`Removed ${CLAUDE_SRC_DIR}/`);\n } else if (cleanup.claudeSrcManifestRemoved) {\n this.logSuccess(`Removed CLI config from ${CLAUDE_SRC_DIR}/`);\n }\n\n if (cleanup.claudeDirRemoved) {\n this.logSuccess(`Removed ${CLAUDE_DIR}/`);\n } else if (cleanup.claudeDirKept) {\n this.log(`Kept ${CLAUDE_DIR}/ (contains user content)`);\n }\n }\n}\n\n/** @internal Exported for testing */\nexport type UninstallTarget = {\n hasPlugins: boolean;\n pluginNames: string[];\n /** Plugin names filtered to only those installed by this CLI (matched against config skills) */\n cliPluginNames: string[];\n hasLocalSkills: boolean;\n hasLocalAgents: boolean;\n hasClaudeDir: boolean;\n /** Whether .claude-src/config.ts exists (the CLI config manifest). */\n hasClaudeSrcConfig: boolean;\n /** Whether .claude-src/config-types.ts exists (companion to config.ts). */\n hasClaudeSrcConfigTypes: boolean;\n pluginsDir: string;\n skillsDir: string;\n agentsDir: string;\n claudeDir: string;\n claudeSrcDir: string;\n /** Resolved project source config from .claude-src/config.ts */\n config: ProjectConfig | null;\n /** Agent names from the generated config (e.g., [\"web-developer\"]) */\n configuredAgents: AgentName[];\n};\n\n/**\n * Everything a global uninstall needs to update the registered projects after\n * the global manifest is removed — captured before removal because it is\n * sourced from the config being deleted.\n */\ntype GlobalPropagationData = {\n globalConfig: ProjectConfig;\n matrix: MergedSkillsMatrix;\n agents: Record<AgentName, AgentDefinition>;\n};\n\ntype SkillRemovalResult = {\n removedCount: number;\n skippedCount: number;\n removedNames: string[];\n skippedNames: string[];\n /** Whether the skills directory was cleaned up (empty after removal) */\n dirCleaned: boolean;\n};\n\ntype AgentRemovalResult = {\n removedCount: number;\n removedNames: string[];\n /** Whether the agents directory was cleaned up (empty after removal) */\n dirCleaned: boolean;\n};\n\ntype UninstallPluginsResult = {\n uninstalledNames: string[];\n totalUninstalled: number;\n};\n\ntype CleanupResult = {\n claudeDirRemoved: boolean;\n /** Whether config.ts/config-types.ts were removed from .claude-src/ */\n claudeSrcManifestRemoved: boolean;\n /** Whether the emptied .claude-src/ directory itself was removed */\n claudeSrcDirRemoved: boolean;\n /** Whether .claude/ still exists with user content after cleanup */\n claudeDirKept: boolean;\n};\n\nfunction hasAnythingToRemove(target: UninstallTarget): boolean {\n return (\n target.hasPlugins ||\n target.hasLocalSkills ||\n target.hasLocalAgents ||\n target.hasClaudeSrcConfig ||\n target.hasClaudeSrcConfigTypes\n );\n}\n\nfunction collectConfiguredAgents(config: Partial<ProjectConfig> | null): AgentName[] {\n if (!config?.agents) return [];\n return config.agents.map((a) => a.name);\n}\n\n/** @internal Exported for testing */\nexport function getCliInstalledPluginKeys(config: Partial<ProjectConfig> | null): Set<string> {\n if (!config?.skills) return new Set();\n const { marketplace } = config;\n return new Set(\n config.skills.flatMap((skill) => [\n // Primary key: skill.id@skill.source\n buildMarketplacePluginRef(skill.id, skill.source),\n // Marketplace variant for plugins installed via marketplace where\n // skill.source may differ (e.g., \"eject\" vs the marketplace name)\n ...(marketplace && skill.source !== marketplace && skill.source !== EJECT_SOURCE\n ? [buildMarketplacePluginRef(skill.id, marketplace)]\n : []),\n ]),\n );\n}\n\n/**\n * Loads the config that drives the removal plan. A config file that exists but\n * cannot be parsed (`ConfigLoadError`) is reported through `onLoadFailed` and\n * then treated exactly like a missing one — an unreadable config is precisely\n * when a user needs to uninstall, so it must never fail the run. Same posture as\n * the `deregisterProjectPath` call site. Only the plan degrades: the plugins and\n * compiled agents the config named can no longer be identified, while file\n * removal proceeds. Any other failure is a real fault and still propagates.\n */\nasync function loadUninstallConfig(\n projectDir: string,\n onLoadFailed: (reason: string) => void,\n): Promise<ProjectConfig | null> {\n try {\n const result = await loadProjectConfigFromDir(projectDir);\n return result?.config ?? null;\n } catch (error) {\n if (!(error instanceof ConfigLoadError)) throw error;\n onLoadFailed(getErrorMessage(error));\n return null;\n }\n}\n\n/**\n * Detects what's installed in a project directory for uninstallation.\n *\n * Checks for plugins, local skills, agents, config directories, and\n * resolves which plugins were installed by this CLI.\n */\nasync function detectUninstallTarget(\n projectDir: string,\n onConfigLoadFailed: (reason: string) => void,\n): Promise<UninstallTarget> {\n const pluginsDir = getProjectPluginsDir(projectDir);\n const { skillsDir, agentsDir } = resolveInstallPaths(projectDir);\n const claudeDir = path.join(projectDir, CLAUDE_DIR);\n const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);\n\n const claudeSrcConfigPath = path.join(claudeSrcDir, STANDARD_FILES.CONFIG_TS);\n const claudeSrcConfigTypesPath = path.join(claudeSrcDir, STANDARD_FILES.CONFIG_TYPES_TS);\n\n const [\n hasLocalSkills,\n hasLocalAgents,\n hasClaudeDir,\n hasClaudeSrcConfig,\n hasClaudeSrcConfigTypes,\n config,\n ] = await Promise.all([\n directoryExists(skillsDir),\n directoryExists(agentsDir),\n directoryExists(claudeDir),\n fileExists(claudeSrcConfigPath),\n fileExists(claudeSrcConfigTypesPath),\n loadUninstallConfig(projectDir, onConfigLoadFailed),\n ]);\n\n let pluginNames: string[] = [];\n try {\n pluginNames = await listPluginNames(projectDir);\n } catch {\n // Best-effort: plugin detection may fail\n }\n\n const activeConfig = config\n ? {\n ...config,\n skills: config.skills?.filter((s) => !s.excluded),\n agents: config.agents?.filter((a) => !a.excluded),\n }\n : null;\n const configuredAgents = collectConfiguredAgents(activeConfig);\n const cliInstalledKeys = getCliInstalledPluginKeys(activeConfig);\n const cliPluginNames = pluginNames.filter((name) => cliInstalledKeys.has(name));\n\n return {\n hasPlugins: cliPluginNames.length > 0,\n pluginNames,\n cliPluginNames,\n hasLocalSkills,\n hasLocalAgents,\n hasClaudeDir,\n hasClaudeSrcConfig,\n hasClaudeSrcConfigTypes,\n pluginsDir,\n skillsDir,\n agentsDir,\n claudeDir,\n claudeSrcDir,\n config,\n configuredAgents,\n };\n}\n\nfunction shouldRemoveSkill(forkedFrom: { source?: string } | null): boolean {\n return forkedFrom !== null;\n}\n\nasync function removeMatchingSkills(\n target: Pick<UninstallTarget, \"hasLocalSkills\" | \"skillsDir\">,\n onRemoved?: (dirName: string) => void,\n onSkipped?: (dirName: string) => void,\n): Promise<SkillRemovalResult> {\n if (!target.hasLocalSkills) {\n return {\n removedCount: 0,\n skippedCount: 0,\n removedNames: [],\n skippedNames: [],\n dirCleaned: false,\n };\n }\n\n const classified = await classifySkillDirs(target.skillsDir);\n const removedNames = await removeClassifiedSkills(\n classified.toRemove,\n target.skillsDir,\n onRemoved,\n );\n classified.toSkip.forEach((name) => onSkipped?.(name));\n const dirCleaned = await cleanupSkillsDir(target.skillsDir, classified.toSkip.length === 0);\n\n return {\n removedCount: removedNames.length,\n skippedCount: classified.toSkip.length,\n removedNames,\n skippedNames: classified.toSkip,\n dirCleaned,\n };\n}\n\nasync function classifySkillDirs(\n skillsDir: string,\n): Promise<{ toRemove: string[]; toSkip: string[] }> {\n const dirNames = await listDirectories(skillsDir);\n const entries = await Promise.all(\n dirNames.map(async (name) => ({\n name,\n forkedFrom: await readForkedFromMetadata(path.join(skillsDir, name)),\n })),\n );\n const [removable, skippable] = partition(entries, (entry) => shouldRemoveSkill(entry.forkedFrom));\n return { toRemove: removable.map((e) => e.name), toSkip: skippable.map((e) => e.name) };\n}\n\nasync function removeClassifiedSkills(\n names: string[],\n skillsDir: string,\n onRemoved?: (name: string) => void,\n): Promise<string[]> {\n for (const name of names) {\n await remove(path.join(skillsDir, name));\n onRemoved?.(name);\n }\n return names;\n}\n\nasync function cleanupSkillsDir(dir: string, allRemoved: boolean): Promise<boolean> {\n if (!allRemoved) return false;\n return removeDirIfEmpty(dir);\n}\n\n/** Removes `dir` when it exists and is empty; true when removed. */\nasync function removeDirIfEmpty(dir: string): Promise<boolean> {\n if (!(await directoryExists(dir))) return false;\n if (!(await isDirectoryEmpty(dir))) return false;\n await remove(dir);\n return true;\n}\n\n/**\n * Removes compiled agent .md files that are listed in the project config.\n *\n * A file is removed only when its basename matches a configured agent\n * (config.agents); agents absent from config are preserved. Cleans up the\n * agents directory if empty after removal.\n *\n * @param onRemoved - Called for each removed agent name (for logging)\n */\nasync function removeMatchingAgents(\n target: Pick<UninstallTarget, \"hasLocalAgents\" | \"agentsDir\" | \"configuredAgents\">,\n onRemoved?: (agentName: string) => void,\n): Promise<AgentRemovalResult> {\n if (!target.hasLocalAgents) {\n return { removedCount: 0, removedNames: [], dirCleaned: false };\n }\n\n if (target.configuredAgents.length === 0) {\n return { removedCount: 0, removedNames: [], dirCleaned: false };\n }\n\n const agentFiles = await listAgentFiles(target.agentsDir);\n const removedNames = agentFiles\n .map((agentFile) => agentFile.replace(/\\.md$/, \"\"))\n // Array<AgentName>.includes rejects a plain string; widen the configured\n // list to readonly string[] so the on-disk basename can be tested for\n // membership in config.agents.\n .filter((agentName) => (target.configuredAgents as readonly string[]).includes(agentName));\n\n for (const agentName of removedNames) {\n await remove(path.join(target.agentsDir, `${agentName}.md`));\n onRemoved?.(agentName);\n }\n\n const dirCleaned = await removeDirIfEmpty(target.agentsDir);\n\n return {\n removedCount: removedNames.length,\n removedNames,\n dirCleaned,\n };\n}\n\n/**\n * Uninstalls CLI-managed plugins by removing them from the Claude CLI\n * and deleting their local directories.\n *\n * Derives scope from per-skill config when available; falls back to project-level.\n *\n * @param onUninstalled - Called for each successfully uninstalled plugin name (for logging)\n * @internal Exported for testing\n */\nexport async function uninstallPlugins(\n target: Pick<UninstallTarget, \"hasPlugins\" | \"cliPluginNames\" | \"pluginsDir\" | \"config\">,\n projectDir: string,\n onUninstalled?: (pluginName: string) => void,\n): Promise<UninstallPluginsResult> {\n if (!target.hasPlugins) {\n return { uninstalledNames: [], totalUninstalled: 0 };\n }\n\n const cliAvailable = await isClaudeCLIAvailable();\n\n for (const pluginName of target.cliPluginNames) {\n if (cliAvailable) {\n // Derive primary scope from per-skill config; shared helper tries both scopes\n // to handle re-scoped plugins where the registry entry may be under the\n // original scope rather than the currently-configured one.\n const skillId = parseMarketplacePluginRef(pluginName);\n const skillConfig = target.config?.skills?.find((s) => s.id === skillId);\n const primaryScope = toClaudePluginScope(skillConfig?.scope);\n await claudePluginUninstallBestEffort(pluginName, primaryScope, projectDir);\n }\n\n const pluginPath = path.join(target.pluginsDir, pluginName);\n await remove(pluginPath);\n onUninstalled?.(pluginName);\n }\n\n // Every iteration either completes or throws (aborting the whole uninstall),\n // so reaching this return means every CLI-managed plugin was removed.\n return {\n uninstalledNames: target.cliPluginNames,\n totalUninstalled: target.cliPluginNames.length,\n };\n}\n\n/**\n * Removes the CLI config manifest (config.ts + config-types.ts) from .claude-src/,\n * then the .claude-src/ directory itself when it has nothing else left. User-owned\n * content in .claude-src/ (e.g. ejected templates) keeps the directory alive.\n */\nasync function removeConfigManifest(\n target: Pick<UninstallTarget, \"claudeSrcDir\" | \"hasClaudeSrcConfig\" | \"hasClaudeSrcConfigTypes\">,\n): Promise<{ manifestRemoved: boolean; dirRemoved: boolean }> {\n let manifestRemoved = false;\n\n if (target.hasClaudeSrcConfig) {\n await remove(path.join(target.claudeSrcDir, STANDARD_FILES.CONFIG_TS));\n manifestRemoved = true;\n }\n if (target.hasClaudeSrcConfigTypes) {\n await remove(path.join(target.claudeSrcDir, STANDARD_FILES.CONFIG_TYPES_TS));\n manifestRemoved = true;\n }\n\n const dirRemoved = manifestRemoved && (await removeDirIfEmpty(target.claudeSrcDir));\n return { manifestRemoved, dirRemoved };\n}\n\n/**\n * Removes the CLI config manifest and cleans up empty .claude/ and .claude-src/\n * directories after uninstall.\n *\n * The config manifest is always removed. The .claude-src/ and .claude/ directories\n * are removed only when they are empty after their CLI-managed contents are gone.\n */\nasync function cleanupEmptyDirs(\n target: Pick<\n UninstallTarget,\n \"hasClaudeDir\" | \"claudeDir\" | \"claudeSrcDir\" | \"hasClaudeSrcConfig\" | \"hasClaudeSrcConfigTypes\"\n >,\n): Promise<CleanupResult> {\n const manifest = await removeConfigManifest(target);\n\n const claudeDirRemoved = target.hasClaudeDir && (await removeDirIfEmpty(target.claudeDir));\n // Nothing else removes .claude itself, so \"kept\" is exactly \"present but not removed\".\n const claudeDirKept =\n !claudeDirRemoved && target.hasClaudeDir && (await directoryExists(target.claudeDir));\n\n return {\n claudeDirRemoved,\n claudeSrcManifestRemoved: manifest.manifestRemoved,\n claudeSrcDirRemoved: manifest.dirRemoved,\n claudeDirKept,\n };\n}\n\nasync function isDirectoryEmpty(dirPath: string): Promise<boolean> {\n try {\n const allEntries = await readdir(dirPath);\n return allEntries.length === 0;\n } catch {\n return true;\n }\n}\n\nasync function listAgentFiles(agentsDir: string): Promise<string[]> {\n try {\n return await listAgentMdFiles(agentsDir);\n } catch {\n return [];\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Confirm
4
- } from "../chunk-ES3NJZON.js";
4
+ } from "../chunk-NR3OZGL4.js";
5
5
  import {
6
6
  promptConfirm
7
- } from "../chunk-C55DN7GE.js";
7
+ } from "../chunk-Q2KG7UV3.js";
8
8
  import {
9
9
  ERROR_MESSAGES,
10
10
  INFO_MESSAGES,
11
11
  STATUS_MESSAGES,
12
12
  SUCCESS_MESSAGES
13
- } from "../chunk-GYG5SE2D.js";
13
+ } from "../chunk-ODNDXQH2.js";
14
14
  import {
15
15
  loadSource
16
- } from "../chunk-Y4CXDA3I.js";
16
+ } from "../chunk-STMHDOZD.js";
17
17
  import {
18
18
  collectScopedSkillDirs,
19
19
  compareSkillsWithSource,
@@ -21,39 +21,35 @@ import {
21
21
  discoverInstalledSkills,
22
22
  findSkillMatch,
23
23
  recompilePropagatedProjectAgents
24
- } from "../chunk-4R6PGHQQ.js";
25
- import "../chunk-3XFUQ6OL.js";
26
- import "../chunk-YBVA7GPW.js";
27
- import "../chunk-NGLQ5W7U.js";
24
+ } from "../chunk-SBHBBZKF.js";
25
+ import "../chunk-IHUY4M22.js";
26
+ import "../chunk-QZZJFYUQ.js";
27
+ import "../chunk-E5X6RJ4E.js";
28
+ import "../chunk-JFLVEFFP.js";
28
29
  import {
29
30
  BaseCommand,
30
31
  EXIT_CODES
31
- } from "../chunk-7QIHKQL5.js";
32
- import "../chunk-SYUOXSPU.js";
33
- import "../chunk-P3PN5SVI.js";
32
+ } from "../chunk-KR65TPKC.js";
33
+ import "../chunk-ZL7PFNHN.js";
34
34
  import {
35
35
  injectForkedFromMetadata,
36
36
  loadProjectConfigFromDir,
37
37
  normalizeProjectPath
38
- } from "../chunk-TVHRMRD3.js";
38
+ } from "../chunk-EEPELKOM.js";
39
39
  import {
40
40
  copy,
41
41
  getErrorMessage
42
- } from "../chunk-3LIU2ZEF.js";
43
- import "../chunk-DG2NGZ7S.js";
44
- import "../chunk-VEP23B5W.js";
42
+ } from "../chunk-PMM2MYMA.js";
43
+ import "../chunk-WKTHWQKM.js";
44
+ import "../chunk-VASLW636.js";
45
45
  import {
46
46
  CLI_INVOKE_COMMAND,
47
47
  LOCAL_SKILLS_PATH,
48
48
  SOURCE_SRC_DIR
49
- } from "../chunk-O5ASLZ2K.js";
50
- import "../chunk-YU2VGX5R.js";
51
- import {
52
- init_esm_shims
53
- } from "../chunk-P56WJ5FA.js";
49
+ } from "../chunk-76ADG7LQ.js";
50
+ import "../chunk-UBEDZ4FD.js";
54
51
 
55
52
  // src/cli/commands/update.tsx
56
- init_esm_shims();
57
53
  import { Flags, Args } from "@oclif/core";
58
54
  import { printTable } from "@oclif/table";
59
55
  import os from "os";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/update.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Flags, Args } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport os from \"os\";\nimport path from \"path\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { copy } from \"../utils/fs.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n loadSource,\n compareSkillsWithSource,\n compileAgents,\n collectScopedSkillDirs,\n findSkillMatch,\n discoverInstalledSkills,\n recompilePropagatedProjectAgents,\n} from \"../lib/operations/index.js\";\nimport { normalizeProjectPath } from \"../lib/config-gate/index.js\";\nimport { loadProjectConfigFromDir } from \"../lib/configuration/project-config.js\";\nimport { CLI_INVOKE_COMMAND, LOCAL_SKILLS_PATH, SOURCE_SRC_DIR } from \"../consts.js\";\nimport {\n ERROR_MESSAGES,\n SUCCESS_MESSAGES,\n STATUS_MESSAGES,\n INFO_MESSAGES,\n} from \"../utils/messages.js\";\nimport { Confirm } from \"../components/common/confirm.js\";\nimport { promptConfirm } from \"../components/common/prompt-confirm.js\";\nimport { injectForkedFromMetadata, type SkillComparisonResult } from \"../lib/skills/index.js\";\nimport type { SourceLoadResult } from \"../lib/loading/source-loader.js\";\nimport type { AgentName, SkillId } from \"../types/index.js\";\n\ntype UpdateConfirmProps = {\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UpdateConfirm: React.FC<UpdateConfirmProps> = ({ onConfirm, onCancel }) => {\n return (\n <Confirm\n message=\"Proceed with update?\"\n onConfirm={onConfirm}\n onCancel={onCancel}\n defaultValue={false}\n />\n );\n};\n\ntype UpdateContext = {\n projectDir: string;\n homeDir: string;\n sourceResult: SourceLoadResult;\n allResults: SkillComparisonResult[];\n skillBaseDir: Map<SkillId, string>;\n};\n\nexport default class Update extends BaseCommand {\n static summary = \"Update local skills from source\";\n\n static description =\n \"Update local skills from the source repository. By default, checks all skills for updates. Specify a skill name to update only that skill.\";\n\n static args = {\n skill: Args.string({\n description: \"Specific skill to update (optional)\",\n required: false,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n };\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> my-skill\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --source /path/to/marketplace\",\n ];\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Update);\n const projectDir = process.cwd();\n\n try {\n const context = await this.loadContext(flags, projectDir);\n if (!context) return;\n\n const outdatedSkills = this.resolveTargetSkills(args.skill, context);\n if (!outdatedSkills) return;\n\n this.printUpdateTable(outdatedSkills);\n\n const confirmed = flags.yes || (await this.confirmUpdate());\n if (!confirmed) return;\n\n this.log(\"\");\n\n const updateResult = await this.executeUpdates(outdatedSkills, context);\n this.printUpdateResults(updateResult);\n\n const recompiledAgents = await this.recompileAfterUpdate(updateResult, context);\n await this.refreshRegisteredProjects(updateResult, context);\n\n this.printCompletionSummary(updateResult, recompiledAgents);\n } catch (error) {\n const message = getErrorMessage(error);\n this.error(`Update failed: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n\n private async loadContext(\n flags: { source?: string },\n projectDir: string,\n ): Promise<UpdateContext | null> {\n const homeDir = os.homedir();\n const { hasProject, hasGlobal } = await collectScopedSkillDirs(projectDir);\n\n if (!hasProject && !hasGlobal) {\n this.warn(ERROR_MESSAGES.NO_LOCAL_SKILLS);\n return null;\n }\n\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const { sourceResult } = await loadSource({\n sourceFlag: flags.source,\n projectDir,\n });\n\n this.log(\n `Loaded from ${sourceResult.isLocal ? \"local\" : \"remote\"}: ${sourceResult.sourcePath}`,\n );\n\n const comparison = await compareSkillsWithSource(\n projectDir,\n sourceResult.sourcePath,\n sourceResult.matrix,\n );\n\n // Later entries overwrite earlier ones, so project wins on duplicate ids.\n const skillBaseDir = new Map<SkillId, string>([\n ...comparison.globalResults.map((r) => [r.id, homeDir] as const),\n ...comparison.projectResults.map((r) => [r.id, projectDir] as const),\n ]);\n\n return {\n projectDir,\n homeDir,\n sourceResult,\n allResults: comparison.merged,\n skillBaseDir,\n };\n }\n\n private resolveTargetSkills(\n skillArg: string | undefined,\n context: UpdateContext,\n ): SkillComparisonResult[] | null {\n if (skillArg) {\n const { match: foundSkill, similar } = findSkillMatch(skillArg, context.allResults);\n\n if (!foundSkill) {\n this.log(\"\");\n this.log(`Error: Skill \"${skillArg}\" not found.`);\n this.log(\"\");\n\n if (similar.length > 0) {\n this.log(\"Did you mean one of these?\");\n for (const name of similar) {\n this.log(` - ${name}`);\n }\n this.log(\"\");\n }\n\n this.log(`Run \\`${CLI_INVOKE_COMMAND} search ${skillArg}\\` to search available skills.`);\n this.log(\"\");\n this.error(ERROR_MESSAGES.SKILL_NOT_FOUND, { exit: EXIT_CODES.ERROR });\n }\n\n if (foundSkill.status === \"current\") {\n this.log(\"\");\n this.log(`Skill \"${foundSkill.id}\" is already up to date.`);\n this.log(\"\");\n this.log(` Local hash: ${foundSkill.localHash}`);\n this.log(` Source hash: ${foundSkill.sourceHash}`);\n this.log(\"\");\n return null;\n }\n\n if (foundSkill.status === \"local-only\") {\n this.log(\"\");\n this.log(`Skill \"${foundSkill.id}\" is a local-only skill (not forked from source).`);\n this.log(\"Cannot update local-only skills.\");\n this.log(\"\");\n return null;\n }\n\n return [foundSkill];\n }\n\n const outdatedSkills = context.allResults.filter((r) => r.status === \"outdated\");\n if (outdatedSkills.length === 0) {\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.ALL_SKILLS_UP_TO_DATE);\n this.log(\"\");\n return null;\n }\n\n return outdatedSkills;\n }\n\n private printUpdateTable(outdatedSkills: SkillComparisonResult[]): void {\n this.log(\"\");\n this.log(\"The following skills will be updated:\");\n this.log(\"\");\n\n printTable({\n data: outdatedSkills.map((skill) => ({\n skill: skill.id,\n localHash: skill.localHash ?? \"-\",\n sourceHash: skill.sourceHash ?? \"-\",\n })),\n columns: [\n { key: \"skill\", name: \"Skill\" },\n { key: \"localHash\", name: \"Local Hash\" },\n { key: \"sourceHash\", name: \"Source Hash\" },\n ],\n headerOptions: { bold: true },\n });\n\n this.log(\"\");\n this.log(`${outdatedSkills.length} skill(s) will be updated.`);\n this.log(\"\");\n }\n\n private async confirmUpdate(): Promise<boolean> {\n const outcome = await promptConfirm(({ onConfirm, onCancel }) => (\n <UpdateConfirm onConfirm={onConfirm} onCancel={onCancel} />\n ));\n\n if (outcome === \"cancelled\") {\n this.log(\"Update cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n return true;\n }\n\n private async executeUpdates(\n outdatedSkills: SkillComparisonResult[],\n context: UpdateContext,\n ): Promise<UpdateLocalSkillsResult> {\n return updateLocalSkills({\n skills: outdatedSkills,\n sourceResult: context.sourceResult,\n skillBaseDir: context.skillBaseDir,\n onProgress: (skillId) => this.log(`Updating ${skillId}...`),\n });\n }\n\n private printUpdateResults(updateResult: UpdateLocalSkillsResult): void {\n for (const item of updateResult.updated) {\n this.log(` Updated ${item.id}`);\n }\n for (const item of updateResult.failed) {\n this.log(` Failed to update ${item.id}: ${item.error}`);\n }\n }\n\n private async recompileAfterUpdate(\n updateResult: UpdateLocalSkillsResult,\n context: UpdateContext,\n ): Promise<AgentName[]> {\n if (updateResult.updated.length === 0) return [];\n\n this.log(\"\");\n this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);\n\n try {\n const { allSkills } = await discoverInstalledSkills(context.projectDir);\n const recompileResult = await compileAgents({\n projectDir: context.projectDir,\n sourcePath: context.sourceResult.sourcePath,\n skills: allSkills,\n });\n\n const recompiledAgents = recompileResult.compiled;\n\n if (recompiledAgents.length > 0) {\n this.log(\"Agents recompiled\");\n for (const agent of recompiledAgents) {\n this.log(` Recompiled: ${agent}`);\n }\n } else {\n this.log(INFO_MESSAGES.NO_AGENTS_TO_RECOMPILE);\n }\n\n if (recompileResult.warnings.length > 0) {\n for (const warning of recompileResult.warnings) {\n this.warn(warning);\n }\n }\n\n return recompiledAgents;\n } catch (error) {\n this.warn(\"Agent recompilation failed\");\n this.warn(`Could not recompile agents: ${getErrorMessage(error)}`);\n return [];\n }\n }\n\n /**\n * Recompiles the agents of every OTHER registered project.\n *\n * `update` replaces the skill directories under `~/.claude/skills/` in place.\n * Every registered project compiled its own `.claude/agents/*.md` from those\n * same directories, so the moment the new content lands those agents are\n * quoting guidance the source no longer contains — with nothing to signal it.\n * This is the content twin of the config fan-out the gate performs for a global\n * CONFIG change, and it reuses the same helper.\n *\n * It writes NO config pair — a skill's content changes nothing any config\n * declares — so it deliberately does not go through config-gate.\n *\n * The cwd is excluded: `recompileAfterUpdate` has already compiled it. Failure\n * is warned, never fatal — the skills were updated either way.\n */\n private async refreshRegisteredProjects(\n updateResult: UpdateLocalSkillsResult,\n context: UpdateContext,\n ): Promise<void> {\n if (updateResult.updated.length === 0) return;\n\n try {\n const registered = await this.registeredProjectsToRefresh(context);\n if (registered.length === 0) return;\n\n const { recompiledCount, failedCount, warnings } =\n await recompilePropagatedProjectAgents(registered);\n\n for (const warning of warnings) {\n this.warn(warning);\n }\n\n const failureSuffix = failedCount > 0 ? ` (${failedCount} failed)` : \"\";\n this.log(`Recompiled agents in ${recompiledCount} registered projects${failureSuffix}\\n`);\n } catch (error) {\n this.warn(\n `Could not refresh registered projects — their compiled agents may still quote the pre-update content: ${getErrorMessage(error)}`,\n );\n }\n }\n\n /**\n * The registered project paths this run still owes a recompile: everything in\n * the global config's `projects` registry except the directory the command ran\n * in. Compared through `normalizeProjectPath`, the same rule the registrations\n * were stored under, so a cwd reached via a symlink still matches its entry.\n */\n private async registeredProjectsToRefresh(context: UpdateContext): Promise<string[]> {\n const loaded = await loadProjectConfigFromDir(context.homeDir);\n const projects = loaded?.config.projects ?? [];\n if (projects.length === 0) return [];\n\n const current = normalizeProjectPath(context.projectDir);\n return projects.filter((projectPath) => projectPath !== current);\n }\n\n private printCompletionSummary(\n updateResult: UpdateLocalSkillsResult,\n recompiledAgents: AgentName[],\n ): void {\n this.log(\"\");\n if (updateResult.failed.length === 0) {\n const agentMsg =\n recompiledAgents.length > 0 ? `, ${recompiledAgents.length} agent(s) recompiled` : \"\";\n this.logSuccess(\n `Update complete! ${updateResult.updated.length} skill(s) updated${agentMsg}.`,\n );\n } else {\n this.warn(\n `Update finished with errors: ${updateResult.updated.length} updated, ${updateResult.failed.length} failed.`,\n );\n }\n this.log(\"\");\n\n if (updateResult.failed.length > 0) {\n this.error(\"Some updates failed\", { exit: EXIT_CODES.ERROR });\n }\n }\n}\n\ntype SkillUpdateResult = {\n id: SkillId;\n newHash: string | null;\n error?: string;\n};\n\ntype UpdateLocalSkillsResult = {\n updated: SkillUpdateResult[];\n failed: SkillUpdateResult[];\n};\n\ntype UpdateLocalSkillsOptions = {\n skills: SkillComparisonResult[];\n sourceResult: SourceLoadResult;\n skillBaseDir: Map<SkillId, string>;\n /** Called before each skill update starts. Use for progress logging. */\n onProgress?: (skillId: string) => void;\n};\n\n/**\n * Updates local skills by copying from source and injecting metadata.\n *\n * For each outdated skill, copies the source version to the local skills\n * directory and injects forked-from metadata for change tracking.\n */\nasync function updateLocalSkills(\n options: UpdateLocalSkillsOptions,\n): Promise<UpdateLocalSkillsResult> {\n const { skills, sourceResult, skillBaseDir, onProgress } = options;\n const updated: SkillUpdateResult[] = [];\n const failed: SkillUpdateResult[] = [];\n\n for (const skill of skills) {\n onProgress?.(skill.id);\n if (!skill.sourcePath || !skill.sourceHash) {\n failed.push({\n id: skill.id,\n newHash: null,\n error: \"No source path available\",\n });\n continue;\n }\n\n const baseDir = skillBaseDir.get(skill.id) ?? process.cwd();\n const localSkillsPath = path.join(baseDir, LOCAL_SKILLS_PATH);\n const destPath = path.join(localSkillsPath, skill.dirName);\n const srcPath = path.join(sourceResult.sourcePath, SOURCE_SRC_DIR, skill.sourcePath);\n\n try {\n await copy(srcPath, destPath);\n await injectForkedFromMetadata(destPath, skill.id, skill.sourceHash);\n updated.push({ id: skill.id, newHash: skill.sourceHash });\n } catch (error) {\n failed.push({ id: skill.id, newHash: null, error: getErrorMessage(error) });\n }\n }\n\n return { updated, failed };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAEA,SAAS,OAAO,YAAY;AAC5B,SAAS,kBAAkB;AAC3B,OAAO,QAAQ;AACf,OAAO,UAAU;AAqCb;AAFJ,IAAM,gBAA8C,CAAC,EAAE,WAAW,SAAS,MAAM;AAC/E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,cAAc;AAAA;AAAA,EAChB;AAEJ;AAUA,IAAqB,SAArB,MAAqB,gBAAe,YAAY;AAAA,EAC9C,OAAO,UAAU;AAAA,EAEjB,OAAO,cACL;AAAA,EAEF,OAAO,OAAO;AAAA,IACZ,OAAO,KAAK,OAAO;AAAA,MACjB,aAAa;AAAA,MACb,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,QAAQ;AAAA,IACb,GAAG,YAAY;AAAA,IACf,KAAK,MAAM,QAAQ;AAAA,MACjB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,WAAW;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA,MAAM,MAAqB;AACzB,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,KAAK,MAAM,OAAM;AAC/C,UAAM,aAAa,QAAQ,IAAI;AAE/B,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,YAAY,OAAO,UAAU;AACxD,UAAI,CAAC,QAAS;AAEd,YAAM,iBAAiB,KAAK,oBAAoB,KAAK,OAAO,OAAO;AACnE,UAAI,CAAC,eAAgB;AAErB,WAAK,iBAAiB,cAAc;AAEpC,YAAM,YAAY,MAAM,OAAQ,MAAM,KAAK,cAAc;AACzD,UAAI,CAAC,UAAW;AAEhB,WAAK,IAAI,EAAE;AAEX,YAAM,eAAe,MAAM,KAAK,eAAe,gBAAgB,OAAO;AACtE,WAAK,mBAAmB,YAAY;AAEpC,YAAM,mBAAmB,MAAM,KAAK,qBAAqB,cAAc,OAAO;AAC9E,YAAM,KAAK,0BAA0B,cAAc,OAAO;AAE1D,WAAK,uBAAuB,cAAc,gBAAgB;AAAA,IAC5D,SAAS,OAAO;AACd,YAAM,UAAU,gBAAgB,KAAK;AACrC,WAAK,MAAM,kBAAkB,OAAO,IAAI,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,MAAc,YACZ,OACA,YAC+B;AAC/B,UAAM,UAAU,GAAG,QAAQ;AAC3B,UAAM,EAAE,YAAY,UAAU,IAAI,MAAM,uBAAuB,UAAU;AAEzE,QAAI,CAAC,cAAc,CAAC,WAAW;AAC7B,WAAK,KAAK,eAAe,eAAe;AACxC,aAAO;AAAA,IACT;AAEA,SAAK,IAAI,gBAAgB,cAAc;AAEvC,UAAM,EAAE,aAAa,IAAI,MAAM,WAAW;AAAA,MACxC,YAAY,MAAM;AAAA,MAClB;AAAA,IACF,CAAC;AAED,SAAK;AAAA,MACH,eAAe,aAAa,UAAU,UAAU,QAAQ,KAAK,aAAa,UAAU;AAAA,IACtF;AAEA,UAAM,aAAa,MAAM;AAAA,MACvB;AAAA,MACA,aAAa;AAAA,MACb,aAAa;AAAA,IACf;AAGA,UAAM,eAAe,IAAI,IAAqB;AAAA,MAC5C,GAAG,WAAW,cAAc,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,OAAO,CAAU;AAAA,MAC/D,GAAG,WAAW,eAAe,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,UAAU,CAAU;AAAA,IACrE,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,WAAW;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,oBACN,UACA,SACgC;AAChC,QAAI,UAAU;AACZ,YAAM,EAAE,OAAO,YAAY,QAAQ,IAAI,eAAe,UAAU,QAAQ,UAAU;AAElF,UAAI,CAAC,YAAY;AACf,aAAK,IAAI,EAAE;AACX,aAAK,IAAI,iBAAiB,QAAQ,cAAc;AAChD,aAAK,IAAI,EAAE;AAEX,YAAI,QAAQ,SAAS,GAAG;AACtB,eAAK,IAAI,4BAA4B;AACrC,qBAAW,QAAQ,SAAS;AAC1B,iBAAK,IAAI,OAAO,IAAI,EAAE;AAAA,UACxB;AACA,eAAK,IAAI,EAAE;AAAA,QACb;AAEA,aAAK,IAAI,SAAS,kBAAkB,WAAW,QAAQ,gCAAgC;AACvF,aAAK,IAAI,EAAE;AACX,aAAK,MAAM,eAAe,iBAAiB,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,MACvE;AAEA,UAAI,WAAW,WAAW,WAAW;AACnC,aAAK,IAAI,EAAE;AACX,aAAK,IAAI,UAAU,WAAW,EAAE,0BAA0B;AAC1D,aAAK,IAAI,EAAE;AACX,aAAK,IAAI,kBAAkB,WAAW,SAAS,EAAE;AACjD,aAAK,IAAI,kBAAkB,WAAW,UAAU,EAAE;AAClD,aAAK,IAAI,EAAE;AACX,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,WAAW,cAAc;AACtC,aAAK,IAAI,EAAE;AACX,aAAK,IAAI,UAAU,WAAW,EAAE,mDAAmD;AACnF,aAAK,IAAI,kCAAkC;AAC3C,aAAK,IAAI,EAAE;AACX,eAAO;AAAA,MACT;AAEA,aAAO,CAAC,UAAU;AAAA,IACpB;AAEA,UAAM,iBAAiB,QAAQ,WAAW,OAAO,CAAC,MAAM,EAAE,WAAW,UAAU;AAC/E,QAAI,eAAe,WAAW,GAAG;AAC/B,WAAK,IAAI,EAAE;AACX,WAAK,WAAW,iBAAiB,qBAAqB;AACtD,WAAK,IAAI,EAAE;AACX,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAiB,gBAA+C;AACtE,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,uCAAuC;AAChD,SAAK,IAAI,EAAE;AAEX,eAAW;AAAA,MACT,MAAM,eAAe,IAAI,CAAC,WAAW;AAAA,QACnC,OAAO,MAAM;AAAA,QACb,WAAW,MAAM,aAAa;AAAA,QAC9B,YAAY,MAAM,cAAc;AAAA,MAClC,EAAE;AAAA,MACF,SAAS;AAAA,QACP,EAAE,KAAK,SAAS,MAAM,QAAQ;AAAA,QAC9B,EAAE,KAAK,aAAa,MAAM,aAAa;AAAA,QACvC,EAAE,KAAK,cAAc,MAAM,cAAc;AAAA,MAC3C;AAAA,MACA,eAAe,EAAE,MAAM,KAAK;AAAA,IAC9B,CAAC;AAED,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,GAAG,eAAe,MAAM,4BAA4B;AAC7D,SAAK,IAAI,EAAE;AAAA,EACb;AAAA,EAEA,MAAc,gBAAkC;AAC9C,UAAM,UAAU,MAAM,cAAc,CAAC,EAAE,WAAW,SAAS,MACzD,oBAAC,iBAAc,WAAsB,UAAoB,CAC1D;AAED,QAAI,YAAY,aAAa;AAC3B,WAAK,IAAI,kBAAkB;AAC3B,WAAK,KAAK,WAAW,SAAS;AAAA,IAChC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eACZ,gBACA,SACkC;AAClC,WAAO,kBAAkB;AAAA,MACvB,QAAQ;AAAA,MACR,cAAc,QAAQ;AAAA,MACtB,cAAc,QAAQ;AAAA,MACtB,YAAY,CAAC,YAAY,KAAK,IAAI,YAAY,OAAO,KAAK;AAAA,IAC5D,CAAC;AAAA,EACH;AAAA,EAEQ,mBAAmB,cAA6C;AACtE,eAAW,QAAQ,aAAa,SAAS;AACvC,WAAK,IAAI,aAAa,KAAK,EAAE,EAAE;AAAA,IACjC;AACA,eAAW,QAAQ,aAAa,QAAQ;AACtC,WAAK,IAAI,sBAAsB,KAAK,EAAE,KAAK,KAAK,KAAK,EAAE;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,MAAc,qBACZ,cACA,SACsB;AACtB,QAAI,aAAa,QAAQ,WAAW,EAAG,QAAO,CAAC;AAE/C,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,gBAAgB,kBAAkB;AAE3C,QAAI;AACF,YAAM,EAAE,UAAU,IAAI,MAAM,wBAAwB,QAAQ,UAAU;AACtE,YAAM,kBAAkB,MAAM,cAAc;AAAA,QAC1C,YAAY,QAAQ;AAAA,QACpB,YAAY,QAAQ,aAAa;AAAA,QACjC,QAAQ;AAAA,MACV,CAAC;AAED,YAAM,mBAAmB,gBAAgB;AAEzC,UAAI,iBAAiB,SAAS,GAAG;AAC/B,aAAK,IAAI,mBAAmB;AAC5B,mBAAW,SAAS,kBAAkB;AACpC,eAAK,IAAI,iBAAiB,KAAK,EAAE;AAAA,QACnC;AAAA,MACF,OAAO;AACL,aAAK,IAAI,cAAc,sBAAsB;AAAA,MAC/C;AAEA,UAAI,gBAAgB,SAAS,SAAS,GAAG;AACvC,mBAAW,WAAW,gBAAgB,UAAU;AAC9C,eAAK,KAAK,OAAO;AAAA,QACnB;AAAA,MACF;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,KAAK,4BAA4B;AACtC,WAAK,KAAK,+BAA+B,gBAAgB,KAAK,CAAC,EAAE;AACjE,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAc,0BACZ,cACA,SACe;AACf,QAAI,aAAa,QAAQ,WAAW,EAAG;AAEvC,QAAI;AACF,YAAM,aAAa,MAAM,KAAK,4BAA4B,OAAO;AACjE,UAAI,WAAW,WAAW,EAAG;AAE7B,YAAM,EAAE,iBAAiB,aAAa,SAAS,IAC7C,MAAM,iCAAiC,UAAU;AAEnD,iBAAW,WAAW,UAAU;AAC9B,aAAK,KAAK,OAAO;AAAA,MACnB;AAEA,YAAM,gBAAgB,cAAc,IAAI,KAAK,WAAW,aAAa;AACrE,WAAK,IAAI,wBAAwB,eAAe,uBAAuB,aAAa;AAAA,CAAI;AAAA,IAC1F,SAAS,OAAO;AACd,WAAK;AAAA,QACH,8GAAyG,gBAAgB,KAAK,CAAC;AAAA,MACjI;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,4BAA4B,SAA2C;AACnF,UAAM,SAAS,MAAM,yBAAyB,QAAQ,OAAO;AAC7D,UAAM,WAAW,QAAQ,OAAO,YAAY,CAAC;AAC7C,QAAI,SAAS,WAAW,EAAG,QAAO,CAAC;AAEnC,UAAM,UAAU,qBAAqB,QAAQ,UAAU;AACvD,WAAO,SAAS,OAAO,CAAC,gBAAgB,gBAAgB,OAAO;AAAA,EACjE;AAAA,EAEQ,uBACN,cACA,kBACM;AACN,SAAK,IAAI,EAAE;AACX,QAAI,aAAa,OAAO,WAAW,GAAG;AACpC,YAAM,WACJ,iBAAiB,SAAS,IAAI,KAAK,iBAAiB,MAAM,yBAAyB;AACrF,WAAK;AAAA,QACH,oBAAoB,aAAa,QAAQ,MAAM,oBAAoB,QAAQ;AAAA,MAC7E;AAAA,IACF,OAAO;AACL,WAAK;AAAA,QACH,gCAAgC,aAAa,QAAQ,MAAM,aAAa,aAAa,OAAO,MAAM;AAAA,MACpG;AAAA,IACF;AACA,SAAK,IAAI,EAAE;AAEX,QAAI,aAAa,OAAO,SAAS,GAAG;AAClC,WAAK,MAAM,uBAAuB,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,IAC9D;AAAA,EACF;AACF;AA2BA,eAAe,kBACb,SACkC;AAClC,QAAM,EAAE,QAAQ,cAAc,cAAc,WAAW,IAAI;AAC3D,QAAM,UAA+B,CAAC;AACtC,QAAM,SAA8B,CAAC;AAErC,aAAW,SAAS,QAAQ;AAC1B,iBAAa,MAAM,EAAE;AACrB,QAAI,CAAC,MAAM,cAAc,CAAC,MAAM,YAAY;AAC1C,aAAO,KAAK;AAAA,QACV,IAAI,MAAM;AAAA,QACV,SAAS;AAAA,QACT,OAAO;AAAA,MACT,CAAC;AACD;AAAA,IACF;AAEA,UAAM,UAAU,aAAa,IAAI,MAAM,EAAE,KAAK,QAAQ,IAAI;AAC1D,UAAM,kBAAkB,KAAK,KAAK,SAAS,iBAAiB;AAC5D,UAAM,WAAW,KAAK,KAAK,iBAAiB,MAAM,OAAO;AACzD,UAAM,UAAU,KAAK,KAAK,aAAa,YAAY,gBAAgB,MAAM,UAAU;AAEnF,QAAI;AACF,YAAM,KAAK,SAAS,QAAQ;AAC5B,YAAM,yBAAyB,UAAU,MAAM,IAAI,MAAM,UAAU;AACnE,cAAQ,KAAK,EAAE,IAAI,MAAM,IAAI,SAAS,MAAM,WAAW,CAAC;AAAA,IAC1D,SAAS,OAAO;AACd,aAAO,KAAK,EAAE,IAAI,MAAM,IAAI,SAAS,MAAM,OAAO,gBAAgB,KAAK,EAAE,CAAC;AAAA,IAC5E;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,OAAO;AAC3B;","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/update.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Flags, Args } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport os from \"os\";\nimport path from \"path\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { copy } from \"../utils/fs.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n loadSource,\n compareSkillsWithSource,\n compileAgents,\n collectScopedSkillDirs,\n findSkillMatch,\n discoverInstalledSkills,\n recompilePropagatedProjectAgents,\n} from \"../lib/operations/index.js\";\nimport { normalizeProjectPath } from \"../lib/config-gate/index.js\";\nimport { loadProjectConfigFromDir } from \"../lib/configuration/project-config.js\";\nimport { CLI_INVOKE_COMMAND, LOCAL_SKILLS_PATH, SOURCE_SRC_DIR } from \"../consts.js\";\nimport {\n ERROR_MESSAGES,\n SUCCESS_MESSAGES,\n STATUS_MESSAGES,\n INFO_MESSAGES,\n} from \"../utils/messages.js\";\nimport { Confirm } from \"../components/common/confirm.js\";\nimport { promptConfirm } from \"../components/common/prompt-confirm.js\";\nimport { injectForkedFromMetadata, type SkillComparisonResult } from \"../lib/skills/index.js\";\nimport type { SourceLoadResult } from \"../lib/loading/source-loader.js\";\nimport type { AgentName, SkillId } from \"../types/index.js\";\n\ntype UpdateConfirmProps = {\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UpdateConfirm: React.FC<UpdateConfirmProps> = ({ onConfirm, onCancel }) => {\n return (\n <Confirm\n message=\"Proceed with update?\"\n onConfirm={onConfirm}\n onCancel={onCancel}\n defaultValue={false}\n />\n );\n};\n\ntype UpdateContext = {\n projectDir: string;\n homeDir: string;\n sourceResult: SourceLoadResult;\n allResults: SkillComparisonResult[];\n skillBaseDir: Map<SkillId, string>;\n};\n\nexport default class Update extends BaseCommand {\n static summary = \"Update local skills from source\";\n\n static description =\n \"Update local skills from the source repository. By default, checks all skills for updates. Specify a skill name to update only that skill.\";\n\n static args = {\n skill: Args.string({\n description: \"Specific skill to update (optional)\",\n required: false,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n };\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> my-skill\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --source /path/to/marketplace\",\n ];\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Update);\n const projectDir = process.cwd();\n\n try {\n const context = await this.loadContext(flags, projectDir);\n if (!context) return;\n\n const outdatedSkills = this.resolveTargetSkills(args.skill, context);\n if (!outdatedSkills) return;\n\n this.printUpdateTable(outdatedSkills);\n\n const confirmed = flags.yes || (await this.confirmUpdate());\n if (!confirmed) return;\n\n this.log(\"\");\n\n const updateResult = await this.executeUpdates(outdatedSkills, context);\n this.printUpdateResults(updateResult);\n\n const recompiledAgents = await this.recompileAfterUpdate(updateResult, context);\n await this.refreshRegisteredProjects(updateResult, context);\n\n this.printCompletionSummary(updateResult, recompiledAgents);\n } catch (error) {\n const message = getErrorMessage(error);\n this.error(`Update failed: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n\n private async loadContext(\n flags: { source?: string },\n projectDir: string,\n ): Promise<UpdateContext | null> {\n const homeDir = os.homedir();\n const { hasProject, hasGlobal } = await collectScopedSkillDirs(projectDir);\n\n if (!hasProject && !hasGlobal) {\n this.warn(ERROR_MESSAGES.NO_LOCAL_SKILLS);\n return null;\n }\n\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const { sourceResult } = await loadSource({\n sourceFlag: flags.source,\n projectDir,\n });\n\n this.log(\n `Loaded from ${sourceResult.isLocal ? \"local\" : \"remote\"}: ${sourceResult.sourcePath}`,\n );\n\n const comparison = await compareSkillsWithSource(\n projectDir,\n sourceResult.sourcePath,\n sourceResult.matrix,\n );\n\n // Later entries overwrite earlier ones, so project wins on duplicate ids.\n const skillBaseDir = new Map<SkillId, string>([\n ...comparison.globalResults.map((r) => [r.id, homeDir] as const),\n ...comparison.projectResults.map((r) => [r.id, projectDir] as const),\n ]);\n\n return {\n projectDir,\n homeDir,\n sourceResult,\n allResults: comparison.merged,\n skillBaseDir,\n };\n }\n\n private resolveTargetSkills(\n skillArg: string | undefined,\n context: UpdateContext,\n ): SkillComparisonResult[] | null {\n if (skillArg) {\n const { match: foundSkill, similar } = findSkillMatch(skillArg, context.allResults);\n\n if (!foundSkill) {\n this.log(\"\");\n this.log(`Error: Skill \"${skillArg}\" not found.`);\n this.log(\"\");\n\n if (similar.length > 0) {\n this.log(\"Did you mean one of these?\");\n for (const name of similar) {\n this.log(` - ${name}`);\n }\n this.log(\"\");\n }\n\n this.log(`Run \\`${CLI_INVOKE_COMMAND} search ${skillArg}\\` to search available skills.`);\n this.log(\"\");\n this.error(ERROR_MESSAGES.SKILL_NOT_FOUND, { exit: EXIT_CODES.ERROR });\n }\n\n if (foundSkill.status === \"current\") {\n this.log(\"\");\n this.log(`Skill \"${foundSkill.id}\" is already up to date.`);\n this.log(\"\");\n this.log(` Local hash: ${foundSkill.localHash}`);\n this.log(` Source hash: ${foundSkill.sourceHash}`);\n this.log(\"\");\n return null;\n }\n\n if (foundSkill.status === \"local-only\") {\n this.log(\"\");\n this.log(`Skill \"${foundSkill.id}\" is a local-only skill (not forked from source).`);\n this.log(\"Cannot update local-only skills.\");\n this.log(\"\");\n return null;\n }\n\n return [foundSkill];\n }\n\n const outdatedSkills = context.allResults.filter((r) => r.status === \"outdated\");\n if (outdatedSkills.length === 0) {\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.ALL_SKILLS_UP_TO_DATE);\n this.log(\"\");\n return null;\n }\n\n return outdatedSkills;\n }\n\n private printUpdateTable(outdatedSkills: SkillComparisonResult[]): void {\n this.log(\"\");\n this.log(\"The following skills will be updated:\");\n this.log(\"\");\n\n printTable({\n data: outdatedSkills.map((skill) => ({\n skill: skill.id,\n localHash: skill.localHash ?? \"-\",\n sourceHash: skill.sourceHash ?? \"-\",\n })),\n columns: [\n { key: \"skill\", name: \"Skill\" },\n { key: \"localHash\", name: \"Local Hash\" },\n { key: \"sourceHash\", name: \"Source Hash\" },\n ],\n headerOptions: { bold: true },\n });\n\n this.log(\"\");\n this.log(`${outdatedSkills.length} skill(s) will be updated.`);\n this.log(\"\");\n }\n\n private async confirmUpdate(): Promise<boolean> {\n const outcome = await promptConfirm(({ onConfirm, onCancel }) => (\n <UpdateConfirm onConfirm={onConfirm} onCancel={onCancel} />\n ));\n\n if (outcome === \"cancelled\") {\n this.log(\"Update cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n return true;\n }\n\n private async executeUpdates(\n outdatedSkills: SkillComparisonResult[],\n context: UpdateContext,\n ): Promise<UpdateLocalSkillsResult> {\n return updateLocalSkills({\n skills: outdatedSkills,\n sourceResult: context.sourceResult,\n skillBaseDir: context.skillBaseDir,\n onProgress: (skillId) => this.log(`Updating ${skillId}...`),\n });\n }\n\n private printUpdateResults(updateResult: UpdateLocalSkillsResult): void {\n for (const item of updateResult.updated) {\n this.log(` Updated ${item.id}`);\n }\n for (const item of updateResult.failed) {\n this.log(` Failed to update ${item.id}: ${item.error}`);\n }\n }\n\n private async recompileAfterUpdate(\n updateResult: UpdateLocalSkillsResult,\n context: UpdateContext,\n ): Promise<AgentName[]> {\n if (updateResult.updated.length === 0) return [];\n\n this.log(\"\");\n this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);\n\n try {\n const { allSkills } = await discoverInstalledSkills(context.projectDir);\n const recompileResult = await compileAgents({\n projectDir: context.projectDir,\n sourcePath: context.sourceResult.sourcePath,\n skills: allSkills,\n });\n\n const recompiledAgents = recompileResult.compiled;\n\n if (recompiledAgents.length > 0) {\n this.log(\"Agents recompiled\");\n for (const agent of recompiledAgents) {\n this.log(` Recompiled: ${agent}`);\n }\n } else {\n this.log(INFO_MESSAGES.NO_AGENTS_TO_RECOMPILE);\n }\n\n if (recompileResult.warnings.length > 0) {\n for (const warning of recompileResult.warnings) {\n this.warn(warning);\n }\n }\n\n return recompiledAgents;\n } catch (error) {\n this.warn(\"Agent recompilation failed\");\n this.warn(`Could not recompile agents: ${getErrorMessage(error)}`);\n return [];\n }\n }\n\n /**\n * Recompiles the agents of every OTHER registered project.\n *\n * `update` replaces the skill directories under `~/.claude/skills/` in place.\n * Every registered project compiled its own `.claude/agents/*.md` from those\n * same directories, so the moment the new content lands those agents are\n * quoting guidance the source no longer contains — with nothing to signal it.\n * This is the content twin of the config fan-out the gate performs for a global\n * CONFIG change, and it reuses the same helper.\n *\n * It writes NO config pair — a skill's content changes nothing any config\n * declares — so it deliberately does not go through config-gate.\n *\n * The cwd is excluded: `recompileAfterUpdate` has already compiled it. Failure\n * is warned, never fatal — the skills were updated either way.\n */\n private async refreshRegisteredProjects(\n updateResult: UpdateLocalSkillsResult,\n context: UpdateContext,\n ): Promise<void> {\n if (updateResult.updated.length === 0) return;\n\n try {\n const registered = await this.registeredProjectsToRefresh(context);\n if (registered.length === 0) return;\n\n const { recompiledCount, failedCount, warnings } =\n await recompilePropagatedProjectAgents(registered);\n\n for (const warning of warnings) {\n this.warn(warning);\n }\n\n const failureSuffix = failedCount > 0 ? ` (${failedCount} failed)` : \"\";\n this.log(`Recompiled agents in ${recompiledCount} registered projects${failureSuffix}\\n`);\n } catch (error) {\n this.warn(\n `Could not refresh registered projects — their compiled agents may still quote the pre-update content: ${getErrorMessage(error)}`,\n );\n }\n }\n\n /**\n * The registered project paths this run still owes a recompile: everything in\n * the global config's `projects` registry except the directory the command ran\n * in. Compared through `normalizeProjectPath`, the same rule the registrations\n * were stored under, so a cwd reached via a symlink still matches its entry.\n */\n private async registeredProjectsToRefresh(context: UpdateContext): Promise<string[]> {\n const loaded = await loadProjectConfigFromDir(context.homeDir);\n const projects = loaded?.config.projects ?? [];\n if (projects.length === 0) return [];\n\n const current = normalizeProjectPath(context.projectDir);\n return projects.filter((projectPath) => projectPath !== current);\n }\n\n private printCompletionSummary(\n updateResult: UpdateLocalSkillsResult,\n recompiledAgents: AgentName[],\n ): void {\n this.log(\"\");\n if (updateResult.failed.length === 0) {\n const agentMsg =\n recompiledAgents.length > 0 ? `, ${recompiledAgents.length} agent(s) recompiled` : \"\";\n this.logSuccess(\n `Update complete! ${updateResult.updated.length} skill(s) updated${agentMsg}.`,\n );\n } else {\n this.warn(\n `Update finished with errors: ${updateResult.updated.length} updated, ${updateResult.failed.length} failed.`,\n );\n }\n this.log(\"\");\n\n if (updateResult.failed.length > 0) {\n this.error(\"Some updates failed\", { exit: EXIT_CODES.ERROR });\n }\n }\n}\n\ntype SkillUpdateResult = {\n id: SkillId;\n newHash: string | null;\n error?: string;\n};\n\ntype UpdateLocalSkillsResult = {\n updated: SkillUpdateResult[];\n failed: SkillUpdateResult[];\n};\n\ntype UpdateLocalSkillsOptions = {\n skills: SkillComparisonResult[];\n sourceResult: SourceLoadResult;\n skillBaseDir: Map<SkillId, string>;\n /** Called before each skill update starts. Use for progress logging. */\n onProgress?: (skillId: string) => void;\n};\n\n/**\n * Updates local skills by copying from source and injecting metadata.\n *\n * For each outdated skill, copies the source version to the local skills\n * directory and injects forked-from metadata for change tracking.\n */\nasync function updateLocalSkills(\n options: UpdateLocalSkillsOptions,\n): Promise<UpdateLocalSkillsResult> {\n const { skills, sourceResult, skillBaseDir, onProgress } = options;\n const updated: SkillUpdateResult[] = [];\n const failed: SkillUpdateResult[] = [];\n\n for (const skill of skills) {\n onProgress?.(skill.id);\n if (!skill.sourcePath || !skill.sourceHash) {\n failed.push({\n id: skill.id,\n newHash: null,\n error: \"No source path available\",\n });\n continue;\n }\n\n const baseDir = skillBaseDir.get(skill.id) ?? process.cwd();\n const localSkillsPath = path.join(baseDir, LOCAL_SKILLS_PATH);\n const destPath = path.join(localSkillsPath, skill.dirName);\n const srcPath = path.join(sourceResult.sourcePath, SOURCE_SRC_DIR, skill.sourcePath);\n\n try {\n await copy(srcPath, destPath);\n await injectForkedFromMetadata(destPath, skill.id, skill.sourceHash);\n updated.push({ id: skill.id, newHash: skill.sourceHash });\n } catch (error) {\n failed.push({ id: skill.id, newHash: null, error: getErrorMessage(error) });\n }\n }\n\n return { updated, failed };\n}\n"],"mappings":"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","names":[]}