@claude-collective/cli 0.13.4 → 0.21.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 (228) hide show
  1. package/CHANGELOG.md +183 -0
  2. package/config/skills-matrix.yaml +180 -113
  3. package/config/stacks.yaml +6 -6
  4. package/dist/{chunk-K3NB6DSG.js → chunk-2LSGX6R4.js} +54 -114
  5. package/dist/chunk-2LSGX6R4.js.map +1 -0
  6. package/dist/chunk-2OKUEELH.js +32 -0
  7. package/dist/chunk-2OKUEELH.js.map +1 -0
  8. package/dist/{chunk-V46GGCCI.js → chunk-374JNMR6.js} +14 -96
  9. package/dist/chunk-374JNMR6.js.map +1 -0
  10. package/dist/chunk-3EHUF54X.js +133 -0
  11. package/dist/chunk-3EHUF54X.js.map +1 -0
  12. package/dist/{chunk-7Q44DMSP.js → chunk-3XR4PALU.js} +92 -145
  13. package/dist/chunk-3XR4PALU.js.map +1 -0
  14. package/dist/{chunk-IAUAQJQ2.js → chunk-5K2ZLUO5.js} +5 -5
  15. package/dist/{chunk-IAUAQJQ2.js.map → chunk-5K2ZLUO5.js.map} +1 -1
  16. package/dist/{chunk-ACNBKXXJ.js → chunk-5KXUDHAB.js} +8 -36
  17. package/dist/chunk-5KXUDHAB.js.map +1 -0
  18. package/dist/chunk-7SLV7CMF.js +615 -0
  19. package/dist/chunk-7SLV7CMF.js.map +1 -0
  20. package/dist/{chunk-CDX4W4DM.js → chunk-A46TPNBJ.js} +61 -32
  21. package/dist/chunk-A46TPNBJ.js.map +1 -0
  22. package/dist/{chunk-TKFPKEV3.js → chunk-AL74GBW4.js} +1 -1
  23. package/dist/chunk-AL74GBW4.js.map +1 -0
  24. package/dist/chunk-BQX23RBV.js +191 -0
  25. package/dist/chunk-BQX23RBV.js.map +1 -0
  26. package/dist/{chunk-IMDW5ZUP.js → chunk-CA4LH4LI.js} +5 -5
  27. package/dist/chunk-CA4LH4LI.js.map +1 -0
  28. package/dist/{chunk-D237EVNB.js → chunk-CBLPAMZO.js} +5 -8
  29. package/dist/chunk-CBLPAMZO.js.map +1 -0
  30. package/dist/{chunk-B7CCVP6Q.js → chunk-CKPQHGXR.js} +52 -274
  31. package/dist/chunk-CKPQHGXR.js.map +1 -0
  32. package/dist/{chunk-SVYPSDWY.js → chunk-CXOFOJCN.js} +6 -10
  33. package/dist/chunk-CXOFOJCN.js.map +1 -0
  34. package/dist/{chunk-UQTEPWU7.js → chunk-EHGD7HIE.js} +2 -6
  35. package/dist/chunk-EHGD7HIE.js.map +1 -0
  36. package/dist/{chunk-76DWXGQE.js → chunk-FJFEKPXF.js} +1 -1
  37. package/dist/chunk-FJFEKPXF.js.map +1 -0
  38. package/dist/{chunk-E3FJH4TF.js → chunk-HEOHU5EZ.js} +2 -13
  39. package/dist/chunk-HEOHU5EZ.js.map +1 -0
  40. package/dist/{chunk-JIPWV2FX.js → chunk-HGCBZUH5.js} +6 -27
  41. package/dist/chunk-HGCBZUH5.js.map +1 -0
  42. package/dist/{chunk-ED4E6Q2T.js → chunk-HPGFY5ZN.js} +4 -4
  43. package/dist/chunk-HPGFY5ZN.js.map +1 -0
  44. package/dist/chunk-INJ2EFRW.js +127 -0
  45. package/dist/chunk-INJ2EFRW.js.map +1 -0
  46. package/dist/{chunk-KAAEN2PO.js → chunk-IOBFMF6X.js} +6 -2
  47. package/dist/{chunk-KAAEN2PO.js.map → chunk-IOBFMF6X.js.map} +1 -1
  48. package/dist/{chunk-K7EVM5LY.js → chunk-KH3HA7J7.js} +8 -33
  49. package/dist/chunk-KH3HA7J7.js.map +1 -0
  50. package/dist/{chunk-4K4ZXQRM.js → chunk-N6JNE326.js} +38 -94
  51. package/dist/chunk-N6JNE326.js.map +1 -0
  52. package/dist/chunk-NAGU7TVZ.js +36 -0
  53. package/dist/chunk-NAGU7TVZ.js.map +1 -0
  54. package/dist/{chunk-Z7G4B5HJ.js → chunk-OQYYMQJR.js} +68 -142
  55. package/dist/chunk-OQYYMQJR.js.map +1 -0
  56. package/dist/{chunk-RFTSZDHV.js → chunk-PLZOUVDD.js} +159 -53
  57. package/dist/chunk-PLZOUVDD.js.map +1 -0
  58. package/dist/chunk-Q3J43SF3.js +21 -0
  59. package/dist/chunk-Q3J43SF3.js.map +1 -0
  60. package/dist/{chunk-3U3R4NCG.js → chunk-T25OEQFI.js} +6 -2
  61. package/dist/chunk-T25OEQFI.js.map +1 -0
  62. package/dist/chunk-UMORK7OK.js +29 -0
  63. package/dist/chunk-UMORK7OK.js.map +1 -0
  64. package/dist/{chunk-ZFPSUQOU.js → chunk-VFHWU7JU.js} +12 -121
  65. package/dist/chunk-VFHWU7JU.js.map +1 -0
  66. package/dist/{chunk-GDH553MV.js → chunk-VS4GVTZE.js} +3 -3
  67. package/dist/chunk-VS4GVTZE.js.map +1 -0
  68. package/dist/chunk-WFEFICFM.js +67 -0
  69. package/dist/chunk-WFEFICFM.js.map +1 -0
  70. package/dist/{chunk-P26A2K5N.js → chunk-WG6KIAPK.js} +6 -16
  71. package/dist/chunk-WG6KIAPK.js.map +1 -0
  72. package/dist/{chunk-X6QONICW.js → chunk-ZEI3ZUDU.js} +3 -7
  73. package/dist/chunk-ZEI3ZUDU.js.map +1 -0
  74. package/dist/chunk-ZNIDWLL5.js +68 -0
  75. package/dist/chunk-ZNIDWLL5.js.map +1 -0
  76. package/dist/chunk-ZSVMS677.js +45 -0
  77. package/dist/chunk-ZSVMS677.js.map +1 -0
  78. package/dist/cli/defaults/agent-mappings.yaml +13 -13
  79. package/dist/commands/build/marketplace.js +8 -14
  80. package/dist/commands/build/marketplace.js.map +1 -1
  81. package/dist/commands/build/plugins.js +10 -21
  82. package/dist/commands/build/plugins.js.map +1 -1
  83. package/dist/commands/build/stack.js +13 -18
  84. package/dist/commands/build/stack.js.map +1 -1
  85. package/dist/commands/compile.js +25 -40
  86. package/dist/commands/compile.js.map +1 -1
  87. package/dist/commands/config/get.js +7 -7
  88. package/dist/commands/config/get.js.map +1 -1
  89. package/dist/commands/config/index.js +6 -6
  90. package/dist/commands/config/index.js.map +1 -1
  91. package/dist/commands/config/path.js +5 -7
  92. package/dist/commands/config/path.js.map +1 -1
  93. package/dist/commands/config/set-project.js +8 -9
  94. package/dist/commands/config/set-project.js.map +1 -1
  95. package/dist/commands/config/show.js +5 -5
  96. package/dist/commands/config/unset-project.js +8 -9
  97. package/dist/commands/config/unset-project.js.map +1 -1
  98. package/dist/commands/diff.js +17 -40
  99. package/dist/commands/diff.js.map +1 -1
  100. package/dist/commands/doctor.js +14 -25
  101. package/dist/commands/doctor.js.map +1 -1
  102. package/dist/commands/edit.js +41 -54
  103. package/dist/commands/edit.js.map +1 -1
  104. package/dist/commands/eject.js +24 -44
  105. package/dist/commands/eject.js.map +1 -1
  106. package/dist/commands/import/skill.js +19 -39
  107. package/dist/commands/import/skill.js.map +1 -1
  108. package/dist/commands/info.js +10 -15
  109. package/dist/commands/info.js.map +1 -1
  110. package/dist/commands/init.js +452 -451
  111. package/dist/commands/init.js.map +1 -1
  112. package/dist/commands/list.js +85 -9
  113. package/dist/commands/list.js.map +1 -1
  114. package/dist/commands/new/agent.js +9 -10
  115. package/dist/commands/new/agent.js.map +1 -1
  116. package/dist/commands/new/skill.js +12 -16
  117. package/dist/commands/new/skill.js.map +1 -1
  118. package/dist/commands/outdated.js +12 -89
  119. package/dist/commands/outdated.js.map +1 -1
  120. package/dist/commands/search.js +12 -18
  121. package/dist/commands/search.js.map +1 -1
  122. package/dist/commands/uninstall.js +12 -21
  123. package/dist/commands/uninstall.js.map +1 -1
  124. package/dist/commands/update.js +26 -146
  125. package/dist/commands/update.js.map +1 -1
  126. package/dist/commands/validate.js +407 -15
  127. package/dist/commands/validate.js.map +1 -1
  128. package/dist/commands/version/bump.js +7 -23
  129. package/dist/commands/version/bump.js.map +1 -1
  130. package/dist/commands/version/index.js +6 -21
  131. package/dist/commands/version/index.js.map +1 -1
  132. package/dist/commands/version/set.js +6 -23
  133. package/dist/commands/version/set.js.map +1 -1
  134. package/dist/commands/version/show.js +6 -21
  135. package/dist/commands/version/show.js.map +1 -1
  136. package/dist/components/common/message.js +2 -6
  137. package/dist/components/common/message.js.map +1 -1
  138. package/dist/components/common/spinner.js.map +1 -1
  139. package/dist/components/skill-search/skill-search.js +1 -1
  140. package/dist/components/wizard/category-grid.js +1 -1
  141. package/dist/components/wizard/category-grid.test.js +20 -92
  142. package/dist/components/wizard/category-grid.test.js.map +1 -1
  143. package/dist/components/wizard/menu-item.js +9 -0
  144. package/dist/components/wizard/section-progress.js +1 -1
  145. package/dist/components/wizard/section-progress.test.js +13 -103
  146. package/dist/components/wizard/section-progress.test.js.map +1 -1
  147. package/dist/components/wizard/step-approach.js +5 -4
  148. package/dist/components/wizard/step-build.js +3 -4
  149. package/dist/components/wizard/step-build.test.js +81 -186
  150. package/dist/components/wizard/step-build.test.js.map +1 -1
  151. package/dist/components/wizard/step-confirm.js +1 -2
  152. package/dist/components/wizard/step-refine.js +1 -2
  153. package/dist/components/wizard/step-refine.test.js +6 -14
  154. package/dist/components/wizard/step-refine.test.js.map +1 -1
  155. package/dist/components/wizard/step-stack.js +5 -3
  156. package/dist/components/wizard/view-title.js +9 -0
  157. package/dist/components/wizard/wizard-layout.js +16 -0
  158. package/dist/components/wizard/wizard-layout.js.map +1 -0
  159. package/dist/components/wizard/wizard-tabs.js +1 -1
  160. package/dist/components/wizard/wizard.js +12 -13
  161. package/dist/config/skills-matrix.yaml +180 -113
  162. package/dist/config/stacks.yaml +6 -6
  163. package/dist/hooks/init.js +5 -7
  164. package/dist/hooks/init.js.map +1 -1
  165. package/dist/src/agents/developer/web-developer/examples.md +1 -6
  166. package/dist/src/agents/meta/documentor/workflow.md +1 -5
  167. package/dist/src/agents/migration/cli-migrator/anti-patterns.md +1 -3
  168. package/dist/src/agents/tester/web-tester/output-format.md +1 -3
  169. package/dist/stores/wizard-store.js +2 -2
  170. package/dist/stores/wizard-store.test.js +60 -23
  171. package/dist/stores/wizard-store.test.js.map +1 -1
  172. package/package.json +1 -1
  173. package/src/agents/developer/web-developer/examples.md +1 -6
  174. package/src/agents/meta/documentor/workflow.md +1 -5
  175. package/src/agents/migration/cli-migrator/anti-patterns.md +1 -3
  176. package/src/agents/tester/web-tester/output-format.md +1 -3
  177. package/dist/chunk-3U3R4NCG.js.map +0 -1
  178. package/dist/chunk-4K4ZXQRM.js.map +0 -1
  179. package/dist/chunk-76DWXGQE.js.map +0 -1
  180. package/dist/chunk-7Q44DMSP.js.map +0 -1
  181. package/dist/chunk-ACNBKXXJ.js.map +0 -1
  182. package/dist/chunk-B7CCVP6Q.js.map +0 -1
  183. package/dist/chunk-BDLUZVKU.js +0 -54
  184. package/dist/chunk-BDLUZVKU.js.map +0 -1
  185. package/dist/chunk-CDX4W4DM.js.map +0 -1
  186. package/dist/chunk-D237EVNB.js.map +0 -1
  187. package/dist/chunk-DRXPNNPB.js +0 -393
  188. package/dist/chunk-DRXPNNPB.js.map +0 -1
  189. package/dist/chunk-E3FJH4TF.js.map +0 -1
  190. package/dist/chunk-ED4E6Q2T.js.map +0 -1
  191. package/dist/chunk-GDH553MV.js.map +0 -1
  192. package/dist/chunk-HLJX2FTL.js +0 -95
  193. package/dist/chunk-HLJX2FTL.js.map +0 -1
  194. package/dist/chunk-I2DSLOXZ.js +0 -75
  195. package/dist/chunk-I2DSLOXZ.js.map +0 -1
  196. package/dist/chunk-I4TPKIYX.js +0 -493
  197. package/dist/chunk-I4TPKIYX.js.map +0 -1
  198. package/dist/chunk-IBE7JIAG.js +0 -129
  199. package/dist/chunk-IBE7JIAG.js.map +0 -1
  200. package/dist/chunk-IMDW5ZUP.js.map +0 -1
  201. package/dist/chunk-JIPWV2FX.js.map +0 -1
  202. package/dist/chunk-K3NB6DSG.js.map +0 -1
  203. package/dist/chunk-K7EVM5LY.js.map +0 -1
  204. package/dist/chunk-NDY25DTL.js +0 -453
  205. package/dist/chunk-NDY25DTL.js.map +0 -1
  206. package/dist/chunk-P26A2K5N.js.map +0 -1
  207. package/dist/chunk-RFTSZDHV.js.map +0 -1
  208. package/dist/chunk-SVYPSDWY.js.map +0 -1
  209. package/dist/chunk-TKFPKEV3.js.map +0 -1
  210. package/dist/chunk-UQTEPWU7.js.map +0 -1
  211. package/dist/chunk-V46GGCCI.js.map +0 -1
  212. package/dist/chunk-X6QONICW.js.map +0 -1
  213. package/dist/chunk-Y2LW7R3Y.js +0 -23
  214. package/dist/chunk-Y2LW7R3Y.js.map +0 -1
  215. package/dist/chunk-Z7G4B5HJ.js.map +0 -1
  216. package/dist/chunk-ZENYS6KW.js +0 -90
  217. package/dist/chunk-ZENYS6KW.js.map +0 -1
  218. package/dist/chunk-ZFPSUQOU.js.map +0 -1
  219. package/dist/commands/config/set.js +0 -61
  220. package/dist/commands/config/set.js.map +0 -1
  221. package/dist/commands/config/unset.js +0 -57
  222. package/dist/commands/config/unset.js.map +0 -1
  223. package/dist/commands/test-imports.js +0 -92
  224. package/dist/commands/test-imports.js.map +0 -1
  225. package/dist/components/wizard/step-stack-options.js +0 -11
  226. package/dist/components/wizard/wizard-footer.js +0 -9
  227. /package/dist/components/wizard/{step-stack-options.js.map → menu-item.js.map} +0 -0
  228. /package/dist/components/wizard/{wizard-footer.js.map → view-title.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/lib/agent-fetcher.ts"],"sourcesContent":["import path from \"path\";\nimport { directoryExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport { PROJECT_ROOT, DIRS, CLAUDE_DIR } from \"../consts\";\nimport { fetchFromSource, type FetchOptions } from \"./source-fetcher\";\nimport type { AgentSourcePaths } from \"../../types\";\n\nexport interface AgentDefinitionOptions extends FetchOptions {\n /** Project directory to check for local templates */\n projectDir?: string;\n}\n\nexport async function getAgentDefinitions(\n remoteSource?: string,\n options: AgentDefinitionOptions = {},\n): Promise<AgentSourcePaths> {\n if (remoteSource) {\n return fetchAgentDefinitionsFromRemote(remoteSource, options);\n }\n return getLocalAgentDefinitions(options);\n}\n\nexport async function getLocalAgentDefinitions(\n options: AgentDefinitionOptions = {},\n): Promise<AgentSourcePaths> {\n const agentsDir = path.join(PROJECT_ROOT, DIRS.agents);\n let templatesDir = path.join(PROJECT_ROOT, DIRS.templates);\n\n if (!(await directoryExists(agentsDir))) {\n throw new Error(\n `Agent partials not found at: ${agentsDir}. ` + `Ensure the CLI is properly installed.`,\n );\n }\n\n // Check for local templates first (from eject templates)\n if (options.projectDir) {\n const localTemplatesDir = path.join(options.projectDir, CLAUDE_DIR, \"templates\");\n if (await directoryExists(localTemplatesDir)) {\n verbose(`Using local templates from: ${localTemplatesDir}`);\n templatesDir = localTemplatesDir;\n }\n }\n\n if (!(await directoryExists(templatesDir))) {\n verbose(`Templates directory not found: ${templatesDir}`);\n }\n\n verbose(`Agent partials loaded from CLI: ${agentsDir}`);\n verbose(`Templates directory: ${templatesDir}`);\n\n return {\n agentsDir,\n templatesDir,\n sourcePath: PROJECT_ROOT,\n };\n}\n\nexport async function fetchAgentDefinitionsFromRemote(\n source: string,\n options: FetchOptions = {},\n): Promise<AgentSourcePaths> {\n verbose(`Fetching agent partials from remote: ${source}`);\n\n const result = await fetchFromSource(source, {\n forceRefresh: options.forceRefresh,\n subdir: \"\",\n });\n\n const agentsDir = path.join(result.path, \"src\", \"agents\");\n const templatesDir = path.join(agentsDir, \"_templates\");\n\n if (!(await directoryExists(agentsDir))) {\n throw new Error(`Agent partials not found at: ${agentsDir}`);\n }\n\n if (!(await directoryExists(templatesDir))) {\n verbose(`Templates directory not found: ${templatesDir}`);\n }\n\n verbose(`Agent partials fetched from: ${result.path}`);\n\n return {\n agentsDir,\n templatesDir,\n sourcePath: result.path,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA,OAAO,UAAU;AAYjB,eAAsB,oBACpB,cACA,UAAkC,CAAC,GACR;AAC3B,MAAI,cAAc;AAChB,WAAO,gCAAgC,cAAc,OAAO;AAAA,EAC9D;AACA,SAAO,yBAAyB,OAAO;AACzC;AAEA,eAAsB,yBACpB,UAAkC,CAAC,GACR;AAC3B,QAAM,YAAY,KAAK,KAAK,cAAc,KAAK,MAAM;AACrD,MAAI,eAAe,KAAK,KAAK,cAAc,KAAK,SAAS;AAEzD,MAAI,CAAE,MAAM,gBAAgB,SAAS,GAAI;AACvC,UAAM,IAAI;AAAA,MACR,gCAAgC,SAAS;AAAA,IAC3C;AAAA,EACF;AAGA,MAAI,QAAQ,YAAY;AACtB,UAAM,oBAAoB,KAAK,KAAK,QAAQ,YAAY,YAAY,WAAW;AAC/E,QAAI,MAAM,gBAAgB,iBAAiB,GAAG;AAC5C,cAAQ,+BAA+B,iBAAiB,EAAE;AAC1D,qBAAe;AAAA,IACjB;AAAA,EACF;AAEA,MAAI,CAAE,MAAM,gBAAgB,YAAY,GAAI;AAC1C,YAAQ,kCAAkC,YAAY,EAAE;AAAA,EAC1D;AAEA,UAAQ,mCAAmC,SAAS,EAAE;AACtD,UAAQ,wBAAwB,YAAY,EAAE;AAE9C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY;AAAA,EACd;AACF;AAEA,eAAsB,gCACpB,QACA,UAAwB,CAAC,GACE;AAC3B,UAAQ,wCAAwC,MAAM,EAAE;AAExD,QAAM,SAAS,MAAM,gBAAgB,QAAQ;AAAA,IAC3C,cAAc,QAAQ;AAAA,IACtB,QAAQ;AAAA,EACV,CAAC;AAED,QAAM,YAAY,KAAK,KAAK,OAAO,MAAM,OAAO,QAAQ;AACxD,QAAM,eAAe,KAAK,KAAK,WAAW,YAAY;AAEtD,MAAI,CAAE,MAAM,gBAAgB,SAAS,GAAI;AACvC,UAAM,IAAI,MAAM,gCAAgC,SAAS,EAAE;AAAA,EAC7D;AAEA,MAAI,CAAE,MAAM,gBAAgB,YAAY,GAAI;AAC1C,YAAQ,kCAAkC,YAAY,EAAE;AAAA,EAC1D;AAEA,UAAQ,gCAAgC,OAAO,IAAI,EAAE;AAErD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY,OAAO;AAAA,EACrB;AACF;","names":[]}
