@agents-inc/cli 0.50.0 → 0.60.1

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 (237) hide show
  1. package/CHANGELOG.md +155 -5
  2. package/dist/{chunk-YDYRAXSY.js → chunk-52M2XF3W.js} +6 -6
  3. package/dist/{chunk-2BWCR762.js → chunk-52XO4ULK.js} +6 -8
  4. package/dist/chunk-52XO4ULK.js.map +1 -0
  5. package/dist/{chunk-KQOU4POU.js → chunk-6G3KZSO4.js} +72 -51
  6. package/dist/chunk-6G3KZSO4.js.map +1 -0
  7. package/dist/{chunk-AWP5A6IM.js → chunk-6OWHQ7HM.js} +14 -12
  8. package/dist/chunk-6OWHQ7HM.js.map +1 -0
  9. package/dist/{chunk-D72AFYQR.js → chunk-7FMEMXJ4.js} +71 -71
  10. package/dist/chunk-7FMEMXJ4.js.map +1 -0
  11. package/dist/{chunk-RA2IPRO2.js → chunk-AJJJE7F7.js} +2 -2
  12. package/dist/{chunk-4R52TQ3K.js → chunk-AX3SZZWA.js} +2 -2
  13. package/dist/{chunk-U2W5SENM.js → chunk-BFD5NZQ4.js} +5 -4
  14. package/dist/chunk-BFD5NZQ4.js.map +1 -0
  15. package/dist/{chunk-HYEUETIC.js → chunk-BKJHAJQW.js} +2 -2
  16. package/dist/{chunk-HYEUETIC.js.map → chunk-BKJHAJQW.js.map} +1 -1
  17. package/dist/{chunk-DCE423KO.js → chunk-BMJZBLP7.js} +5 -5
  18. package/dist/{chunk-GBOW6FUW.js → chunk-BNQ5O6LE.js} +2 -2
  19. package/dist/{chunk-KAO3LKB5.js → chunk-C577AJE7.js} +3 -3
  20. package/dist/{chunk-C3Q43WLC.js → chunk-CIG7IKX3.js} +4 -4
  21. package/dist/chunk-EC3UJRKZ.js +1534 -0
  22. package/dist/chunk-EC3UJRKZ.js.map +1 -0
  23. package/dist/{chunk-I6IOGZSZ.js → chunk-EMIUPGPL.js} +11 -15
  24. package/dist/chunk-EMIUPGPL.js.map +1 -0
  25. package/dist/{chunk-4QWDB2MD.js → chunk-G6WHCALR.js} +127 -105
  26. package/dist/chunk-G6WHCALR.js.map +1 -0
  27. package/dist/{chunk-JFF7P4LC.js → chunk-H7WJK7NJ.js} +22 -6
  28. package/dist/chunk-H7WJK7NJ.js.map +1 -0
  29. package/dist/chunk-HGTC76BX.js +16 -0
  30. package/dist/chunk-HGTC76BX.js.map +1 -0
  31. package/dist/{chunk-RDWGYKDY.js → chunk-K6OLORQL.js} +6 -6
  32. package/dist/{chunk-XDSVV5GZ.js → chunk-KIWFEBKH.js} +41 -11
  33. package/dist/chunk-KIWFEBKH.js.map +1 -0
  34. package/dist/{chunk-WBHPCBVN.js → chunk-LWXRUR6B.js} +66 -94
  35. package/dist/chunk-LWXRUR6B.js.map +1 -0
  36. package/dist/{chunk-CMNKHDOX.js → chunk-MGNYPVOJ.js} +2 -2
  37. package/dist/{chunk-5FPIKTSA.js → chunk-MKCHLXMY.js} +7 -7
  38. package/dist/{chunk-U7X4V4HE.js → chunk-MMFQNJPE.js} +2 -2
  39. package/dist/{chunk-WLZHCM7O.js → chunk-MR6OBL3B.js} +3 -11
  40. package/dist/{chunk-WLZHCM7O.js.map → chunk-MR6OBL3B.js.map} +1 -1
  41. package/dist/{chunk-RFKDGJAJ.js → chunk-O6BA7Q2B.js} +6 -6
  42. package/dist/chunk-O6BA7Q2B.js.map +1 -0
  43. package/dist/chunk-OCEFD7V6.js +201 -0
  44. package/dist/chunk-OCEFD7V6.js.map +1 -0
  45. package/dist/{chunk-YZTWZVGX.js → chunk-PUT7X3GA.js} +1 -1
  46. package/dist/chunk-PUT7X3GA.js.map +1 -0
  47. package/dist/{chunk-WFFV254H.js → chunk-RO6LX3UV.js} +110 -82
  48. package/dist/chunk-RO6LX3UV.js.map +1 -0
  49. package/dist/{chunk-QYLCINGC.js → chunk-SDKCQXWE.js} +2 -2
  50. package/dist/{chunk-M3GQ2R3E.js → chunk-SEJF7CGJ.js} +19 -7
  51. package/dist/chunk-SEJF7CGJ.js.map +1 -0
  52. package/dist/{chunk-SPFHPHYL.js → chunk-SZRK3VOR.js} +24 -14
  53. package/dist/chunk-SZRK3VOR.js.map +1 -0
  54. package/dist/{chunk-QB5HHTAA.js → chunk-TC3NHO34.js} +28 -12
  55. package/dist/chunk-TC3NHO34.js.map +1 -0
  56. package/dist/{chunk-5L724R4C.js → chunk-TGLRDEEL.js} +8 -13
  57. package/dist/chunk-TGLRDEEL.js.map +1 -0
  58. package/dist/{chunk-HMSHB5EQ.js → chunk-TZXYBG3R.js} +3544 -3037
  59. package/dist/chunk-TZXYBG3R.js.map +1 -0
  60. package/dist/{chunk-PGY5XROM.js → chunk-VR3CDXDT.js} +2 -6
  61. package/dist/chunk-VR3CDXDT.js.map +1 -0
  62. package/dist/{chunk-5FCHJLM7.js → chunk-WF6RM73R.js} +252 -38
  63. package/dist/chunk-WF6RM73R.js.map +1 -0
  64. package/dist/{chunk-3VOL4WEG.js → chunk-WYVDNGJB.js} +3 -3
  65. package/dist/{chunk-WJHFV6RI.js → chunk-X5EG4EFP.js} +2 -2
  66. package/dist/{chunk-JWYRXE6C.js → chunk-XUDTFI4M.js} +2 -2
  67. package/dist/{chunk-7LV4V6A4.js → chunk-YHCYKUA3.js} +14 -10
  68. package/dist/chunk-YHCYKUA3.js.map +1 -0
  69. package/dist/commands/build/marketplace.js +4 -4
  70. package/dist/commands/build/plugins.js +9 -7
  71. package/dist/commands/build/plugins.js.map +1 -1
  72. package/dist/commands/build/stack.js +13 -10
  73. package/dist/commands/build/stack.js.map +1 -1
  74. package/dist/commands/compile.js +42 -71
  75. package/dist/commands/compile.js.map +1 -1
  76. package/dist/commands/config/index.js +7 -5
  77. package/dist/commands/config/index.js.map +1 -1
  78. package/dist/commands/config/path.js +8 -6
  79. package/dist/commands/config/path.js.map +1 -1
  80. package/dist/commands/config/show.js +7 -5
  81. package/dist/commands/diff.js +9 -7
  82. package/dist/commands/diff.js.map +1 -1
  83. package/dist/commands/doctor.js +20 -16
  84. package/dist/commands/doctor.js.map +1 -1
  85. package/dist/commands/edit.js +175 -79
  86. package/dist/commands/edit.js.map +1 -1
  87. package/dist/commands/eject.js +20 -41
  88. package/dist/commands/eject.js.map +1 -1
  89. package/dist/commands/import/skill.js +10 -18
  90. package/dist/commands/import/skill.js.map +1 -1
  91. package/dist/commands/info.js +21 -20
  92. package/dist/commands/info.js.map +1 -1
  93. package/dist/commands/init.js +32 -31
  94. package/dist/commands/list.js +8 -6
  95. package/dist/commands/list.js.map +1 -1
  96. package/dist/commands/new/agent.js +23 -11
  97. package/dist/commands/new/agent.js.map +1 -1
  98. package/dist/commands/new/marketplace.js +63 -46
  99. package/dist/commands/new/marketplace.js.map +1 -1
  100. package/dist/commands/new/skill.js +11 -9
  101. package/dist/commands/outdated.js +9 -7
  102. package/dist/commands/outdated.js.map +1 -1
  103. package/dist/commands/search.js +45 -35
  104. package/dist/commands/search.js.map +1 -1
  105. package/dist/commands/uninstall.js +93 -123
  106. package/dist/commands/uninstall.js.map +1 -1
  107. package/dist/commands/update.js +11 -9
  108. package/dist/commands/update.js.map +1 -1
  109. package/dist/commands/validate.js +23 -27
  110. package/dist/commands/validate.js.map +1 -1
  111. package/dist/components/common/confirm.test.js +4 -4
  112. package/dist/components/skill-search/skill-search.js +3 -3
  113. package/dist/components/wizard/category-grid.js +3 -3
  114. package/dist/components/wizard/category-grid.test.js +4 -4
  115. package/dist/components/wizard/category-grid.test.js.map +1 -1
  116. package/dist/components/wizard/checkbox-grid.js +5 -5
  117. package/dist/components/wizard/checkbox-grid.test.js +6 -6
  118. package/dist/components/wizard/domain-selection.js +12 -11
  119. package/dist/components/wizard/help-modal.js +2 -2
  120. package/dist/components/wizard/menu-item.js +1 -1
  121. package/dist/components/wizard/search-modal.js +2 -2
  122. package/dist/components/wizard/search-modal.test.js +3 -3
  123. package/dist/components/wizard/search-modal.test.js.map +1 -1
  124. package/dist/components/wizard/section-progress.js +2 -2
  125. package/dist/components/wizard/section-progress.test.js +4 -4
  126. package/dist/components/wizard/section-progress.test.js.map +1 -1
  127. package/dist/components/wizard/selection-card.js +2 -2
  128. package/dist/components/wizard/source-grid.js +4 -4
  129. package/dist/components/wizard/source-grid.test.js +5 -5
  130. package/dist/components/wizard/source-grid.test.js.map +1 -1
  131. package/dist/components/wizard/stack-selection.js +9 -8
  132. package/dist/components/wizard/step-agents.js +11 -10
  133. package/dist/components/wizard/step-agents.test.js +13 -12
  134. package/dist/components/wizard/step-agents.test.js.map +1 -1
  135. package/dist/components/wizard/step-build.js +11 -9
  136. package/dist/components/wizard/step-build.test.js +18 -22
  137. package/dist/components/wizard/step-build.test.js.map +1 -1
  138. package/dist/components/wizard/step-confirm.js +4 -4
  139. package/dist/components/wizard/step-confirm.test.js +83 -23
  140. package/dist/components/wizard/step-confirm.test.js.map +1 -1
  141. package/dist/components/wizard/step-refine.js +2 -2
  142. package/dist/components/wizard/step-refine.test.js +3 -3
  143. package/dist/components/wizard/step-settings.js +9 -7
  144. package/dist/components/wizard/step-settings.test.js +13 -11
  145. package/dist/components/wizard/step-settings.test.js.map +1 -1
  146. package/dist/components/wizard/step-sources.js +13 -11
  147. package/dist/components/wizard/step-sources.test.js +19 -17
  148. package/dist/components/wizard/step-sources.test.js.map +1 -1
  149. package/dist/components/wizard/step-stack.js +15 -14
  150. package/dist/components/wizard/step-stack.test.js +17 -16
  151. package/dist/components/wizard/step-stack.test.js.map +1 -1
  152. package/dist/components/wizard/view-title.js +2 -2
  153. package/dist/components/wizard/wizard-layout.js +10 -8
  154. package/dist/components/wizard/wizard-tabs.js +2 -2
  155. package/dist/components/wizard/wizard-tabs.test.js +2 -2
  156. package/dist/components/wizard/wizard.js +29 -27
  157. package/dist/config-exports.js +20 -0
  158. package/dist/config-exports.js.map +1 -0
  159. package/dist/hooks/init.js +34 -33
  160. package/dist/hooks/init.js.map +1 -1
  161. package/dist/loader-2O32KKAQ.js +19 -0
  162. package/dist/source-loader-A6B3NDI4.js +16 -0
  163. package/dist/source-loader-A6B3NDI4.js.map +1 -0
  164. package/dist/source-manager-Q7IQSGIX.js +18 -0
  165. package/dist/source-manager-Q7IQSGIX.js.map +1 -0
  166. package/dist/src/agents/meta/agent-summoner/workflow.md +3 -3
  167. package/dist/src/agents/meta/skill-summoner/critical-reminders.md +2 -2
  168. package/dist/src/agents/meta/skill-summoner/critical-requirements.md +1 -1
  169. package/dist/src/agents/meta/skill-summoner/intro.md +1 -1
  170. package/dist/src/agents/meta/skill-summoner/output-format.md +3 -3
  171. package/dist/src/agents/meta/skill-summoner/workflow.md +8 -8
  172. package/dist/stores/wizard-store.js +6 -5
  173. package/dist/stores/wizard-store.test.js +299 -59
  174. package/dist/stores/wizard-store.test.js.map +1 -1
  175. package/package.json +5 -1
  176. package/src/agents/meta/agent-summoner/workflow.md +3 -3
  177. package/src/agents/meta/skill-summoner/critical-reminders.md +2 -2
  178. package/src/agents/meta/skill-summoner/critical-requirements.md +1 -1
  179. package/src/agents/meta/skill-summoner/intro.md +1 -1
  180. package/src/agents/meta/skill-summoner/output-format.md +3 -3
  181. package/src/agents/meta/skill-summoner/workflow.md +8 -8
  182. package/src/schemas/metadata.schema.json +6 -0
  183. package/src/schemas/stacks.schema.json +1 -1
  184. package/config/skill-categories.yaml +0 -344
  185. package/config/skill-rules.yaml +0 -740
  186. package/config/stacks.yaml +0 -1864
  187. package/dist/chunk-26MXZUHU.js +0 -183
  188. package/dist/chunk-26MXZUHU.js.map +0 -1
  189. package/dist/chunk-2BWCR762.js.map +0 -1
  190. package/dist/chunk-4QWDB2MD.js.map +0 -1
  191. package/dist/chunk-5FCHJLM7.js.map +0 -1
  192. package/dist/chunk-5L724R4C.js.map +0 -1
  193. package/dist/chunk-7LV4V6A4.js.map +0 -1
  194. package/dist/chunk-AWP5A6IM.js.map +0 -1
  195. package/dist/chunk-D72AFYQR.js.map +0 -1
  196. package/dist/chunk-HMSHB5EQ.js.map +0 -1
  197. package/dist/chunk-I6IOGZSZ.js.map +0 -1
  198. package/dist/chunk-JFF7P4LC.js.map +0 -1
  199. package/dist/chunk-KQOU4POU.js.map +0 -1
  200. package/dist/chunk-M3GQ2R3E.js.map +0 -1
  201. package/dist/chunk-PGY5XROM.js.map +0 -1
  202. package/dist/chunk-QB5HHTAA.js.map +0 -1
  203. package/dist/chunk-RFKDGJAJ.js.map +0 -1
  204. package/dist/chunk-SPFHPHYL.js.map +0 -1
  205. package/dist/chunk-U2W5SENM.js.map +0 -1
  206. package/dist/chunk-UAD3SC27.js +0 -107
  207. package/dist/chunk-UAD3SC27.js.map +0 -1
  208. package/dist/chunk-WBHPCBVN.js.map +0 -1
  209. package/dist/chunk-WFFV254H.js.map +0 -1
  210. package/dist/chunk-XDSVV5GZ.js.map +0 -1
  211. package/dist/chunk-YZTWZVGX.js.map +0 -1
  212. package/dist/commands/config/get.js +0 -61
  213. package/dist/commands/config/get.js.map +0 -1
  214. package/dist/commands/config/set-project.js +0 -61
  215. package/dist/commands/config/set-project.js.map +0 -1
  216. package/dist/commands/config/unset-project.js +0 -57
  217. package/dist/commands/config/unset-project.js.map +0 -1
  218. package/dist/config/skill-categories.yaml +0 -344
  219. package/dist/config/skill-rules.yaml +0 -740
  220. package/dist/config/stacks.yaml +0 -1864
  221. package/dist/source-manager-BVB2SG73.js +0 -16
  222. /package/dist/{chunk-YDYRAXSY.js.map → chunk-52M2XF3W.js.map} +0 -0
  223. /package/dist/{chunk-RA2IPRO2.js.map → chunk-AJJJE7F7.js.map} +0 -0
  224. /package/dist/{chunk-4R52TQ3K.js.map → chunk-AX3SZZWA.js.map} +0 -0
  225. /package/dist/{chunk-DCE423KO.js.map → chunk-BMJZBLP7.js.map} +0 -0
  226. /package/dist/{chunk-GBOW6FUW.js.map → chunk-BNQ5O6LE.js.map} +0 -0
  227. /package/dist/{chunk-KAO3LKB5.js.map → chunk-C577AJE7.js.map} +0 -0
  228. /package/dist/{chunk-C3Q43WLC.js.map → chunk-CIG7IKX3.js.map} +0 -0
  229. /package/dist/{chunk-RDWGYKDY.js.map → chunk-K6OLORQL.js.map} +0 -0
  230. /package/dist/{chunk-CMNKHDOX.js.map → chunk-MGNYPVOJ.js.map} +0 -0
  231. /package/dist/{chunk-5FPIKTSA.js.map → chunk-MKCHLXMY.js.map} +0 -0
  232. /package/dist/{chunk-U7X4V4HE.js.map → chunk-MMFQNJPE.js.map} +0 -0
  233. /package/dist/{chunk-QYLCINGC.js.map → chunk-SDKCQXWE.js.map} +0 -0
  234. /package/dist/{chunk-3VOL4WEG.js.map → chunk-WYVDNGJB.js.map} +0 -0
  235. /package/dist/{chunk-WJHFV6RI.js.map → chunk-X5EG4EFP.js.map} +0 -0
  236. /package/dist/{chunk-JWYRXE6C.js.map → chunk-XUDTFI4M.js.map} +0 -0
  237. /package/dist/{source-manager-BVB2SG73.js.map → loader-2O32KKAQ.js.map} +0 -0
