@claude-collective/cli 0.21.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/CHANGELOG.md +192 -0
  2. package/README.md +41 -27
  3. package/config/skills-matrix.yaml +38 -37
  4. package/config/stacks.yaml +8 -14
  5. package/dist/{chunk-ZNIDWLL5.js → chunk-3X5D7RM5.js} +4 -3
  6. package/dist/chunk-3X5D7RM5.js.map +1 -0
  7. package/dist/chunk-4357L7VK.js +251 -0
  8. package/dist/chunk-4357L7VK.js.map +1 -0
  9. package/dist/chunk-4S4FCAA2.js +100 -0
  10. package/dist/chunk-4S4FCAA2.js.map +1 -0
  11. package/dist/chunk-7UPXT32F.js +197 -0
  12. package/dist/chunk-7UPXT32F.js.map +1 -0
  13. package/dist/{chunk-DHET7RCE.js → chunk-AWKZ5BDL.js} +9 -2
  14. package/dist/{chunk-DHET7RCE.js.map → chunk-AWKZ5BDL.js.map} +1 -1
  15. package/dist/{chunk-6Q3Y7KVB.js → chunk-DBRUQQUF.js} +8 -2
  16. package/dist/chunk-DBRUQQUF.js.map +1 -0
  17. package/dist/{chunk-OQYYMQJR.js → chunk-ETCVEV3S.js} +8 -11
  18. package/dist/chunk-ETCVEV3S.js.map +1 -0
  19. package/dist/chunk-ETQ3BPGU.js +4204 -0
  20. package/dist/chunk-ETQ3BPGU.js.map +1 -0
  21. package/dist/{chunk-ZSVMS677.js → chunk-F4RD5FYM.js} +2 -2
  22. package/dist/chunk-F4RD5FYM.js.map +1 -0
  23. package/dist/{chunk-5KXUDHAB.js → chunk-GGFOD5PK.js} +6 -9
  24. package/dist/chunk-GGFOD5PK.js.map +1 -0
  25. package/dist/{chunk-UMORK7OK.js → chunk-H7SSBSPR.js} +2 -2
  26. package/dist/chunk-H7SSBSPR.js.map +1 -0
  27. package/dist/chunk-HWD32NP7.js +19 -0
  28. package/dist/chunk-HWD32NP7.js.map +1 -0
  29. package/dist/{chunk-HGCBZUH5.js → chunk-I3YYG5IO.js} +9 -10
  30. package/dist/chunk-I3YYG5IO.js.map +1 -0
  31. package/dist/{chunk-RTE64SJA.js → chunk-IXBCRT3F.js} +2 -2
  32. package/dist/chunk-IXBCRT3F.js.map +1 -0
  33. package/dist/{chunk-WFEFICFM.js → chunk-KWYO3M5Q.js} +5 -5
  34. package/dist/chunk-KWYO3M5Q.js.map +1 -0
  35. package/dist/{chunk-HEOHU5EZ.js → chunk-MCTSHLAF.js} +22 -11
  36. package/dist/chunk-MCTSHLAF.js.map +1 -0
  37. package/dist/chunk-NQJ47R4N.js +1092 -0
  38. package/dist/chunk-NQJ47R4N.js.map +1 -0
  39. package/dist/{chunk-FJFEKPXF.js → chunk-O6ZTD7ZI.js} +14 -3
  40. package/dist/chunk-O6ZTD7ZI.js.map +1 -0
  41. package/dist/chunk-OBXAY23Y.js +56 -0
  42. package/dist/chunk-OBXAY23Y.js.map +1 -0
  43. package/dist/{chunk-XY3XDVMI.js → chunk-QR2EBWL2.js} +3 -3
  44. package/dist/chunk-R5KJVI54.js +311 -0
  45. package/dist/chunk-R5KJVI54.js.map +1 -0
  46. package/dist/{chunk-2LSGX6R4.js → chunk-R7B63JAP.js} +83 -25
  47. package/dist/chunk-R7B63JAP.js.map +1 -0
  48. package/dist/{chunk-66UDJBF6.js → chunk-REJGRCVQ.js} +2 -2
  49. package/dist/chunk-TDZE4TDG.js +220 -0
  50. package/dist/chunk-TDZE4TDG.js.map +1 -0
  51. package/dist/{chunk-CBLPAMZO.js → chunk-TMED5DQ2.js} +68 -42
  52. package/dist/chunk-TMED5DQ2.js.map +1 -0
  53. package/dist/{chunk-Q3J43SF3.js → chunk-U7HFKR74.js} +2 -2
  54. package/dist/chunk-U7HFKR74.js.map +1 -0
  55. package/dist/{chunk-3EHUF54X.js → chunk-UEMRJI2K.js} +17 -4
  56. package/dist/chunk-UEMRJI2K.js.map +1 -0
  57. package/dist/{chunk-Z2CWURZ6.js → chunk-UNN7523L.js} +2 -2
  58. package/dist/chunk-V2ZIH7HV.js +29 -0
  59. package/dist/chunk-V2ZIH7HV.js.map +1 -0
  60. package/dist/{chunk-ZEI3ZUDU.js → chunk-VVYNZZUX.js} +7 -15
  61. package/dist/chunk-VVYNZZUX.js.map +1 -0
  62. package/dist/{chunk-A46TPNBJ.js → chunk-XENOESJZ.js} +7 -16
  63. package/dist/chunk-XENOESJZ.js.map +1 -0
  64. package/dist/chunk-ZDREFYD2.js +696 -0
  65. package/dist/chunk-ZDREFYD2.js.map +1 -0
  66. package/dist/chunk-ZW2PELOH.js +197 -0
  67. package/dist/chunk-ZW2PELOH.js.map +1 -0
  68. package/dist/cli/defaults/agent-mappings.yaml +0 -1
  69. package/dist/commands/build/marketplace.js +22 -21
  70. package/dist/commands/build/marketplace.js.map +1 -1
  71. package/dist/commands/build/plugins.js +35 -231
  72. package/dist/commands/build/plugins.js.map +1 -1
  73. package/dist/commands/build/stack.js +11 -18
  74. package/dist/commands/build/stack.js.map +1 -1
  75. package/dist/commands/compile.js +36 -58
  76. package/dist/commands/compile.js.map +1 -1
  77. package/dist/commands/config/get.js +8 -8
  78. package/dist/commands/config/get.js.map +1 -1
  79. package/dist/commands/config/index.js +7 -7
  80. package/dist/commands/config/index.js.map +1 -1
  81. package/dist/commands/config/path.js +6 -6
  82. package/dist/commands/config/path.js.map +1 -1
  83. package/dist/commands/config/set-project.js +8 -8
  84. package/dist/commands/config/set-project.js.map +1 -1
  85. package/dist/commands/config/show.js +7 -7
  86. package/dist/commands/config/unset-project.js +8 -8
  87. package/dist/commands/config/unset-project.js.map +1 -1
  88. package/dist/commands/diff.js +10 -16
  89. package/dist/commands/diff.js.map +1 -1
  90. package/dist/commands/doctor.js +18 -51
  91. package/dist/commands/doctor.js.map +1 -1
  92. package/dist/commands/edit.js +112 -57
  93. package/dist/commands/edit.js.map +1 -1
  94. package/dist/commands/eject.js +17 -49
  95. package/dist/commands/eject.js.map +1 -1
  96. package/dist/commands/import/skill.js +26 -26
  97. package/dist/commands/import/skill.js.map +1 -1
  98. package/dist/commands/info.js +15 -17
  99. package/dist/commands/info.js.map +1 -1
  100. package/dist/commands/init.js +103 -727
  101. package/dist/commands/init.js.map +1 -1
  102. package/dist/commands/list.js +8 -87
  103. package/dist/commands/list.js.map +1 -1
  104. package/dist/commands/new/agent.js +8 -12
  105. package/dist/commands/new/agent.js.map +1 -1
  106. package/dist/commands/new/skill.js +6 -6
  107. package/dist/commands/new/skill.js.map +1 -1
  108. package/dist/commands/outdated.js +15 -19
  109. package/dist/commands/outdated.js.map +1 -1
  110. package/dist/commands/search.js +21 -34
  111. package/dist/commands/search.js.map +1 -1
  112. package/dist/commands/uninstall.js +15 -14
  113. package/dist/commands/uninstall.js.map +1 -1
  114. package/dist/commands/update.js +13 -24
  115. package/dist/commands/update.js.map +1 -1
  116. package/dist/commands/validate.js +44 -487
  117. package/dist/commands/validate.js.map +1 -1
  118. package/dist/commands/version/bump.js +11 -11
  119. package/dist/commands/version/bump.js.map +1 -1
  120. package/dist/commands/version/index.js +9 -10
  121. package/dist/commands/version/index.js.map +1 -1
  122. package/dist/commands/version/set.js +10 -8
  123. package/dist/commands/version/set.js.map +1 -1
  124. package/dist/commands/version/show.js +9 -10
  125. package/dist/commands/version/show.js.map +1 -1
  126. package/dist/components/common/confirm.js +2 -2
  127. package/dist/components/common/confirm.test.js +203 -0
  128. package/dist/components/common/confirm.test.js.map +1 -0
  129. package/dist/components/common/message.js +1 -1
  130. package/dist/components/common/spinner.js +1 -1
  131. package/dist/components/common/spinner.js.map +1 -1
  132. package/dist/components/skill-search/skill-search.js +3 -3
  133. package/dist/components/wizard/category-grid.js +2 -2
  134. package/dist/components/wizard/category-grid.test.js +132 -78
  135. package/dist/components/wizard/category-grid.test.js.map +1 -1
  136. package/dist/components/wizard/menu-item.js +2 -2
  137. package/dist/components/wizard/search-modal.js +9 -0
  138. package/dist/components/wizard/search-modal.js.map +1 -0
  139. package/dist/components/wizard/search-modal.test.js +216 -0
  140. package/dist/components/wizard/search-modal.test.js.map +1 -0
  141. package/dist/components/wizard/section-progress.js +2 -2
  142. package/dist/components/wizard/section-progress.test.js +4 -4
  143. package/dist/components/wizard/section-progress.test.js.map +1 -1
  144. package/dist/components/wizard/source-grid.js +10 -0
  145. package/dist/components/wizard/source-grid.js.map +1 -0
  146. package/dist/components/wizard/source-grid.test.js +500 -0
  147. package/dist/components/wizard/source-grid.test.js.map +1 -0
  148. package/dist/components/wizard/step-approach.js +7 -6
  149. package/dist/components/wizard/step-approach.test.js +115 -0
  150. package/dist/components/wizard/step-approach.test.js.map +1 -0
  151. package/dist/components/wizard/step-build.js +9 -4
  152. package/dist/components/wizard/step-build.test.js +103 -122
  153. package/dist/components/wizard/step-build.test.js.map +1 -1
  154. package/dist/components/wizard/step-confirm.js +3 -2
  155. package/dist/components/wizard/step-confirm.test.js +364 -0
  156. package/dist/components/wizard/step-confirm.test.js.map +1 -0
  157. package/dist/components/wizard/step-refine.js +2 -2
  158. package/dist/components/wizard/step-refine.test.js +19 -13
  159. package/dist/components/wizard/step-refine.test.js.map +1 -1
  160. package/dist/components/wizard/step-settings.js +14 -0
  161. package/dist/components/wizard/step-settings.js.map +1 -0
  162. package/dist/components/wizard/step-settings.test.js +240 -0
  163. package/dist/components/wizard/step-settings.test.js.map +1 -0
  164. package/dist/components/wizard/step-sources.js +17 -0
  165. package/dist/components/wizard/step-sources.js.map +1 -0
  166. package/dist/components/wizard/step-sources.test.js +290 -0
  167. package/dist/components/wizard/step-sources.test.js.map +1 -0
  168. package/dist/components/wizard/step-stack.js +7 -6
  169. package/dist/components/wizard/step-stack.test.js +344 -0
  170. package/dist/components/wizard/step-stack.test.js.map +1 -0
  171. package/dist/components/wizard/view-title.js +2 -2
  172. package/dist/components/wizard/wizard-layout.js +6 -5
  173. package/dist/components/wizard/wizard-tabs.js +2 -2
  174. package/dist/components/wizard/wizard-tabs.test.js +292 -0
  175. package/dist/components/wizard/wizard-tabs.test.js.map +1 -0
  176. package/dist/components/wizard/wizard.js +22 -14
  177. package/dist/config/skills-matrix.yaml +38 -37
  178. package/dist/config/stacks.yaml +8 -14
  179. package/dist/hooks/init.js +5 -5
  180. package/dist/hooks/init.js.map +1 -1
  181. package/dist/index.js +1 -1
  182. package/dist/index.js.map +1 -1
  183. package/dist/{magic-string.es-RGXYGAW3.js → magic-string.es-PAH2SOTR.js} +2 -2
  184. package/dist/source-manager-EYO3F2DV.js +16 -0
  185. package/dist/source-manager-EYO3F2DV.js.map +1 -0
  186. package/dist/src/agents/_templates/agent.liquid +1 -1
  187. package/dist/src/agents/developer/api-developer/agent.yaml +1 -1
  188. package/dist/src/agents/developer/cli-developer/agent.yaml +1 -1
  189. package/dist/src/agents/developer/web-architecture/agent.yaml +1 -1
  190. package/dist/src/agents/developer/web-developer/agent.yaml +1 -1
  191. package/dist/src/agents/meta/agent-summoner/agent.yaml +1 -1
  192. package/dist/src/agents/meta/documentor/agent.yaml +1 -1
  193. package/dist/src/agents/meta/skill-summoner/agent.yaml +1 -1
  194. package/dist/src/agents/migration/cli-migrator/agent.yaml +1 -1
  195. package/dist/src/agents/pattern/pattern-scout/agent.yaml +1 -1
  196. package/dist/src/agents/pattern/web-pattern-critique/agent.yaml +1 -1
  197. package/dist/src/agents/planning/web-pm/agent.yaml +1 -1
  198. package/dist/src/agents/researcher/api-researcher/agent.yaml +1 -1
  199. package/dist/src/agents/researcher/web-researcher/agent.yaml +1 -1
  200. package/dist/src/agents/reviewer/api-reviewer/agent.yaml +1 -1
  201. package/dist/src/agents/reviewer/cli-reviewer/agent.yaml +1 -1
  202. package/dist/src/agents/reviewer/web-reviewer/agent.yaml +1 -1
  203. package/dist/src/agents/tester/cli-tester/agent.yaml +1 -1
  204. package/dist/src/agents/tester/web-tester/agent.yaml +1 -1
  205. package/dist/stores/wizard-store.js +4 -3
  206. package/dist/stores/wizard-store.test.js +51 -82
  207. package/dist/stores/wizard-store.test.js.map +1 -1
  208. package/package.json +5 -3
  209. package/src/agents/_templates/agent.liquid +1 -1
  210. package/src/agents/developer/api-developer/agent.yaml +1 -1
  211. package/src/agents/developer/cli-developer/agent.yaml +1 -1
  212. package/src/agents/developer/web-architecture/agent.yaml +1 -1
  213. package/src/agents/developer/web-developer/agent.yaml +1 -1
  214. package/src/agents/meta/agent-summoner/agent.yaml +1 -1
  215. package/src/agents/meta/documentor/agent.yaml +1 -1
  216. package/src/agents/meta/skill-summoner/agent.yaml +1 -1
  217. package/src/agents/migration/cli-migrator/agent.yaml +1 -1
  218. package/src/agents/pattern/pattern-scout/agent.yaml +1 -1
  219. package/src/agents/pattern/web-pattern-critique/agent.yaml +1 -1
  220. package/src/agents/planning/web-pm/agent.yaml +1 -1
  221. package/src/agents/researcher/api-researcher/agent.yaml +1 -1
  222. package/src/agents/researcher/web-researcher/agent.yaml +1 -1
  223. package/src/agents/reviewer/api-reviewer/agent.yaml +1 -1
  224. package/src/agents/reviewer/cli-reviewer/agent.yaml +1 -1
  225. package/src/agents/reviewer/web-reviewer/agent.yaml +1 -1
  226. package/src/agents/tester/cli-tester/agent.yaml +1 -1
  227. package/src/agents/tester/web-tester/agent.yaml +1 -1
  228. package/dist/chunk-2LSGX6R4.js.map +0 -1
  229. package/dist/chunk-2OKUEELH.js +0 -32
  230. package/dist/chunk-2OKUEELH.js.map +0 -1
  231. package/dist/chunk-374JNMR6.js +0 -212
  232. package/dist/chunk-374JNMR6.js.map +0 -1
  233. package/dist/chunk-3EHUF54X.js.map +0 -1
  234. package/dist/chunk-3XR4PALU.js +0 -529
  235. package/dist/chunk-3XR4PALU.js.map +0 -1
  236. package/dist/chunk-5K2ZLUO5.js +0 -57
  237. package/dist/chunk-5K2ZLUO5.js.map +0 -1
  238. package/dist/chunk-5KXUDHAB.js.map +0 -1
  239. package/dist/chunk-6Q3Y7KVB.js.map +0 -1
  240. package/dist/chunk-7SLV7CMF.js +0 -615
  241. package/dist/chunk-7SLV7CMF.js.map +0 -1
  242. package/dist/chunk-A46TPNBJ.js.map +0 -1
  243. package/dist/chunk-AL74GBW4.js +0 -69
  244. package/dist/chunk-AL74GBW4.js.map +0 -1
  245. package/dist/chunk-BQX23RBV.js +0 -191
  246. package/dist/chunk-BQX23RBV.js.map +0 -1
  247. package/dist/chunk-CA4LH4LI.js +0 -132
  248. package/dist/chunk-CA4LH4LI.js.map +0 -1
  249. package/dist/chunk-CBLPAMZO.js.map +0 -1
  250. package/dist/chunk-CKPQHGXR.js +0 -417
  251. package/dist/chunk-CKPQHGXR.js.map +0 -1
  252. package/dist/chunk-CXOFOJCN.js +0 -80
  253. package/dist/chunk-CXOFOJCN.js.map +0 -1
  254. package/dist/chunk-EHGD7HIE.js +0 -104
  255. package/dist/chunk-EHGD7HIE.js.map +0 -1
  256. package/dist/chunk-EHS3TWWP.js +0 -95
  257. package/dist/chunk-EHS3TWWP.js.map +0 -1
  258. package/dist/chunk-FJFEKPXF.js.map +0 -1
  259. package/dist/chunk-HEOHU5EZ.js.map +0 -1
  260. package/dist/chunk-HGCBZUH5.js.map +0 -1
  261. package/dist/chunk-HPGFY5ZN.js +0 -114
  262. package/dist/chunk-HPGFY5ZN.js.map +0 -1
  263. package/dist/chunk-INJ2EFRW.js +0 -127
  264. package/dist/chunk-INJ2EFRW.js.map +0 -1
  265. package/dist/chunk-IOBFMF6X.js +0 -61
  266. package/dist/chunk-IOBFMF6X.js.map +0 -1
  267. package/dist/chunk-KH3HA7J7.js +0 -116
  268. package/dist/chunk-KH3HA7J7.js.map +0 -1
  269. package/dist/chunk-N6JNE326.js +0 -261
  270. package/dist/chunk-N6JNE326.js.map +0 -1
  271. package/dist/chunk-NAGU7TVZ.js +0 -36
  272. package/dist/chunk-NAGU7TVZ.js.map +0 -1
  273. package/dist/chunk-OQYYMQJR.js.map +0 -1
  274. package/dist/chunk-PLZOUVDD.js +0 -419
  275. package/dist/chunk-PLZOUVDD.js.map +0 -1
  276. package/dist/chunk-Q3J43SF3.js.map +0 -1
  277. package/dist/chunk-RTE64SJA.js.map +0 -1
  278. package/dist/chunk-T25OEQFI.js +0 -26
  279. package/dist/chunk-T25OEQFI.js.map +0 -1
  280. package/dist/chunk-UMORK7OK.js.map +0 -1
  281. package/dist/chunk-VFHWU7JU.js +0 -287
  282. package/dist/chunk-VFHWU7JU.js.map +0 -1
  283. package/dist/chunk-VS4GVTZE.js +0 -91
  284. package/dist/chunk-VS4GVTZE.js.map +0 -1
  285. package/dist/chunk-WFEFICFM.js.map +0 -1
  286. package/dist/chunk-WG6KIAPK.js +0 -54
  287. package/dist/chunk-WG6KIAPK.js.map +0 -1
  288. package/dist/chunk-ZEI3ZUDU.js.map +0 -1
  289. package/dist/chunk-ZNIDWLL5.js.map +0 -1
  290. package/dist/chunk-ZSVMS677.js.map +0 -1
  291. /package/dist/{chunk-XY3XDVMI.js.map → chunk-QR2EBWL2.js.map} +0 -0
  292. /package/dist/{chunk-66UDJBF6.js.map → chunk-REJGRCVQ.js.map} +0 -0
  293. /package/dist/{chunk-Z2CWURZ6.js.map → chunk-UNN7523L.js.map} +0 -0
  294. /package/dist/{magic-string.es-RGXYGAW3.js.map → magic-string.es-PAH2SOTR.js.map} +0 -0