@@ -51,11 +51,7 @@ async function isClaudeCLIAvailable() {
51
51
  }
52
52
  async function claudePluginMarketplaceList() {
53
53
  try {
54
- const result = await execCommand(
55
- "claude",
56
- ["plugin", "marketplace", "list", "--json"],
57
- {}
58
- );
54
+ const result = await execCommand("claude", ["plugin", "marketplace", "list", "--json"], {});
59
55
  if (result.exitCode !== 0) {
60
56
  return [];
61
57
  }
@@ -105,4 +101,4 @@ export {
105
101
  claudePluginMarketplaceAdd,
106
102
  claudePluginUninstall
107
103
  };
108
- //# sourceMappingURL=chunk-UQTEPWU7.js.map
104
+ //# sourceMappingURL=chunk-EHGD7HIE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/utils/exec.ts"],"sourcesContent":["import { spawn } from \"child_process\";\n\nexport interface ExecResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\n/**\n * Execute a command and return the result\n */\nexport async function execCommand(\n command: string,\n args: string[],\n options?: { cwd?: string; env?: NodeJS.ProcessEnv },\n): Promise<ExecResult> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, {\n cwd: options?.cwd,\n env: { ...process.env, ...options?.env },\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n proc.stdout.on(\"data\", (data) => {\n stdout += data.toString();\n });\n\n proc.stderr.on(\"data\", (data) => {\n stderr += data.toString();\n });\n\n proc.on(\"close\", (code) => {\n resolve({\n stdout,\n stderr,\n exitCode: code ?? 1,\n });\n });\n\n proc.on(\"error\", (err) => {\n reject(err);\n });\n });\n}\n\n/**\n * Install a plugin using the native claude CLI\n */\nexport async function claudePluginInstall(\n pluginPath: string,\n scope: \"project\" | \"user\",\n projectDir: string,\n): Promise<void> {\n const args = [\"plugin\", \"install\", pluginPath, \"--scope\", scope];\n const result = await execCommand(\"claude\", args, { cwd: projectDir });\n\n if (result.exitCode !== 0) {\n const errorMessage = result.stderr || result.stdout || \"Unknown error\";\n throw new Error(`Plugin installation failed: ${errorMessage.trim()}`);\n }\n}\n\n/**\n * Check if the claude CLI is available\n */\nexport async function isClaudeCLIAvailable(): Promise<boolean> {\n try {\n const result = await execCommand(\"claude\", [\"--version\"], {});\n return result.exitCode === 0;\n } catch {\n return false;\n }\n}\n\nexport interface MarketplaceInfo {\n name: string;\n source: string;\n repo?: string;\n path?: string;\n}\n\n/**\n * List configured marketplaces in Claude Code\n */\nexport async function claudePluginMarketplaceList(): Promise<MarketplaceInfo[]> {\n try {\n const result = await execCommand(\"claude\", [\"plugin\", \"marketplace\", \"list\", \"--json\"], {});\n\n if (result.exitCode !== 0) {\n return [];\n }\n\n return JSON.parse(result.stdout);\n } catch {\n // Returns empty array if claude CLI is not available or parsing fails\n return [];\n }\n}\n\n/**\n * Check if a marketplace with the given name exists\n */\nexport async function claudePluginMarketplaceExists(name: string): Promise<boolean> {\n const marketplaces = await claudePluginMarketplaceList();\n return marketplaces.some((m) => m.name === name);\n}\n\n/**\n * Add a marketplace to Claude Code from a GitHub repository\n */\nexport async function claudePluginMarketplaceAdd(githubRepo: string, name: string): Promise<void> {\n const args = [\"plugin\", \"marketplace\", \"add\", githubRepo, \"--name\", name];\n let result;\n try {\n result = await execCommand(\"claude\", args, {});\n } catch (err) {\n throw new Error(\n `Failed to add marketplace: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n );\n }\n\n if (result.exitCode !== 0) {\n const errorMessage = result.stderr || result.stdout || \"Unknown error\";\n if (errorMessage.includes(\"already installed\")) {\n return;\n }\n throw new Error(`Failed to add marketplace: ${errorMessage.trim()}`);\n }\n}\n\n/**\n * Uninstall a plugin using the native claude CLI\n */\nexport async function claudePluginUninstall(\n pluginName: string,\n scope: \"project\" | \"user\",\n projectDir: string,\n): Promise<void> {\n const args = [\"plugin\", \"uninstall\", pluginName, \"--scope\", scope];\n const result = await execCommand(\"claude\", args, { cwd: projectDir });\n\n if (result.exitCode !== 0) {\n const errorMessage = result.stderr || result.stdout || \"Unknown error\";\n // Ignore \"not installed\" errors - plugin may already be removed\n if (errorMessage.includes(\"not installed\") || errorMessage.includes(\"not found\")) {\n return;\n }\n throw new Error(`Plugin uninstall failed: ${errorMessage.trim()}`);\n }\n}\n"],"mappings":"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","names":[]}
@@ -56,4 +56,4 @@ export {
56
56
  DEFAULT_DISPLAY_VERSION,
57
57
  DEFAULT_PRESELECTED_SKILLS
58
58
  };
59
- //# sourceMappingURL=chunk-76DWXGQE.js.map
59
+ //# sourceMappingURL=chunk-FJFEKPXF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/consts.ts"],"sourcesContent":["import path from \"path\";\nimport os from \"os\";\nimport { fileURLToPath } from \"url\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// After tsup build, dist/ is flat, so we go up one level from dist/ to get CLI root\n// In development (src/cli/consts.ts), we go up two levels\nconst isInDist = __dirname.includes(\"/dist\");\nexport const CLI_ROOT = isInDist ? path.resolve(__dirname, \"..\") : path.resolve(__dirname, \"../..\");\nexport const PROJECT_ROOT = CLI_ROOT;\n\nexport const OUTPUT_DIR = \".claude\";\nexport const GITHUB_REPO = \"claude-collective/skills\";\nexport const DEFAULT_MATRIX_PATH = \"src/config/skills-matrix.yaml\";\n\nexport const PLUGIN_NAME = \"claude-collective\";\n\nexport const CLAUDE_DIR = \".claude\";\nexport const CLAUDE_SRC_DIR = \".claude-src\";\nexport const PLUGINS_SUBDIR = \"plugins\";\nexport const PLUGIN_MANIFEST_DIR = \".claude-plugin\";\nexport const PLUGIN_MANIFEST_FILE = \"plugin.json\";\n\nexport const CACHE_DIR = path.join(os.homedir(), \".cache\", \"claude-collective\");\n\nexport const SKILLS_MATRIX_PATH = \"config/skills-matrix.yaml\";\nexport const SKILLS_DIR_PATH = \"src/skills\";\nexport const LOCAL_SKILLS_PATH = \".claude/skills\";\n\nexport const DIRS = {\n agents: \"src/agents\",\n skills: \"src/skills\",\n stacks: \"src/stacks\",\n templates: \"src/agents/_templates\",\n commands: \"src/commands\",\n} as const;\n\nexport const DEFAULT_VERSION = \"1.0.0\";\n\n/** Uses \"0.0.0\" to clearly indicate \"no version was explicitly set\" */\nexport const DEFAULT_DISPLAY_VERSION = \"0.0.0\";\n\n/**\n * Skills that are preselected by default in the wizard.\n * These are foundational methodology skills that apply to all projects.\n *\n * Note: Skill IDs are in normalized kebab-case format (no author suffix, slashes replaced with dashes).\n */\nexport const DEFAULT_PRESELECTED_SKILLS = [\n \"meta-methodology-anti-over-engineering\",\n \"meta-methodology-context-management\",\n \"meta-methodology-improvement-protocol\",\n \"meta-methodology-investigation-requirements\",\n \"meta-methodology-success-criteria\",\n \"meta-methodology-write-verification\",\n] as const;\n"],"mappings":";;;;;;AAAA;AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,SAAS,qBAAqB;AAE9B,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAY,KAAK,QAAQ,UAAU;AAIzC,IAAM,WAAW,UAAU,SAAS,OAAO;AACpC,IAAM,WAAW,WAAW,KAAK,QAAQ,WAAW,IAAI,IAAI,KAAK,QAAQ,WAAW,OAAO;AAC3F,IAAM,eAAe;AAQrB,IAAM,aAAa;AACnB,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AACvB,IAAM,sBAAsB;AAC5B,IAAM,uBAAuB;AAE7B,IAAM,YAAY,KAAK,KAAK,GAAG,QAAQ,GAAG,UAAU,mBAAmB;AAEvE,IAAM,qBAAqB;AAC3B,IAAM,kBAAkB;AACxB,IAAM,oBAAoB;AAE1B,IAAM,OAAO;AAAA,EAClB,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,UAAU;AACZ;AAEO,IAAM,kBAAkB;AAGxB,IAAM,0BAA0B;AAQhC,IAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
@@ -1,7 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- WizardFooter
4
- } from "./chunk-Y2LW7R3Y.js";
5
2
  import {
6
3
  init_esm_shims
7
4
  } from "./chunk-DHET7RCE.js";
@@ -62,19 +59,11 @@ var StepRefine = ({
62
59
  " Customize skill sources ",
63
60
  /* @__PURE__ */ jsx(Text, { color: "gray", children: "(coming soon)" })
64
61
  ] }) }),