@@ -1,18 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- BaseCommand,
4
- EXIT_CODES
5
- } from "../chunk-PGY5XROM.js";
6
2
  import {
7
3
  copySkillsToLocalFlattened,
8
4
  loadProjectSourceConfig,
9
5
  loadSkillsMatrixFromSource,
10
6
  resolveSource,
11
7
  saveSourceToProjectConfig
12
- } from "../chunk-HMSHB5EQ.js";
8
+ } from "../chunk-TZXYBG3R.js";
9
+ import "../chunk-OCEFD7V6.js";
13
10
  import {
14
11
  typedKeys
15
12
  } from "../chunk-T4EXUIBY.js";
13
+ import {
14
+ BaseCommand,
15
+ EXIT_CODES
16
+ } from "../chunk-VR3CDXDT.js";
16
17
  import {
17
18
  copy,
18
19
  directoryExists,
@@ -20,16 +21,16 @@ import {
20
21
  fileExists,
21
22
  listDirectories,
22
23
  writeFile
23
- } from "../chunk-WBHPCBVN.js";
24
+ } from "../chunk-LWXRUR6B.js";
24
25
  import {
25
26
  CLAUDE_SRC_DIR,
26
27
  DEFAULT_BRANDING,
27
28
  DIRS,
28
29
  LOCAL_SKILLS_PATH,
29
30
  PROJECT_ROOT,
30
- STANDARD_FILES,
31
- YAML_FORMATTING
32
- } from "../chunk-AWP5A6IM.js";
31
+ STANDARD_FILES
32
+ } from "../chunk-6OWHQ7HM.js";
33
+ import "../chunk-EC3UJRKZ.js";
33
34
  import {
34
35
  init_esm_shims
35
36
  } from "../chunk-DHET7RCE.js";
@@ -39,7 +40,6 @@ init_esm_shims();
39
40
  import { Args, Flags } from "@oclif/core";
40
41
  import path from "path";
41
42
  import os from "os";
42
- import { stringify as stringifyYaml } from "yaml";
43
43
  var EJECT_TYPES = ["agent-partials", "templates", "skills", "all"];
44
44
  var Eject = class _Eject extends BaseCommand {
45
45
  static summary = "Eject skills, agent partials, or templates for local customization";
@@ -162,23 +162,22 @@ var Eject = class _Eject extends BaseCommand {
162
162
  }
163
163
  if (flags.source) {
164
164
  await saveSourceToProjectConfig(projectDir, flags.source);
165
- this.log(`Source saved to .claude-src/config.yaml`);
165
+ this.log(`Source saved to .claude-src/config.ts`);
166
166
  }
167
167
  await this.ensureMinimalConfig(projectDir, flags.source, sourceResult);
168
168
  this.log("");
169
169
  this.logSuccess("Eject complete!");
170
170
  this.log("");
171
171
  }