@@ -1,261 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- compileAgentForPlugin,
4
- createLiquidEngine,
5
- resolveAgents,
6
- resolveStackSkills
7
- } from "./chunk-7SLV7CMF.js";
8
- import {
9
- getPluginAgentsDir
10
- } from "./chunk-HPGFY5ZN.js";
11
- import {
12
- loadProjectConfig
13
- } from "./chunk-VFHWU7JU.js";
14
- import {
15
- loadAllAgents,
16
- loadPluginSkills,
17
- loadProjectAgents
18
- } from "./chunk-BQX23RBV.js";
19
- import {
20
- verbose
21
- } from "./chunk-T25OEQFI.js";
22
- import {
23
- ensureDir,
24
- fileExists,
25
- glob,
26
- readFile,
27
- writeFile
28
- } from "./chunk-AL74GBW4.js";
29
- import {
30
- init_esm_shims
31
- } from "./chunk-DHET7RCE.js";
32
-
33
- // src/cli/lib/agent-recompiler.ts
34
- init_esm_shims();
35
- import path from "path";
36
-
37
- // src/cli/lib/custom-agent-resolver.ts
38
- init_esm_shims();
39
- var DEFAULT_TOOLS = ["Read", "Grep", "Glob"];
40
- var CUSTOM_AGENT_PATH = "_custom";
41
- function resolveCustomAgent(agentId, customConfig, builtinAgents) {
42
- let baseAgent = {};
43
- if (customConfig.extends) {
44
- const base = builtinAgents[customConfig.extends];
45
- if (!base) {
46
- const availableAgents = Object.keys(builtinAgents);
47
- const agentList = availableAgents.length > 0 ? `Available agents: ${availableAgents.slice(0, 5).join(", ")}${availableAgents.length > 5 ? ` (and ${availableAgents.length - 5} more)` : ""}` : "No built-in agents found";
48
- throw new Error(
49
- `Custom agent "${agentId}" extends unknown agent "${customConfig.extends}". ${agentList}`
50
- );
51
- }
52
- baseAgent = { ...base };
53
- }
54
- let disallowedTools;
55
- if (customConfig.disallowed_tools || baseAgent.disallowed_tools) {
56
- const merged = /* @__PURE__ */ new Set([
57
- ...baseAgent.disallowed_tools || [],
58
- ...customConfig.disallowed_tools || []
59
- ]);
60
- disallowedTools = [...merged];
61
- }
62
- let hooks;
63
- if (customConfig.hooks || baseAgent.hooks) {
64
- hooks = { ...baseAgent.hooks };
65
- if (customConfig.hooks) {
66
- for (const [hookType, hookDefs] of Object.entries(customConfig.hooks)) {
67
- if (hooks[hookType]) {
68
- hooks[hookType] = [...hooks[hookType], ...hookDefs];
69
- } else {
70
- hooks[hookType] = hookDefs;
71
- }
72
- }
73
- }
74
- }
75
- return {
76
- title: customConfig.title,
77
- description: customConfig.description,
78
- model: customConfig.model || baseAgent.model,
79
- tools: customConfig.tools || baseAgent.tools || DEFAULT_TOOLS,
80
- disallowed_tools: disallowedTools,
81
- permission_mode: customConfig.permission_mode || baseAgent.permission_mode,
82
- hooks,
83
- // Use extended agent's path for template resolution, or _custom for standalone
84
- path: baseAgent.path || CUSTOM_AGENT_PATH,
85
- sourceRoot: baseAgent.sourceRoot
86
- };
87
- }
88
- function resolveCustomAgents(customAgents, builtinAgents) {
89
- const resolved = {};
90
- for (const [id, config] of Object.entries(customAgents)) {
91
- resolved[id] = resolveCustomAgent(id, config, builtinAgents);
92
- }
93
- return resolved;
94
- }
95
- function hasAgentIdConflict(customAgentId, builtinAgents) {
96
- return customAgentId in builtinAgents;
97
- }
98
- function validateCustomAgentIds(customAgents, builtinAgents) {
99
- const errors = [];
100
- for (const customId of Object.keys(customAgents)) {
101
- if (hasAgentIdConflict(customId, builtinAgents)) {
102
- errors.push(
103
- `Custom agent "${customId}" conflicts with built-in agent of the same name. Choose a unique name.`
104
- );
105
- }
106
- }
107
- return errors;
108
- }
109
-
110
- // src/cli/lib/agent-recompiler.ts
111
- import { parse as parseYaml } from "yaml";
112
- async function getExistingAgentNames(pluginDir) {
113
- const agentsDir = getPluginAgentsDir(pluginDir);
114
- const files = await glob("*.md", agentsDir);
115
- return files.map((f) => path.basename(f, ".md"));
116
- }
117
- async function loadConfigWithFallback(pluginDir) {
118
- const legacyConfigPath = path.join(pluginDir, "config.yaml");
119
- if (await fileExists(legacyConfigPath)) {
120
- try {
121
- const content = await readFile(legacyConfigPath);
122
- const parsed = parseYaml(content);
123
- if (parsed && typeof parsed === "object") {
124
- verbose(`Loaded config.yaml from ${legacyConfigPath}`);
125
- return {
126
- config: parsed,
127
- configPath: legacyConfigPath,
128
- isLegacy: false
129
- };
130
- }
131
- } catch (error) {
132
- verbose(`Failed to parse config.yaml: ${error}`);
133
- }
134
- }
135
- return loadProjectConfig(pluginDir);
136
- }
137
- async function recompileAgents(options) {
138
- const {
139
- pluginDir,
140
- sourcePath,
141
- agents: specifiedAgents,
142
- skills: providedSkills,
143
- projectDir,
144
- outputDir
145
- } = options;
146
- const result = {
147
- compiled: [],
148
- failed: [],
149
- warnings: []
150
- };
151
- let loadedConfig = await loadConfigWithFallback(pluginDir);
152
- if (!loadedConfig && projectDir) {
153
- loadedConfig = await loadConfigWithFallback(projectDir);
154
- }
155
- const projectConfig = loadedConfig?.config ?? null;
156
- const builtinAgents = await loadAllAgents(sourcePath);
157
- const projectAgents = projectDir ? await loadProjectAgents(projectDir) : {};
158
- let allAgents = {
159
- ...builtinAgents,
160
- ...projectAgents
161
- };
162
- if (projectConfig?.custom_agents) {
163
- const idConflicts = validateCustomAgentIds(projectConfig.custom_agents, builtinAgents);
164
- if (idConflicts.length > 0) {
165
- for (const error of idConflicts) {
166
- result.warnings.push(error);
167
- }
168
- }
169
- try {
170
- const resolvedCustomAgents = resolveCustomAgents(projectConfig.custom_agents, builtinAgents);
171
- allAgents = { ...builtinAgents, ...resolvedCustomAgents };
172
- verbose(`Resolved ${Object.keys(resolvedCustomAgents).length} custom agents`);
173
- } catch (error) {
174
- result.warnings.push(
175
- `Failed to resolve custom agents: ${error instanceof Error ? error.message : String(error)}`
176
- );
177
- }
178
- }
179
- let agentNames;
180
- if (specifiedAgents) {
181
- agentNames = specifiedAgents;
182
- } else if (projectConfig?.agents) {
183
- agentNames = projectConfig.agents;
184
- verbose(`Using agents from config.yaml: ${agentNames.join(", ")}`);
185
- } else if (outputDir) {
186
- agentNames = Object.keys(allAgents);
187
- verbose(`Using all available agents from source: ${agentNames.join(", ")}`);
188
- } else {
189
- agentNames = await getExistingAgentNames(pluginDir);
190
- }
191
- if (agentNames.length === 0) {
192
- result.warnings.push("No agents found to recompile");
193
- return result;
194
- }
195
- verbose(`Recompiling ${agentNames.length} agents in ${outputDir ?? pluginDir}`);
196
- const pluginSkills = providedSkills ?? await loadPluginSkills(pluginDir);
197
- const compileAgents = {};
198
- for (const agentName of agentNames) {
199
- if (allAgents[agentName]) {
200
- const customAgentConfig = projectConfig?.custom_agents?.[agentName];
201
- if (customAgentConfig?.skills && customAgentConfig.skills.length > 0) {
202
- const skillRefs = customAgentConfig.skills.map((s) => ({
203
- id: typeof s === "string" ? s : s.id,
204
- usage: `when working with ${(typeof s === "string" ? s : s.id).split(" ")[0]}`,
205
- preloaded: (typeof s === "object" && "preloaded" in s && s.preloaded) ?? false
206
- }));
207
- compileAgents[agentName] = { skills: skillRefs };
208
- verbose(` Agent ${agentName}: ${skillRefs.length} skills from custom_agents`);
209
- } else if (projectConfig?.agent_skills?.[agentName]) {
210
- const skillRefs = resolveStackSkills(projectConfig, agentName, pluginSkills);
211
- compileAgents[agentName] = { skills: skillRefs };
212
- verbose(` Agent ${agentName}: ${skillRefs.length} skills from config`);
213
- } else if (projectConfig?.skills) {
214
- const skillRefs = projectConfig.skills.map((s) => {
215
- const id = typeof s === "string" ? s : s.id;
216
- const preloaded = typeof s === "object" && "preloaded" in s ? s.preloaded ?? false : false;
217
- return {
218
- id,
219
- usage: `when working with ${id.split(" ")[0]}`,
220
- preloaded
221
- };
222
- });
223
- compileAgents[agentName] = { skills: skillRefs };
224
- verbose(` Agent ${agentName}: ${skillRefs.length} skills (all)`);
225
- } else {
226
- compileAgents[agentName] = {};
227
- }
228
- } else {
229
- result.warnings.push(`Agent "${agentName}" not found in source definitions`);
230
- }
231
- }
232
- const compileConfig = {
233
- name: projectConfig?.name || path.basename(pluginDir),
234
- description: projectConfig?.description || "Recompiled plugin",
235
- claude_md: "",
236
- agents: compileAgents
237
- };
238
- const engine = await createLiquidEngine(projectDir);
239
- const resolvedAgents = await resolveAgents(allAgents, pluginSkills, compileConfig, sourcePath);
240
- const agentsDir = outputDir ?? getPluginAgentsDir(pluginDir);
241
- await ensureDir(agentsDir);
242
- for (const [name, agent] of Object.entries(resolvedAgents)) {
243
- try {
244
- const output = await compileAgentForPlugin(name, agent, sourcePath, engine);
245
- await writeFile(path.join(agentsDir, `${name}.md`), output);
246
- result.compiled.push(name);
247
- verbose(` Recompiled: ${name}`);
248
- } catch (error) {
249
- result.failed.push(name);
250
- result.warnings.push(
251
- `Failed to compile ${name}: ${error instanceof Error ? error.message : String(error)}`
252
- );
253
- }
254
- }
255
- return result;
256
- }
257
-
258
- export {
259
- recompileAgents
260
- };
261
- //# sourceMappingURL=chunk-N6JNE326.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/lib/agent-recompiler.ts","../src/cli/lib/custom-agent-resolver.ts"],"sourcesContent":["import path from \"path\";\nimport { glob, writeFile, ensureDir, readFile, fileExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport { loadAllAgents, loadPluginSkills, loadProjectAgents } from \"./loader\";\nimport { resolveAgents, resolveStackSkills } from \"./resolver\";\nimport { compileAgentForPlugin } from \"./stack-plugin-compiler\";\nimport { getPluginAgentsDir } from \"./plugin-finder\";\nimport { createLiquidEngine } from \"./compiler\";\nimport { loadProjectConfig, type LoadedProjectConfig } from \"./project-config\";\nimport { resolveCustomAgents, validateCustomAgentIds } from \"./custom-agent-resolver\";\nimport { parse as parseYaml } from \"yaml\";\nimport type {\n CompileConfig,\n CompileAgentConfig,\n SkillReference,\n SkillDefinition,\n ProjectConfig,\n AgentDefinition,\n} from \"../../types\";\n\nexport interface RecompileAgentsOptions {\n pluginDir: string;\n sourcePath: string;\n agents?: string[];\n skills?: Record<string, SkillDefinition>;\n projectDir?: string;\n outputDir?: string;\n}\n\nexport interface RecompileAgentsResult {\n compiled: string[];\n failed: string[];\n warnings: string[];\n}\n\nasync function getExistingAgentNames(pluginDir: string): Promise<string[]> {\n const agentsDir = getPluginAgentsDir(pluginDir);\n const files = await glob(\"*.md\", agentsDir);\n return files.map((f) => path.basename(f, \".md\"));\n}\n\n/**\n * Load config from either:\n * 1. pluginDir/config.yaml (legacy plugin location)\n * 2. pluginDir/.claude/config.yaml (new project config location)\n *\n * This provides backward compatibility with existing plugins.\n */\nasync function loadConfigWithFallback(pluginDir: string): Promise<LoadedProjectConfig | null> {\n // First try the legacy plugin location (pluginDir/config.yaml)\n const legacyConfigPath = path.join(pluginDir, \"config.yaml\");\n if (await fileExists(legacyConfigPath)) {\n try {\n const content = await readFile(legacyConfigPath);\n const parsed = parseYaml(content);\n\n if (parsed && typeof parsed === \"object\") {\n verbose(`Loaded config.yaml from ${legacyConfigPath}`);\n return {\n config: parsed as ProjectConfig,\n configPath: legacyConfigPath,\n isLegacy: false,\n };\n }\n } catch (error) {\n verbose(`Failed to parse config.yaml: ${error}`);\n }\n }\n\n // Fall back to project config location (.claude/config.yaml)\n return loadProjectConfig(pluginDir);\n}\n\nexport async function recompileAgents(\n options: RecompileAgentsOptions,\n): Promise<RecompileAgentsResult> {\n const {\n pluginDir,\n sourcePath,\n agents: specifiedAgents,\n skills: providedSkills,\n projectDir,\n outputDir,\n } = options;\n\n const result: RecompileAgentsResult = {\n compiled: [],\n failed: [],\n warnings: [],\n };\n\n // Load project config (handles both legacy plugin config and new ProjectConfig)\n // Try plugin dir first, then fall back to project dir for local mode\n let loadedConfig = await loadConfigWithFallback(pluginDir);\n if (!loadedConfig && projectDir) {\n loadedConfig = await loadConfigWithFallback(projectDir);\n }\n const projectConfig = loadedConfig?.config ?? null;\n\n // Load built-in agents from source\n const builtinAgents = await loadAllAgents(sourcePath);\n\n // Load project agents from .claude-src/agents/ (if projectDir provided)\n const projectAgents = projectDir ? await loadProjectAgents(projectDir) : {};\n\n // Resolve custom agents and merge with built-in agents\n // Priority: custom_agents > project agents > built-in agents\n let allAgents: Record<string, AgentDefinition> = {\n ...builtinAgents,\n ...projectAgents,\n };\n if (projectConfig?.custom_agents) {\n // Validate custom agent IDs don't conflict with built-in agents\n const idConflicts = validateCustomAgentIds(projectConfig.custom_agents, builtinAgents);\n if (idConflicts.length > 0) {\n for (const error of idConflicts) {\n result.warnings.push(error);\n }\n }\n\n // Resolve custom agents to AgentDefinition\n try {\n const resolvedCustomAgents = resolveCustomAgents(projectConfig.custom_agents, builtinAgents);\n // Merge: custom agents can override built-in if same name (though we warn above)\n allAgents = { ...builtinAgents, ...resolvedCustomAgents };\n verbose(`Resolved ${Object.keys(resolvedCustomAgents).length} custom agents`);\n } catch (error) {\n result.warnings.push(\n `Failed to resolve custom agents: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n let agentNames: string[];\n if (specifiedAgents) {\n agentNames = specifiedAgents;\n } else if (projectConfig?.agents) {\n agentNames = projectConfig.agents;\n verbose(`Using agents from config.yaml: ${agentNames.join(\", \")}`);\n } else if (outputDir) {\n agentNames = Object.keys(allAgents);\n verbose(`Using all available agents from source: ${agentNames.join(\", \")}`);\n } else {\n agentNames = await getExistingAgentNames(pluginDir);\n }\n\n if (agentNames.length === 0) {\n result.warnings.push(\"No agents found to recompile\");\n return result;\n }\n\n verbose(`Recompiling ${agentNames.length} agents in ${outputDir ?? pluginDir}`);\n\n const pluginSkills = providedSkills ?? (await loadPluginSkills(pluginDir));\n\n const compileAgents: Record<string, CompileAgentConfig> = {};\n for (const agentName of agentNames) {\n if (allAgents[agentName]) {\n // Check if this is a custom agent with its own skills defined\n const customAgentConfig = projectConfig?.custom_agents?.[agentName];\n if (customAgentConfig?.skills && customAgentConfig.skills.length > 0) {\n // Custom agent has explicit skills defined\n const skillRefs: SkillReference[] = customAgentConfig.skills.map((s) => ({\n id: typeof s === \"string\" ? s : s.id,\n usage: `when working with ${(typeof s === \"string\" ? s : s.id).split(\" \")[0]}`,\n preloaded: (typeof s === \"object\" && \"preloaded\" in s && s.preloaded) ?? false,\n }));\n compileAgents[agentName] = { skills: skillRefs };\n verbose(` Agent ${agentName}: ${skillRefs.length} skills from custom_agents`);\n } else if (projectConfig?.agent_skills?.[agentName]) {\n const skillRefs = resolveStackSkills(projectConfig, agentName, pluginSkills);\n compileAgents[agentName] = { skills: skillRefs };\n verbose(` Agent ${agentName}: ${skillRefs.length} skills from config`);\n } else if (projectConfig?.skills) {\n // Fall back to all skills in the config\n const skillRefs: SkillReference[] = projectConfig.skills.map((s) => {\n const id = typeof s === \"string\" ? s : s.id;\n const preloaded =\n typeof s === \"object\" && \"preloaded\" in s ? (s.preloaded ?? false) : false;\n return {\n id,\n usage: `when working with ${id.split(\" \")[0]}`,\n preloaded,\n };\n });\n compileAgents[agentName] = { skills: skillRefs };\n verbose(` Agent ${agentName}: ${skillRefs.length} skills (all)`);\n } else {\n compileAgents[agentName] = {};\n }\n } else {\n result.warnings.push(`Agent \"${agentName}\" not found in source definitions`);\n }\n }\n\n const compileConfig: CompileConfig = {\n name: projectConfig?.name || path.basename(pluginDir),\n description: projectConfig?.description || \"Recompiled plugin\",\n claude_md: \"\",\n agents: compileAgents,\n };\n\n const engine = await createLiquidEngine(projectDir);\n const resolvedAgents = await resolveAgents(allAgents, pluginSkills, compileConfig, sourcePath);\n\n const agentsDir = outputDir ?? getPluginAgentsDir(pluginDir);\n await ensureDir(agentsDir);\n\n for (const [name, agent] of Object.entries(resolvedAgents)) {\n try {\n const output = await compileAgentForPlugin(name, agent, sourcePath, engine);\n await writeFile(path.join(agentsDir, `${name}.md`), output);\n result.compiled.push(name);\n verbose(` Recompiled: ${name}`);\n } catch (error) {\n result.failed.push(name);\n result.warnings.push(\n `Failed to compile ${name}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n return result;\n}\n","import type { CustomAgentConfig, AgentDefinition } from \"../../types\";\n\n/** Default tools for standalone custom agents (no extends) */\nconst DEFAULT_TOOLS = [\"Read\", \"Grep\", \"Glob\"];\n\n/** Marker path for standalone custom agents (no extends) */\nconst CUSTOM_AGENT_PATH = \"_custom\";\n\n/**\n * Resolve a custom agent config to a full AgentDefinition.\n * If extends is specified, inherit from the base agent.\n *\n * @param agentId - The custom agent's identifier\n * @param customConfig - The custom agent configuration from config.yaml\n * @param builtinAgents - Record of built-in agent definitions to extend from\n * @returns Fully resolved AgentDefinition\n * @throws Error if extends references an unknown agent\n */\nexport function resolveCustomAgent(\n agentId: string,\n customConfig: CustomAgentConfig,\n builtinAgents: Record<string, AgentDefinition>,\n): AgentDefinition {\n let baseAgent: Partial<AgentDefinition> = {};\n\n if (customConfig.extends) {\n const base = builtinAgents[customConfig.extends];\n if (!base) {\n const availableAgents = Object.keys(builtinAgents);\n const agentList =\n availableAgents.length > 0\n ? `Available agents: ${availableAgents.slice(0, 5).join(\", \")}${availableAgents.length > 5 ? ` (and ${availableAgents.length - 5} more)` : \"\"}`\n : \"No built-in agents found\";\n throw new Error(\n `Custom agent \"${agentId}\" extends unknown agent \"${customConfig.extends}\". ${agentList}`,\n );\n }\n baseAgent = { ...base };\n }\n\n // Merge disallowed_tools: custom + inherited\n let disallowedTools: string[] | undefined;\n if (customConfig.disallowed_tools || baseAgent.disallowed_tools) {\n const merged = new Set<string>([\n ...(baseAgent.disallowed_tools || []),\n ...(customConfig.disallowed_tools || []),\n ]);\n disallowedTools = [...merged];\n }\n\n // Merge hooks: custom hooks added to inherited\n let hooks: AgentDefinition[\"hooks\"] | undefined;\n if (customConfig.hooks || baseAgent.hooks) {\n hooks = { ...baseAgent.hooks };\n if (customConfig.hooks) {\n for (const [hookType, hookDefs] of Object.entries(customConfig.hooks)) {\n if (hooks[hookType]) {\n hooks[hookType] = [...hooks[hookType], ...hookDefs];\n } else {\n hooks[hookType] = hookDefs;\n }\n }\n }\n }\n\n return {\n title: customConfig.title,\n description: customConfig.description,\n model: customConfig.model || baseAgent.model,\n tools: customConfig.tools || baseAgent.tools || DEFAULT_TOOLS,\n disallowed_tools: disallowedTools,\n permission_mode: customConfig.permission_mode || baseAgent.permission_mode,\n hooks,\n // Use extended agent's path for template resolution, or _custom for standalone\n path: baseAgent.path || CUSTOM_AGENT_PATH,\n sourceRoot: baseAgent.sourceRoot,\n };\n}\n\n/**\n * Resolve all custom agents from config to AgentDefinition records.\n *\n * @param customAgents - Record of custom agent configs from config.yaml\n * @param builtinAgents - Record of built-in agent definitions\n * @returns Record of resolved AgentDefinitions keyed by custom agent ID\n */\nexport function resolveCustomAgents(\n customAgents: Record<string, CustomAgentConfig>,\n builtinAgents: Record<string, AgentDefinition>,\n): Record<string, AgentDefinition> {\n const resolved: Record<string, AgentDefinition> = {};\n\n for (const [id, config] of Object.entries(customAgents)) {\n resolved[id] = resolveCustomAgent(id, config, builtinAgents);\n }\n\n return resolved;\n}\n\n/**\n * Check if a custom agent ID conflicts with a built-in agent ID.\n *\n * @param customAgentId - The custom agent's identifier\n * @param builtinAgents - Record of built-in agent definitions\n * @returns true if there's a conflict\n */\nexport function hasAgentIdConflict(\n customAgentId: string,\n builtinAgents: Record<string, AgentDefinition>,\n): boolean {\n return customAgentId in builtinAgents;\n}\n\n/**\n * Validate custom agents don't conflict with built-in agents.\n *\n * @param customAgents - Record of custom agent configs\n * @param builtinAgents - Record of built-in agent definitions\n * @returns Array of error messages (empty if no conflicts)\n */\nexport function validateCustomAgentIds(\n customAgents: Record<string, CustomAgentConfig>,\n builtinAgents: Record<string, AgentDefinition>,\n): string[] {\n const errors: string[] = [];\n\n for (const customId of Object.keys(customAgents)) {\n if (hasAgentIdConflict(customId, builtinAgents)) {\n errors.push(\n `Custom agent \"${customId}\" conflicts with built-in agent of the same name. Choose a unique name.`,\n );\n }\n }\n\n return errors;\n}\n"],"mappings":"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","names":[]}
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- ensureDir,
4
- fileExists,
5
- readFile,
6
- writeFile
7
- } from "./chunk-AL74GBW4.js";
8
- import {
9
- CLAUDE_SRC_DIR
10
- } from "./chunk-FJFEKPXF.js";
11
- import {
12
- init_esm_shims
13
- } from "./chunk-DHET7RCE.js";
14
-
15
- // src/cli/lib/config-saver.ts
16
- init_esm_shims();
17
- import path from "path";
18
- import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
19
- var YAML_INDENT = 2;
20
- async function saveSourceToProjectConfig(projectDir, source) {
21
- const configPath = path.join(projectDir, CLAUDE_SRC_DIR, "config.yaml");
22
- let config = {};
23
- if (await fileExists(configPath)) {
24
- const content = await readFile(configPath);
25
- config = parseYaml(content) || {};
26
- }
27
- config.source = source;
28
- await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));
29
- const configYaml = stringifyYaml(config, { indent: YAML_INDENT });
30
- await writeFile(configPath, configYaml);
31
- }
32
-
33
- export {
34
- saveSourceToProjectConfig
35
- };
36
- //# sourceMappingURL=chunk-NAGU7TVZ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/lib/config-saver.ts"],"sourcesContent":["import path from \"path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { fileExists, readFile, writeFile, ensureDir } from \"../utils/fs\";\nimport { CLAUDE_SRC_DIR } from \"../consts\";\n\nconst YAML_INDENT = 2;\n\n/**\n * Save source to project-level .claude-src/config.yaml.\n * Creates the config file if it doesn't exist, or merges with existing config.\n */\nexport async function saveSourceToProjectConfig(projectDir: string, source: string): Promise<void> {\n const configPath = path.join(projectDir, CLAUDE_SRC_DIR, \"config.yaml\");\n\n let config: Record<string, unknown> = {};\n if (await fileExists(configPath)) {\n const content = await readFile(configPath);\n config = (parseYaml(content) as Record<string, unknown>) || {};\n }\n\n config.source = source;\n\n await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));\n const configYaml = stringifyYaml(config, { indent: YAML_INDENT });\n await writeFile(configPath, configYaml);\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA,OAAO,UAAU;AACjB,SAAS,SAAS,WAAW,aAAa,qBAAqB;AAI/D,IAAM,cAAc;AAMpB,eAAsB,0BAA0B,YAAoB,QAA+B;AACjG,QAAM,aAAa,KAAK,KAAK,YAAY,gBAAgB,aAAa;AAEtE,MAAI,SAAkC,CAAC;AACvC,MAAI,MAAM,WAAW,UAAU,GAAG;AAChC,UAAM,UAAU,MAAM,SAAS,UAAU;AACzC,aAAU,UAAU,OAAO,KAAiC,CAAC;AAAA,EAC/D;AAEA,SAAO,SAAS;AAEhB,QAAM,UAAU,KAAK,KAAK,YAAY,cAAc,CAAC;AACrD,QAAM,aAAa,cAAc,QAAQ,EAAE,QAAQ,YAAY,CAAC;AAChE,QAAM,UAAU,YAAY,UAAU;AACxC;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/components/wizard/category-grid.tsx"],"sourcesContent":["/**\n * CategoryGrid component - Section-based selection for wizard Build step.\n *\n * Displays categories as sections with technology options as horizontal tags.\n * Supports keyboard navigation (arrows, vim keys) and visual states.\n *\n * Visual states:\n * - Selected: cyan background + black text\n * - Recommended: cyan text (no background)\n * - Focused: gray background\n * - Disabled: dimmed text\n * - Normal: plain text\n * - Locked section: visible but dimmed, not navigable\n *\n * Section layout: Each category is a section with header, underline, and flowing tags.\n */\nimport React, { useCallback, useEffect } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\n// Types\n\nexport type OptionState = \"normal\" | \"recommended\" | \"discouraged\" | \"disabled\";\n\nexport interface CategoryOption {\n id: string;\n label: string;\n state: OptionState;\n stateReason?: string;\n selected: boolean;\n local?: boolean;\n}\n\nexport interface CategoryRow {\n id: string;\n name: string;\n required: boolean;\n exclusive: boolean;\n options: CategoryOption[];\n}\n\nexport interface CategoryGridProps {\n /** Categories to display (filtered by domain from matrix) */\n categories: CategoryRow[];\n /** Focused row index (section index) */\n focusedRow: number;\n /** Focused column index (option index within section) */\n focusedCol: number;\n /** Show descriptions under each technology */\n showDescriptions: boolean;\n /** Expert mode - shows all options, disables smart ordering */\n expertMode: boolean;\n /** Called when user toggles a technology */\n onToggle: (categoryId: string, technologyId: string) => void;\n /** Called when focus changes */\n onFocusChange: (row: number, col: number) => void;\n /** Called when show descriptions is toggled */\n onToggleDescriptions: () => void;\n}\n\n// Constants\n\n/** Required indicator */\nconst SYMBOL_REQUIRED = \"*\";\n\n/** Background colors for different states */\nconst BG_SELECTED = \"cyan\"; // Cyan background for selected\nconst BG_FOCUSED = \"#333\"; // Dark gray for focused\n\n/** Framework category ID for locking logic */\nconst FRAMEWORK_CATEGORY_ID = \"framework\";\n\n// Helper Functions\n\n/**\n * Sort options based on state (recommended first, discouraged last).\n * In expert mode, returns options as-is.\n */\nconst sortOptions = (options: CategoryOption[], expertMode: boolean): CategoryOption[] => {\n if (expertMode) {\n return options;\n }\n\n const stateOrder: Record<OptionState, number> = {\n recommended: 0,\n normal: 1,\n discouraged: 2,\n disabled: 3,\n };\n\n return [...options].sort((a, b) => {\n return stateOrder[a.state] - stateOrder[b.state];\n });\n};\n\n/**\n * Find the next non-disabled option index in a direction.\n * Returns current index if no valid option found.\n */\nconst findNextValidOption = (\n options: CategoryOption[],\n currentIndex: number,\n direction: 1 | -1,\n wrap: boolean = true,\n): number => {\n const length = options.length;\n if (length === 0) return currentIndex;\n\n let index = currentIndex;\n let attempts = 0;\n\n while (attempts < length) {\n index += direction;\n\n if (wrap) {\n // Wrap around\n if (index < 0) index = length - 1;\n if (index >= length) index = 0;\n } else {\n // Clamp to bounds\n if (index < 0) index = 0;\n if (index >= length) index = length - 1;\n }\n\n if (options[index] && options[index].state !== \"disabled\") {\n return index;\n }\n\n attempts++;\n }\n\n // All options are disabled, return current\n return currentIndex;\n};\n\n/**\n * Find a valid starting column for a row.\n * Returns 0 if all options are disabled.\n */\nconst findValidStartColumn = (options: CategoryOption[]): number => {\n for (let i = 0; i < options.length; i++) {\n if (options[i] && options[i].state !== \"disabled\") {\n return i;\n }\n }\n return 0;\n};\n\n/**\n * Check if a section is locked (for framework-first flow).\n * A section is locked if:\n * - It's not the framework section\n * - No framework has been selected yet\n */\nconst isSectionLocked = (categoryId: string, categories: CategoryRow[]): boolean => {\n // Framework section is never locked\n if (categoryId === FRAMEWORK_CATEGORY_ID) {\n return false;\n }\n\n // Find framework category and check if any option is selected\n const frameworkCategory = categories.find((cat) => cat.id === FRAMEWORK_CATEGORY_ID);\n\n if (!frameworkCategory) {\n // No framework category exists, nothing is locked\n return false;\n }\n\n // Check if any framework option is selected\n const hasFrameworkSelected = frameworkCategory.options.some((opt) => opt.selected);\n\n // Lock if no framework is selected\n return !hasFrameworkSelected;\n};\n\n/**\n * Find the next unlocked section index in a direction.\n */\nconst findNextUnlockedSection = (\n categories: { id: string; sortedOptions: CategoryOption[] }[],\n currentIndex: number,\n direction: 1 | -1,\n allCategories: CategoryRow[],\n): number => {\n const length = categories.length;\n if (length === 0) return currentIndex;\n\n let index = currentIndex;\n let attempts = 0;\n\n while (attempts < length) {\n index += direction;\n\n // Wrap around\n if (index < 0) index = length - 1;\n if (index >= length) index = 0;\n\n const category = categories[index];\n if (category && !isSectionLocked(category.id, allCategories)) {\n return index;\n }\n\n attempts++;\n }\n\n // All sections are locked (shouldn't happen), return current\n return currentIndex;\n};\n\ninterface SkillTagProps {\n option: CategoryOption;\n isFocused: boolean;\n isLocked: boolean;\n}\n\nconst SkillTag: React.FC<SkillTagProps> = ({ option, isFocused, isLocked }) => {\n const getColor = (): { text: string; border: string } | undefined => {\n if (isLocked || option.state === \"disabled\") {\n return {\n text: \"gray\",\n border: \"gray\",\n };\n }\n if (option.selected) {\n return {\n text: \"cyan\",\n border: \"cyan\",\n };\n }\n if (option.state === \"recommended\") {\n return {\n text: \"white\",\n border: \"gray\",\n };\n }\n if (option.state === \"discouraged\") {\n return {\n text: \"yellow\",\n border: \"yellow\",\n };\n }\n return undefined;\n };\n\n const isBold = isFocused || option.selected;\n const isDimmed = isLocked || option.state === \"disabled\";\n const focusBorderColor = option.selected ? \"cyan\" : \"white\";\n\n return (\n <Box\n marginRight={1}\n borderColor={isFocused ? focusBorderColor : getColor()?.border}\n borderStyle=\"single\"\n borderDimColor={isDimmed}\n >\n <Text color={getColor()?.text} bold={isBold} dimColor={false}>\n {\" \"}\n {option.local && (\n <>\n <Text backgroundColor=\"gray\"> L </Text>{\" \"}\n </>\n )}\n {option.label}{\" \"}\n </Text>\n </Box>\n );\n};\n\ninterface CategorySectionProps {\n category: CategoryRow;\n options: CategoryOption[];\n isLocked: boolean;\n isFocused: boolean;\n focusedOptionIndex: number;\n showDescriptions: boolean;\n}\n\nconst CategorySection: React.FC<CategorySectionProps> = ({\n category,\n options,\n isLocked,\n isFocused,\n focusedOptionIndex,\n showDescriptions,\n}) => {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box flexDirection=\"row\">\n <Text dimColor={isLocked}>{category.name}</Text>\n {category.required && (\n <Text color={isLocked ? \"gray\" : \"red\"} dimColor={isLocked}>\n {\" \"}\n {SYMBOL_REQUIRED}\n </Text>\n )}\n </Box>\n\n <Box flexDirection=\"row\" flexWrap=\"wrap\" marginTop={0}>\n {options.map((option, index) => (\n <Box key={option.id} flexDirection=\"column\">\n <SkillTag\n option={option}\n isFocused={isFocused && index === focusedOptionIndex && !isLocked}\n isLocked={isLocked}\n />\n {showDescriptions && option.stateReason && !isLocked && (\n <Box marginLeft={1} marginBottom={0}>\n <Text dimColor wrap=\"truncate-end\">\n {option.stateReason}\n </Text>\n </Box>\n )}\n </Box>\n ))}\n </Box>\n </Box>\n );\n};\n\n// Main Component\n\nexport const CategoryGrid: React.FC<CategoryGridProps> = ({\n categories,\n focusedRow,\n focusedCol,\n showDescriptions,\n expertMode,\n onToggle,\n onFocusChange,\n onToggleDescriptions,\n}) => {\n // Process categories with sorted options\n const processedCategories = categories.map((category) => ({\n ...category,\n sortedOptions: sortOptions(category.options, expertMode),\n }));\n\n // Get current row and its options\n const currentRow = processedCategories[focusedRow];\n const currentOptions = currentRow?.sortedOptions || [];\n const currentLocked = currentRow ? isSectionLocked(currentRow.id, categories) : false;\n\n // Ensure focusedCol is valid when row changes or options change\n useEffect(() => {\n if (!currentRow) return;\n\n const maxCol = currentOptions.length - 1;\n if (focusedCol > maxCol) {\n // Clamp to max column\n const newCol = Math.max(0, maxCol);\n onFocusChange(focusedRow, newCol);\n } else if (currentOptions[focusedCol]?.state === \"disabled\") {\n // Current option is disabled, find a valid one\n const validCol = findValidStartColumn(currentOptions);\n if (validCol !== focusedCol) {\n onFocusChange(focusedRow, validCol);\n }\n }\n }, [focusedRow, currentOptions, focusedCol, onFocusChange, currentRow]);\n\n // If current section is locked, move to first unlocked section\n useEffect(() => {\n if (currentRow && currentLocked) {\n const unlockedIndex = findNextUnlockedSection(processedCategories, focusedRow, 1, categories);\n if (unlockedIndex !== focusedRow) {\n const newRowOptions = processedCategories[unlockedIndex]?.sortedOptions || [];\n const newCol = findValidStartColumn(newRowOptions);\n onFocusChange(unlockedIndex, newCol);\n }\n }\n }, [currentRow, currentLocked, focusedRow, processedCategories, categories, onFocusChange]);\n\n // Handle keyboard navigation\n useInput(\n useCallback(\n (\n input: string,\n key: {\n leftArrow: boolean;\n rightArrow: boolean;\n upArrow: boolean;\n downArrow: boolean;\n tab: boolean;\n shift: boolean;\n },\n ) => {\n // Toggle descriptions with Shift+Tab (Tab now jumps sections)\n if (key.tab && key.shift) {\n onToggleDescriptions();\n return;\n }\n\n // Tab jumps to next unlocked section\n if (key.tab && !key.shift) {\n const nextSection = findNextUnlockedSection(\n processedCategories,\n focusedRow,\n 1,\n categories,\n );\n if (nextSection !== focusedRow) {\n const newRowOptions = processedCategories[nextSection]?.sortedOptions || [];\n const newCol = findValidStartColumn(newRowOptions);\n onFocusChange(nextSection, newCol);\n }\n return;\n }\n\n // Toggle descriptions with 'd'\n if (input === \"d\" || input === \"D\") {\n onToggleDescriptions();\n return;\n }\n\n // Toggle selection with Space (only if section is unlocked)\n if (input === \" \") {\n if (currentLocked) return;\n const currentOption = currentOptions[focusedCol];\n if (currentOption && currentOption.state !== \"disabled\") {\n onToggle(currentRow.id, currentOption.id);\n }\n return;\n }\n\n // Navigation\n const isLeft = key.leftArrow || input === \"h\";\n const isRight = key.rightArrow || input === \"l\";\n const isUp = key.upArrow || input === \"k\";\n const isDown = key.downArrow || input === \"j\";\n\n if (isLeft) {\n if (currentLocked) return;\n const newCol = findNextValidOption(currentOptions, focusedCol, -1, true);\n onFocusChange(focusedRow, newCol);\n } else if (isRight) {\n if (currentLocked) return;\n const newCol = findNextValidOption(currentOptions, focusedCol, 1, true);\n onFocusChange(focusedRow, newCol);\n } else if (isUp) {\n // Move to previous unlocked section\n const newRow = findNextUnlockedSection(processedCategories, focusedRow, -1, categories);\n const newRowOptions = processedCategories[newRow]?.sortedOptions || [];\n // Try to keep same column, or find valid one\n let newCol = Math.min(focusedCol, newRowOptions.length - 1);\n if (newRowOptions[newCol]?.state === \"disabled\") {\n newCol = findValidStartColumn(newRowOptions);\n }\n onFocusChange(newRow, newCol);\n } else if (isDown) {\n // Move to next unlocked section\n const newRow = findNextUnlockedSection(processedCategories, focusedRow, 1, categories);\n const newRowOptions = processedCategories[newRow]?.sortedOptions || [];\n // Try to keep same column, or find valid one\n let newCol = Math.min(focusedCol, newRowOptions.length - 1);\n if (newRowOptions[newCol]?.state === \"disabled\") {\n newCol = findValidStartColumn(newRowOptions);\n }\n onFocusChange(newRow, newCol);\n }\n },\n [\n focusedRow,\n focusedCol,\n currentOptions,\n currentRow,\n currentLocked,\n processedCategories,\n categories,\n onToggle,\n onFocusChange,\n onToggleDescriptions,\n ],\n ),\n );\n\n if (categories.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text dimColor>No categories to display.</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n {processedCategories.map((category, rowIndex) => {\n const isLocked = isSectionLocked(category.id, categories);\n\n return (\n <CategorySection\n key={category.id}\n category={category}\n options={category.sortedOptions}\n isLocked={isLocked}\n isFocused={rowIndex === focusedRow}\n focusedOptionIndex={focusedCol}\n showDescriptions={showDescriptions}\n />\n );\n })}\n </Box>\n );\n};\n"],"mappings":"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","names":[]}