65
- /* @__PURE__ */ jsx(Box, { paddingLeft: 4, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Choose alternative skills for each technology" }) }),
66
- /* @__PURE__ */ jsx(Text, { children: " " }),
67
- /* @__PURE__ */ jsx(
68
- WizardFooter,
69
- {
70
- navigation: "\u2191/\u2193 navigate",
71
- action: "ENTER continue ESC back"
72
- }
73
- )
62
+ /* @__PURE__ */ jsx(Box, { paddingLeft: 4, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Choose alternative skills for each technology" }) })
74
63
  ] });
75
64
  };
76
65
 
77
66
  export {
78
67
  StepRefine
79
68
  };
80
- //# sourceMappingURL=chunk-E3FJH4TF.js.map
69
+ //# sourceMappingURL=chunk-HEOHU5EZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/step-refine.tsx"],"sourcesContent":["/**\n * StepRefine component - Refine step for skill source selection.\n *\n * For Phase 7, this implements only the \"Use all recommended\" path.\n * The \"Customize\" option (skills.sh integration) is deferred to Phase 8.\n *\n * Visual design:\n * - Prominent \"Use all recommended\" option with border (default/selected)\n * - Grayed out \"Customize\" option with \"(coming soon)\" label\n * - Keyboard navigation: Enter to continue, Escape to go back\n */\nimport React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type RefineAction = \"all-recommended\" | \"customize\" | null;\n\nexport interface StepRefineProps {\n /** Count of selected technologies */\n technologyCount: number;\n /** Current selection: use all recommended or customize */\n refineAction: RefineAction;\n /** Callback when action is selected (only non-null values) */\n onSelectAction: (action: \"all-recommended\" | \"customize\") => void;\n /** Continue to confirm step */\n onContinue: () => void;\n /** Go back to build step */\n onBack: () => void;\n}\n\n// =============================================================================\n// Main Component\n// =============================================================================\n\nexport const StepRefine: React.FC<StepRefineProps> = ({\n technologyCount,\n refineAction,\n onSelectAction,\n onContinue,\n onBack,\n}) => {\n useInput((input, key) => {\n if (key.return) {\n onContinue();\n }\n if (key.escape) {\n onBack();\n }\n // Arrow keys to move between options (for future)\n // For now, only \"all-recommended\" is selectable\n if (key.upArrow || key.downArrow) {\n onSelectAction(\"all-recommended\");\n }\n });\n\n // Determine if \"all-recommended\" is the current selection\n // Default to \"all-recommended\" if nothing selected\n const isRecommendedSelected = refineAction === \"all-recommended\" || refineAction === null;\n\n return (\n <Box flexDirection=\"column\" paddingX={2}>\n {/* Technology count header */}\n <Text>\n Your stack includes{\" \"}\n <Text color=\"cyan\" bold>\n {technologyCount}\n </Text>{\" \"}\n technologies.\n </Text>\n <Text> </Text>\n\n {/* Recommended option - highlighted with border */}\n <Box\n borderStyle=\"round\"\n borderColor={isRecommendedSelected ? \"green\" : \"gray\"}\n paddingX={2}\n paddingY={1}\n marginBottom={1}\n >\n <Box flexDirection=\"column\">\n <Text color=\"green\" bold>\n {\">\"} Use all recommended skills (verified)\n </Text>\n <Text> </Text>\n <Text dimColor>This is the fastest option. All skills are verified and</Text>\n <Text dimColor>maintained by Claude Collective.</Text>\n </Box>\n </Box>\n\n {/* Customize option - disabled/grayed */}\n <Box paddingLeft={2}>\n <Text dimColor>\n {\"○\"} Customize skill sources <Text color=\"gray\">(coming soon)</Text>\n </Text>\n </Box>\n <Box paddingLeft={4}>\n <Text dimColor>Choose alternative skills for each technology</Text>\n </Box>\n </Box>\n );\n};\n"],"mappings":";;;;;;AAAA;AAYA,SAAS,KAAK,MAAM,gBAAgB;AAqD9B,SAEE,KAFF;AA5BC,IAAM,aAAwC,CAAC;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,WAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,IAAI,QAAQ;AACd,iBAAW;AAAA,IACb;AACA,QAAI,IAAI,QAAQ;AACd,aAAO;AAAA,IACT;AAGA,QAAI,IAAI,WAAW,IAAI,WAAW;AAChC,qBAAe,iBAAiB;AAAA,IAClC;AAAA,EACF,CAAC;AAID,QAAM,wBAAwB,iBAAiB,qBAAqB,iBAAiB;AAErF,SACE,qBAAC,OAAI,eAAc,UAAS,UAAU,GAEpC;AAAA,yBAAC,QAAK;AAAA;AAAA,MACgB;AAAA,MACpB,oBAAC,QAAK,OAAM,QAAO,MAAI,MACpB,2BACH;AAAA,MAAQ;AAAA,MAAI;AAAA,OAEd;AAAA,IACA,oBAAC,QAAK,eAAC;AAAA,IAGP;AAAA,MAAC;AAAA;AAAA,QACC,aAAY;AAAA,QACZ,aAAa,wBAAwB,UAAU;AAAA,QAC/C,UAAU;AAAA,QACV,UAAU;AAAA,QACV,cAAc;AAAA,QAEd,+BAAC,OAAI,eAAc,UACjB;AAAA,+BAAC,QAAK,OAAM,SAAQ,MAAI,MACrB;AAAA;AAAA,YAAI;AAAA,aACP;AAAA,UACA,oBAAC,QAAK,eAAC;AAAA,UACP,oBAAC,QAAK,UAAQ,MAAC,qEAAuD;AAAA,UACtE,oBAAC,QAAK,UAAQ,MAAC,8CAAgC;AAAA,WACjD;AAAA;AAAA,IACF;AAAA,IAGA,oBAAC,OAAI,aAAa,GAChB,+BAAC,QAAK,UAAQ,MACX;AAAA;AAAA,MAAI;AAAA,MAAyB,oBAAC,QAAK,OAAM,QAAO,2BAAa;AAAA,OAChE,GACF;AAAA,IACA,oBAAC,OAAI,aAAa,GAChB,8BAAC,QAAK,UAAQ,MAAC,2DAA6C,GAC9D;AAAA,KACF;AAEJ;","names":[]}
@@ -7,13 +7,11 @@ import {
7
7
  SOURCE_ENV_VAR,
8
8
  formatAgentsSourceOrigin,
9
9
  formatSourceOrigin,
10
- getGlobalConfigPath,
11
10
  getProjectConfigPath,
12
- loadGlobalConfig,
13
11
  loadProjectConfig,
14
12
  resolveAgentsSource,
15
13
  resolveSource
16
- } from "./chunk-V46GGCCI.js";
14
+ } from "./chunk-374JNMR6.js";
17
15
  import {
18
16
  init_esm_shims
19
17
  } from "./chunk-DHET7RCE.js";