172
- // Ensures a minimal config.yaml exists so `agentsinc compile` works after eject
172
+ // Ensures a minimal config exists so `agentsinc compile` works after eject
173
173
  async ensureMinimalConfig(projectDir, sourceFlag, sourceResult) {
174
- const configPath = path.join(projectDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_YAML);
175
- if (await fileExists(configPath)) {
174
+ const tsConfigPath = path.join(projectDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS);
175
+ if (await fileExists(tsConfigPath)) {
176
176
  return;
177
177
  }
178
178
  const projectName = path.basename(projectDir);
179
179
  const config = {
180
- name: projectName,
181
- installMode: "local"
180
+ name: projectName
182
181
  };
183
182
  const resolvedConfig = sourceResult?.sourceConfig ?? await resolveSource(sourceFlag, projectDir);
184
183
  if (sourceFlag) {
@@ -197,32 +196,12 @@ var Eject = class _Eject extends BaseCommand {
197
196
  config.agentsSource = existingProjectConfig.agentsSource;
198
197
  }
199
198
  await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));
200
- let configContent = stringifyYaml(config, { indent: YAML_FORMATTING.INDENT });
201
- const exampleStackComment = `
202
- # Example stack configuration (uncomment and customize):
203
- #
204
- # skills:
205
- # - web-framework-react
206
- # - web-styling-scss-modules
207
- # - api-framework-hono
208
- # - api-database-drizzle
209
- #
210
- # agents:
211
- # - web-developer
212
- # - api-developer
213
- # - web-reviewer
214
- #
215
- # stack:
216
- # web-developer:
217
- # framework: web-framework-react
218
- # styling: web-styling-scss-modules
219
- # api-developer:
220
- # api: api-framework-hono
221
- # database: api-database-drizzle
199
+ const cleaned = JSON.parse(JSON.stringify(config));
200
+ const body = JSON.stringify(cleaned, null, 2);
201
+ const content = `export default ${body};
222
202
  `;
223
- configContent += exampleStackComment;
224
- await writeFile(configPath, configContent);
225
- this.logSuccess(`Created ${CLAUDE_SRC_DIR}/config.yaml`);
203
+ await writeFile(tsConfigPath, content);
204
+ this.logSuccess(`Created ${CLAUDE_SRC_DIR}/config.ts`);
226
205
  }
227
206
  async ejectAgentPartials(outputBase, force, directOutput = false, templatesFlag = false) {
228
207
  const sourceDir = templatesFlag ? path.join(PROJECT_ROOT, DIRS.templates) : path.join(PROJECT_ROOT, DIRS.agents);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/eject.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport os from \"os\";\nimport { stringify as stringifyYaml } from \"yaml\";\nimport { BaseCommand } from \"../base-command.js\";\nimport {\n copy,\n ensureDir,\n directoryExists,\n fileExists,\n listDirectories,\n writeFile,\n} from \"../utils/fs.js\";\nimport {\n CLAUDE_SRC_DIR,\n DEFAULT_BRANDING,\n DIRS,\n LOCAL_SKILLS_PATH,\n PROJECT_ROOT,\n STANDARD_FILES,\n YAML_FORMATTING,\n} from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { loadSkillsMatrixFromSource, type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { copySkillsToLocalFlattened } from \"../lib/skills/index.js\";\nimport type { SkillId } from \"../types/index.js\";\nimport { typedKeys } from \"../utils/typed-object.js\";\nimport {\n loadProjectSourceConfig,\n resolveSource,\n saveSourceToProjectConfig,\n} from \"../lib/configuration/index.js\";\n\nconst EJECT_TYPES = [\"agent-partials\", \"templates\", \"skills\", \"all\"] as const;\ntype EjectType = (typeof EJECT_TYPES)[number];\n\nexport default class Eject extends BaseCommand {\n static summary = \"Eject skills, agent partials, or templates for local customization\";\n static description =\n \"Copy agent partials, templates, or skills to your project for customization. \" +\n \"Agent partials and templates are always copied from the CLI. \" +\n \"Skills are copied from the configured source (public marketplace by default).\";\n\n static examples = [\n {\n description: \"Eject agent partials for customization\",\n command: \"<%= config.bin %> <%= command.id %> agent-partials\",\n },\n {\n description: \"Eject only agent templates\",\n command: \"<%= config.bin %> <%= command.id %> templates\",\n },\n {\n description: \"Eject skills to local directory\",\n command: \"<%= config.bin %> <%= command.id %> skills\",\n },\n {\n description: \"Eject everything with force overwrite\",\n command: \"<%= config.bin %> <%= command.id %> all --force\",\n },\n {\n description: \"Eject to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> skills -o ./custom-dir\",\n },\n ];\n\n static args = {\n type: Args.string({\n description: \"What to eject: agent-partials, templates, skills, all\",\n required: false,\n options: EJECT_TYPES as unknown as string[],\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing files\",\n default: false,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output directory (default: .claude/ in current directory)\",\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote source\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Eject);\n const projectDir = process.cwd();\n\n if (!args.type) {\n this.error(\"Please specify what to eject: agent-partials, templates, skills, or all\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!EJECT_TYPES.includes(args.type as EjectType)) {\n this.error(`Unknown eject type: ${args.type}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n let outputBase: string;\n if (flags.output) {\n const expandedPath = flags.output.startsWith(\"~\")\n ? path.join(os.homedir(), flags.output.slice(1))\n : flags.output;\n outputBase = path.resolve(projectDir, expandedPath);\n\n if (await fileExists(outputBase)) {\n this.error(`Output path exists as a file: ${outputBase}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n } else {\n outputBase = path.join(projectDir, CLAUDE_SRC_DIR);\n }\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Eject`);\n this.log(\"\");\n\n if (flags.output) {\n this.log(`Output directory: ${outputBase}`);\n }\n\n const ejectType = args.type as EjectType;\n const directOutput = !!flags.output;\n\n let sourceResult: SourceLoadResult | undefined;\n if (ejectType === \"skills\" || ejectType === \"all\") {\n sourceResult = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n projectDir,\n forceRefresh: flags.refresh,\n });\n }\n\n switch (ejectType) {\n case \"agent-partials\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, false);\n break;\n case \"templates\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, true);\n break;\n case \"skills\":\n await this.ejectSkills(\n projectDir,\n flags.force,\n sourceResult!,\n directOutput,\n directOutput ? outputBase : undefined,\n );\n break;\n case \"all\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, false);\n await this.ejectAgentPartials(outputBase, true, directOutput, true);\n await this.ejectSkills(\n projectDir,\n flags.force,\n sourceResult!,\n directOutput,\n directOutput ? outputBase : undefined,\n );\n break;\n default:\n break;\n }\n\n if (flags.source) {\n await saveSourceToProjectConfig(projectDir, flags.source);\n this.log(`Source saved to .claude-src/config.yaml`);\n }\n\n await this.ensureMinimalConfig(projectDir, flags.source, sourceResult);\n\n this.log(\"\");\n this.logSuccess(\"Eject complete!\");\n this.log(\"\");\n }\n\n // Ensures a minimal config.yaml exists so `agentsinc compile` works after eject\n private async ensureMinimalConfig(\n projectDir: string,\n sourceFlag?: string,\n sourceResult?: SourceLoadResult,\n ): Promise<void> {\n const configPath = path.join(projectDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_YAML);\n\n if (await fileExists(configPath)) {\n return;\n }\n\n const projectName = path.basename(projectDir);\n\n const config: Record<string, unknown> = {\n name: projectName,\n installMode: \"local\",\n };\n\n const resolvedConfig =\n sourceResult?.sourceConfig ?? (await resolveSource(sourceFlag, projectDir));\n\n if (sourceFlag) {\n config.source = sourceFlag;\n } else if (resolvedConfig.source) {\n config.source = resolvedConfig.source;\n }\n\n if (resolvedConfig.marketplace) {\n config.marketplace = resolvedConfig.marketplace;\n }\n\n const existingProjectConfig = await loadProjectSourceConfig(projectDir);\n if (existingProjectConfig?.author) {\n config.author = existingProjectConfig.author;\n }\n if (existingProjectConfig?.agentsSource) {\n config.agentsSource = existingProjectConfig.agentsSource;\n }\n\n await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));\n\n let configContent = stringifyYaml(config, { indent: YAML_FORMATTING.INDENT });\n\n const exampleStackComment = `\n# Example stack configuration (uncomment and customize):\n#\n# skills:\n# - web-framework-react\n# - web-styling-scss-modules\n# - api-framework-hono\n# - api-database-drizzle\n#\n# agents:\n# - web-developer\n# - api-developer\n# - web-reviewer\n#\n# stack:\n# web-developer:\n# framework: web-framework-react\n# styling: web-styling-scss-modules\n# api-developer:\n# api: api-framework-hono\n# database: api-database-drizzle\n`;\n\n configContent += exampleStackComment;\n await writeFile(configPath, configContent);\n\n this.logSuccess(`Created ${CLAUDE_SRC_DIR}/config.yaml`);\n }\n\n private async ejectAgentPartials(\n outputBase: string,\n force: boolean,\n directOutput = false,\n templatesFlag = false,\n ): Promise<void> {\n const sourceDir = templatesFlag\n ? path.join(PROJECT_ROOT, DIRS.templates)\n : path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(sourceDir))) {\n this.warn(\n templatesFlag ? \"No agent templates found in CLI.\" : \"No agent partials found in CLI.\",\n );\n return;\n }\n\n const destDir = directOutput\n ? outputBase\n : templatesFlag\n ? path.join(outputBase, path.basename(DIRS.agents), path.basename(DIRS.templates))\n : path.join(outputBase, path.basename(DIRS.agents));\n\n const templatesBasename = path.basename(DIRS.templates);\n\n if ((await directoryExists(destDir)) && !force) {\n if (templatesFlag) {\n this.warn(`Agent templates already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n\n const hasTemplates = await directoryExists(path.join(destDir, templatesBasename));\n if ((await this.hasAgentPartialDirs(destDir)) && !hasTemplates) {\n this.warn(`Agent partials already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n }\n\n await ensureDir(destDir);\n\n const skipTemplates =\n !templatesFlag && !force && (await directoryExists(path.join(destDir, templatesBasename)));\n\n if (skipTemplates) {\n const sourceEntries = await listDirectories(sourceDir);\n const nonTemplateEntries = sourceEntries.filter((entry) => entry !== templatesBasename);\n for (const entry of nonTemplateEntries) {\n await copy(path.join(sourceDir, entry), path.join(destDir, entry));\n }\n this.warn(\n \"Agent templates already exist — skipping templates, only ejecting agent partials.\",\n );\n } else {\n await copy(sourceDir, destDir);\n }\n\n this.logSuccess(\n `${templatesFlag ? \"Agent templates\" : \"Agent partials\"} ejected to ${destDir}`,\n );\n this.log(\n templatesFlag\n ? \"You can now customize agent templates locally.\"\n : \"You can now customize templates, agent intro, workflow, and examples locally.\",\n );\n }\n\n /** Checks whether the agents directory contains any agent subdirectories (not just _templates). */\n private async hasAgentPartialDirs(agentsDir: string): Promise<boolean> {\n const subdirs = await listDirectories(agentsDir);\n const templatesBasename = path.basename(DIRS.templates);\n return subdirs.some((dir) => dir !== templatesBasename);\n }\n\n private async ejectSkills(\n projectDir: string,\n force: boolean,\n sourceResult: SourceLoadResult,\n directOutput = false,\n customOutputBase?: string,\n ): Promise<void> {\n const destDir =\n directOutput && customOutputBase\n ? customOutputBase\n : path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if ((await directoryExists(destDir)) && !force) {\n this.warn(`Skills already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n\n const skillIds = typedKeys<SkillId>(sourceResult.matrix.skills).filter(\n (skillId) => !sourceResult.matrix.skills[skillId]?.local,\n );\n\n if (skillIds.length === 0) {\n this.warn(\"No skills found in source to eject.\");\n return;\n }\n\n await ensureDir(destDir);\n\n const copiedSkills = await copySkillsToLocalFlattened(\n skillIds,\n destDir,\n sourceResult.matrix,\n sourceResult,\n );\n\n const sourceLabel = sourceResult.isLocal\n ? sourceResult.sourcePath\n : sourceResult.marketplace || sourceResult.sourceConfig.source;\n\n this.logSuccess(`${copiedSkills.length} skills ejected to ${destDir} from ${sourceLabel}`);\n this.log(\"You can now customize skill content locally.\");\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/eject.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport os from \"os\";\nimport { BaseCommand } from \"../base-command.js\";\nimport {\n copy,\n ensureDir,\n directoryExists,\n fileExists,\n listDirectories,\n writeFile,\n} from \"../utils/fs.js\";\nimport {\n CLAUDE_SRC_DIR,\n DEFAULT_BRANDING,\n DIRS,\n LOCAL_SKILLS_PATH,\n PROJECT_ROOT,\n STANDARD_FILES,\n} from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { loadSkillsMatrixFromSource, type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { copySkillsToLocalFlattened } from \"../lib/skills/index.js\";\nimport type { SkillId } from \"../types/index.js\";\nimport { typedKeys } from \"../utils/typed-object.js\";\nimport {\n loadProjectSourceConfig,\n resolveSource,\n saveSourceToProjectConfig,\n} from \"../lib/configuration/index.js\";\n\nconst EJECT_TYPES = [\"agent-partials\", \"templates\", \"skills\", \"all\"] as const;\ntype EjectType = (typeof EJECT_TYPES)[number];\n\nexport default class Eject extends BaseCommand {\n static summary = \"Eject skills, agent partials, or templates for local customization\";\n static description =\n \"Copy agent partials, templates, or skills to your project for customization. \" +\n \"Agent partials and templates are always copied from the CLI. \" +\n \"Skills are copied from the configured source (public marketplace by default).\";\n\n static examples = [\n {\n description: \"Eject agent partials for customization\",\n command: \"<%= config.bin %> <%= command.id %> agent-partials\",\n },\n {\n description: \"Eject only agent templates\",\n command: \"<%= config.bin %> <%= command.id %> templates\",\n },\n {\n description: \"Eject skills to local directory\",\n command: \"<%= config.bin %> <%= command.id %> skills\",\n },\n {\n description: \"Eject everything with force overwrite\",\n command: \"<%= config.bin %> <%= command.id %> all --force\",\n },\n {\n description: \"Eject to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> skills -o ./custom-dir\",\n },\n ];\n\n static args = {\n type: Args.string({\n description: \"What to eject: agent-partials, templates, skills, all\",\n required: false,\n options: EJECT_TYPES as unknown as string[],\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing files\",\n default: false,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output directory (default: .claude/ in current directory)\",\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote source\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Eject);\n const projectDir = process.cwd();\n\n if (!args.type) {\n this.error(\"Please specify what to eject: agent-partials, templates, skills, or all\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!EJECT_TYPES.includes(args.type as EjectType)) {\n this.error(`Unknown eject type: ${args.type}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n let outputBase: string;\n if (flags.output) {\n const expandedPath = flags.output.startsWith(\"~\")\n ? path.join(os.homedir(), flags.output.slice(1))\n : flags.output;\n outputBase = path.resolve(projectDir, expandedPath);\n\n if (await fileExists(outputBase)) {\n this.error(`Output path exists as a file: ${outputBase}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n } else {\n outputBase = path.join(projectDir, CLAUDE_SRC_DIR);\n }\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Eject`);\n this.log(\"\");\n\n if (flags.output) {\n this.log(`Output directory: ${outputBase}`);\n }\n\n const ejectType = args.type as EjectType;\n const directOutput = !!flags.output;\n\n let sourceResult: SourceLoadResult | undefined;\n if (ejectType === \"skills\" || ejectType === \"all\") {\n sourceResult = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n projectDir,\n forceRefresh: flags.refresh,\n });\n }\n\n switch (ejectType) {\n case \"agent-partials\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, false);\n break;\n case \"templates\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, true);\n break;\n case \"skills\":\n await this.ejectSkills(\n projectDir,\n flags.force,\n sourceResult!,\n directOutput,\n directOutput ? outputBase : undefined,\n );\n break;\n case \"all\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, false);\n await this.ejectAgentPartials(outputBase, true, directOutput, true);\n await this.ejectSkills(\n projectDir,\n flags.force,\n sourceResult!,\n directOutput,\n directOutput ? outputBase : undefined,\n );\n break;\n default:\n break;\n }\n\n if (flags.source) {\n await saveSourceToProjectConfig(projectDir, flags.source);\n this.log(`Source saved to .claude-src/config.ts`);\n }\n\n await this.ensureMinimalConfig(projectDir, flags.source, sourceResult);\n\n this.log(\"\");\n this.logSuccess(\"Eject complete!\");\n this.log(\"\");\n }\n\n // Ensures a minimal config exists so `agentsinc compile` works after eject\n private async ensureMinimalConfig(\n projectDir: string,\n sourceFlag?: string,\n sourceResult?: SourceLoadResult,\n ): Promise<void> {\n const tsConfigPath = path.join(projectDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS);\n\n if (await fileExists(tsConfigPath)) {\n return;\n }\n\n const projectName = path.basename(projectDir);\n\n const config: Record<string, unknown> = {\n name: projectName,\n };\n\n const resolvedConfig =\n sourceResult?.sourceConfig ?? (await resolveSource(sourceFlag, projectDir));\n\n if (sourceFlag) {\n config.source = sourceFlag;\n } else if (resolvedConfig.source) {\n config.source = resolvedConfig.source;\n }\n\n if (resolvedConfig.marketplace) {\n config.marketplace = resolvedConfig.marketplace;\n }\n\n const existingProjectConfig = await loadProjectSourceConfig(projectDir);\n if (existingProjectConfig?.author) {\n config.author = existingProjectConfig.author;\n }\n if (existingProjectConfig?.agentsSource) {\n config.agentsSource = existingProjectConfig.agentsSource;\n }\n\n await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));\n\n // JSON.parse(JSON.stringify(x)) removes undefined values\n const cleaned = JSON.parse(JSON.stringify(config));\n const body = JSON.stringify(cleaned, null, 2);\n const content = `export default ${body};\\n`;\n\n await writeFile(tsConfigPath, content);\n\n this.logSuccess(`Created ${CLAUDE_SRC_DIR}/config.ts`);\n }\n\n private async ejectAgentPartials(\n outputBase: string,\n force: boolean,\n directOutput = false,\n templatesFlag = false,\n ): Promise<void> {\n const sourceDir = templatesFlag\n ? path.join(PROJECT_ROOT, DIRS.templates)\n : path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(sourceDir))) {\n this.warn(\n templatesFlag ? \"No agent templates found in CLI.\" : \"No agent partials found in CLI.\",\n );\n return;\n }\n\n const destDir = directOutput\n ? outputBase\n : templatesFlag\n ? path.join(outputBase, path.basename(DIRS.agents), path.basename(DIRS.templates))\n : path.join(outputBase, path.basename(DIRS.agents));\n\n const templatesBasename = path.basename(DIRS.templates);\n\n if ((await directoryExists(destDir)) && !force) {\n if (templatesFlag) {\n this.warn(`Agent templates already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n\n const hasTemplates = await directoryExists(path.join(destDir, templatesBasename));\n if ((await this.hasAgentPartialDirs(destDir)) && !hasTemplates) {\n this.warn(`Agent partials already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n }\n\n await ensureDir(destDir);\n\n const skipTemplates =\n !templatesFlag && !force && (await directoryExists(path.join(destDir, templatesBasename)));\n\n if (skipTemplates) {\n const sourceEntries = await listDirectories(sourceDir);\n const nonTemplateEntries = sourceEntries.filter((entry) => entry !== templatesBasename);\n for (const entry of nonTemplateEntries) {\n await copy(path.join(sourceDir, entry), path.join(destDir, entry));\n }\n this.warn(\n \"Agent templates already exist — skipping templates, only ejecting agent partials.\",\n );\n } else {\n await copy(sourceDir, destDir);\n }\n\n this.logSuccess(\n `${templatesFlag ? \"Agent templates\" : \"Agent partials\"} ejected to ${destDir}`,\n );\n this.log(\n templatesFlag\n ? \"You can now customize agent templates locally.\"\n : \"You can now customize templates, agent intro, workflow, and examples locally.\",\n );\n }\n\n /** Checks whether the agents directory contains any agent subdirectories (not just _templates). */\n private async hasAgentPartialDirs(agentsDir: string): Promise<boolean> {\n const subdirs = await listDirectories(agentsDir);\n const templatesBasename = path.basename(DIRS.templates);\n return subdirs.some((dir) => dir !== templatesBasename);\n }\n\n private async ejectSkills(\n projectDir: string,\n force: boolean,\n sourceResult: SourceLoadResult,\n directOutput = false,\n customOutputBase?: string,\n ): Promise<void> {\n const destDir =\n directOutput && customOutputBase\n ? customOutputBase\n : path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if ((await directoryExists(destDir)) && !force) {\n this.warn(`Skills already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n\n const skillIds = typedKeys<SkillId>(sourceResult.matrix.skills).filter(\n (skillId) => !sourceResult.matrix.skills[skillId]?.local,\n );\n\n if (skillIds.length === 0) {\n this.warn(\"No skills found in source to eject.\");\n return;\n }\n\n await ensureDir(destDir);\n\n const copiedSkills = await copySkillsToLocalFlattened(\n skillIds,\n destDir,\n sourceResult.matrix,\n sourceResult,\n );\n\n const sourceLabel = sourceResult.isLocal\n ? sourceResult.sourcePath\n : sourceResult.marketplace || sourceResult.sourceConfig.source;\n\n this.logSuccess(`${copiedSkills.length} skills ejected to ${destDir} from ${sourceLabel}`);\n this.log(\"You can now customize skill content locally.\");\n }\n}\n"],"mappings":"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","names":[]}
@@ -2,18 +2,19 @@
2
2
  import {
3
3
  INFO_MESSAGES,
4
4
  STATUS_MESSAGES
5
- } from "../../chunk-WLZHCM7O.js";
6
- import {
7
- BaseCommand,
8
- EXIT_CODES
9
- } from "../../chunk-PGY5XROM.js";
5
+ } from "../../chunk-MR6OBL3B.js";
10
6
  import {
11
7
  IMPORT_DEFAULTS,
12
8
  computeFileHash,
13
9
  fetchFromSource,
14
10
  getCurrentDate
15
- } from "../../chunk-HMSHB5EQ.js";
11
+ } from "../../chunk-TZXYBG3R.js";
12
+ import "../../chunk-OCEFD7V6.js";
16
13
  import "../../chunk-T4EXUIBY.js";