@@ -22,7 +20,7 @@ import {
22
20
  init_esm_shims();
23
21
  var ConfigShow = class _ConfigShow extends BaseCommand {
24
22
  static summary = "Show current effective configuration";
25
- static description = "Display the current effective configuration with all layers (env, project, global, default)";
23
+ static description = "Display the current effective configuration with all layers (env, project, default)";
26
24
  static flags = {
27
25
  ...BaseCommand.baseFlags
28
26
  };
@@ -46,9 +44,7 @@ var ConfigShow = class _ConfigShow extends BaseCommand {
46
44
  this.log("Agents Source:");
47
45
  if (agentsResolved.agentsSource) {
48
46
  this.log(` ${agentsResolved.agentsSource}`);
49
- this.log(
50
- ` (from ${formatAgentsSourceOrigin(agentsResolved.agentsSourceOrigin)})`
51
- );
47
+ this.log(` (from ${formatAgentsSourceOrigin(agentsResolved.agentsSourceOrigin)})`);
52
48
  } else {
53
49
  this.log(` (not configured - using local CLI)`);
54
50
  }
@@ -79,27 +75,10 @@ var ConfigShow = class _ConfigShow extends BaseCommand {
79
75
  } else {
80
76
  this.log(` (not configured)`);
81
77
  }
82
- const globalConfig = await loadGlobalConfig();
83
- const globalConfigPath = getGlobalConfigPath();
84
- this.log(` 3. Global config:`);
85
- this.log(` ${globalConfigPath}`);
86
- if (globalConfig?.source || globalConfig?.marketplace || globalConfig?.agents_source) {
87
- if (globalConfig?.source) {
88
- this.log(` source: ${globalConfig.source}`);
89
- }
90
- if (globalConfig?.marketplace) {
91
- this.log(` marketplace: ${globalConfig.marketplace}`);
92
- }
93
- if (globalConfig?.agents_source) {
94
- this.log(` agents_source: ${globalConfig.agents_source}`);
95
- }
96
- } else {
97
- this.log(` (not configured)`);
98
- }
99
- this.log(` 4. Default:`);
78
+ this.log(` 3. Default:`);
100
79
  this.log(` ${DEFAULT_SOURCE}`);
101
80
  this.log("");
102
- this.log("Precedence: flag > env > project > global > default");
81
+ this.log("Precedence: flag > env > project > default");
103
82
  this.log("");
104
83
  }
105
84
  };
@@ -107,4 +86,4 @@ var ConfigShow = class _ConfigShow extends BaseCommand {
107
86
  export {
108
87
  ConfigShow
109
88
  };
110
- //# sourceMappingURL=chunk-JIPWV2FX.js.map
89
+ //# sourceMappingURL=chunk-HGCBZUH5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/config/show.ts"],"sourcesContent":["import { BaseCommand } from \"../../base-command.js\";\nimport {\n resolveSource,\n resolveAgentsSource,\n loadProjectConfig,\n getProjectConfigPath,\n formatSourceOrigin,\n formatAgentsSourceOrigin,\n DEFAULT_SOURCE,\n SOURCE_ENV_VAR,\n} from \"../../lib/config.js\";\n\nexport default class ConfigShow extends BaseCommand {\n static summary = \"Show current effective configuration\";\n static description =\n \"Display the current effective configuration with all layers (env, project, default)\";\n\n static flags = {\n ...BaseCommand.baseFlags,\n };\n\n async run(): Promise<void> {\n await this.parse(ConfigShow);\n\n const projectDir = process.cwd();\n\n this.log(\"\\nClaude Collective Configuration\\n\");\n\n const resolved = await resolveSource(undefined, projectDir);\n\n this.log(\"Source:\");\n this.log(` ${resolved.source}`);\n this.log(` (from ${formatSourceOrigin(resolved.sourceOrigin)})`);\n this.log(\"\");\n\n this.log(\"Marketplace:\");\n if (resolved.marketplace) {\n this.log(` ${resolved.marketplace}`);\n } else {\n this.log(` (not configured)`);\n }\n this.log(\"\");\n\n const agentsResolved = await resolveAgentsSource(undefined, projectDir);\n this.log(\"Agents Source:\");\n if (agentsResolved.agentsSource) {\n this.log(` ${agentsResolved.agentsSource}`);\n this.log(` (from ${formatAgentsSourceOrigin(agentsResolved.agentsSourceOrigin)})`);\n } else {\n this.log(` (not configured - using local CLI)`);\n }\n this.log(\"\");\n\n this.log(\"Configuration Layers:\");\n this.log(\"\");\n\n const envValue = process.env[SOURCE_ENV_VAR];\n this.log(` 1. Environment (${SOURCE_ENV_VAR}):`);\n if (envValue) {\n this.log(` ${envValue}`);\n } else {\n this.log(` (not set)`);\n }\n\n const projectConfig = await loadProjectConfig(projectDir);\n const projectConfigPath = getProjectConfigPath(projectDir);\n this.log(` 2. Project config:`);\n this.log(` ${projectConfigPath}`);\n if (projectConfig?.source || projectConfig?.marketplace || projectConfig?.agents_source) {\n if (projectConfig?.source) {\n this.log(` source: ${projectConfig.source}`);\n }\n if (projectConfig?.marketplace) {\n this.log(` marketplace: ${projectConfig.marketplace}`);\n }\n if (projectConfig?.agents_source) {\n this.log(` agents_source: ${projectConfig.agents_source}`);\n }\n } else {\n this.log(` (not configured)`);\n }\n\n this.log(` 3. Default:`);\n this.log(` ${DEFAULT_SOURCE}`);\n\n this.log(\"\");\n this.log(\"Precedence: flag > env > project > default\");\n this.log(\"\");\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAYA,IAAqB,aAArB,MAAqB,oBAAmB,YAAY;AAAA,EAClD,OAAO,UAAU;AAAA,EACjB,OAAO,cACL;AAAA,EAEF,OAAO,QAAQ;AAAA,IACb,GAAG,YAAY;AAAA,EACjB;AAAA,EAEA,MAAM,MAAqB;AACzB,UAAM,KAAK,MAAM,WAAU;AAE3B,UAAM,aAAa,QAAQ,IAAI;AAE/B,SAAK,IAAI,qCAAqC;AAE9C,UAAM,WAAW,MAAM,cAAc,QAAW,UAAU;AAE1D,SAAK,IAAI,SAAS;AAClB,SAAK,IAAI,KAAK,SAAS,MAAM,EAAE;AAC/B,SAAK,IAAI,WAAW,mBAAmB,SAAS,YAAY,CAAC,GAAG;AAChE,SAAK,IAAI,EAAE;AAEX,SAAK,IAAI,cAAc;AACvB,QAAI,SAAS,aAAa;AACxB,WAAK,IAAI,KAAK,SAAS,WAAW,EAAE;AAAA,IACtC,OAAO;AACL,WAAK,IAAI,oBAAoB;AAAA,IAC/B;AACA,SAAK,IAAI,EAAE;AAEX,UAAM,iBAAiB,MAAM,oBAAoB,QAAW,UAAU;AACtE,SAAK,IAAI,gBAAgB;AACzB,QAAI,eAAe,cAAc;AAC/B,WAAK,IAAI,KAAK,eAAe,YAAY,EAAE;AAC3C,WAAK,IAAI,WAAW,yBAAyB,eAAe,kBAAkB,CAAC,GAAG;AAAA,IACpF,OAAO;AACL,WAAK,IAAI,sCAAsC;AAAA,IACjD;AACA,SAAK,IAAI,EAAE;AAEX,SAAK,IAAI,uBAAuB;AAChC,SAAK,IAAI,EAAE;AAEX,UAAM,WAAW,QAAQ,IAAI,cAAc;AAC3C,SAAK,IAAI,qBAAqB,cAAc,IAAI;AAChD,QAAI,UAAU;AACZ,WAAK,IAAI,QAAQ,QAAQ,EAAE;AAAA,IAC7B,OAAO;AACL,WAAK,IAAI,gBAAgB;AAAA,IAC3B;AAEA,UAAM,gBAAgB,MAAM,kBAAkB,UAAU;AACxD,UAAM,oBAAoB,qBAAqB,UAAU;AACzD,SAAK,IAAI,sBAAsB;AAC/B,SAAK,IAAI,QAAQ,iBAAiB,EAAE;AACpC,QAAI,eAAe,UAAU,eAAe,eAAe,eAAe,eAAe;AACvF,UAAI,eAAe,QAAQ;AACzB,aAAK,IAAI,gBAAgB,cAAc,MAAM,EAAE;AAAA,MACjD;AACA,UAAI,eAAe,aAAa;AAC9B,aAAK,IAAI,qBAAqB,cAAc,WAAW,EAAE;AAAA,MAC3D;AACA,UAAI,eAAe,eAAe;AAChC,aAAK,IAAI,uBAAuB,cAAc,aAAa,EAAE;AAAA,MAC/D;AAAA,IACF,OAAO;AACL,WAAK,IAAI,uBAAuB;AAAA,IAClC;AAEA,SAAK,IAAI,eAAe;AACxB,SAAK,IAAI,QAAQ,cAAc,EAAE;AAEjC,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,4CAA4C;AACrD,SAAK,IAAI,EAAE;AAAA,EACb;AACF;","names":[]}
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  verbose
4
- } from "./chunk-3U3R4NCG.js";
4
+ } from "./chunk-T25OEQFI.js";
5
5
  import {
6
6
  fileExists,
7
7
  glob,
8
8
  readFile
9
- } from "./chunk-TKFPKEV3.js";
9
+ } from "./chunk-AL74GBW4.js";
10
10
  import {
11
11
  CLAUDE_DIR,
12
12
  PLUGINS_SUBDIR,
13
13
  PLUGIN_MANIFEST_DIR,
14
14
  PLUGIN_MANIFEST_FILE
15
- } from "./chunk-76DWXGQE.js";
15
+ } from "./chunk-FJFEKPXF.js";
16
16
  import {
17
17
  init_esm_shims
18
18
  } from "./chunk-DHET7RCE.js";