14
+ import {
15
+ BaseCommand,
16
+ EXIT_CODES
17
+ } from "../../chunk-VR3CDXDT.js";
17
18
  import {
18
19
  copy,
19
20
  directoryExists,
@@ -24,14 +25,15 @@ import {
24
25
  listDirectories,
25
26
  readFile,
26
27
  writeFile
27
- } from "../../chunk-WBHPCBVN.js";
28
+ } from "../../chunk-LWXRUR6B.js";
28
29
  import {
29
30
  DEFAULT_SKILLS_SUBDIR,
30
31
  GITHUB_SOURCE,
31
32
  LOCAL_SKILLS_PATH,
32
33
  STANDARD_FILES,
33
34
  YAML_FORMATTING
34
- } from "../../chunk-AWP5A6IM.js";
35
+ } from "../../chunk-6OWHQ7HM.js";
36
+ import "../../chunk-EC3UJRKZ.js";
35
37
  import {
36
38
  init_esm_shims
37
39
  } from "../../chunk-DHET7RCE.js";
@@ -229,16 +231,6 @@ Use --list to see all available skills.`,
229
231
  skillsToImport = [flags.skill];
230
232
  }
231
233
  const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);
232
- if (flags["dry-run"]) {
233
- this.log("");
234
- this.log("[DRY RUN] Would import the following skills:");
235
- for (const skill of skillsToImport) {
236
- const destPath = path.join(destDir, skill);
237
- const exists = await directoryExists(destPath);
238
- this.log(` - ${skill} -> ${destPath}${exists ? " (exists)" : ""}`);
239
- }
240
- return;
241
- }
242
234
  this.log("");
243
235
  this.log(`Importing ${skillsToImport.length} skill(s)...`);
244
236
  let imported = 0;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/commands/import/skill.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { BaseCommand } from \"../../base-command.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { EXIT_CODES } from \"../../lib/exit-codes.js\";\nimport { fetchFromSource } from \"../../lib/loading/index.js\";\nimport { importedSkillMetadataSchema } from \"../../lib/schemas.js\";\nimport { getCurrentDate, computeFileHash } from \"../../lib/versioning.js\";\nimport {\n copy,\n directoryExists,\n fileExists,\n listDirectories,\n readFile,\n writeFile,\n ensureDir,\n} from \"../../utils/fs.js\";\nimport {\n DEFAULT_SKILLS_SUBDIR,\n GITHUB_SOURCE,\n LOCAL_SKILLS_PATH,\n STANDARD_FILES,\n YAML_FORMATTING,\n} from \"../../consts.js\";\nimport { IMPORT_DEFAULTS } from \"../../lib/metadata-keys.js\";\nimport { STATUS_MESSAGES, INFO_MESSAGES } from \"../../utils/messages.js\";\n\n/**\n * Metadata for tracking third-party imports. Different from ForkedFromMetadata\n * in skill-metadata.ts which tracks internal fork lineage (uses skillId\n * instead of source/skillName).\n */\ntype ImportedForkedFromMetadata = {\n source: string;\n skillName: string;\n contentHash: string;\n date: string;\n};\n\ntype SkillMetadata = {\n forkedFrom?: ImportedForkedFromMetadata;\n [key: string]: unknown;\n};\n\nconst SKILL_MD_FILE = STANDARD_FILES.SKILL_MD;\nconst METADATA_YAML_FILE = STANDARD_FILES.METADATA_YAML;\nconst METADATA_JSON_FILE = STANDARD_FILES.METADATA_JSON;\n\nfunction parseGitHubSource(source: string): {\n gigetSource: string;\n displaySource: string;\n} {\n if (source.startsWith(GITHUB_SOURCE.HTTPS_PREFIX)) {\n const path = source.replace(GITHUB_SOURCE.HTTPS_PREFIX, \"\");\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${path}`,\n displaySource: source,\n };\n }\n\n if (\n source.startsWith(GITHUB_SOURCE.GITHUB_PREFIX) ||\n source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ) {\n const normalized = source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ? GITHUB_SOURCE.GITHUB_PREFIX + source.slice(GITHUB_SOURCE.GH_PREFIX.length)\n : source;\n return {\n gigetSource: normalized,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${normalized.replace(GITHUB_SOURCE.GITHUB_PREFIX, \"\")}`,\n };\n }\n\n if (source.includes(\"/\") && !source.includes(\":\")) {\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${source}`,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${source}`,\n };\n }\n\n return {\n gigetSource: source,\n displaySource: source,\n };\n}\n\nasync function discoverValidSkills(skillsDir: string, skillDirs: string[]): Promise<string[]> {\n const validSkills: string[] = [];\n\n for (const skillDir of skillDirs) {\n const skillMdPath = path.join(skillsDir, skillDir, SKILL_MD_FILE);\n if (await fileExists(skillMdPath)) {\n validSkills.push(skillDir);\n }\n }\n\n return validSkills.sort();\n}\n\nexport default class ImportSkill extends BaseCommand {\n static summary = \"Import a skill from a third-party GitHub repository\";\n static description =\n \"Download and import skills from external GitHub repositories into your local \" +\n \".claude/skills/ directory. Supports importing specific skills or listing available skills.\";\n\n static examples = [\n {\n description: \"List available skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --list\",\n },\n {\n description: \"Import a specific skill\",\n command:\n \"<%= config.bin %> import skill github:vercel-labs/agent-skills --skill react-best-practices\",\n },\n {\n description: \"Import all skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --all\",\n },\n {\n description: \"Import with custom skills directory\",\n command:\n \"<%= config.bin %> import skill github:owner/repo --skill my-skill --subdir custom-skills\",\n },\n ];\n\n static args = {\n source: Args.string({\n description:\n \"GitHub repository source (github:owner/repo, https://github.com/owner/repo, or owner/repo)\",\n required: true,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n skill: Flags.string({\n char: \"n\",\n description: \"Name of the specific skill to import\",\n required: false,\n }),\n all: Flags.boolean({\n char: \"a\",\n description: \"Import all skills from the repository\",\n default: false,\n }),\n list: Flags.boolean({\n char: \"l\",\n description: \"List available skills without importing\",\n default: false,\n }),\n subdir: Flags.string({\n description: \"Subdirectory containing skills (default: skills)\",\n default: DEFAULT_SKILLS_SUBDIR,\n }),\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing skills\",\n default: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote (ignore cache)\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(ImportSkill);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(\"Import Third-Party Skill\");\n this.log(\"\");\n\n if (!flags.list && !flags.skill && !flags.all) {\n this.error(\"Please specify --skill <name>, --all, or --list to list available skills\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (flags.skill && flags.all) {\n this.error(\"Cannot use --skill and --all together\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n const { gigetSource, displaySource } = parseGitHubSource(args.source);\n this.log(`Source: ${displaySource}`);\n\n this.log(STATUS_MESSAGES.FETCHING_REPOSITORY);\n\n let repoPath: string;\n try {\n const result = await fetchFromSource(gigetSource, {\n forceRefresh: flags.refresh,\n });\n repoPath = result.path;\n this.log(result.fromCache ? \"Using cached source\" : \"Downloaded fresh copy\");\n } catch (error) {\n this.error(error instanceof Error ? error.message : `Failed to fetch: ${args.source}`, {\n exit: EXIT_CODES.NETWORK_ERROR,\n });\n }\n\n // Validate --subdir to prevent path traversal outside repository boundary\n const subdir = flags.subdir;\n if (/\\0/.test(subdir)) {\n this.error(\"--subdir contains null bytes\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n if (path.isAbsolute(subdir)) {\n this.error(`--subdir must be a relative path, got: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n const skillsDir = path.resolve(path.join(repoPath, subdir));\n const resolvedRepoPath = path.resolve(repoPath);\n if (!skillsDir.startsWith(resolvedRepoPath + path.sep) && skillsDir !== resolvedRepoPath) {\n this.error(`--subdir path escapes repository boundary: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!(await directoryExists(skillsDir))) {\n this.error(\n `Skills directory not found: ${flags.subdir}\\n` +\n `The repository doesn't have a '${flags.subdir}' directory.\\n` +\n `Use --subdir to specify a different location.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const availableSkills = await discoverValidSkills(skillsDir, skillDirs);\n\n if (availableSkills.length === 0) {\n this.error(`No valid skills found in ${flags.subdir}/\\nSkills must have a SKILL.md file.`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n if (flags.list) {\n this.log(\"\");\n this.log(`Available skills (${availableSkills.length}):`);\n this.log(\"\");\n for (const skill of availableSkills) {\n this.log(` - ${skill}`);\n }\n this.log(\"\");\n this.log(\"Use --skill <name> to import a specific skill, or --all to import all.\");\n return;\n }\n\n let skillsToImport: string[] = [];\n\n if (flags.all) {\n skillsToImport = availableSkills;\n } else if (flags.skill) {\n if (!availableSkills.includes(flags.skill)) {\n this.error(\n `Skill '${flags.skill}' not found in repository.\\n` +\n `Available skills: ${availableSkills.join(\", \")}\\n` +\n `Use --list to see all available skills.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n skillsToImport = [flags.skill];\n }\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if (flags[\"dry-run\"]) {\n this.log(\"\");\n this.log(\"[DRY RUN] Would import the following skills:\");\n for (const skill of skillsToImport) {\n const destPath = path.join(destDir, skill);\n const exists = await directoryExists(destPath);\n this.log(` - ${skill} -> ${destPath}${exists ? \" (exists)\" : \"\"}`);\n }\n return;\n }\n\n this.log(\"\");\n this.log(`Importing ${skillsToImport.length} skill(s)...`);\n\n let imported = 0;\n let skipped = 0;\n\n for (const skillName of skillsToImport) {\n const sourcePath = path.join(skillsDir, skillName);\n const destPath = path.join(destDir, skillName);\n\n if (await directoryExists(destPath)) {\n if (!flags.force) {\n this.warn(`Skipping '${skillName}': already exists. Use --force to overwrite.`);\n skipped++;\n continue;\n }\n }\n\n try {\n await this.importSkill(sourcePath, destPath, skillName, displaySource);\n this.logSuccess(`Imported: ${skillName}`);\n imported++;\n } catch (error) {\n this.warn(`Failed to import '${skillName}': ${getErrorMessage(error)}`);\n skipped++;\n }\n }\n\n this.log(\"\");\n this.logSuccess(`Import complete: ${imported} imported, ${skipped} skipped`);\n this.log(`Skills location: ${destDir}`);\n this.log(\"\");\n this.log(INFO_MESSAGES.RUN_COMPILE);\n this.log(\"\");\n }\n\n private async importSkill(\n sourcePath: string,\n destPath: string,\n skillName: string,\n source: string,\n ): Promise<void> {\n const skillMdPath = path.join(sourcePath, SKILL_MD_FILE);\n if (!(await fileExists(skillMdPath))) {\n throw new Error(\n `Missing required SKILL.md file at ${skillMdPath}\\n` +\n `Every skill must have a SKILL.md file containing the skill's prompt content.\\n` +\n `Create one with:\\n` +\n ` echo \"# ${skillName}\" > ${path.join(sourcePath, SKILL_MD_FILE)}`,\n );\n }\n\n const contentHash = await computeFileHash(skillMdPath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await this.injectForkedFromMetadata(destPath, skillName, source, contentHash);\n }\n\n private async injectForkedFromMetadata(\n destPath: string,\n skillName: string,\n source: string,\n contentHash: string,\n ): Promise<void> {\n const metadataYamlPath = path.join(destPath, METADATA_YAML_FILE);\n const metadataJsonPath = path.join(destPath, METADATA_JSON_FILE);\n\n const forkedFrom: ImportedForkedFromMetadata = {\n source,\n skillName: skillName,\n contentHash: contentHash,\n date: getCurrentDate(),\n };\n\n if (await fileExists(metadataYamlPath)) {\n const rawContent = await readFile(metadataYamlPath);\n const lines = rawContent.split(\"\\n\");\n let yamlContent = rawContent;\n let schemaComment = \"\";\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 raw = parseYaml(yamlContent);\n const parseResult = importedSkillMetadataSchema.safeParse(raw);\n if (!parseResult.success) {\n this.warn(\n `Malformed metadata.yaml at ${metadataYamlPath} — existing fields may be lost\\n` +\n ` Validation errors: ${parseResult.error.issues.map((i) => i.message).join(\", \")}\\n` +\n ` Expected fields: displayName (string), cliDescription (string), category (string)\\n` +\n ` Validate your YAML syntax at https://yamllint.com`,\n );\n }\n const metadata = parseResult.success\n ? (parseResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const newYamlContent = stringifyYaml(metadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, schemaComment + newYamlContent);\n return;\n }\n\n if (await fileExists(metadataJsonPath)) {\n const rawContent = await readFile(metadataJsonPath);\n let jsonParsed: unknown;\n try {\n jsonParsed = JSON.parse(rawContent);\n } catch {\n this.warn(\n `Malformed JSON in ${metadataJsonPath} — skipping metadata injection\\n` +\n ` Common issues: trailing commas, unquoted keys, single quotes instead of double quotes\\n` +\n ` Validate your JSON at https://jsonlint.com`,\n );\n return;\n }\n const jsonResult = importedSkillMetadataSchema.safeParse(jsonParsed);\n const metadata = jsonResult.success\n ? (jsonResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const yamlContent = stringifyYaml(metadata, { lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE });\n await writeFile(metadataYamlPath, yamlContent);\n return;\n }\n\n const minimalMetadata: SkillMetadata = {\n displayName: skillName\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \"),\n cliDescription: \"Imported from third-party repository\",\n category: IMPORT_DEFAULTS.CATEGORY,\n author: IMPORT_DEFAULTS.AUTHOR,\n forkedFrom: forkedFrom,\n };\n\n const yamlContent = stringifyYaml(minimalMetadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, yamlContent);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,SAAS,MAAM,aAAa;AAC5B,OAAO,UAAU;AACjB,SAAS,SAAS,WAAW,aAAa,qBAAqB;AA2C/D,IAAM,gBAAgB,eAAe;AACrC,IAAM,qBAAqB,eAAe;AAC1C,IAAM,qBAAqB,eAAe;AAE1C,SAAS,kBAAkB,QAGzB;AACA,MAAI,OAAO,WAAW,cAAc,YAAY,GAAG;AACjD,UAAMA,QAAO,OAAO,QAAQ,cAAc,cAAc,EAAE;AAC1D,WAAO;AAAA,MACL,aAAa,GAAG,cAAc,aAAa,GAAGA,KAAI;AAAA,MAClD,eAAe;AAAA,IACjB;AAAA,EACF;AAEA,MACE,OAAO,WAAW,cAAc,aAAa,KAC7C,OAAO,WAAW,cAAc,SAAS,GACzC;AACA,UAAM,aAAa,OAAO,WAAW,cAAc,SAAS,IACxD,cAAc,gBAAgB,OAAO,MAAM,cAAc,UAAU,MAAM,IACzE;AACJ,WAAO;AAAA,MACL,aAAa;AAAA,MACb,eAAe,GAAG,cAAc,YAAY,GAAG,WAAW,QAAQ,cAAc,eAAe,EAAE,CAAC;AAAA,IACpG;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG,KAAK,CAAC,OAAO,SAAS,GAAG,GAAG;AACjD,WAAO;AAAA,MACL,aAAa,GAAG,cAAc,aAAa,GAAG,MAAM;AAAA,MACpD,eAAe,GAAG,cAAc,YAAY,GAAG,MAAM;AAAA,IACvD;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AACF;AAEA,eAAe,oBAAoB,WAAmB,WAAwC;AAC5F,QAAM,cAAwB,CAAC;AAE/B,aAAW,YAAY,WAAW;AAChC,UAAM,cAAc,KAAK,KAAK,WAAW,UAAU,aAAa;AAChE,QAAI,MAAM,WAAW,WAAW,GAAG;AACjC,kBAAY,KAAK,QAAQ;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO,YAAY,KAAK;AAC1B;AAEA,IAAqB,cAArB,MAAqB,qBAAoB,YAAY;AAAA,EACnD,OAAO,UAAU;AAAA,EACjB,OAAO,cACL;AAAA,EAGF,OAAO,WAAW;AAAA,IAChB;AAAA,MACE,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,SACE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,SACE;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,OAAO,OAAO;AAAA,IACZ,QAAQ,KAAK,OAAO;AAAA,MAClB,aACE;AAAA,MACF,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,QAAQ;AAAA,IACb,GAAG,YAAY;AAAA,IACf,OAAO,MAAM,OAAO;AAAA,MAClB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ,CAAC;AAAA,IACD,KAAK,MAAM,QAAQ;AAAA,MACjB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,IACD,MAAM,MAAM,QAAQ;AAAA,MAClB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,IACD,QAAQ,MAAM,OAAO;AAAA,MACnB,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,IACD,OAAO,MAAM,QAAQ;AAAA,MACnB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,IACD,SAAS,MAAM,QAAQ;AAAA,MACrB,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAqB;AACzB,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,KAAK,MAAM,YAAW;AACpD,UAAM,aAAa,QAAQ,IAAI;AAE/B,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,0BAA0B;AACnC,SAAK,IAAI,EAAE;AAEX,QAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,SAAS,CAAC,MAAM,KAAK;AAC7C,WAAK,MAAM,4EAA4E;AAAA,QACrF,MAAM,WAAW;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,QAAI,MAAM,SAAS,MAAM,KAAK;AAC5B,WAAK,MAAM,yCAAyC;AAAA,QAClD,MAAM,WAAW;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,UAAM,EAAE,aAAa,cAAc,IAAI,kBAAkB,KAAK,MAAM;AACpE,SAAK,IAAI,WAAW,aAAa,EAAE;AAEnC,SAAK,IAAI,gBAAgB,mBAAmB;AAE5C,QAAI;AACJ,QAAI;AACF,YAAM,SAAS,MAAM,gBAAgB,aAAa;AAAA,QAChD,cAAc,MAAM;AAAA,MACtB,CAAC;AACD,iBAAW,OAAO;AAClB,WAAK,IAAI,OAAO,YAAY,wBAAwB,uBAAuB;AAAA,IAC7E,SAAS,OAAO;AACd,WAAK,MAAM,iBAAiB,QAAQ,MAAM,UAAU,oBAAoB,KAAK,MAAM,IAAI;AAAA,QACrF,MAAM,WAAW;AAAA,MACnB,CAAC;AAAA,IACH;AAGA,UAAM,SAAS,MAAM;AACrB,QAAI,KAAK,KAAK,MAAM,GAAG;AACrB,WAAK,MAAM,gCAAgC;AAAA,QACzC,MAAM,WAAW;AAAA,MACnB,CAAC;AAAA,IACH;AACA,QAAI,KAAK,WAAW,MAAM,GAAG;AAC3B,WAAK,MAAM,0CAA0C,MAAM,IAAI;AAAA,QAC7D,MAAM,WAAW;AAAA,MACnB,CAAC;AAAA,IACH;AACA,UAAM,YAAY,KAAK,QAAQ,KAAK,KAAK,UAAU,MAAM,CAAC;AAC1D,UAAM,mBAAmB,KAAK,QAAQ,QAAQ;AAC9C,QAAI,CAAC,UAAU,WAAW,mBAAmB,KAAK,GAAG,KAAK,cAAc,kBAAkB;AACxF,WAAK,MAAM,8CAA8C,MAAM,IAAI;AAAA,QACjE,MAAM,WAAW;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,QAAI,CAAE,MAAM,gBAAgB,SAAS,GAAI;AACvC,WAAK;AAAA,QACH,+BAA+B,MAAM,MAAM;AAAA,iCACP,MAAM,MAAM;AAAA;AAAA,QAEhD,EAAE,MAAM,WAAW,aAAa;AAAA,MAClC;AAAA,IACF;AAEA,UAAM,YAAY,MAAM,gBAAgB,SAAS;AACjD,UAAM,kBAAkB,MAAM,oBAAoB,WAAW,SAAS;AAEtE,QAAI,gBAAgB,WAAW,GAAG;AAChC,WAAK,MAAM,4BAA4B,MAAM,MAAM;AAAA,oCAAwC;AAAA,QACzF,MAAM,WAAW;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,QAAI,MAAM,MAAM;AACd,WAAK,IAAI,EAAE;AACX,WAAK,IAAI,qBAAqB,gBAAgB,MAAM,IAAI;AACxD,WAAK,IAAI,EAAE;AACX,iBAAW,SAAS,iBAAiB;AACnC,aAAK,IAAI,OAAO,KAAK,EAAE;AAAA,MACzB;AACA,WAAK,IAAI,EAAE;AACX,WAAK,IAAI,wEAAwE;AACjF;AAAA,IACF;AAEA,QAAI,iBAA2B,CAAC;AAEhC,QAAI,MAAM,KAAK;AACb,uBAAiB;AAAA,IACnB,WAAW,MAAM,OAAO;AACtB,UAAI,CAAC,gBAAgB,SAAS,MAAM,KAAK,GAAG;AAC1C,aAAK;AAAA,UACH,UAAU,MAAM,KAAK;AAAA,oBACE,gBAAgB,KAAK,IAAI,CAAC;AAAA;AAAA,UAEjD,EAAE,MAAM,WAAW,aAAa;AAAA,QAClC;AAAA,MACF;AACA,uBAAiB,CAAC,MAAM,KAAK;AAAA,IAC/B;AAEA,UAAM,UAAU,KAAK,KAAK,YAAY,iBAAiB;AAEvD,QAAI,MAAM,SAAS,GAAG;AACpB,WAAK,IAAI,EAAE;AACX,WAAK,IAAI,8CAA8C;AACvD,iBAAW,SAAS,gBAAgB;AAClC,cAAM,WAAW,KAAK,KAAK,SAAS,KAAK;AACzC,cAAM,SAAS,MAAM,gBAAgB,QAAQ;AAC7C,aAAK,IAAI,OAAO,KAAK,OAAO,QAAQ,GAAG,SAAS,cAAc,EAAE,EAAE;AAAA,MACpE;AACA;AAAA,IACF;AAEA,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,aAAa,eAAe,MAAM,cAAc;AAEzD,QAAI,WAAW;AACf,QAAI,UAAU;AAEd,eAAW,aAAa,gBAAgB;AACtC,YAAM,aAAa,KAAK,KAAK,WAAW,SAAS;AACjD,YAAM,WAAW,KAAK,KAAK,SAAS,SAAS;AAE7C,UAAI,MAAM,gBAAgB,QAAQ,GAAG;AACnC,YAAI,CAAC,MAAM,OAAO;AAChB,eAAK,KAAK,aAAa,SAAS,8CAA8C;AAC9E;AACA;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AACF,cAAM,KAAK,YAAY,YAAY,UAAU,WAAW,aAAa;AACrE,aAAK,WAAW,aAAa,SAAS,EAAE;AACxC;AAAA,MACF,SAAS,OAAO;AACd,aAAK,KAAK,qBAAqB,SAAS,MAAM,gBAAgB,KAAK,CAAC,EAAE;AACtE;AAAA,MACF;AAAA,IACF;AAEA,SAAK,IAAI,EAAE;AACX,SAAK,WAAW,oBAAoB,QAAQ,cAAc,OAAO,UAAU;AAC3E,SAAK,IAAI,oBAAoB,OAAO,EAAE;AACtC,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,cAAc,WAAW;AAClC,SAAK,IAAI,EAAE;AAAA,EACb;AAAA,EAEA,MAAc,YACZ,YACA,UACA,WACA,QACe;AACf,UAAM,cAAc,KAAK,KAAK,YAAY,aAAa;AACvD,QAAI,CAAE,MAAM,WAAW,WAAW,GAAI;AACpC,YAAM,IAAI;AAAA,QACR,qCAAqC,WAAW;AAAA;AAAA;AAAA,YAGjC,SAAS,OAAO,KAAK,KAAK,YAAY,aAAa,CAAC;AAAA,MACrE;AAAA,IACF;AAEA,UAAM,cAAc,MAAM,gBAAgB,WAAW;AAErD,UAAM,UAAU,KAAK,QAAQ,QAAQ,CAAC;AACtC,UAAM,KAAK,YAAY,QAAQ;AAE/B,UAAM,KAAK,yBAAyB,UAAU,WAAW,QAAQ,WAAW;AAAA,EAC9E;AAAA,EAEA,MAAc,yBACZ,UACA,WACA,QACA,aACe;AACf,UAAM,mBAAmB,KAAK,KAAK,UAAU,kBAAkB;AAC/D,UAAM,mBAAmB,KAAK,KAAK,UAAU,kBAAkB;AAE/D,UAAM,aAAyC;AAAA,MAC7C;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,eAAe;AAAA,IACvB;AAEA,QAAI,MAAM,WAAW,gBAAgB,GAAG;AACtC,YAAM,aAAa,MAAM,SAAS,gBAAgB;AAClD,YAAM,QAAQ,WAAW,MAAM,IAAI;AACnC,UAAIC,eAAc;AAClB,UAAI,gBAAgB;AAEpB,UAAI,MAAM,CAAC,GAAG,WAAW,yBAAyB,GAAG;AACnD,wBAAgB,GAAG,MAAM,CAAC,CAAC;AAAA;AAC3B,QAAAA,eAAc,MAAM,MAAM,CAAC,EAAE,KAAK,IAAI;AAAA,MACxC;AAEA,YAAM,MAAM,UAAUA,YAAW;AACjC,YAAM,cAAc,4BAA4B,UAAU,GAAG;AAC7D,UAAI,CAAC,YAAY,SAAS;AACxB,aAAK;AAAA,UACH,8BAA8B,gBAAgB;AAAA,uBACpB,YAAY,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,QAGrF;AAAA,MACF;AACA,YAAM,WAAW,YAAY,UACxB,YAAY,OACb,EAAE,YAAY,OAAU;AAC5B,eAAS,aAAa;AAEtB,YAAM,iBAAiB,cAAc,UAAU;AAAA,QAC7C,WAAW,gBAAgB;AAAA,MAC7B,CAAC;AACD,YAAM,UAAU,kBAAkB,gBAAgB,cAAc;AAChE;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,gBAAgB,GAAG;AACtC,YAAM,aAAa,MAAM,SAAS,gBAAgB;AAClD,UAAI;AACJ,UAAI;AACF,qBAAa,KAAK,MAAM,UAAU;AAAA,MACpC,QAAQ;AACN,aAAK;AAAA,UACH,qBAAqB,gBAAgB;AAAA;AAAA;AAAA,QAGvC;AACA;AAAA,MACF;AACA,YAAM,aAAa,4BAA4B,UAAU,UAAU;AACnE,YAAM,WAAW,WAAW,UACvB,WAAW,OACZ,EAAE,YAAY,OAAU;AAC5B,eAAS,aAAa;AAEtB,YAAMA,eAAc,cAAc,UAAU,EAAE,WAAW,gBAAgB,gBAAgB,CAAC;AAC1F,YAAM,UAAU,kBAAkBA,YAAW;AAC7C;AAAA,IACF;AAEA,UAAM,kBAAiC;AAAA,MACrC,aAAa,UACV,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EAC1D,KAAK,GAAG;AAAA,MACX,gBAAgB;AAAA,MAChB,UAAU,gBAAgB;AAAA,MAC1B,QAAQ,gBAAgB;AAAA,MACxB;AAAA,IACF;AAEA,UAAM,cAAc,cAAc,iBAAiB;AAAA,MACjD,WAAW,gBAAgB;AAAA,IAC7B,CAAC;AACD,UAAM,UAAU,kBAAkB,WAAW;AAAA,EAC/C;AACF;","names":["path","yamlContent"]}
1
+ {"version":3,"sources":["../../../src/cli/commands/import/skill.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { BaseCommand } from \"../../base-command.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { EXIT_CODES } from \"../../lib/exit-codes.js\";\nimport { fetchFromSource } from \"../../lib/loading/index.js\";\nimport { importedSkillMetadataSchema } from \"../../lib/schemas.js\";\nimport { getCurrentDate, computeFileHash } from \"../../lib/versioning.js\";\nimport {\n copy,\n directoryExists,\n fileExists,\n listDirectories,\n readFile,\n writeFile,\n ensureDir,\n} from \"../../utils/fs.js\";\nimport {\n DEFAULT_SKILLS_SUBDIR,\n GITHUB_SOURCE,\n LOCAL_SKILLS_PATH,\n STANDARD_FILES,\n YAML_FORMATTING,\n} from \"../../consts.js\";\nimport { IMPORT_DEFAULTS } from \"../../lib/metadata-keys.js\";\nimport { STATUS_MESSAGES, INFO_MESSAGES } from \"../../utils/messages.js\";\n\n/**\n * Metadata for tracking third-party imports. Different from ForkedFromMetadata\n * in skill-metadata.ts which tracks internal fork lineage (uses skillId\n * instead of source/skillName).\n */\ntype ImportedForkedFromMetadata = {\n source: string;\n skillName: string;\n contentHash: string;\n date: string;\n};\n\ntype SkillMetadata = {\n forkedFrom?: ImportedForkedFromMetadata;\n [key: string]: unknown;\n};\n\nconst SKILL_MD_FILE = STANDARD_FILES.SKILL_MD;\nconst METADATA_YAML_FILE = STANDARD_FILES.METADATA_YAML;\nconst METADATA_JSON_FILE = STANDARD_FILES.METADATA_JSON;\n\nfunction parseGitHubSource(source: string): {\n gigetSource: string;\n displaySource: string;\n} {\n if (source.startsWith(GITHUB_SOURCE.HTTPS_PREFIX)) {\n const path = source.replace(GITHUB_SOURCE.HTTPS_PREFIX, \"\");\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${path}`,\n displaySource: source,\n };\n }\n\n if (\n source.startsWith(GITHUB_SOURCE.GITHUB_PREFIX) ||\n source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ) {\n const normalized = source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ? GITHUB_SOURCE.GITHUB_PREFIX + source.slice(GITHUB_SOURCE.GH_PREFIX.length)\n : source;\n return {\n gigetSource: normalized,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${normalized.replace(GITHUB_SOURCE.GITHUB_PREFIX, \"\")}`,\n };\n }\n\n if (source.includes(\"/\") && !source.includes(\":\")) {\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${source}`,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${source}`,\n };\n }\n\n return {\n gigetSource: source,\n displaySource: source,\n };\n}\n\nasync function discoverValidSkills(skillsDir: string, skillDirs: string[]): Promise<string[]> {\n const validSkills: string[] = [];\n\n for (const skillDir of skillDirs) {\n const skillMdPath = path.join(skillsDir, skillDir, SKILL_MD_FILE);\n if (await fileExists(skillMdPath)) {\n validSkills.push(skillDir);\n }\n }\n\n return validSkills.sort();\n}\n\nexport default class ImportSkill extends BaseCommand {\n static summary = \"Import a skill from a third-party GitHub repository\";\n static description =\n \"Download and import skills from external GitHub repositories into your local \" +\n \".claude/skills/ directory. Supports importing specific skills or listing available skills.\";\n\n static examples = [\n {\n description: \"List available skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --list\",\n },\n {\n description: \"Import a specific skill\",\n command:\n \"<%= config.bin %> import skill github:vercel-labs/agent-skills --skill react-best-practices\",\n },\n {\n description: \"Import all skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --all\",\n },\n {\n description: \"Import with custom skills directory\",\n command:\n \"<%= config.bin %> import skill github:owner/repo --skill my-skill --subdir custom-skills\",\n },\n ];\n\n static args = {\n source: Args.string({\n description:\n \"GitHub repository source (github:owner/repo, https://github.com/owner/repo, or owner/repo)\",\n required: true,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n skill: Flags.string({\n char: \"n\",\n description: \"Name of the specific skill to import\",\n required: false,\n }),\n all: Flags.boolean({\n char: \"a\",\n description: \"Import all skills from the repository\",\n default: false,\n }),\n list: Flags.boolean({\n char: \"l\",\n description: \"List available skills without importing\",\n default: false,\n }),\n subdir: Flags.string({\n description: \"Subdirectory containing skills (default: skills)\",\n default: DEFAULT_SKILLS_SUBDIR,\n }),\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing skills\",\n default: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote (ignore cache)\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(ImportSkill);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(\"Import Third-Party Skill\");\n this.log(\"\");\n\n if (!flags.list && !flags.skill && !flags.all) {\n this.error(\"Please specify --skill <name>, --all, or --list to list available skills\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (flags.skill && flags.all) {\n this.error(\"Cannot use --skill and --all together\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n const { gigetSource, displaySource } = parseGitHubSource(args.source);\n this.log(`Source: ${displaySource}`);\n\n this.log(STATUS_MESSAGES.FETCHING_REPOSITORY);\n\n let repoPath: string;\n try {\n const result = await fetchFromSource(gigetSource, {\n forceRefresh: flags.refresh,\n });\n repoPath = result.path;\n this.log(result.fromCache ? \"Using cached source\" : \"Downloaded fresh copy\");\n } catch (error) {\n this.error(error instanceof Error ? error.message : `Failed to fetch: ${args.source}`, {\n exit: EXIT_CODES.NETWORK_ERROR,\n });\n }\n\n // Validate --subdir to prevent path traversal outside repository boundary\n const subdir = flags.subdir;\n if (/\\0/.test(subdir)) {\n this.error(\"--subdir contains null bytes\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n if (path.isAbsolute(subdir)) {\n this.error(`--subdir must be a relative path, got: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n const skillsDir = path.resolve(path.join(repoPath, subdir));\n const resolvedRepoPath = path.resolve(repoPath);\n if (!skillsDir.startsWith(resolvedRepoPath + path.sep) && skillsDir !== resolvedRepoPath) {\n this.error(`--subdir path escapes repository boundary: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!(await directoryExists(skillsDir))) {\n this.error(\n `Skills directory not found: ${flags.subdir}\\n` +\n `The repository doesn't have a '${flags.subdir}' directory.\\n` +\n `Use --subdir to specify a different location.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const availableSkills = await discoverValidSkills(skillsDir, skillDirs);\n\n if (availableSkills.length === 0) {\n this.error(`No valid skills found in ${flags.subdir}/\\nSkills must have a SKILL.md file.`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n if (flags.list) {\n this.log(\"\");\n this.log(`Available skills (${availableSkills.length}):`);\n this.log(\"\");\n for (const skill of availableSkills) {\n this.log(` - ${skill}`);\n }\n this.log(\"\");\n this.log(\"Use --skill <name> to import a specific skill, or --all to import all.\");\n return;\n }\n\n let skillsToImport: string[] = [];\n\n if (flags.all) {\n skillsToImport = availableSkills;\n } else if (flags.skill) {\n if (!availableSkills.includes(flags.skill)) {\n this.error(\n `Skill '${flags.skill}' not found in repository.\\n` +\n `Available skills: ${availableSkills.join(\", \")}\\n` +\n `Use --list to see all available skills.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n skillsToImport = [flags.skill];\n }\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n\n this.log(\"\");\n this.log(`Importing ${skillsToImport.length} skill(s)...`);\n\n let imported = 0;\n let skipped = 0;\n\n for (const skillName of skillsToImport) {\n const sourcePath = path.join(skillsDir, skillName);\n const destPath = path.join(destDir, skillName);\n\n if (await directoryExists(destPath)) {\n if (!flags.force) {\n this.warn(`Skipping '${skillName}': already exists. Use --force to overwrite.`);\n skipped++;\n continue;\n }\n }\n\n try {\n await this.importSkill(sourcePath, destPath, skillName, displaySource);\n this.logSuccess(`Imported: ${skillName}`);\n imported++;\n } catch (error) {\n this.warn(`Failed to import '${skillName}': ${getErrorMessage(error)}`);\n skipped++;\n }\n }\n\n this.log(\"\");\n this.logSuccess(`Import complete: ${imported} imported, ${skipped} skipped`);\n this.log(`Skills location: ${destDir}`);\n this.log(\"\");\n this.log(INFO_MESSAGES.RUN_COMPILE);\n this.log(\"\");\n }\n\n private async importSkill(\n sourcePath: string,\n destPath: string,\n skillName: string,\n source: string,\n ): Promise<void> {\n const skillMdPath = path.join(sourcePath, SKILL_MD_FILE);\n if (!(await fileExists(skillMdPath))) {\n throw new Error(\n `Missing required SKILL.md file at ${skillMdPath}\\n` +\n `Every skill must have a SKILL.md file containing the skill's prompt content.\\n` +\n `Create one with:\\n` +\n ` echo \"# ${skillName}\" > ${path.join(sourcePath, SKILL_MD_FILE)}`,\n );\n }\n\n const contentHash = await computeFileHash(skillMdPath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await this.injectForkedFromMetadata(destPath, skillName, source, contentHash);\n }\n\n private async injectForkedFromMetadata(\n destPath: string,\n skillName: string,\n source: string,\n contentHash: string,\n ): Promise<void> {\n const metadataYamlPath = path.join(destPath, METADATA_YAML_FILE);\n const metadataJsonPath = path.join(destPath, METADATA_JSON_FILE);\n\n const forkedFrom: ImportedForkedFromMetadata = {\n source,\n skillName: skillName,\n contentHash: contentHash,\n date: getCurrentDate(),\n };\n\n if (await fileExists(metadataYamlPath)) {\n const rawContent = await readFile(metadataYamlPath);\n const lines = rawContent.split(\"\\n\");\n let yamlContent = rawContent;\n let schemaComment = \"\";\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 raw = parseYaml(yamlContent);\n const parseResult = importedSkillMetadataSchema.safeParse(raw);\n if (!parseResult.success) {\n this.warn(\n `Malformed metadata.yaml at ${metadataYamlPath} — existing fields may be lost\\n` +\n ` Validation errors: ${parseResult.error.issues.map((i) => i.message).join(\", \")}\\n` +\n ` Expected fields: displayName (string), cliDescription (string), category (string)\\n` +\n ` Validate your YAML syntax at https://yamllint.com`,\n );\n }\n const metadata = parseResult.success\n ? (parseResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const newYamlContent = stringifyYaml(metadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, schemaComment + newYamlContent);\n return;\n }\n\n if (await fileExists(metadataJsonPath)) {\n const rawContent = await readFile(metadataJsonPath);\n let jsonParsed: unknown;\n try {\n jsonParsed = JSON.parse(rawContent);\n } catch {\n this.warn(\n `Malformed JSON in ${metadataJsonPath} — skipping metadata injection\\n` +\n ` Common issues: trailing commas, unquoted keys, single quotes instead of double quotes\\n` +\n ` Validate your JSON at https://jsonlint.com`,\n );\n return;\n }\n const jsonResult = importedSkillMetadataSchema.safeParse(jsonParsed);\n const metadata = jsonResult.success\n ? (jsonResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const yamlContent = stringifyYaml(metadata, { lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE });\n await writeFile(metadataYamlPath, yamlContent);\n return;\n }\n\n const minimalMetadata: SkillMetadata = {\n displayName: skillName\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \"),\n cliDescription: \"Imported from third-party repository\",\n category: IMPORT_DEFAULTS.CATEGORY,\n author: IMPORT_DEFAULTS.AUTHOR,\n forkedFrom: forkedFrom,\n };\n\n const yamlContent = stringifyYaml(minimalMetadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, yamlContent);\n }\n}\n"],"mappings":"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","names":["path","yamlContent"]}
@@ -1,24 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  STATUS_MESSAGES
4
- } from "../chunk-WLZHCM7O.js";
5
- import {
6
- BaseCommand,
7
- EXIT_CODES
8
- } from "../chunk-PGY5XROM.js";
4
+ } from "../chunk-MR6OBL3B.js";
9
5
  import {
10
6
  discoverLocalSkills,
11
7
  loadSkillsMatrixFromSource
12
- } from "../chunk-HMSHB5EQ.js";
8
+ } from "../chunk-TZXYBG3R.js";
9
+ import "../chunk-OCEFD7V6.js";
13
10
  import "../chunk-T4EXUIBY.js";
11
+ import {
12
+ BaseCommand,
13
+ EXIT_CODES
14
+ } from "../chunk-VR3CDXDT.js";
14
15
  import {
15
16
  fileExists,
16
17
  readFile
17
- } from "../chunk-WBHPCBVN.js";
18
+ } from "../chunk-LWXRUR6B.js";
18
19
  import {
19
20
  CLI_BIN_NAME,
20
21
  STANDARD_FILES
21
- } from "../chunk-AWP5A6IM.js";
22
+ } from "../chunk-6OWHQ7HM.js";
23
+ import "../chunk-EC3UJRKZ.js";
22
24
  import {
23
25
  init_esm_shims
24
26
  } from "../chunk-DHET7RCE.js";
@@ -60,12 +62,6 @@ function getPreviewLines(content, maxLines) {
60
62
  }
61
63
  return result;
62
64
  }
63
- function formatRelations(relations) {
64
- if (relations.length === 0) {
65
- return "(none)";
66
- }
67
- return relations.map((r) => r.skillId).join(", ");
68
- }
69
65
  function formatRequirements(requirements) {
70
66
  if (requirements.length === 0) {
71
67
  return "(none)";
@@ -87,7 +83,7 @@ function findSuggestions(skills, query, maxSuggestions) {
87
83
  for (const skill of Object.values(skills)) {
88
84
  if (!skill) continue;
89
85
  if (matches.length >= maxSuggestions) break;
90
- if (skill.id.toLowerCase().includes(lowerQuery) || skill.displayName?.toLowerCase().includes(lowerQuery)) {
86
+ if (skill.id.toLowerCase().includes(lowerQuery) || skill.displayName.toLowerCase().includes(lowerQuery) || skill.slug?.toLowerCase().includes(lowerQuery)) {
91
87
  matches.push(skill.id);
92
88
  }
93
89
  }
@@ -96,9 +92,10 @@ function findSuggestions(skills, query, maxSuggestions) {
96
92
  function formatSkillInfo(skill, isInstalled) {
97
93
  const lines = [];
98
94
  lines.push(`Skill: ${skill.id}`);
99
- if (skill.displayName) {
100
- lines.push(`Alias: ${skill.displayName}`);
95
+ if (skill.slug) {
96
+ lines.push(`Slug: ${skill.slug}`);
101
97
  }
98
+ lines.push(`Display Name: ${skill.displayName}`);
102
99
  lines.push(`Author: ${skill.author}`);
103
100
  lines.push(`Category: ${skill.category}`);
104
101
  lines.push("");
@@ -108,8 +105,12 @@ function formatSkillInfo(skill, isInstalled) {
108
105
  lines.push(`Tags: ${formatTags(skill.tags)}`);
109
106
  lines.push("");
110
107
  lines.push(`Requires: ${formatRequirements(skill.requires)}`);
111
- lines.push(`Conflicts with: ${formatRelations(skill.conflictsWith)}`);
112
- lines.push(`Recommends: ${formatRelations(skill.recommends)}`);
108
+ lines.push(
109
+ `Conflicts with: ${skill.conflictsWith.length > 0 ? skill.conflictsWith.map((r) => r.skillId).join(", ") : "(none)"}`
110
+ );
111
+ lines.push(
112
+ `Recommended: ${skill.isRecommended ? `Yes${skill.recommendedReason ? ` \u2014 ${skill.recommendedReason}` : ""}` : "No"}`
113
+ );
113
114
  if (skill.usageGuidance) {
114
115
  lines.push("");
115
116
  lines.push("Usage Guidance:");
@@ -160,7 +161,7 @@ var Info = class _Info extends BaseCommand {
160
161
  this.log(`Loaded from ${isLocal ? "local" : "remote"}: ${sourcePath}`);
161
162
  let skill = matrix.skills[args.skill];
162
163
  if (!skill) {
163
- const fullId = matrix.displayNameToId[args.skill];
164
+ const fullId = matrix.slugMap.slugToId[args.skill];
164
165
  if (fullId) {
165
166
  skill = matrix.skills[fullId];
166
167
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/info.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { BaseCommand } from \"../base-command.js\";\nimport { loadSkillsMatrixFromSource } from \"../lib/loading/index.js\";\nimport { discoverLocalSkills } from \"../lib/skills/index.js\";\nimport { fileExists, readFile } from \"../utils/fs.js\";\nimport { CLI_BIN_NAME, STANDARD_FILES } from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { STATUS_MESSAGES } from \"../utils/messages.js\";\nimport type {\n ResolvedSkill,\n SkillDisplayName,\n SkillId,\n SkillRelation,\n SkillRequirement,\n} from \"../types/index.js\";\n\nconst CONTENT_PREVIEW_LINES = 10;\nconst MAX_LINE_LENGTH = 80;\nconst MAX_SUGGESTIONS = 5;\n\nfunction stripFrontmatter(content: string): string {\n const lines = content.split(\"\\n\");\n let inFrontmatter = false;\n let frontmatterEndIndex = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line === \"---\") {\n if (!inFrontmatter) {\n inFrontmatter = true;\n } else {\n frontmatterEndIndex = i + 1;\n break;\n }\n }\n }\n\n return lines.slice(frontmatterEndIndex).join(\"\\n\");\n}\n\nfunction getPreviewLines(content: string, maxLines: number): string[] {\n const body = stripFrontmatter(content);\n const lines = body.split(\"\\n\");\n const result: string[] = [];\n\n for (const line of lines) {\n if (result.length >= maxLines) break;\n if (line.trim() || result.length > 0) {\n const truncated =\n line.length > MAX_LINE_LENGTH ? `${line.slice(0, MAX_LINE_LENGTH - 3)}...` : line;\n result.push(truncated);\n }\n }\n\n return result;\n}\n\nfunction formatRelations(relations: SkillRelation[]): string {\n if (relations.length === 0) {\n return \"(none)\";\n }\n return relations.map((r) => r.skillId).join(\", \");\n}\n\nfunction formatRequirements(requirements: SkillRequirement[]): string {\n if (requirements.length === 0) {\n return \"(none)\";\n }\n return requirements\n .map((req) => {\n const prefix = req.needsAny ? \"any of: \" : \"\";\n return prefix + req.skillIds.join(\", \");\n })\n .join(\"; \");\n}\n\nfunction formatTags(tags: string[]): string {\n if (tags.length === 0) {\n return \"(none)\";\n }\n return tags.join(\", \");\n}\n\nfunction findSuggestions(\n skills: Partial<Record<SkillId, ResolvedSkill>>,\n query: string,\n maxSuggestions: number,\n): string[] {\n const lowerQuery = query.toLowerCase();\n const matches: string[] = [];\n\n for (const skill of Object.values(skills)) {\n if (!skill) continue;\n if (matches.length >= maxSuggestions) break;\n if (\n skill.id.toLowerCase().includes(lowerQuery) ||\n skill.displayName?.toLowerCase().includes(lowerQuery)\n ) {\n matches.push(skill.id);\n }\n }\n\n return matches;\n}\n\nfunction formatSkillInfo(skill: ResolvedSkill, isInstalled: boolean): string {\n const lines: string[] = [];\n\n lines.push(`Skill: ${skill.id}`);\n if (skill.displayName) {\n lines.push(`Alias: ${skill.displayName}`);\n }\n lines.push(`Author: ${skill.author}`);\n lines.push(`Category: ${skill.category}`);\n lines.push(\"\");\n lines.push(\"Description:\");\n lines.push(` ${skill.description}`);\n lines.push(\"\");\n lines.push(`Tags: ${formatTags(skill.tags)}`);\n lines.push(\"\");\n lines.push(`Requires: ${formatRequirements(skill.requires)}`);\n lines.push(`Conflicts with: ${formatRelations(skill.conflictsWith)}`);\n lines.push(`Recommends: ${formatRelations(skill.recommends)}`);\n\n if (skill.usageGuidance) {\n lines.push(\"\");\n lines.push(\"Usage Guidance:\");\n lines.push(` ${skill.usageGuidance}`);\n }\n\n lines.push(\"\");\n lines.push(`Local Status: ${isInstalled ? \"Installed\" : \"Not installed\"}`);\n\n return lines.join(\"\\n\");\n}\n\nexport default class Info extends BaseCommand {\n static summary = \"Show detailed information about a skill\";\n static description =\n \"Display comprehensive information about a skill including metadata, relationships, and content preview\";\n\n static examples = [\n {\n description: \"Show info for a skill by ID\",\n command: \"<%= config.bin %> <%= command.id %> web-framework-react\",\n },\n {\n description: \"Show info without content preview\",\n command: \"<%= config.bin %> <%= command.id %> web-framework-react --no-preview\",\n },\n {\n description: \"Show info from a custom source\",\n command: \"<%= config.bin %> <%= command.id %> my-skill --source github:org/marketplace\",\n },\n ];\n\n static args = {\n skill: Args.string({\n description: \"Skill ID or alias to look up\",\n required: true,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n preview: Flags.boolean({\n description: \"Show content preview from SKILL.md\",\n default: true,\n allowNo: true,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Info);\n\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const { matrix, sourcePath, isLocal } = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n });\n\n this.log(`Loaded from ${isLocal ? \"local\" : \"remote\"}: ${sourcePath}`);\n\n // CLI arg is an untyped string — cast at data boundary\n let skill: ResolvedSkill | undefined = matrix.skills[args.skill as SkillId];\n\n if (!skill) {\n // Try alias lookup — CLI arg is an untyped string\n const fullId = matrix.displayNameToId[args.skill as SkillDisplayName];\n if (fullId) {\n skill = matrix.skills[fullId];\n }\n }\n\n if (!skill) {\n const suggestions = findSuggestions(matrix.skills, args.skill, MAX_SUGGESTIONS);\n\n this.log(\"\");\n this.error(`Skill \"${args.skill}\" not found.`, { exit: false });\n\n if (suggestions.length > 0) {\n this.log(\"\");\n this.log(\"Did you mean one of these?\");\n for (const suggestion of suggestions) {\n this.log(` - ${suggestion}`);\n }\n }\n\n this.log(\"\");\n this.logInfo(`Use '${CLI_BIN_NAME} search <query>' to find available skills.`);\n this.log(\"\");\n this.exit(EXIT_CODES.ERROR);\n }\n\n const localSkillsResult = await discoverLocalSkills(process.cwd());\n const localSkillIds = localSkillsResult?.skills.map((s) => s.id) || [];\n const isInstalled = localSkillIds.includes(skill.id);\n\n this.log(\"\");\n this.log(formatSkillInfo(skill, isInstalled));\n\n if (flags.preview) {\n let skillMdPath: string;\n\n if (skill.local && skill.localPath) {\n skillMdPath = path.join(process.cwd(), skill.localPath, STANDARD_FILES.SKILL_MD);\n } else {\n const sourceDir = isLocal ? sourcePath : path.dirname(sourcePath);\n skillMdPath = path.join(sourceDir, skill.path, STANDARD_FILES.SKILL_MD);\n }\n\n if (await fileExists(skillMdPath)) {\n const content = await readFile(skillMdPath);\n const previewLines = getPreviewLines(content, CONTENT_PREVIEW_LINES);\n\n if (previewLines.length > 0) {\n this.log(\"\");\n this.log(`--- Content Preview (first ${CONTENT_PREVIEW_LINES} lines) ---`);\n for (const line of previewLines) {\n this.log(line);\n }\n }\n }\n }\n\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/info.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { BaseCommand } from \"../base-command.js\";\nimport { loadSkillsMatrixFromSource } from \"../lib/loading/index.js\";\nimport { discoverLocalSkills } from \"../lib/skills/index.js\";\nimport { fileExists, readFile } from \"../utils/fs.js\";\nimport { CLI_BIN_NAME, STANDARD_FILES } from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { STATUS_MESSAGES } from \"../utils/messages.js\";\nimport type { ResolvedSkill, SkillSlug, SkillId, SkillRequirement } from \"../types/index.js\";\n\nconst CONTENT_PREVIEW_LINES = 10;\nconst MAX_LINE_LENGTH = 80;\nconst MAX_SUGGESTIONS = 5;\n\nfunction stripFrontmatter(content: string): string {\n const lines = content.split(\"\\n\");\n let inFrontmatter = false;\n let frontmatterEndIndex = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line === \"---\") {\n if (!inFrontmatter) {\n inFrontmatter = true;\n } else {\n frontmatterEndIndex = i + 1;\n break;\n }\n }\n }\n\n return lines.slice(frontmatterEndIndex).join(\"\\n\");\n}\n\nfunction getPreviewLines(content: string, maxLines: number): string[] {\n const body = stripFrontmatter(content);\n const lines = body.split(\"\\n\");\n const result: string[] = [];\n\n for (const line of lines) {\n if (result.length >= maxLines) break;\n if (line.trim() || result.length > 0) {\n const truncated =\n line.length > MAX_LINE_LENGTH ? `${line.slice(0, MAX_LINE_LENGTH - 3)}...` : line;\n result.push(truncated);\n }\n }\n\n return result;\n}\n\nfunction formatRequirements(requirements: SkillRequirement[]): string {\n if (requirements.length === 0) {\n return \"(none)\";\n }\n return requirements\n .map((req) => {\n const prefix = req.needsAny ? \"any of: \" : \"\";\n return prefix + req.skillIds.join(\", \");\n })\n .join(\"; \");\n}\n\nfunction formatTags(tags: string[]): string {\n if (tags.length === 0) {\n return \"(none)\";\n }\n return tags.join(\", \");\n}\n\nfunction findSuggestions(\n skills: Partial<Record<SkillId, ResolvedSkill>>,\n query: string,\n maxSuggestions: number,\n): string[] {\n const lowerQuery = query.toLowerCase();\n const matches: string[] = [];\n\n for (const skill of Object.values(skills)) {\n if (!skill) continue;\n if (matches.length >= maxSuggestions) break;\n if (\n skill.id.toLowerCase().includes(lowerQuery) ||\n skill.displayName.toLowerCase().includes(lowerQuery) ||\n skill.slug?.toLowerCase().includes(lowerQuery)\n ) {\n matches.push(skill.id);\n }\n }\n\n return matches;\n}\n\nfunction formatSkillInfo(skill: ResolvedSkill, isInstalled: boolean): string {\n const lines: string[] = [];\n\n lines.push(`Skill: ${skill.id}`);\n if (skill.slug) {\n lines.push(`Slug: ${skill.slug}`);\n }\n lines.push(`Display Name: ${skill.displayName}`);\n lines.push(`Author: ${skill.author}`);\n lines.push(`Category: ${skill.category}`);\n lines.push(\"\");\n lines.push(\"Description:\");\n lines.push(` ${skill.description}`);\n lines.push(\"\");\n lines.push(`Tags: ${formatTags(skill.tags)}`);\n lines.push(\"\");\n lines.push(`Requires: ${formatRequirements(skill.requires)}`);\n lines.push(\n `Conflicts with: ${skill.conflictsWith.length > 0 ? skill.conflictsWith.map((r) => r.skillId).join(\", \") : \"(none)\"}`,\n );\n lines.push(\n `Recommended: ${skill.isRecommended ? `Yes${skill.recommendedReason ? ` — ${skill.recommendedReason}` : \"\"}` : \"No\"}`,\n );\n\n if (skill.usageGuidance) {\n lines.push(\"\");\n lines.push(\"Usage Guidance:\");\n lines.push(` ${skill.usageGuidance}`);\n }\n\n lines.push(\"\");\n lines.push(`Local Status: ${isInstalled ? \"Installed\" : \"Not installed\"}`);\n\n return lines.join(\"\\n\");\n}\n\nexport default class Info extends BaseCommand {\n static summary = \"Show detailed information about a skill\";\n static description =\n \"Display comprehensive information about a skill including metadata, relationships, and content preview\";\n\n static examples = [\n {\n description: \"Show info for a skill by ID\",\n command: \"<%= config.bin %> <%= command.id %> web-framework-react\",\n },\n {\n description: \"Show info without content preview\",\n command: \"<%= config.bin %> <%= command.id %> web-framework-react --no-preview\",\n },\n {\n description: \"Show info from a custom source\",\n command: \"<%= config.bin %> <%= command.id %> my-skill --source github:org/marketplace\",\n },\n ];\n\n static args = {\n skill: Args.string({\n description: \"Skill ID or alias to look up\",\n required: true,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n preview: Flags.boolean({\n description: \"Show content preview from SKILL.md\",\n default: true,\n allowNo: true,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Info);\n\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const { matrix, sourcePath, isLocal } = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n });\n\n this.log(`Loaded from ${isLocal ? \"local\" : \"remote\"}: ${sourcePath}`);\n\n // CLI arg is an untyped string — cast at data boundary\n let skill: ResolvedSkill | undefined = matrix.skills[args.skill as SkillId];\n\n if (!skill) {\n // Try slug lookup — CLI arg is an untyped string\n const fullId = matrix.slugMap.slugToId[args.skill as SkillSlug];\n if (fullId) {\n skill = matrix.skills[fullId];\n }\n }\n\n if (!skill) {\n const suggestions = findSuggestions(matrix.skills, args.skill, MAX_SUGGESTIONS);\n\n this.log(\"\");\n this.error(`Skill \"${args.skill}\" not found.`, { exit: false });\n\n if (suggestions.length > 0) {\n this.log(\"\");\n this.log(\"Did you mean one of these?\");\n for (const suggestion of suggestions) {\n this.log(` - ${suggestion}`);\n }\n }\n\n this.log(\"\");\n this.logInfo(`Use '${CLI_BIN_NAME} search <query>' to find available skills.`);\n this.log(\"\");\n this.exit(EXIT_CODES.ERROR);\n }\n\n const localSkillsResult = await discoverLocalSkills(process.cwd());\n const localSkillIds = localSkillsResult?.skills.map((s) => s.id) || [];\n const isInstalled = localSkillIds.includes(skill.id);\n\n this.log(\"\");\n this.log(formatSkillInfo(skill, isInstalled));\n\n if (flags.preview) {\n let skillMdPath: string;\n\n if (skill.local && skill.localPath) {\n skillMdPath = path.join(process.cwd(), skill.localPath, STANDARD_FILES.SKILL_MD);\n } else {\n const sourceDir = isLocal ? sourcePath : path.dirname(sourcePath);\n skillMdPath = path.join(sourceDir, skill.path, STANDARD_FILES.SKILL_MD);\n }\n\n if (await fileExists(skillMdPath)) {\n const content = await readFile(skillMdPath);\n const previewLines = getPreviewLines(content, CONTENT_PREVIEW_LINES);\n\n if (previewLines.length > 0) {\n this.log(\"\");\n this.log(`--- Content Preview (first ${CONTENT_PREVIEW_LINES} lines) ---`);\n for (const line of previewLines) {\n this.log(line);\n }\n }\n }\n }\n\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -4,43 +4,44 @@ import {
4
4
  formatDashboardText,
5
5
  getDashboardData,
6
6
  showDashboard
7
- } from "../chunk-4QWDB2MD.js";
8
- import "../chunk-KQOU4POU.js";
9
- import "../chunk-I6IOGZSZ.js";
10
- import "../chunk-U7X4V4HE.js";
11
- import "../chunk-YDYRAXSY.js";
12
- import "../chunk-SPFHPHYL.js";
13
- import "../chunk-5FPIKTSA.js";
14
- import "../chunk-DCE423KO.js";
15
- import "../chunk-M3GQ2R3E.js";
16
- import "../chunk-QB5HHTAA.js";
7
+ } from "../chunk-G6WHCALR.js";
8
+ import "../chunk-6G3KZSO4.js";
9
+ import "../chunk-52M2XF3W.js";
10
+ import "../chunk-SZRK3VOR.js";
11
+ import "../chunk-MKCHLXMY.js";
12
+ import "../chunk-EMIUPGPL.js";
13
+ import "../chunk-MMFQNJPE.js";
14
+ import "../chunk-HGTC76BX.js";
15
+ import "../chunk-SEJF7CGJ.js";
16
+ import "../chunk-TC3NHO34.js";
17
17
  import "../chunk-K77I4XGL.js";
18
- import "../chunk-XDSVV5GZ.js";
19
- import "../chunk-2BWCR762.js";
20
- import "../chunk-WJHFV6RI.js";
21
- import "../chunk-RFKDGJAJ.js";
18
+ import "../chunk-KIWFEBKH.js";
19
+ import "../chunk-O6BA7Q2B.js";
22
20
  import "../chunk-7SOPVGDV.js";
23
- import "../chunk-QYLCINGC.js";
21
+ import "../chunk-SDKCQXWE.js";
24
22
  import "../chunk-KUV24B5M.js";
25
- import "../chunk-JFF7P4LC.js";
23
+ import "../chunk-BMJZBLP7.js";
24
+ import "../chunk-X5EG4EFP.js";
25
+ import "../chunk-H7WJK7NJ.js";
26
26
  import "../chunk-GG4BSB6S.js";
27
- import "../chunk-5L724R4C.js";
28
- import "../chunk-HYEUETIC.js";
29
- import "../chunk-C3Q43WLC.js";
30
- import "../chunk-3VOL4WEG.js";
31
- import "../chunk-CMNKHDOX.js";
32
- import "../chunk-GBOW6FUW.js";
33
- import "../chunk-JWYRXE6C.js";
27
+ import "../chunk-TGLRDEEL.js";
28
+ import "../chunk-BKJHAJQW.js";
29
+ import "../chunk-CIG7IKX3.js";
30
+ import "../chunk-WYVDNGJB.js";
31
+ import "../chunk-MGNYPVOJ.js";
32
+ import "../chunk-BNQ5O6LE.js";
33
+ import "../chunk-52XO4ULK.js";
34
+ import "../chunk-WF6RM73R.js";
35
+ import "../chunk-XUDTFI4M.js";
34
36
  import "../chunk-U3IGFMCY.js";
35
- import "../chunk-26MXZUHU.js";
36
- import "../chunk-5FCHJLM7.js";
37
- import "../chunk-UAD3SC27.js";
38
- import "../chunk-WLZHCM7O.js";
39
- import "../chunk-PGY5XROM.js";
40
- import "../chunk-HMSHB5EQ.js";
37
+ import "../chunk-MR6OBL3B.js";
38
+ import "../chunk-TZXYBG3R.js";
39
+ import "../chunk-OCEFD7V6.js";
41
40
  import "../chunk-T4EXUIBY.js";
42
- import "../chunk-WBHPCBVN.js";
43
- import "../chunk-AWP5A6IM.js";
41
+ import "../chunk-VR3CDXDT.js";
42
+ import "../chunk-LWXRUR6B.js";
43
+ import "../chunk-6OWHQ7HM.js";
44
+ import "../chunk-EC3UJRKZ.js";
44
45
  import "../chunk-DHET7RCE.js";
45
46
  export {
46
47
  Init as default,
@@ -1,17 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- BaseCommand
4
- } from "../chunk-PGY5XROM.js";
5
2
  import {
6
3
  formatInstallationDisplay,
7
4
  getInstallationInfo
8
- } from "../chunk-HMSHB5EQ.js";
5
+ } from "../chunk-TZXYBG3R.js";
6
+ import "../chunk-OCEFD7V6.js";
9
7
  import "../chunk-T4EXUIBY.js";
10
- import "../chunk-WBHPCBVN.js";
8
+ import {
9
+ BaseCommand
10
+ } from "../chunk-VR3CDXDT.js";
11
+ import "../chunk-LWXRUR6B.js";
11
12
  import {
12
13
  CLI_BIN_NAME,
13
14
  DEFAULT_BRANDING
14
- } from "../chunk-AWP5A6IM.js";
15
+ } from "../chunk-6OWHQ7HM.js";
16
+ import "../chunk-EC3UJRKZ.js";
15
17
  import {
16
18
  init_esm_shims
17
19
  } from "../chunk-DHET7RCE.js";