@@ -111,4 +111,4 @@ export {
111
111
  readPluginManifest,
112
112
  getPluginSkillIds
113
113
  };
114
- //# sourceMappingURL=chunk-ED4E6Q2T.js.map
114
+ //# sourceMappingURL=chunk-HPGFY5ZN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/lib/plugin-finder.ts"],"sourcesContent":["import path from \"path\";\nimport os from \"os\";\nimport { fileExists, readFile, glob } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport { CLAUDE_DIR, PLUGINS_SUBDIR, PLUGIN_MANIFEST_DIR, PLUGIN_MANIFEST_FILE } from \"../consts\";\nimport type { PluginManifest } from \"../../types\";\nimport type { MergedSkillsMatrix } from \"../types-matrix\";\n\nexport function getUserPluginsDir(): string {\n return path.join(os.homedir(), CLAUDE_DIR, PLUGINS_SUBDIR);\n}\n\nexport function getCollectivePluginDir(projectDir?: string): string {\n const dir = projectDir ?? process.cwd();\n return path.join(dir, CLAUDE_DIR, PLUGINS_SUBDIR, \"claude-collective\");\n}\n\nexport function getProjectPluginsDir(projectDir?: string): string {\n const dir = projectDir ?? process.cwd();\n return path.join(dir, CLAUDE_DIR, PLUGINS_SUBDIR);\n}\n\nexport function getPluginSkillsDir(pluginDir: string): string {\n return path.join(pluginDir, \"skills\");\n}\n\nexport function getPluginAgentsDir(pluginDir: string): string {\n return path.join(pluginDir, \"agents\");\n}\n\nexport function getPluginManifestPath(pluginDir: string): string {\n return path.join(pluginDir, PLUGIN_MANIFEST_DIR, PLUGIN_MANIFEST_FILE);\n}\n\nexport async function readPluginManifest(pluginDir: string): Promise<PluginManifest | null> {\n const manifestPath = getPluginManifestPath(pluginDir);\n\n if (!(await fileExists(manifestPath))) {\n verbose(` No manifest at ${manifestPath}`);\n return null;\n }\n\n try {\n const content = await readFile(manifestPath);\n const manifest = JSON.parse(content) as PluginManifest;\n\n if (!manifest.name || typeof manifest.name !== \"string\") {\n verbose(` Invalid manifest at ${manifestPath}: missing name`);\n return null;\n }\n\n return manifest;\n } catch (error) {\n verbose(` Failed to parse manifest at ${manifestPath}: ${error}`);\n return null;\n }\n}\n\nexport async function getPluginSkillIds(\n pluginSkillsDir: string,\n matrix: MergedSkillsMatrix,\n): Promise<string[]> {\n const skillFiles = await glob(\"**/SKILL.md\", pluginSkillsDir);\n const skillIds: string[] = [];\n\n const nameToId = new Map<string, string>();\n for (const [id, skill] of Object.entries(matrix.skills)) {\n nameToId.set(skill.name.toLowerCase(), id);\n if (skill.alias) {\n nameToId.set(skill.alias.toLowerCase(), id);\n }\n }\n\n const dirToId = new Map<string, string>();\n for (const [id, skill] of Object.entries(matrix.skills)) {\n const baseName = skill.name.toLowerCase().replace(/\\s+/g, \"-\");\n dirToId.set(baseName, id);\n\n const idParts = id.split(\"/\");\n const lastPart = idParts[idParts.length - 1];\n if (lastPart) {\n dirToId.set(lastPart.toLowerCase(), id);\n }\n }\n\n for (const skillFile of skillFiles) {\n const fullPath = path.join(pluginSkillsDir, skillFile);\n const content = await readFile(fullPath);\n\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (frontmatterMatch) {\n const frontmatter = frontmatterMatch[1];\n const nameMatch = frontmatter.match(/^name:\\s*[\"']?(.+?)[\"']?\\s*$/m);\n if (nameMatch) {\n const skillName = nameMatch[1].trim();\n const skillId = nameToId.get(skillName.toLowerCase());\n if (skillId) {\n skillIds.push(skillId);\n continue;\n }\n }\n }\n\n const dirPath = path.dirname(skillFile);\n const dirName = path.basename(dirPath);\n const skillId = dirToId.get(dirName.toLowerCase());\n if (skillId) {\n skillIds.push(skillId);\n }\n }\n\n return skillIds;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA,OAAO,UAAU;AAYV,SAAS,uBAAuB,YAA6B;AAClE,QAAM,MAAM,cAAc,QAAQ,IAAI;AACtC,SAAO,KAAK,KAAK,KAAK,YAAY,gBAAgB,mBAAmB;AACvE;AAEO,SAAS,qBAAqB,YAA6B;AAChE,QAAM,MAAM,cAAc,QAAQ,IAAI;AACtC,SAAO,KAAK,KAAK,KAAK,YAAY,cAAc;AAClD;AAEO,SAAS,mBAAmB,WAA2B;AAC5D,SAAO,KAAK,KAAK,WAAW,QAAQ;AACtC;AAEO,SAAS,mBAAmB,WAA2B;AAC5D,SAAO,KAAK,KAAK,WAAW,QAAQ;AACtC;AAEO,SAAS,sBAAsB,WAA2B;AAC/D,SAAO,KAAK,KAAK,WAAW,qBAAqB,oBAAoB;AACvE;AAEA,eAAsB,mBAAmB,WAAmD;AAC1F,QAAM,eAAe,sBAAsB,SAAS;AAEpD,MAAI,CAAE,MAAM,WAAW,YAAY,GAAI;AACrC,YAAQ,oBAAoB,YAAY,EAAE;AAC1C,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,YAAY;AAC3C,UAAM,WAAW,KAAK,MAAM,OAAO;AAEnC,QAAI,CAAC,SAAS,QAAQ,OAAO,SAAS,SAAS,UAAU;AACvD,cAAQ,yBAAyB,YAAY,gBAAgB;AAC7D,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,iCAAiC,YAAY,KAAK,KAAK,EAAE;AACjE,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBACpB,iBACA,QACmB;AACnB,QAAM,aAAa,MAAM,KAAK,eAAe,eAAe;AAC5D,QAAM,WAAqB,CAAC;AAE5B,QAAM,WAAW,oBAAI,IAAoB;AACzC,aAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,OAAO,MAAM,GAAG;AACvD,aAAS,IAAI,MAAM,KAAK,YAAY,GAAG,EAAE;AACzC,QAAI,MAAM,OAAO;AACf,eAAS,IAAI,MAAM,MAAM,YAAY,GAAG,EAAE;AAAA,IAC5C;AAAA,EACF;AAEA,QAAM,UAAU,oBAAI,IAAoB;AACxC,aAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,OAAO,MAAM,GAAG;AACvD,UAAM,WAAW,MAAM,KAAK,YAAY,EAAE,QAAQ,QAAQ,GAAG;AAC7D,YAAQ,IAAI,UAAU,EAAE;AAExB,UAAM,UAAU,GAAG,MAAM,GAAG;AAC5B,UAAM,WAAW,QAAQ,QAAQ,SAAS,CAAC;AAC3C,QAAI,UAAU;AACZ,cAAQ,IAAI,SAAS,YAAY,GAAG,EAAE;AAAA,IACxC;AAAA,EACF;AAEA,aAAW,aAAa,YAAY;AAClC,UAAM,WAAW,KAAK,KAAK,iBAAiB,SAAS;AACrD,UAAM,UAAU,MAAM,SAAS,QAAQ;AAEvC,UAAM,mBAAmB,QAAQ,MAAM,uBAAuB;AAC9D,QAAI,kBAAkB;AACpB,YAAM,cAAc,iBAAiB,CAAC;AACtC,YAAM,YAAY,YAAY,MAAM,+BAA+B;AACnE,UAAI,WAAW;AACb,cAAM,YAAY,UAAU,CAAC,EAAE,KAAK;AACpC,cAAMA,WAAU,SAAS,IAAI,UAAU,YAAY,CAAC;AACpD,YAAIA,UAAS;AACX,mBAAS,KAAKA,QAAO;AACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,KAAK,QAAQ,SAAS;AACtC,UAAM,UAAU,KAAK,SAAS,OAAO;AACrC,UAAM,UAAU,QAAQ,IAAI,QAAQ,YAAY,CAAC;AACjD,QAAI,SAAS;AACX,eAAS,KAAK,OAAO;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;","names":["skillId"]}
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ getCurrentDate,
4
+ hashFile
5
+ } from "./chunk-IOBFMF6X.js";
6
+ import {
7
+ fileExists,
8
+ listDirectories,
9
+ readFile,
10
+ writeFile
11
+ } from "./chunk-AL74GBW4.js";
12
+ import {
13
+ LOCAL_SKILLS_PATH
14
+ } from "./chunk-FJFEKPXF.js";
15
+ import {
16
+ init_esm_shims
17
+ } from "./chunk-DHET7RCE.js";
18
+
19
+ // src/cli/lib/skill-metadata.ts
20
+ init_esm_shims();
21
+ import path from "path";
22
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
23
+ async function readForkedFromMetadata(skillDir) {
24
+ const metadataPath = path.join(skillDir, "metadata.yaml");
25
+ if (!await fileExists(metadataPath)) {
26
+ return null;
27
+ }
28
+ const content = await readFile(metadataPath);
29
+ const metadata = parseYaml(content);
30
+ return metadata.forked_from ?? null;
31
+ }
32
+ async function getLocalSkillsWithMetadata(projectDir) {
33
+ const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);
34
+ const result = /* @__PURE__ */ new Map();
35
+ if (!await fileExists(localSkillsPath)) {
36
+ return result;
37
+ }
38
+ const skillDirs = await listDirectories(localSkillsPath);
39
+ for (const dirName of skillDirs) {
40
+ const skillDir = path.join(localSkillsPath, dirName);
41
+ const forkedFrom = await readForkedFromMetadata(skillDir);
42
+ const skillId = forkedFrom?.skill_id ?? dirName;
43
+ result.set(skillId, { dirName, forkedFrom });
44
+ }
45
+ return result;
46
+ }
47
+ async function computeSourceHash(sourcePath, skillPath) {
48
+ const skillMdPath = path.join(sourcePath, "src", skillPath, "SKILL.md");
49
+ if (!await fileExists(skillMdPath)) {
50
+ return null;
51
+ }
52
+ return hashFile(skillMdPath);
53
+ }
54
+ async function compareSkills(projectDir, sourcePath, sourceSkills) {
55
+ const results = [];
56
+ const localSkills = await getLocalSkillsWithMetadata(projectDir);
57
+ for (const [skillId, { dirName, forkedFrom }] of localSkills) {
58
+ if (!forkedFrom) {
59
+ results.push({
60
+ id: skillId,
61
+ localHash: null,
62
+ sourceHash: null,
63
+ status: "local-only",
64
+ dirName
65
+ });
66
+ continue;
67
+ }
68
+ const localHash = forkedFrom.content_hash;
69
+ const sourceSkill = sourceSkills[forkedFrom.skill_id];
70
+ if (!sourceSkill) {
71
+ results.push({
72
+ id: forkedFrom.skill_id,
73
+ localHash,
74
+ sourceHash: null,
75
+ status: "local-only",
76
+ dirName
77
+ });
78
+ continue;
79
+ }
80
+ const sourceHash = await computeSourceHash(sourcePath, sourceSkill.path);
81
+ if (sourceHash === null) {
82
+ results.push({
83
+ id: forkedFrom.skill_id,
84
+ localHash,
85
+ sourceHash: null,
86
+ status: "local-only",
87
+ dirName
88
+ });
89
+ continue;
90
+ }
91
+ const status = localHash === sourceHash ? "current" : "outdated";
92
+ results.push({
93
+ id: forkedFrom.skill_id,
94
+ localHash,
95
+ sourceHash,
96
+ status,
97
+ dirName,
98
+ sourcePath: sourceSkill.path
99
+ });
100
+ }
101
+ results.sort((a, b) => a.id.localeCompare(b.id));
102
+ return results;
103
+ }
104
+ async function injectForkedFromMetadata(destPath, skillId, contentHash) {
105
+ const metadataPath = path.join(destPath, "metadata.yaml");
106
+ const rawContent = await readFile(metadataPath);
107
+ const lines = rawContent.split("\n");
108
+ let yamlContent = rawContent;
109
+ if (lines[0]?.startsWith("# yaml-language-server:")) {
110
+ yamlContent = lines.slice(1).join("\n");
111
+ }
112
+ const metadata = parseYaml(yamlContent);
113
+ metadata.forked_from = {
114
+ skill_id: skillId,
115
+ content_hash: contentHash,
116
+ date: getCurrentDate()
117
+ };
118
+ const newYamlContent = stringifyYaml(metadata, { lineWidth: 0 });
119
+ await writeFile(metadataPath, newYamlContent);
120
+ }
121
+
122
+ export {
123
+ readForkedFromMetadata,
124
+ compareSkills,
125
+ injectForkedFromMetadata
126
+ };
127
+ //# sourceMappingURL=chunk-INJ2EFRW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/lib/skill-metadata.ts"],"sourcesContent":["import path from \"path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { fileExists, readFile, writeFile, listDirectories } from \"../utils/fs\";\nimport { hashFile } from \"./versioning\";\nimport { getCurrentDate } from \"./versioning\";\nimport { LOCAL_SKILLS_PATH } from \"../consts\";\n\n/**\n * ForkedFrom metadata stored in local skill's metadata.yaml\n */\nexport interface ForkedFromMetadata {\n skill_id: string;\n content_hash: string;\n date: string;\n}\n\n/**\n * Local skill metadata structure\n */\nexport interface LocalSkillMetadata {\n forked_from?: ForkedFromMetadata;\n [key: string]: unknown;\n}\n\n/**\n * Result of comparing a local skill to its source\n */\nexport interface SkillComparisonResult {\n id: string;\n localHash: string | null;\n sourceHash: string | null;\n status: \"current\" | \"outdated\" | \"local-only\";\n dirName: string;\n sourcePath?: string;\n}\n\n/**\n * Read forked_from metadata from a local skill's metadata.yaml\n */\nexport async function readForkedFromMetadata(skillDir: string): Promise<ForkedFromMetadata | null> {\n const metadataPath = path.join(skillDir, \"metadata.yaml\");\n\n if (!(await fileExists(metadataPath))) {\n return null;\n }\n\n const content = await readFile(metadataPath);\n const metadata = parseYaml(content) as LocalSkillMetadata;\n\n return metadata.forked_from ?? null;\n}\n\n/**\n * Get local skills with their forked_from metadata\n */\nexport async function getLocalSkillsWithMetadata(\n projectDir: string,\n): Promise<Map<string, { dirName: string; forkedFrom: ForkedFromMetadata | null }>> {\n const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);\n const result = new Map<string, { dirName: string; forkedFrom: ForkedFromMetadata | null }>();\n\n if (!(await fileExists(localSkillsPath))) {\n return result;\n }\n\n const skillDirs = await listDirectories(localSkillsPath);\n\n for (const dirName of skillDirs) {\n const skillDir = path.join(localSkillsPath, dirName);\n const forkedFrom = await readForkedFromMetadata(skillDir);\n\n // Use the skill_id from forked_from if available, otherwise use directory name\n const skillId = forkedFrom?.skill_id ?? dirName;\n\n result.set(skillId, { dirName, forkedFrom });\n }\n\n return result;\n}\n\n/**\n * Compute source hash for a skill's SKILL.md file\n */\nexport async function computeSourceHash(\n sourcePath: string,\n skillPath: string,\n): Promise<string | null> {\n const skillMdPath = path.join(sourcePath, \"src\", skillPath, \"SKILL.md\");\n\n if (!(await fileExists(skillMdPath))) {\n return null;\n }\n\n return hashFile(skillMdPath);\n}\n\n/**\n * Compare local skills against source and determine status\n */\nexport async function compareSkills(\n projectDir: string,\n sourcePath: string,\n sourceSkills: Record<string, { path: string }>,\n): Promise<SkillComparisonResult[]> {\n const results: SkillComparisonResult[] = [];\n const localSkills = await getLocalSkillsWithMetadata(projectDir);\n\n for (const [skillId, { dirName, forkedFrom }] of localSkills) {\n if (!forkedFrom) {\n // Local-only skill (no forked_from metadata)\n results.push({\n id: skillId,\n localHash: null,\n sourceHash: null,\n status: \"local-only\",\n dirName,\n });\n continue;\n }\n\n const localHash = forkedFrom.content_hash;\n const sourceSkill = sourceSkills[forkedFrom.skill_id];\n\n if (!sourceSkill) {\n // Skill was forked from a source that no longer exists\n results.push({\n id: forkedFrom.skill_id,\n localHash,\n sourceHash: null,\n status: \"local-only\",\n dirName,\n });\n continue;\n }\n\n const sourceHash = await computeSourceHash(sourcePath, sourceSkill.path);\n\n if (sourceHash === null) {\n results.push({\n id: forkedFrom.skill_id,\n localHash,\n sourceHash: null,\n status: \"local-only\",\n dirName,\n });\n continue;\n }\n\n const status = localHash === sourceHash ? \"current\" : \"outdated\";\n\n results.push({\n id: forkedFrom.skill_id,\n localHash,\n sourceHash,\n status,\n dirName,\n sourcePath: sourceSkill.path,\n });\n }\n\n // Sort results by skill ID\n results.sort((a, b) => a.id.localeCompare(b.id));\n\n return results;\n}\n\n/**\n * Inject or update forked_from metadata in a skill's metadata.yaml.\n */\nexport async function injectForkedFromMetadata(\n destPath: string,\n skillId: string,\n contentHash: string,\n): Promise<void> {\n const metadataPath = path.join(destPath, \"metadata.yaml\");\n const rawContent = await readFile(metadataPath);\n\n const lines = rawContent.split(\"\\n\");\n let yamlContent = rawContent;\n\n if (lines[0]?.startsWith(\"# yaml-language-server:\")) {\n yamlContent = lines.slice(1).join(\"\\n\");\n }\n\n const metadata = parseYaml(yamlContent) as LocalSkillMetadata;\n\n metadata.forked_from = {\n skill_id: skillId,\n content_hash: contentHash,\n date: getCurrentDate(),\n };\n\n const newYamlContent = stringifyYaml(metadata, { lineWidth: 0 });\n await writeFile(metadataPath, newYamlContent);\n}\n"],"mappings":"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","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  fileExists,
4
4
  glob,
5
5
  readFile
6
- } from "./chunk-TKFPKEV3.js";
6
+ } from "./chunk-AL74GBW4.js";
7
7
  import {
8
8
  init_esm_shims
9
9
  } from "./chunk-DHET7RCE.js";
@@ -16,6 +16,9 @@ import { stringify as stringifyYaml, parse as parseYaml } from "yaml";
16
16
  var HASH_PREFIX_LENGTH = 7;
17
17
  var HASHABLE_FILES = ["SKILL.md", "reference.md"];
18
18
  var HASHABLE_DIRS = ["examples", "scripts"];
19
+ function getCurrentDate() {
20
+ return (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
21
+ }
19
22
  function hashString(content) {
20
23
  const hash = createHash("sha256");
21
24
  hash.update(content);
@@ -50,8 +53,9 @@ async function hashSkillFolder(skillPath) {
50
53
  }
51
54
 
52
55
  export {
56
+ getCurrentDate,
53
57
  hashString,
54
58
  hashFile,
55
59
  hashSkillFolder
56
60
  };
57
- //# sourceMappingURL=chunk-KAAEN2PO.js.map
61
+ //# sourceMappingURL=chunk-IOBFMF6X.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/lib/versioning.ts"],"sourcesContent":["import { createHash } from \"crypto\";\nimport path from \"path\";\nimport { stringify as stringifyYaml, parse as parseYaml } from \"yaml\";\nimport { readFile, writeFile, glob, fileExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\n\nconst HASH_PREFIX_LENGTH = 7;\n\nconst METADATA_FILE_NAME = \"metadata.yaml\";\n\nconst HASHABLE_FILES = [\"SKILL.md\", \"reference.md\"];\n\nconst HASHABLE_DIRS = [\"examples\", \"scripts\"];\n\ninterface VersionedMetadata {\n version: number;\n content_hash?: string;\n updated?: string;\n [key: string]: unknown;\n}\n\nexport interface VersionCheckResult {\n skillPath: string;\n previousVersion: number;\n newVersion: number;\n previousHash: string | undefined;\n newHash: string;\n changed: boolean;\n}\n\nexport function getCurrentDate(): string {\n return new Date().toISOString().split(\"T\")[0];\n}\n\nexport function hashString(content: string): string {\n const hash = createHash(\"sha256\");\n hash.update(content);\n return hash.digest(\"hex\").slice(0, HASH_PREFIX_LENGTH);\n}\n\nexport async function hashFile(filePath: string): Promise<string> {\n const content = await readFile(filePath);\n return hashString(content);\n}\n\nexport async function hashSkillFolder(skillPath: string): Promise<string> {\n const contents: string[] = [];\n\n for (const fileName of HASHABLE_FILES) {\n const filePath = path.join(skillPath, fileName);\n if (await fileExists(filePath)) {\n const content = await readFile(filePath);\n contents.push(`${fileName}:${content}`);\n }\n }\n\n for (const dirName of HASHABLE_DIRS) {\n const dirPath = path.join(skillPath, dirName);\n if (await fileExists(dirPath)) {\n const files = await glob(\"**/*\", dirPath);\n for (const file of files.sort()) {\n const filePath = path.join(dirPath, file);\n const content = await readFile(filePath);\n contents.push(`${dirName}/${file}:${content}`);\n }\n }\n }\n\n const combined = contents.join(\"\\n---\\n\");\n return hashString(combined);\n}\n\nasync function readMetadata(\n skillPath: string,\n): Promise<{ metadata: VersionedMetadata; schemaComment: string }> {\n const metadataPath = path.join(skillPath, METADATA_FILE_NAME);\n const rawContent = await readFile(metadataPath);\n\n const lines = rawContent.split(\"\\n\");\n let schemaComment = \"\";\n let yamlContent = rawContent;\n\n if (lines[0]?.startsWith(\"# yaml-language-server:\")) {\n schemaComment = lines[0] + \"\\n\";\n yamlContent = lines.slice(1).join(\"\\n\");\n }\n\n const metadata = parseYaml(yamlContent) as VersionedMetadata;\n return { metadata, schemaComment };\n}\n\nasync function writeMetadata(\n skillPath: string,\n metadata: VersionedMetadata,\n schemaComment: string,\n): Promise<void> {\n const metadataPath = path.join(skillPath, METADATA_FILE_NAME);\n const yamlContent = stringifyYaml(metadata, { lineWidth: 0 });\n await writeFile(metadataPath, schemaComment + yamlContent);\n}\n\nexport async function versionSkill(\n skillPath: string,\n): Promise<VersionCheckResult> {\n const newHash = await hashSkillFolder(skillPath);\n\n const { metadata, schemaComment } = await readMetadata(skillPath);\n const previousVersion = metadata.version;\n const previousHash = metadata.content_hash;\n\n const changed = previousHash !== newHash;\n\n if (changed) {\n metadata.version = previousVersion + 1;\n metadata.content_hash = newHash;\n metadata.updated = getCurrentDate();\n\n await writeMetadata(skillPath, metadata, schemaComment);\n\n verbose(\n ` Version bumped: ${skillPath} (v${previousVersion} -> v${metadata.version})`,\n );\n }\n\n return {\n skillPath,\n previousVersion,\n newVersion: changed ? previousVersion + 1 : previousVersion,\n previousHash,\n newHash,\n changed,\n };\n}\n\nexport async function versionAllSkills(\n skillsDir: string,\n): Promise<VersionCheckResult[]> {\n const results: VersionCheckResult[] = [];\n\n const metadataFiles = await glob(\"**/metadata.yaml\", skillsDir);\n\n for (const metadataFile of metadataFiles) {\n const skillPath = path.join(skillsDir, path.dirname(metadataFile));\n\n try {\n const result = await versionSkill(skillPath);\n results.push(result);\n } catch (error) {\n console.warn(\n ` Warning: Failed to version skill at ${skillPath}: ${error}`,\n );\n }\n }\n\n return results;\n}\n\nexport function printVersionResults(results: VersionCheckResult[]): void {\n const changed = results.filter((r) => r.changed);\n const unchanged = results.filter((r) => !r.changed);\n\n if (changed.length > 0) {\n console.log(`\\n Version Updates:`);\n for (const result of changed) {\n const skillName = path.basename(result.skillPath);\n console.log(\n ` ✓ ${skillName}: v${result.previousVersion} -> v${result.newVersion}`,\n );\n }\n }\n\n console.log(\n `\\n Summary: ${changed.length} updated, ${unchanged.length} unchanged`,\n );\n}\n"],"mappings":";;;;;;;;;;;AAAA;AAAA,SAAS,kBAAkB;AAC3B,OAAO,UAAU;AACjB,SAAS,aAAa,eAAe,SAAS,iBAAiB;AAI/D,IAAM,qBAAqB;AAI3B,IAAM,iBAAiB,CAAC,YAAY,cAAc;AAElD,IAAM,gBAAgB,CAAC,YAAY,SAAS;AAsBrC,SAAS,WAAW,SAAyB;AAClD,QAAM,OAAO,WAAW,QAAQ;AAChC,OAAK,OAAO,OAAO;AACnB,SAAO,KAAK,OAAO,KAAK,EAAE,MAAM,GAAG,kBAAkB;AACvD;AAEA,eAAsB,SAAS,UAAmC;AAChE,QAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,SAAO,WAAW,OAAO;AAC3B;AAEA,eAAsB,gBAAgB,WAAoC;AACxE,QAAM,WAAqB,CAAC;AAE5B,aAAW,YAAY,gBAAgB;AACrC,UAAM,WAAW,KAAK,KAAK,WAAW,QAAQ;AAC9C,QAAI,MAAM,WAAW,QAAQ,GAAG;AAC9B,YAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,eAAS,KAAK,GAAG,QAAQ,IAAI,OAAO,EAAE;AAAA,IACxC;AAAA,EACF;AAEA,aAAW,WAAW,eAAe;AACnC,UAAM,UAAU,KAAK,KAAK,WAAW,OAAO;AAC5C,QAAI,MAAM,WAAW,OAAO,GAAG;AAC7B,YAAM,QAAQ,MAAM,KAAK,QAAQ,OAAO;AACxC,iBAAW,QAAQ,MAAM,KAAK,GAAG;AAC/B,cAAM,WAAW,KAAK,KAAK,SAAS,IAAI;AACxC,cAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,iBAAS,KAAK,GAAG,OAAO,IAAI,IAAI,IAAI,OAAO,EAAE;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,SAAS,KAAK,SAAS;AACxC,SAAO,WAAW,QAAQ;AAC5B;","names":[]}
1
+ {"version":3,"sources":["../src/cli/lib/versioning.ts"],"sourcesContent":["import { createHash } from \"crypto\";\nimport path from \"path\";\nimport { stringify as stringifyYaml, parse as parseYaml } from \"yaml\";\nimport { readFile, writeFile, glob, fileExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\n\nconst HASH_PREFIX_LENGTH = 7;\n\nconst METADATA_FILE_NAME = \"metadata.yaml\";\n\nconst HASHABLE_FILES = [\"SKILL.md\", \"reference.md\"];\n\nconst HASHABLE_DIRS = [\"examples\", \"scripts\"];\n\ninterface VersionedMetadata {\n version: number;\n content_hash?: string;\n updated?: string;\n [key: string]: unknown;\n}\n\nexport interface VersionCheckResult {\n skillPath: string;\n previousVersion: number;\n newVersion: number;\n previousHash: string | undefined;\n newHash: string;\n changed: boolean;\n}\n\nexport function getCurrentDate(): string {\n return new Date().toISOString().split(\"T\")[0];\n}\n\nexport function hashString(content: string): string {\n const hash = createHash(\"sha256\");\n hash.update(content);\n return hash.digest(\"hex\").slice(0, HASH_PREFIX_LENGTH);\n}\n\nexport async function hashFile(filePath: string): Promise<string> {\n const content = await readFile(filePath);\n return hashString(content);\n}\n\nexport async function hashSkillFolder(skillPath: string): Promise<string> {\n const contents: string[] = [];\n\n for (const fileName of HASHABLE_FILES) {\n const filePath = path.join(skillPath, fileName);\n if (await fileExists(filePath)) {\n const content = await readFile(filePath);\n contents.push(`${fileName}:${content}`);\n }\n }\n\n for (const dirName of HASHABLE_DIRS) {\n const dirPath = path.join(skillPath, dirName);\n if (await fileExists(dirPath)) {\n const files = await glob(\"**/*\", dirPath);\n for (const file of files.sort()) {\n const filePath = path.join(dirPath, file);\n const content = await readFile(filePath);\n contents.push(`${dirName}/${file}:${content}`);\n }\n }\n }\n\n const combined = contents.join(\"\\n---\\n\");\n return hashString(combined);\n}\n\nasync function readMetadata(\n skillPath: string,\n): Promise<{ metadata: VersionedMetadata; schemaComment: string }> {\n const metadataPath = path.join(skillPath, METADATA_FILE_NAME);\n const rawContent = await readFile(metadataPath);\n\n const lines = rawContent.split(\"\\n\");\n let schemaComment = \"\";\n let yamlContent = rawContent;\n\n if (lines[0]?.startsWith(\"# yaml-language-server:\")) {\n schemaComment = lines[0] + \"\\n\";\n yamlContent = lines.slice(1).join(\"\\n\");\n }\n\n const metadata = parseYaml(yamlContent) as VersionedMetadata;\n return { metadata, schemaComment };\n}\n\nasync function writeMetadata(\n skillPath: string,\n metadata: VersionedMetadata,\n schemaComment: string,\n): Promise<void> {\n const metadataPath = path.join(skillPath, METADATA_FILE_NAME);\n const yamlContent = stringifyYaml(metadata, { lineWidth: 0 });\n await writeFile(metadataPath, schemaComment + yamlContent);\n}\n\nexport async function versionSkill(skillPath: string): Promise<VersionCheckResult> {\n const newHash = await hashSkillFolder(skillPath);\n\n const { metadata, schemaComment } = await readMetadata(skillPath);\n const previousVersion = metadata.version;\n const previousHash = metadata.content_hash;\n\n const changed = previousHash !== newHash;\n\n if (changed) {\n metadata.version = previousVersion + 1;\n metadata.content_hash = newHash;\n metadata.updated = getCurrentDate();\n\n await writeMetadata(skillPath, metadata, schemaComment);\n\n verbose(` Version bumped: ${skillPath} (v${previousVersion} -> v${metadata.version})`);\n }\n\n return {\n skillPath,\n previousVersion,\n newVersion: changed ? previousVersion + 1 : previousVersion,\n previousHash,\n newHash,\n changed,\n };\n}\n\nexport async function versionAllSkills(skillsDir: string): Promise<VersionCheckResult[]> {\n const results: VersionCheckResult[] = [];\n\n const metadataFiles = await glob(\"**/metadata.yaml\", skillsDir);\n\n for (const metadataFile of metadataFiles) {\n const skillPath = path.join(skillsDir, path.dirname(metadataFile));\n\n try {\n const result = await versionSkill(skillPath);\n results.push(result);\n } catch (error) {\n console.warn(` Warning: Failed to version skill at ${skillPath}: ${error}`);\n }\n }\n\n return results;\n}\n\nexport function printVersionResults(results: VersionCheckResult[]): void {\n const changed = results.filter((r) => r.changed);\n const unchanged = results.filter((r) => !r.changed);\n\n if (changed.length > 0) {\n console.log(`\\n Version Updates:`);\n for (const result of changed) {\n const skillName = path.basename(result.skillPath);\n console.log(` ✓ ${skillName}: v${result.previousVersion} -> v${result.newVersion}`);\n }\n }\n\n console.log(`\\n Summary: ${changed.length} updated, ${unchanged.length} unchanged`);\n}\n"],"mappings":";;;;;;;;;;;AAAA;AAAA,SAAS,kBAAkB;AAC3B,OAAO,UAAU;AACjB,SAAS,aAAa,eAAe,SAAS,iBAAiB;AAI/D,IAAM,qBAAqB;AAI3B,IAAM,iBAAiB,CAAC,YAAY,cAAc;AAElD,IAAM,gBAAgB,CAAC,YAAY,SAAS;AAkBrC,SAAS,iBAAyB;AACvC,UAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAC9C;AAEO,SAAS,WAAW,SAAyB;AAClD,QAAM,OAAO,WAAW,QAAQ;AAChC,OAAK,OAAO,OAAO;AACnB,SAAO,KAAK,OAAO,KAAK,EAAE,MAAM,GAAG,kBAAkB;AACvD;AAEA,eAAsB,SAAS,UAAmC;AAChE,QAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,SAAO,WAAW,OAAO;AAC3B;AAEA,eAAsB,gBAAgB,WAAoC;AACxE,QAAM,WAAqB,CAAC;AAE5B,aAAW,YAAY,gBAAgB;AACrC,UAAM,WAAW,KAAK,KAAK,WAAW,QAAQ;AAC9C,QAAI,MAAM,WAAW,QAAQ,GAAG;AAC9B,YAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,eAAS,KAAK,GAAG,QAAQ,IAAI,OAAO,EAAE;AAAA,IACxC;AAAA,EACF;AAEA,aAAW,WAAW,eAAe;AACnC,UAAM,UAAU,KAAK,KAAK,WAAW,OAAO;AAC5C,QAAI,MAAM,WAAW,OAAO,GAAG;AAC7B,YAAM,QAAQ,MAAM,KAAK,QAAQ,OAAO;AACxC,iBAAW,QAAQ,MAAM,KAAK,GAAG;AAC/B,cAAM,WAAW,KAAK,KAAK,SAAS,IAAI;AACxC,cAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,iBAAS,KAAK,GAAG,OAAO,IAAI,IAAI,IAAI,OAAO,EAAE;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,SAAS,KAAK,SAAS;AACxC,SAAO,WAAW,QAAQ;AAC5B;","names":[]}
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ injectForkedFromMetadata
4
+ } from "./chunk-INJ2EFRW.js";
2
5
  import {
3
6
  hashFile
4
- } from "./chunk-KAAEN2PO.js";
7
+ } from "./chunk-IOBFMF6X.js";
5
8
  import {
6
9
  copy,
7
- ensureDir,
8
- readFile,
9
- writeFile
10
- } from "./chunk-TKFPKEV3.js";
10
+ ensureDir
11
+ } from "./chunk-AL74GBW4.js";
11
12
  import {
12
13
  init_esm_shims
13
14
  } from "./chunk-DHET7RCE.js";
@@ -15,8 +16,6 @@ import {
15
16
  // src/cli/lib/skill-copier.ts
16
17
  init_esm_shims();
17
18
  import path from "path";
18
- import { stringify as stringifyYaml, parse as parseYaml } from "yaml";
19
- var METADATA_FILE_NAME = "metadata.yaml";
20
19
  function getSkillDestPath(skill, stackDir) {
21
20
  const skillRelativePath = skill.path.replace(/^skills\//, "");
22
21
  return path.join(stackDir, "skills", skillRelativePath);
@@ -25,26 +24,6 @@ async function generateSkillHash(skillSourcePath) {
25
24
  const skillMdPath = path.join(skillSourcePath, "SKILL.md");
26
25
  return hashFile(skillMdPath);
27
26
  }
28
- function getCurrentDate() {
29
- return (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
30
- }
31
- async function injectForkedFromMetadata(destPath, skillId, contentHash) {
32
- const metadataPath = path.join(destPath, METADATA_FILE_NAME);
33
- const rawContent = await readFile(metadataPath);
34
- const lines = rawContent.split("\n");
35
- let yamlContent = rawContent;
36
- if (lines[0]?.startsWith("# yaml-language-server:")) {
37
- yamlContent = lines.slice(1).join("\n");
38
- }
39
- const metadata = parseYaml(yamlContent);
40
- metadata.forked_from = {
41
- skill_id: skillId,
42
- content_hash: contentHash,
43
- date: getCurrentDate()
44
- };
45
- const newYamlContent = stringifyYaml(metadata, { lineWidth: 0 });
46
- await writeFile(metadataPath, newYamlContent);
47
- }
48
27
  function getSkillSourcePathFromSource(skill, sourceResult) {
49
28
  return path.join(sourceResult.sourcePath, "src", skill.path);
50
29
  }
@@ -124,11 +103,7 @@ async function copySkillsToLocalFlattened(selectedSkillIds, localSkillsDir, matr
124
103
  });
125
104
  continue;
126
105
  }
127
- const copied = await copySkillToLocalFlattened(
128
- skill,
129
- localSkillsDir,
130
- sourceResult
131
- );
106
+ const copied = await copySkillToLocalFlattened(skill, localSkillsDir, sourceResult);
132
107
  copiedSkills.push(copied);
133
108
  }
134
109
  return copiedSkills;
@@ -138,4 +113,4 @@ export {
138
113
  copySkillsToPluginFromSource,
139
114
  copySkillsToLocalFlattened
140
115
  };
141
- //# sourceMappingURL=chunk-K7EVM5LY.js.map
116
+ //# sourceMappingURL=chunk-KH3HA7J7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/lib/skill-copier.ts"],"sourcesContent":["import path from \"path\";\nimport { copy, ensureDir } from \"../utils/fs\";\nimport { hashFile } from \"./versioning\";\nimport type { MergedSkillsMatrix, ResolvedSkill } from \"../types-matrix\";\nimport type { SourceLoadResult } from \"./source-loader\";\nimport { injectForkedFromMetadata } from \"./skill-metadata\";\n\nexport interface CopiedSkill {\n skillId: string;\n contentHash: string;\n sourcePath: string;\n destPath: string;\n local?: boolean;\n}\n\nfunction getSkillSourcePath(skill: ResolvedSkill, registryRoot: string): string {\n return path.join(registryRoot, \"src\", skill.path);\n}\n\nfunction getSkillDestPath(skill: ResolvedSkill, stackDir: string): string {\n const skillRelativePath = skill.path.replace(/^skills\\//, \"\");\n return path.join(stackDir, \"skills\", skillRelativePath);\n}\n\nasync function generateSkillHash(skillSourcePath: string): Promise<string> {\n const skillMdPath = path.join(skillSourcePath, \"SKILL.md\");\n return hashFile(skillMdPath);\n}\n\nexport async function copySkill(\n skill: ResolvedSkill,\n stackDir: string,\n registryRoot: string,\n): Promise<CopiedSkill> {\n const sourcePath = getSkillSourcePath(skill, registryRoot);\n const destPath = getSkillDestPath(skill, stackDir);\n\n const contentHash = await generateSkillHash(sourcePath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await injectForkedFromMetadata(destPath, skill.id, contentHash);\n\n return {\n skillId: skill.id,\n contentHash,\n sourcePath,\n destPath,\n };\n}\n\nfunction getSkillSourcePathFromSource(\n skill: ResolvedSkill,\n sourceResult: SourceLoadResult,\n): string {\n return path.join(sourceResult.sourcePath, \"src\", skill.path);\n}\n\nexport async function copySkillFromSource(\n skill: ResolvedSkill,\n stackDir: string,\n sourceResult: SourceLoadResult,\n): Promise<CopiedSkill> {\n const sourcePath = getSkillSourcePathFromSource(skill, sourceResult);\n const destPath = getSkillDestPath(skill, stackDir);\n\n const contentHash = await generateSkillHash(sourcePath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await injectForkedFromMetadata(destPath, skill.id, contentHash);\n\n return {\n skillId: skill.id,\n contentHash,\n sourcePath,\n destPath,\n };\n}\n\nexport async function copySkillsToPluginFromSource(\n selectedSkillIds: string[],\n pluginDir: string,\n matrix: MergedSkillsMatrix,\n sourceResult: SourceLoadResult,\n): Promise<CopiedSkill[]> {\n const copiedSkills: CopiedSkill[] = [];\n\n for (const skillId of selectedSkillIds) {\n const skill = matrix.skills[skillId];\n if (!skill) {\n console.warn(`Warning: Skill not found in matrix: ${skillId}`);\n continue;\n }\n\n if (skill.local && skill.localPath) {\n const localSkillPath = path.join(process.cwd(), skill.localPath);\n const contentHash = await generateSkillHash(localSkillPath);\n\n copiedSkills.push({\n skillId: skill.id,\n sourcePath: skill.localPath,\n destPath: skill.localPath,\n contentHash,\n local: true,\n });\n continue;\n }\n\n const copied = await copySkillFromSource(skill, pluginDir, sourceResult);\n copiedSkills.push(copied);\n }\n\n return copiedSkills;\n}\n\n/**\n * Get the destination path for a skill when copying to local flattened structure.\n *\n * Uses the normalized skill ID (kebab-case) as the folder name.\n *\n * @example\n * // skill.id = \"web-framework-react\"\n * // Returns: \"{localSkillsDir}/web-framework-react\"\n */\nfunction getFlattenedSkillDestPath(skill: ResolvedSkill, localSkillsDir: string): string {\n return path.join(localSkillsDir, skill.id);\n}\n\nasync function copySkillToLocalFlattened(\n skill: ResolvedSkill,\n localSkillsDir: string,\n sourceResult: SourceLoadResult,\n): Promise<CopiedSkill> {\n const sourcePath = getSkillSourcePathFromSource(skill, sourceResult);\n const destPath = getFlattenedSkillDestPath(skill, localSkillsDir);\n\n const contentHash = await generateSkillHash(sourcePath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await injectForkedFromMetadata(destPath, skill.id, contentHash);\n\n return {\n skillId: skill.id,\n contentHash,\n sourcePath,\n destPath,\n };\n}\n\nexport async function copySkillsToLocalFlattened(\n selectedSkillIds: string[],\n localSkillsDir: string,\n matrix: MergedSkillsMatrix,\n sourceResult: SourceLoadResult,\n): Promise<CopiedSkill[]> {\n const copiedSkills: CopiedSkill[] = [];\n\n for (const skillId of selectedSkillIds) {\n const skill = matrix.skills[skillId];\n if (!skill) {\n console.warn(`Warning: Skill not found in matrix: ${skillId}`);\n continue;\n }\n\n if (skill.local && skill.localPath) {\n const localSkillPath = path.join(process.cwd(), skill.localPath);\n const contentHash = await generateSkillHash(localSkillPath);\n\n copiedSkills.push({\n skillId: skill.id,\n sourcePath: skill.localPath,\n destPath: skill.localPath,\n contentHash,\n local: true,\n });\n continue;\n }\n\n const copied = await copySkillToLocalFlattened(skill, localSkillsDir, sourceResult);\n copiedSkills.push(copied);\n }\n\n return copiedSkills;\n}\n"],"mappings":"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","names":[]}