@claude-collective/cli 0.13.4 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/CHANGELOG.md +183 -0
  2. package/config/skills-matrix.yaml +180 -113
  3. package/config/stacks.yaml +6 -6
  4. package/dist/{chunk-K3NB6DSG.js → chunk-2LSGX6R4.js} +54 -114
  5. package/dist/chunk-2LSGX6R4.js.map +1 -0
  6. package/dist/chunk-2OKUEELH.js +32 -0
  7. package/dist/chunk-2OKUEELH.js.map +1 -0
  8. package/dist/{chunk-V46GGCCI.js → chunk-374JNMR6.js} +14 -96
  9. package/dist/chunk-374JNMR6.js.map +1 -0
  10. package/dist/chunk-3EHUF54X.js +133 -0
  11. package/dist/chunk-3EHUF54X.js.map +1 -0
  12. package/dist/{chunk-7Q44DMSP.js → chunk-3XR4PALU.js} +92 -145
  13. package/dist/chunk-3XR4PALU.js.map +1 -0
  14. package/dist/{chunk-IAUAQJQ2.js → chunk-5K2ZLUO5.js} +5 -5
  15. package/dist/{chunk-IAUAQJQ2.js.map → chunk-5K2ZLUO5.js.map} +1 -1
  16. package/dist/{chunk-ACNBKXXJ.js → chunk-5KXUDHAB.js} +8 -36
  17. package/dist/chunk-5KXUDHAB.js.map +1 -0
  18. package/dist/chunk-7SLV7CMF.js +615 -0
  19. package/dist/chunk-7SLV7CMF.js.map +1 -0
  20. package/dist/{chunk-CDX4W4DM.js → chunk-A46TPNBJ.js} +61 -32
  21. package/dist/chunk-A46TPNBJ.js.map +1 -0
  22. package/dist/{chunk-TKFPKEV3.js → chunk-AL74GBW4.js} +1 -1
  23. package/dist/chunk-AL74GBW4.js.map +1 -0
  24. package/dist/chunk-BQX23RBV.js +191 -0
  25. package/dist/chunk-BQX23RBV.js.map +1 -0
  26. package/dist/{chunk-IMDW5ZUP.js → chunk-CA4LH4LI.js} +5 -5
  27. package/dist/chunk-CA4LH4LI.js.map +1 -0
  28. package/dist/{chunk-D237EVNB.js → chunk-CBLPAMZO.js} +5 -8
  29. package/dist/chunk-CBLPAMZO.js.map +1 -0
  30. package/dist/{chunk-B7CCVP6Q.js → chunk-CKPQHGXR.js} +52 -274
  31. package/dist/chunk-CKPQHGXR.js.map +1 -0
  32. package/dist/{chunk-SVYPSDWY.js → chunk-CXOFOJCN.js} +6 -10
  33. package/dist/chunk-CXOFOJCN.js.map +1 -0
  34. package/dist/{chunk-UQTEPWU7.js → chunk-EHGD7HIE.js} +2 -6
  35. package/dist/chunk-EHGD7HIE.js.map +1 -0
  36. package/dist/{chunk-76DWXGQE.js → chunk-FJFEKPXF.js} +1 -1
  37. package/dist/chunk-FJFEKPXF.js.map +1 -0
  38. package/dist/{chunk-E3FJH4TF.js → chunk-HEOHU5EZ.js} +2 -13
  39. package/dist/chunk-HEOHU5EZ.js.map +1 -0
  40. package/dist/{chunk-JIPWV2FX.js → chunk-HGCBZUH5.js} +6 -27
  41. package/dist/chunk-HGCBZUH5.js.map +1 -0
  42. package/dist/{chunk-ED4E6Q2T.js → chunk-HPGFY5ZN.js} +4 -4
  43. package/dist/chunk-HPGFY5ZN.js.map +1 -0
  44. package/dist/chunk-INJ2EFRW.js +127 -0
  45. package/dist/chunk-INJ2EFRW.js.map +1 -0
  46. package/dist/{chunk-KAAEN2PO.js → chunk-IOBFMF6X.js} +6 -2
  47. package/dist/{chunk-KAAEN2PO.js.map → chunk-IOBFMF6X.js.map} +1 -1
  48. package/dist/{chunk-K7EVM5LY.js → chunk-KH3HA7J7.js} +8 -33
  49. package/dist/chunk-KH3HA7J7.js.map +1 -0
  50. package/dist/{chunk-4K4ZXQRM.js → chunk-N6JNE326.js} +38 -94
  51. package/dist/chunk-N6JNE326.js.map +1 -0
  52. package/dist/chunk-NAGU7TVZ.js +36 -0
  53. package/dist/chunk-NAGU7TVZ.js.map +1 -0
  54. package/dist/{chunk-Z7G4B5HJ.js → chunk-OQYYMQJR.js} +68 -142
  55. package/dist/chunk-OQYYMQJR.js.map +1 -0
  56. package/dist/{chunk-RFTSZDHV.js → chunk-PLZOUVDD.js} +159 -53
  57. package/dist/chunk-PLZOUVDD.js.map +1 -0
  58. package/dist/chunk-Q3J43SF3.js +21 -0
  59. package/dist/chunk-Q3J43SF3.js.map +1 -0
  60. package/dist/{chunk-3U3R4NCG.js → chunk-T25OEQFI.js} +6 -2
  61. package/dist/chunk-T25OEQFI.js.map +1 -0
  62. package/dist/chunk-UMORK7OK.js +29 -0
  63. package/dist/chunk-UMORK7OK.js.map +1 -0
  64. package/dist/{chunk-ZFPSUQOU.js → chunk-VFHWU7JU.js} +12 -121
  65. package/dist/chunk-VFHWU7JU.js.map +1 -0
  66. package/dist/{chunk-GDH553MV.js → chunk-VS4GVTZE.js} +3 -3
  67. package/dist/chunk-VS4GVTZE.js.map +1 -0
  68. package/dist/chunk-WFEFICFM.js +67 -0
  69. package/dist/chunk-WFEFICFM.js.map +1 -0
  70. package/dist/{chunk-P26A2K5N.js → chunk-WG6KIAPK.js} +6 -16
  71. package/dist/chunk-WG6KIAPK.js.map +1 -0
  72. package/dist/{chunk-X6QONICW.js → chunk-ZEI3ZUDU.js} +3 -7
  73. package/dist/chunk-ZEI3ZUDU.js.map +1 -0
  74. package/dist/chunk-ZNIDWLL5.js +68 -0
  75. package/dist/chunk-ZNIDWLL5.js.map +1 -0
  76. package/dist/chunk-ZSVMS677.js +45 -0
  77. package/dist/chunk-ZSVMS677.js.map +1 -0
  78. package/dist/cli/defaults/agent-mappings.yaml +13 -13
  79. package/dist/commands/build/marketplace.js +8 -14
  80. package/dist/commands/build/marketplace.js.map +1 -1
  81. package/dist/commands/build/plugins.js +10 -21
  82. package/dist/commands/build/plugins.js.map +1 -1
  83. package/dist/commands/build/stack.js +13 -18
  84. package/dist/commands/build/stack.js.map +1 -1
  85. package/dist/commands/compile.js +25 -40
  86. package/dist/commands/compile.js.map +1 -1
  87. package/dist/commands/config/get.js +7 -7
  88. package/dist/commands/config/get.js.map +1 -1
  89. package/dist/commands/config/index.js +6 -6
  90. package/dist/commands/config/index.js.map +1 -1
  91. package/dist/commands/config/path.js +5 -7
  92. package/dist/commands/config/path.js.map +1 -1
  93. package/dist/commands/config/set-project.js +8 -9
  94. package/dist/commands/config/set-project.js.map +1 -1
  95. package/dist/commands/config/show.js +5 -5
  96. package/dist/commands/config/unset-project.js +8 -9
  97. package/dist/commands/config/unset-project.js.map +1 -1
  98. package/dist/commands/diff.js +17 -40
  99. package/dist/commands/diff.js.map +1 -1
  100. package/dist/commands/doctor.js +14 -25
  101. package/dist/commands/doctor.js.map +1 -1
  102. package/dist/commands/edit.js +41 -54
  103. package/dist/commands/edit.js.map +1 -1
  104. package/dist/commands/eject.js +24 -44
  105. package/dist/commands/eject.js.map +1 -1
  106. package/dist/commands/import/skill.js +19 -39
  107. package/dist/commands/import/skill.js.map +1 -1
  108. package/dist/commands/info.js +10 -15
  109. package/dist/commands/info.js.map +1 -1
  110. package/dist/commands/init.js +452 -451
  111. package/dist/commands/init.js.map +1 -1
  112. package/dist/commands/list.js +85 -9
  113. package/dist/commands/list.js.map +1 -1
  114. package/dist/commands/new/agent.js +9 -10
  115. package/dist/commands/new/agent.js.map +1 -1
  116. package/dist/commands/new/skill.js +12 -16
  117. package/dist/commands/new/skill.js.map +1 -1
  118. package/dist/commands/outdated.js +12 -89
  119. package/dist/commands/outdated.js.map +1 -1
  120. package/dist/commands/search.js +12 -18
  121. package/dist/commands/search.js.map +1 -1
  122. package/dist/commands/uninstall.js +12 -21
  123. package/dist/commands/uninstall.js.map +1 -1
  124. package/dist/commands/update.js +26 -146
  125. package/dist/commands/update.js.map +1 -1
  126. package/dist/commands/validate.js +407 -15
  127. package/dist/commands/validate.js.map +1 -1
  128. package/dist/commands/version/bump.js +7 -23
  129. package/dist/commands/version/bump.js.map +1 -1
  130. package/dist/commands/version/index.js +6 -21
  131. package/dist/commands/version/index.js.map +1 -1
  132. package/dist/commands/version/set.js +6 -23
  133. package/dist/commands/version/set.js.map +1 -1
  134. package/dist/commands/version/show.js +6 -21
  135. package/dist/commands/version/show.js.map +1 -1
  136. package/dist/components/common/message.js +2 -6
  137. package/dist/components/common/message.js.map +1 -1
  138. package/dist/components/common/spinner.js.map +1 -1
  139. package/dist/components/skill-search/skill-search.js +1 -1
  140. package/dist/components/wizard/category-grid.js +1 -1
  141. package/dist/components/wizard/category-grid.test.js +20 -92
  142. package/dist/components/wizard/category-grid.test.js.map +1 -1
  143. package/dist/components/wizard/menu-item.js +9 -0
  144. package/dist/components/wizard/section-progress.js +1 -1
  145. package/dist/components/wizard/section-progress.test.js +13 -103
  146. package/dist/components/wizard/section-progress.test.js.map +1 -1
  147. package/dist/components/wizard/step-approach.js +5 -4
  148. package/dist/components/wizard/step-build.js +3 -4
  149. package/dist/components/wizard/step-build.test.js +81 -186
  150. package/dist/components/wizard/step-build.test.js.map +1 -1
  151. package/dist/components/wizard/step-confirm.js +1 -2
  152. package/dist/components/wizard/step-refine.js +1 -2
  153. package/dist/components/wizard/step-refine.test.js +6 -14
  154. package/dist/components/wizard/step-refine.test.js.map +1 -1
  155. package/dist/components/wizard/step-stack.js +5 -3
  156. package/dist/components/wizard/view-title.js +9 -0
  157. package/dist/components/wizard/wizard-layout.js +16 -0
  158. package/dist/components/wizard/wizard-layout.js.map +1 -0
  159. package/dist/components/wizard/wizard-tabs.js +1 -1
  160. package/dist/components/wizard/wizard.js +12 -13
  161. package/dist/config/skills-matrix.yaml +180 -113
  162. package/dist/config/stacks.yaml +6 -6
  163. package/dist/hooks/init.js +5 -7
  164. package/dist/hooks/init.js.map +1 -1
  165. package/dist/src/agents/developer/web-developer/examples.md +1 -6
  166. package/dist/src/agents/meta/documentor/workflow.md +1 -5
  167. package/dist/src/agents/migration/cli-migrator/anti-patterns.md +1 -3
  168. package/dist/src/agents/tester/web-tester/output-format.md +1 -3
  169. package/dist/stores/wizard-store.js +2 -2
  170. package/dist/stores/wizard-store.test.js +60 -23
  171. package/dist/stores/wizard-store.test.js.map +1 -1
  172. package/package.json +1 -1
  173. package/src/agents/developer/web-developer/examples.md +1 -6
  174. package/src/agents/meta/documentor/workflow.md +1 -5
  175. package/src/agents/migration/cli-migrator/anti-patterns.md +1 -3
  176. package/src/agents/tester/web-tester/output-format.md +1 -3
  177. package/dist/chunk-3U3R4NCG.js.map +0 -1
  178. package/dist/chunk-4K4ZXQRM.js.map +0 -1
  179. package/dist/chunk-76DWXGQE.js.map +0 -1
  180. package/dist/chunk-7Q44DMSP.js.map +0 -1
  181. package/dist/chunk-ACNBKXXJ.js.map +0 -1
  182. package/dist/chunk-B7CCVP6Q.js.map +0 -1
  183. package/dist/chunk-BDLUZVKU.js +0 -54
  184. package/dist/chunk-BDLUZVKU.js.map +0 -1
  185. package/dist/chunk-CDX4W4DM.js.map +0 -1
  186. package/dist/chunk-D237EVNB.js.map +0 -1
  187. package/dist/chunk-DRXPNNPB.js +0 -393
  188. package/dist/chunk-DRXPNNPB.js.map +0 -1
  189. package/dist/chunk-E3FJH4TF.js.map +0 -1
  190. package/dist/chunk-ED4E6Q2T.js.map +0 -1
  191. package/dist/chunk-GDH553MV.js.map +0 -1
  192. package/dist/chunk-HLJX2FTL.js +0 -95
  193. package/dist/chunk-HLJX2FTL.js.map +0 -1
  194. package/dist/chunk-I2DSLOXZ.js +0 -75
  195. package/dist/chunk-I2DSLOXZ.js.map +0 -1
  196. package/dist/chunk-I4TPKIYX.js +0 -493
  197. package/dist/chunk-I4TPKIYX.js.map +0 -1
  198. package/dist/chunk-IBE7JIAG.js +0 -129
  199. package/dist/chunk-IBE7JIAG.js.map +0 -1
  200. package/dist/chunk-IMDW5ZUP.js.map +0 -1
  201. package/dist/chunk-JIPWV2FX.js.map +0 -1
  202. package/dist/chunk-K3NB6DSG.js.map +0 -1
  203. package/dist/chunk-K7EVM5LY.js.map +0 -1
  204. package/dist/chunk-NDY25DTL.js +0 -453
  205. package/dist/chunk-NDY25DTL.js.map +0 -1
  206. package/dist/chunk-P26A2K5N.js.map +0 -1
  207. package/dist/chunk-RFTSZDHV.js.map +0 -1
  208. package/dist/chunk-SVYPSDWY.js.map +0 -1
  209. package/dist/chunk-TKFPKEV3.js.map +0 -1
  210. package/dist/chunk-UQTEPWU7.js.map +0 -1
  211. package/dist/chunk-V46GGCCI.js.map +0 -1
  212. package/dist/chunk-X6QONICW.js.map +0 -1
  213. package/dist/chunk-Y2LW7R3Y.js +0 -23
  214. package/dist/chunk-Y2LW7R3Y.js.map +0 -1
  215. package/dist/chunk-Z7G4B5HJ.js.map +0 -1
  216. package/dist/chunk-ZENYS6KW.js +0 -90
  217. package/dist/chunk-ZENYS6KW.js.map +0 -1
  218. package/dist/chunk-ZFPSUQOU.js.map +0 -1
  219. package/dist/commands/config/set.js +0 -61
  220. package/dist/commands/config/set.js.map +0 -1
  221. package/dist/commands/config/unset.js +0 -57
  222. package/dist/commands/config/unset.js.map +0 -1
  223. package/dist/commands/test-imports.js +0 -92
  224. package/dist/commands/test-imports.js.map +0 -1
  225. package/dist/components/wizard/step-stack-options.js +0 -11
  226. package/dist/components/wizard/wizard-footer.js +0 -9
  227. /package/dist/components/wizard/{step-stack-options.js.map → menu-item.js.map} +0 -0
  228. /package/dist/components/wizard/{wizard-footer.js.map → view-title.js.map} +0 -0
@@ -4,51 +4,54 @@ import {
4
4
  claudePluginMarketplaceAdd,
5
5
  claudePluginMarketplaceExists,
6
6
  isClaudeCLIAvailable
7
- } from "../chunk-UQTEPWU7.js";
7
+ } from "../chunk-EHGD7HIE.js";
8
8
  import {
9
9
  Wizard
10
- } from "../chunk-K3NB6DSG.js";
11
- import "../chunk-E3FJH4TF.js";
12
- import "../chunk-HLJX2FTL.js";
13
- import "../chunk-CDX4W4DM.js";
14
- import "../chunk-I2DSLOXZ.js";
15
- import "../chunk-ZENYS6KW.js";
16
- import "../chunk-7Q44DMSP.js";
17
- import "../chunk-Z7G4B5HJ.js";
18
- import "../chunk-BDLUZVKU.js";
19
- import "../chunk-X6QONICW.js";
20
- import "../chunk-Y2LW7R3Y.js";
21
- import "../chunk-D237EVNB.js";
10
+ } from "../chunk-2LSGX6R4.js";
11
+ import "../chunk-A46TPNBJ.js";
12
+ import "../chunk-3EHUF54X.js";
13
+ import "../chunk-ZNIDWLL5.js";
14
+ import "../chunk-WFEFICFM.js";
15
+ import "../chunk-3XR4PALU.js";
16
+ import "../chunk-Q3J43SF3.js";
17
+ import "../chunk-ZEI3ZUDU.js";
18
+ import "../chunk-OQYYMQJR.js";
19
+ import "../chunk-UMORK7OK.js";
22
20
  import "../chunk-Z2CWURZ6.js";
21
+ import "../chunk-CBLPAMZO.js";
23
22
  import {
24
23
  compileAgentForPlugin,
25
- compileStackPlugin
26
- } from "../chunk-DRXPNNPB.js";
27
- import "../chunk-GDH553MV.js";
28
- import {
24
+ compileStackPlugin,
29
25
  createLiquidEngine,
30
26
  resolveAgentSkillsFromStack,
31
27
  resolveAgents,
32
28
  resolveStackSkills
33
- } from "../chunk-I4TPKIYX.js";
29
+ } from "../chunk-7SLV7CMF.js";
30
+ import "../chunk-VS4GVTZE.js";
34
31
  import {
35
32
  getCollectivePluginDir
36
- } from "../chunk-ED4E6Q2T.js";
33
+ } from "../chunk-HPGFY5ZN.js";
37
34
  import {
38
35
  loadProjectConfig as loadProjectConfig2
39
- } from "../chunk-ZFPSUQOU.js";
36
+ } from "../chunk-VFHWU7JU.js";
37
+ import {
38
+ saveSourceToProjectConfig
39
+ } from "../chunk-NAGU7TVZ.js";
40
40
  import {
41
41
  copySkillsToLocalFlattened
42
- } from "../chunk-K7EVM5LY.js";
43
- import "../chunk-KAAEN2PO.js";
42
+ } from "../chunk-KH3HA7J7.js";
43
+ import "../chunk-INJ2EFRW.js";
44
+ import "../chunk-IOBFMF6X.js";
44
45
  import {
45
46
  loadSkillsMatrixFromSource
46
- } from "../chunk-RFTSZDHV.js";
47
+ } from "../chunk-PLZOUVDD.js";
47
48
  import {
48
- loadAllAgents,
49
49
  loadStackById
50
- } from "../chunk-B7CCVP6Q.js";
51
- import "../chunk-IMDW5ZUP.js";
50
+ } from "../chunk-CKPQHGXR.js";
51
+ import "../chunk-CA4LH4LI.js";
52
+ import {
53
+ loadAllAgents
54
+ } from "../chunk-BQX23RBV.js";
52
55
  import {
53
56
  BaseCommand,
54
57
  EXIT_CODES
@@ -56,10 +59,10 @@ import {
56
59
  import {
57
60
  formatSourceOrigin,
58
61
  loadProjectConfig
59
- } from "../chunk-V46GGCCI.js";
62
+ } from "../chunk-374JNMR6.js";
60
63
  import {
61
64
  verbose
62
- } from "../chunk-3U3R4NCG.js";
65
+ } from "../chunk-T25OEQFI.js";
63
66
  import {
64
67
  directoryExists,
65
68
  ensureDir,
@@ -67,13 +70,13 @@ import {
67
70
  readFile,
68
71
  remove,
69
72
  writeFile
70
- } from "../chunk-TKFPKEV3.js";
73
+ } from "../chunk-AL74GBW4.js";
71
74
  import {
72
75
  CLAUDE_DIR,
73
76
  CLAUDE_SRC_DIR,
74
77
  LOCAL_SKILLS_PATH,
75
78
  PROJECT_ROOT
76
- } from "../chunk-76DWXGQE.js";
79
+ } from "../chunk-FJFEKPXF.js";
77
80
  import {
78
81
  init_esm_shims
79
82
  } from "../chunk-DHET7RCE.js";
@@ -82,146 +85,97 @@ import {
82
85
  init_esm_shims();
83
86
  import { Flags } from "@oclif/core";
84
87
  import { render } from "ink";
85
- import path3 from "path";
86
- import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
88
+ import path4 from "path";
87
89
 
88
- // src/cli/lib/permission-checker.tsx
90
+ // src/cli/lib/local-installer.ts
89
91
  init_esm_shims();
90
92
  import path from "path";
91
- import { Text, Box } from "ink";
92
- import { jsx, jsxs } from "react/jsx-runtime";
93
- async function checkPermissions(projectRoot) {
94
- const settingsPath = path.join(projectRoot, ".claude", "settings.json");
95
- const localSettingsPath = path.join(
96
- projectRoot,
97
- ".claude",
98
- "settings.local.json"
99
- );
100
- let permissions;
101
- for (const filePath of [localSettingsPath, settingsPath]) {
102
- if (await fileExists(filePath)) {
103
- try {
104
- const content = await readFile(filePath);
105
- const parsed = JSON.parse(content);
106
- if (parsed.permissions) {
107
- permissions = parsed.permissions;
108
- break;
109
- }
110
- } catch {
111
- }
112
- }
113
- }
114
- if (!permissions) {
115
- return /* @__PURE__ */ jsxs(
116
- Box,
117
- {
118
- flexDirection: "column",
119
- borderStyle: "round",
120
- borderColor: "yellow",
121
- padding: 1,
122
- children: [
123
- /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "Permission Notice" }),
124
- /* @__PURE__ */ jsx(Text, { children: "No permissions configured in .claude/settings.json" }),
125
- /* @__PURE__ */ jsx(Text, { children: "Agents will prompt for approval on each tool use." }),
126
- /* @__PURE__ */ jsx(Text, { children: " " }),
127
- /* @__PURE__ */ jsx(Text, { children: "For autonomous operation, add to .claude/settings.json:" }),
128
- /* @__PURE__ */ jsx(Text, { children: " " }),
129
- /* @__PURE__ */ jsx(Text, { color: "dim", children: "{" }),
130
- /* @__PURE__ */ jsx(Text, { color: "dim", children: ' "permissions": {' }),
131
- /* @__PURE__ */ jsx(Text, { color: "dim", children: ' "allow": [' }),
132
- /* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Read(*)",' }),
133
- /* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Bash(git *)",' }),
134
- /* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Bash(bun *)"' }),
135
- /* @__PURE__ */ jsx(Text, { color: "dim", children: " ]" }),
136
- /* @__PURE__ */ jsx(Text, { color: "dim", children: " }" }),
137
- /* @__PURE__ */ jsx(Text, { color: "dim", children: "}" })
138
- ]
139
- }
140
- );
141
- }
142
- const hasRestrictiveBash = permissions.deny?.some(
143
- (rule) => rule === "Bash(*)" || rule === "Bash"
144
- );
145
- const hasNoAllows = !permissions.allow || permissions.allow.length === 0;
146
- if (hasRestrictiveBash || hasNoAllows) {
147
- return /* @__PURE__ */ jsxs(
148
- Box,
149
- {
150
- flexDirection: "column",
151
- borderStyle: "round",
152
- borderColor: "yellow",
153
- padding: 1,
154
- children: [
155
- /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "Permission Warnings" }),
156
- hasRestrictiveBash && /* @__PURE__ */ jsx(Text, { children: "\u26A0 Bash is denied in permissions. Some agents require Bash for git, testing, and build commands." }),
157
- hasNoAllows && /* @__PURE__ */ jsx(Text, { children: "\u26A0 No allow rules configured. Agents will prompt for each tool use." })
158
- ]
159
- }
160
- );
161
- }
162
- return null;
163
- }
93
+ import { stringify as stringifyYaml } from "yaml";
164
94
 
165
- // src/cli/lib/stack-installer.ts
95
+ // src/cli/lib/config-merger.ts
166
96
  init_esm_shims();
167
- import os from "os";
168
- import path2 from "path";
169
- async function compileStackToTemp(options) {
170
- const tempDir = path2.join(os.tmpdir(), `cc-stack-${Date.now()}`);
171
- await ensureDir(tempDir);
172
- const result = await compileStackPlugin({
173
- stackId: options.stackId,
174
- outputDir: tempDir,
175
- projectRoot: options.projectRoot,
176
- agentSourcePath: options.agentSourcePath
177
- });
178
- return {
179
- result,
180
- cleanup: async () => {
181
- await remove(tempDir);
97
+ async function mergeWithExistingConfig(newConfig, context) {
98
+ const localConfig = { ...newConfig };
99
+ const existingFullConfig = await loadProjectConfig2(context.projectDir);
100
+ if (existingFullConfig) {
101
+ const existingConfig = existingFullConfig.config;
102
+ if (existingConfig.name) {
103
+ localConfig.name = existingConfig.name;
104
+ }
105
+ if (existingConfig.description) {
106
+ localConfig.description = existingConfig.description;
107
+ }
108
+ if (existingConfig.source) {
109
+ localConfig.source = existingConfig.source;
110
+ }
111
+ if (existingConfig.skills && existingConfig.skills.length > 0) {
112
+ const existingSkillIds = new Set(
113
+ existingConfig.skills.map((s) => typeof s === "string" ? s : s.id)
114
+ );
115
+ const newSkillIds = localConfig.skills?.filter(
116
+ (s) => !existingSkillIds.has(typeof s === "string" ? s : s.id)
117
+ ) || [];
118
+ localConfig.skills = [...existingConfig.skills, ...newSkillIds];
119
+ }
120
+ if (existingConfig.agents && existingConfig.agents.length > 0) {
121
+ const existingAgentIds = new Set(existingConfig.agents);
122
+ const newAgentIds = localConfig.agents.filter((a) => !existingAgentIds.has(a));
123
+ localConfig.agents = [...existingConfig.agents, ...newAgentIds];
124
+ }
125
+ if (existingConfig.stack) {
126
+ const mergedStack = { ...localConfig.stack };
127
+ for (const [agentId, agentConfig] of Object.entries(existingConfig.stack)) {
128
+ mergedStack[agentId] = { ...mergedStack[agentId], ...agentConfig };
129
+ }
130
+ localConfig.stack = mergedStack;
131
+ }
132
+ if (existingConfig.author) {
133
+ localConfig.author = existingConfig.author;
134
+ }
135
+ if (existingConfig.agents_source) {
136
+ localConfig.agents_source = existingConfig.agents_source;
137
+ }
138
+ if (existingConfig.marketplace) {
139
+ localConfig.marketplace = existingConfig.marketplace;
140
+ }
141
+ if (existingConfig.philosophy) {
142
+ localConfig.philosophy = existingConfig.philosophy;
143
+ }
144
+ if (existingConfig.framework) {
145
+ localConfig.framework = existingConfig.framework;
146
+ }
147
+ if (existingConfig.principles) {
148
+ localConfig.principles = existingConfig.principles;
149
+ }
150
+ if (existingConfig.tags) {
151
+ localConfig.tags = existingConfig.tags;
152
+ }
153
+ if (existingConfig.agent_skills) {
154
+ localConfig.agent_skills = existingConfig.agent_skills;
155
+ }
156
+ if (existingConfig.preload_patterns) {
157
+ localConfig.preload_patterns = existingConfig.preload_patterns;
158
+ }
159
+ if (existingConfig.custom_agents) {
160
+ localConfig.custom_agents = existingConfig.custom_agents;
161
+ }
162
+ if (existingConfig.hooks) {
163
+ localConfig.hooks = existingConfig.hooks;
182
164
  }
183
- };
184
- }
185
- async function installStackAsPlugin(options) {
186
- const { stackId, projectDir, sourcePath, agentSourcePath, marketplace } = options;
187
- const claudeAvailable = await isClaudeCLIAvailable();
188
- if (!claudeAvailable) {
189
- throw new Error(
190
- "Claude CLI not found. Please install Claude Code first: https://claude.ai/code"
191
- );
192
- }
193
- if (marketplace) {
194
- verbose(`Installing from marketplace: ${stackId}@${marketplace}`);
195
- const pluginRef = `${stackId}@${marketplace}`;
196
- await claudePluginInstall(pluginRef, "project", projectDir);
197
165
  return {
198
- pluginName: stackId,
199
- stackName: stackId,
200
- agents: [],
201
- skills: [],
202
- pluginPath: pluginRef,
203
- fromMarketplace: true
166
+ config: localConfig,
167
+ merged: true,
168
+ existingConfigPath: existingFullConfig.configPath
204
169
  };
205
170
  }
206
- verbose(`Compiling stack locally: ${stackId}`);
207
- const { result, cleanup } = await compileStackToTemp({
208
- stackId,
209
- projectRoot: sourcePath,
210
- agentSourcePath
211
- });
212
- try {
213
- await claudePluginInstall(result.pluginPath, "project", projectDir);
214
- return {
215
- pluginName: `stack-${stackId}`,
216
- stackName: result.stackName,
217
- agents: result.agents,
218
- skills: result.skillPlugins,
219
- pluginPath: result.pluginPath,
220
- fromMarketplace: false
221
- };
222
- } finally {
223
- await cleanup();
171
+ const existingProjectConfig = await loadProjectConfig(context.projectDir);
172
+ if (existingProjectConfig?.author) {
173
+ localConfig.author = existingProjectConfig.author;
174
+ }
175
+ if (existingProjectConfig?.agents_source) {
176
+ localConfig.agents_source = existingProjectConfig.agents_source;
224
177
  }
178
+ return { config: localConfig, merged: false };
225
179
  }
226
180
 
227
181
  // src/cli/lib/config-generator.ts
@@ -240,7 +194,7 @@ function getCachedDefaults() {
240
194
 
241
195
  // src/cli/lib/skill-agent-mappings.ts
242
196
  var SKILL_TO_AGENTS = {
243
- "frontend/*": [
197
+ "web/*": [
244
198
  "web-developer",
245
199
  "web-reviewer",
246
200
  "web-researcher",
@@ -251,7 +205,7 @@ var SKILL_TO_AGENTS = {
251
205
  "skill-summoner",
252
206
  "documentor"
253
207
  ],
254
- "backend/*": [
208
+ "api/*": [
255
209
  "api-developer",
256
210
  "api-reviewer",
257
211
  "api-researcher",
@@ -272,7 +226,7 @@ var SKILL_TO_AGENTS = {
272
226
  "skill-summoner",
273
227
  "documentor"
274
228
  ],
275
- "setup/*": [
229
+ "infra/*": [
276
230
  "web-architecture",
277
231
  "web-developer",
278
232
  "api-developer",
@@ -338,9 +292,9 @@ var SKILL_TO_AGENTS = {
338
292
  "skill-summoner",
339
293
  "documentor"
340
294
  ],
341
- "frontend/testing": ["web-tester", "web-developer", "web-reviewer"],
342
- "backend/testing": ["web-tester", "api-developer", "api-reviewer"],
343
- "frontend/mocks": ["web-tester", "web-developer", "web-reviewer"]
295
+ "web/testing": ["web-tester", "web-developer", "web-reviewer"],
296
+ "api/testing": ["web-tester", "api-developer", "api-reviewer"],
297
+ "web/mocks": ["web-tester", "web-developer", "web-reviewer"]
344
298
  };
345
299
  var PRELOADED_SKILLS = {
346
300
  "web-developer": ["framework", "styling"],
@@ -361,15 +315,15 @@ var PRELOADED_SKILLS = {
361
315
  "skill-summoner": []
362
316
  };
363
317
  var SUBCATEGORY_ALIASES = {
364
- framework: "frontend/framework",
365
- styling: "frontend/styling",
366
- api: "backend/api",
367
- database: "backend/database",
368
- mocks: "frontend/mocks",
318
+ framework: "web/framework",
319
+ styling: "web/styling",
320
+ api: "api/api",
321
+ database: "api/database",
322
+ mocks: "web/mocks",
369
323
  testing: "testing",
370
324
  reviewing: "reviewing",
371
325
  "research-methodology": "research/research-methodology",
372
- monorepo: "setup/monorepo",
326
+ monorepo: "infra/monorepo",
373
327
  cli: "cli"
374
328
  };
375
329
  var DEFAULT_AGENTS = ["agent-summoner", "skill-summoner", "documentor"];
@@ -487,11 +441,7 @@ function generateProjectConfigFromSkills(name, selectedSkillIds, matrix, options
487
441
  config.author = options.author;
488
442
  }
489
443
  if (options?.includeAgentSkills) {
490
- const agentSkills = buildAgentSkills(
491
- selectedSkillIds,
492
- matrix,
493
- neededAgents
494
- );
444
+ const agentSkills = buildAgentSkills(selectedSkillIds, matrix, neededAgents);
495
445
  if (Object.keys(agentSkills).length > 0) {
496
446
  config.agent_skills = agentSkills;
497
447
  }
@@ -513,12 +463,7 @@ function buildAgentSkills(selectedSkillIds, matrix, neededAgents) {
513
463
  if (!agentSkills[agentId]) {
514
464
  agentSkills[agentId] = [];
515
465
  }
516
- const isPreloaded = shouldPreloadSkill(
517
- skillPath,
518
- skillId,
519
- category,
520
- agentId
521
- );
466
+ const isPreloaded = shouldPreloadSkill(skillPath, skillId, category, agentId);
522
467
  if (isPreloaded) {
523
468
  agentSkills[agentId].push({ id: skillId, preloaded: true });
524
469
  } else {
@@ -535,9 +480,7 @@ function buildStackProperty(stack, skillAliases) {
535
480
  continue;
536
481
  }
537
482
  const resolvedMappings = {};
538
- for (const [subcategoryId, alias] of Object.entries(
539
- agentConfig
540
- )) {
483
+ for (const [subcategoryId, alias] of Object.entries(agentConfig)) {
541
484
  const skillId = skillAliases[alias];
542
485
  if (skillId) {
543
486
  resolvedMappings[subcategoryId] = skillId;
@@ -552,9 +495,291 @@ function buildStackProperty(stack, skillAliases) {
552
495
  return result;
553
496
  }
554
497
 
498
+ // src/cli/lib/local-installer.ts
499
+ var PLUGIN_NAME = "claude-collective";
500
+ var YAML_INDENT = 2;
501
+ var YAML_LINE_WIDTH = 120;
502
+ function buildLocalSkillsMap(copiedSkills, matrix) {
503
+ const localSkillsForResolution = {};
504
+ for (const copiedSkill of copiedSkills) {
505
+ const skill = matrix.skills[copiedSkill.skillId];
506
+ if (skill) {
507
+ localSkillsForResolution[copiedSkill.skillId] = {
508
+ id: copiedSkill.skillId,
509
+ name: skill.name,
510
+ description: skill.description || "",
511
+ canonicalId: copiedSkill.skillId,
512
+ path: copiedSkill.destPath,
513
+ content: ""
514
+ // Content not needed for skill references
515
+ };
516
+ }
517
+ }
518
+ return localSkillsForResolution;
519
+ }
520
+ async function buildLocalConfig(wizardResult, sourceResult, skillAliases) {
521
+ const loadedStack = wizardResult.selectedStackId ? await loadStackById(wizardResult.selectedStackId, PROJECT_ROOT) : null;
522
+ let localConfig;
523
+ if (wizardResult.selectedStackId) {
524
+ if (loadedStack) {
525
+ const agentIds = Object.keys(loadedStack.agents);
526
+ const stackProperty = buildStackProperty(loadedStack, skillAliases);
527
+ localConfig = {
528
+ name: PLUGIN_NAME,
529
+ installMode: wizardResult.installMode,
530
+ description: loadedStack.description,
531
+ skills: wizardResult.selectedSkills.map((id) => id),
532
+ agents: agentIds,
533
+ philosophy: loadedStack.philosophy,
534
+ stack: stackProperty
535
+ };
536
+ } else {
537
+ throw new Error(
538
+ `Stack '${wizardResult.selectedStackId}' not found in config/stacks.yaml. Available stacks are defined in the CLI's config/stacks.yaml file.`
539
+ );
540
+ }
541
+ } else {
542
+ localConfig = generateProjectConfigFromSkills(
543
+ PLUGIN_NAME,
544
+ wizardResult.selectedSkills,
545
+ sourceResult.matrix
546
+ );
547
+ }
548
+ return { config: localConfig, loadedStack };
549
+ }
550
+ function setConfigMetadata(config, wizardResult, sourceResult, sourceFlag) {
551
+ config.installMode = wizardResult.installMode;
552
+ if (sourceFlag) {
553
+ config.source = sourceFlag;
554
+ } else if (sourceResult.sourceConfig.source) {
555
+ config.source = sourceResult.sourceConfig.source;
556
+ }
557
+ if (sourceResult.marketplace) {
558
+ config.marketplace = sourceResult.marketplace;
559
+ }
560
+ }
561
+ function buildCompileAgents(config, agents, loadedStack, skillAliases, localSkills) {
562
+ const compileAgents = {};
563
+ for (const agentId of config.agents) {
564
+ if (agents[agentId]) {
565
+ if (loadedStack) {
566
+ const skillRefs = resolveAgentSkillsFromStack(agentId, loadedStack, skillAliases);
567
+ compileAgents[agentId] = { skills: skillRefs };
568
+ } else if (config.agent_skills?.[agentId]) {
569
+ const skillRefs = resolveStackSkills(config, agentId, localSkills);
570
+ compileAgents[agentId] = { skills: skillRefs };
571
+ } else {
572
+ compileAgents[agentId] = {};
573
+ }
574
+ }
575
+ }
576
+ return compileAgents;
577
+ }
578
+ async function compileAndWriteAgents(compileConfig, agents, localSkills, sourceResult, loadedStack, skillAliases, projectDir, agentsDir) {
579
+ const engine = await createLiquidEngine(projectDir);
580
+ const resolvedAgents = await resolveAgents(
581
+ agents,
582
+ localSkills,
583
+ compileConfig,
584
+ sourceResult.sourcePath,
585
+ loadedStack ?? void 0,
586
+ skillAliases
587
+ );
588
+ const compiledAgentNames = [];
589
+ for (const [name, agent] of Object.entries(resolvedAgents)) {
590
+ const output = await compileAgentForPlugin(name, agent, sourceResult.sourcePath, engine);
591
+ await writeFile(path.join(agentsDir, `${name}.md`), output);
592
+ compiledAgentNames.push(name);
593
+ }
594
+ return compiledAgentNames;
595
+ }
596
+ async function installLocal(options) {
597
+ const { wizardResult, sourceResult, projectDir, sourceFlag } = options;
598
+ const matrix = sourceResult.matrix;
599
+ const localSkillsDir = path.join(projectDir, LOCAL_SKILLS_PATH);
600
+ const localAgentsDir = path.join(projectDir, CLAUDE_DIR, "agents");
601
+ const localConfigPath = path.join(projectDir, CLAUDE_SRC_DIR, "config.yaml");
602
+ await ensureDir(localSkillsDir);
603
+ await ensureDir(localAgentsDir);
604
+ await ensureDir(path.dirname(localConfigPath));
605
+ const copiedSkills = await copySkillsToLocalFlattened(
606
+ wizardResult.selectedSkills,
607
+ localSkillsDir,
608
+ matrix,
609
+ sourceResult
610
+ );
611
+ const localSkillsForResolution = buildLocalSkillsMap(copiedSkills, matrix);
612
+ const skillAliases = matrix.aliases || {};
613
+ const cliAgents = await loadAllAgents(PROJECT_ROOT);
614
+ const localAgents = await loadAllAgents(sourceResult.sourcePath);
615
+ const agents = { ...cliAgents, ...localAgents };
616
+ const { config: builtConfig, loadedStack } = await buildLocalConfig(
617
+ wizardResult,
618
+ sourceResult,
619
+ skillAliases
620
+ );
621
+ setConfigMetadata(builtConfig, wizardResult, sourceResult, sourceFlag);
622
+ const mergeResult = await mergeWithExistingConfig(builtConfig, { projectDir });
623
+ const finalConfig = mergeResult.config;
624
+ const configYaml = stringifyYaml(finalConfig, {
625
+ indent: YAML_INDENT,
626
+ lineWidth: YAML_LINE_WIDTH
627
+ });
628
+ await writeFile(localConfigPath, configYaml);
629
+ const compileAgentsConfig = buildCompileAgents(
630
+ finalConfig,
631
+ agents,
632
+ loadedStack,
633
+ skillAliases,
634
+ localSkillsForResolution
635
+ );
636
+ const compileConfig = {
637
+ name: PLUGIN_NAME,
638
+ description: finalConfig.description || `Local setup with ${wizardResult.selectedSkills.length} skills`,
639
+ claude_md: "",
640
+ agents: compileAgentsConfig
641
+ };
642
+ const compiledAgentNames = await compileAndWriteAgents(
643
+ compileConfig,
644
+ agents,
645
+ localSkillsForResolution,
646
+ sourceResult,
647
+ loadedStack,
648
+ skillAliases,
649
+ projectDir,
650
+ localAgentsDir
651
+ );
652
+ return {
653
+ copiedSkills,
654
+ config: finalConfig,
655
+ configPath: localConfigPath,
656
+ compiledAgents: compiledAgentNames,
657
+ wasMerged: mergeResult.merged,
658
+ mergedConfigPath: mergeResult.existingConfigPath,
659
+ skillsDir: localSkillsDir,
660
+ agentsDir: localAgentsDir
661
+ };
662
+ }
663
+
664
+ // src/cli/lib/permission-checker.tsx
665
+ init_esm_shims();
666
+ import path2 from "path";
667
+ import { Text, Box } from "ink";
668
+ import { jsx, jsxs } from "react/jsx-runtime";
669
+ async function checkPermissions(projectRoot) {
670
+ const settingsPath = path2.join(projectRoot, ".claude", "settings.json");
671
+ const localSettingsPath = path2.join(projectRoot, ".claude", "settings.local.json");
672
+ let permissions;
673
+ for (const filePath of [localSettingsPath, settingsPath]) {
674
+ if (await fileExists(filePath)) {
675
+ try {
676
+ const content = await readFile(filePath);
677
+ const parsed = JSON.parse(content);
678
+ if (parsed.permissions) {
679
+ permissions = parsed.permissions;
680
+ break;
681
+ }
682
+ } catch {
683
+ }
684
+ }
685
+ }
686
+ if (!permissions) {
687
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", padding: 1, children: [
688
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "Permission Notice" }),
689
+ /* @__PURE__ */ jsx(Text, { children: "No permissions configured in .claude/settings.json" }),
690
+ /* @__PURE__ */ jsx(Text, { children: "Agents will prompt for approval on each tool use." }),
691
+ /* @__PURE__ */ jsx(Text, { children: " " }),
692
+ /* @__PURE__ */ jsx(Text, { children: "For autonomous operation, add to .claude/settings.json:" }),
693
+ /* @__PURE__ */ jsx(Text, { children: " " }),
694
+ /* @__PURE__ */ jsx(Text, { color: "dim", children: "{" }),
695
+ /* @__PURE__ */ jsx(Text, { color: "dim", children: ' "permissions": {' }),
696
+ /* @__PURE__ */ jsx(Text, { color: "dim", children: ' "allow": [' }),
697
+ /* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Read(*)",' }),
698
+ /* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Bash(git *)",' }),
699
+ /* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Bash(bun *)"' }),
700
+ /* @__PURE__ */ jsx(Text, { color: "dim", children: " ]" }),
701
+ /* @__PURE__ */ jsx(Text, { color: "dim", children: " }" }),
702
+ /* @__PURE__ */ jsx(Text, { color: "dim", children: "}" })
703
+ ] });
704
+ }
705
+ const hasRestrictiveBash = permissions.deny?.some(
706
+ (rule) => rule === "Bash(*)" || rule === "Bash"
707
+ );
708
+ const hasNoAllows = !permissions.allow || permissions.allow.length === 0;
709
+ if (hasRestrictiveBash || hasNoAllows) {
710
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", padding: 1, children: [
711
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "Permission Warnings" }),
712
+ hasRestrictiveBash && /* @__PURE__ */ jsx(Text, { children: "\u26A0 Bash is denied in permissions. Some agents require Bash for git, testing, and build commands." }),
713
+ hasNoAllows && /* @__PURE__ */ jsx(Text, { children: "\u26A0 No allow rules configured. Agents will prompt for each tool use." })
714
+ ] });
715
+ }
716
+ return null;
717
+ }
718
+
719
+ // src/cli/lib/stack-installer.ts
720
+ init_esm_shims();
721
+ import os from "os";
722
+ import path3 from "path";
723
+ async function compileStackToTemp(options) {
724
+ const tempDir = path3.join(os.tmpdir(), `cc-stack-${Date.now()}`);
725
+ await ensureDir(tempDir);
726
+ const result = await compileStackPlugin({
727
+ stackId: options.stackId,
728
+ outputDir: tempDir,
729
+ projectRoot: options.projectRoot,
730
+ agentSourcePath: options.agentSourcePath
731
+ });
732
+ return {
733
+ result,
734
+ cleanup: async () => {
735
+ await remove(tempDir);
736
+ }
737
+ };
738
+ }
739
+ async function installStackAsPlugin(options) {
740
+ const { stackId, projectDir, sourcePath, agentSourcePath, marketplace } = options;
741
+ const claudeAvailable = await isClaudeCLIAvailable();
742
+ if (!claudeAvailable) {
743
+ throw new Error(
744
+ "Claude CLI not found. Please install Claude Code first: https://claude.ai/code"
745
+ );
746
+ }
747
+ if (marketplace) {
748
+ verbose(`Installing from marketplace: ${stackId}@${marketplace}`);
749
+ const pluginRef = `${stackId}@${marketplace}`;
750
+ await claudePluginInstall(pluginRef, "project", projectDir);
751
+ return {
752
+ pluginName: stackId,
753
+ stackName: stackId,
754
+ agents: [],
755
+ skills: [],
756
+ pluginPath: pluginRef,
757
+ fromMarketplace: true
758
+ };
759
+ }
760
+ verbose(`Compiling stack locally: ${stackId}`);
761
+ const { result, cleanup } = await compileStackToTemp({
762
+ stackId,
763
+ projectRoot: sourcePath,
764
+ agentSourcePath
765
+ });
766
+ try {
767
+ await claudePluginInstall(result.pluginPath, "project", projectDir);
768
+ return {
769
+ pluginName: `stack-${stackId}`,
770
+ stackName: result.stackName,
771
+ agents: result.agents,
772
+ skills: result.skillPlugins,
773
+ pluginPath: result.pluginPath,
774
+ fromMarketplace: false
775
+ };
776
+ } finally {
777
+ await cleanup();
778
+ }
779
+ }
780
+
555
781
  // src/cli/commands/init.tsx
556
782
  import { jsx as jsx2 } from "react/jsx-runtime";
557
- var PLUGIN_NAME = "claude-collective";
558
783
  var Init = class _Init extends BaseCommand {
559
784
  static summary = "Initialize Claude Collective in this project";
560
785
  static description = "Interactive wizard to set up skills and agents. Supports Plugin Mode (native install) and Local Mode (copy to .claude/).";
@@ -568,7 +793,16 @@ var Init = class _Init extends BaseCommand {
568
793
  async run() {
569
794
  const { flags } = await this.parse(_Init);
570
795
  const projectDir = process.cwd();
571
- this.log("Claude Collective Setup\n");
796
+ this.log(
797
+ `
798
+ \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557
799
+ \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
800
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551
801
+ \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551
802
+ \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557
803
+ \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D
804
+ `
805
+ );
572
806
  if (flags["dry-run"]) {
573
807
  this.log("[dry-run] Preview mode - no files will be created\n");
574
808
  }
@@ -580,7 +814,6 @@ var Init = class _Init extends BaseCommand {
580
814
  this.log("No changes made.");
581
815
  return;
582
816
  }
583
- this.log("Loading skills matrix...");
584
817
  let sourceResult;
585
818
  try {
586
819
  sourceResult = await loadSkillsMatrixFromSource({
@@ -589,15 +822,10 @@ var Init = class _Init extends BaseCommand {
589
822
  forceRefresh: flags.refresh
590
823
  });
591
824
  const sourceInfo = sourceResult.isLocal ? "local" : formatSourceOrigin(sourceResult.sourceConfig.sourceOrigin);
592
- this.log(
593
- `Loaded ${Object.keys(sourceResult.matrix.skills).length} skills (${sourceInfo})
594
- `
595
- );
596
825
  } catch (error) {
597
- this.error(
598
- error instanceof Error ? error.message : "Unknown error occurred",
599
- { exit: EXIT_CODES.ERROR }
600
- );
826
+ this.error(error instanceof Error ? error.message : "Unknown error occurred", {
827
+ exit: EXIT_CODES.ERROR
828
+ });
601
829
  }
602
830
  let wizardResult = null;
603
831
  const { waitUntilExit } = render(
@@ -637,7 +865,6 @@ var Init = class _Init extends BaseCommand {
637
865
  this.log(
638
866
  `Install mode: ${result.installMode === "plugin" ? "Plugin (native install)" : "Local (copy to .claude/skills/)"}`
639
867
  );
640
- this.log("\n");
641
868
  if (dryRun) {
642
869
  if (result.installMode === "plugin" && result.selectedStackId) {
643
870
  const useMarketplace = !!sourceResult.marketplace;
@@ -661,13 +888,11 @@ var Init = class _Init extends BaseCommand {
661
888
  }
662
889
  } else {
663
890
  if (result.installMode === "plugin") {
664
- this.log(
665
- `[dry-run] Individual skill plugin installation not yet supported`
666
- );
891
+ this.log(`[dry-run] Individual skill plugin installation not yet supported`);
667
892
  this.log(`[dry-run] Would fall back to Local Mode...`);
668
893
  }
669
- const localSkillsDir = path3.join(projectDir, LOCAL_SKILLS_PATH);
670
- const localAgentsDir = path3.join(projectDir, CLAUDE_DIR, "agents");
894
+ const localSkillsDir = path4.join(projectDir, LOCAL_SKILLS_PATH);
895
+ const localAgentsDir = path4.join(projectDir, CLAUDE_DIR, "agents");
671
896
  this.log(
672
897
  `[dry-run] Would copy ${result.selectedSkills.length} skills to ${localSkillsDir}`
673
898
  );
@@ -682,13 +907,9 @@ var Init = class _Init extends BaseCommand {
682
907
  await this.installPluginMode(result, sourceResult, flags);
683
908
  return;
684
909
  } else {
685
- this.warn(
686
- "Individual skill plugin installation not yet supported in Plugin Mode."
687
- );
910
+ this.warn("Individual skill plugin installation not yet supported in Plugin Mode.");
688
911
  this.log(`Falling back to Local Mode (copying to .claude/skills/)...`);
689
- this.log(
690
- "To use Plugin Mode, select a pre-built stack instead of individual skills.\n"
691
- );
912
+ this.log("To use Plugin Mode, select a pre-built stack instead of individual skills.\n");
692
913
  }
693
914
  }
694
915
  await this.installLocalMode(result, sourceResult, flags);
@@ -702,9 +923,7 @@ var Init = class _Init extends BaseCommand {
702
923
  }
703
924
  const projectDir = process.cwd();
704
925
  if (sourceResult.marketplace) {
705
- const marketplaceExists = await claudePluginMarketplaceExists(
706
- sourceResult.marketplace
707
- );
926
+ const marketplaceExists = await claudePluginMarketplaceExists(sourceResult.marketplace);
708
927
  if (!marketplaceExists) {
709
928
  this.log(`Registering marketplace "${sourceResult.marketplace}"...`);
710
929
  try {
@@ -731,10 +950,8 @@ var Init = class _Init extends BaseCommand {
731
950
  marketplace: sourceResult.marketplace
732
951
  });
733
952
  const installedFrom = installResult.fromMarketplace ? `from marketplace` : `(compiled locally)`;
734
- this.log(
735
- `Installed stack plugin: ${installResult.pluginName} ${installedFrom}
736
- `
737
- );
953
+ this.log(`Installed stack plugin: ${installResult.pluginName} ${installedFrom}
954
+ `);
738
955
  this.log("Claude Collective initialized successfully!\n");
739
956
  this.log(`Stack "${installResult.stackName}" installed as plugin`);
740
957
  if (installResult.agents.length > 0) {
@@ -747,7 +964,8 @@ Skills bundled: ${installResult.skills.length}`);
747
964
  }
748
965
  this.log("");
749
966
  if (flags.source) {
750
- await this.saveSourceToProjectConfig(projectDir, flags.source);
967
+ await saveSourceToProjectConfig(projectDir, flags.source);
968
+ this.log(`Source saved to .claude-src/config.yaml`);
751
969
  }
752
970
  const permissionWarning = await checkPermissions(projectDir);
753
971
  if (permissionWarning) {
@@ -760,265 +978,48 @@ Skills bundled: ${installResult.skills.length}`);
760
978
  });
761
979
  }
762
980
  }
763
- /**
764
- * Save source to project-level .claude-src/config.yaml.
765
- */
766
- async saveSourceToProjectConfig(projectDir, source) {
767
- const configPath = path3.join(projectDir, CLAUDE_SRC_DIR, "config.yaml");
768
- let config = {};
769
- if (await fileExists(configPath)) {
770
- const content = await readFile(configPath);
771
- config = parseYaml2(content) || {};
772
- }
773
- config.source = source;
774
- await ensureDir(path3.join(projectDir, CLAUDE_SRC_DIR));
775
- const configYaml = stringifyYaml(config, { indent: 2 });
776
- await writeFile(configPath, configYaml);
777
- this.log(`Source saved to .claude-src/config.yaml`);
778
- }
779
981
  /**
780
982
  * Install in Local Mode: copy skills and compile agents to .claude/.
781
983
  */
782
984
  async installLocalMode(result, sourceResult, flags) {
783
985
  const projectDir = process.cwd();
784
986
  const matrix = sourceResult.matrix;
785
- const localSkillsDir = path3.join(projectDir, LOCAL_SKILLS_PATH);
786
- const localAgentsDir = path3.join(projectDir, CLAUDE_DIR, "agents");
787
- const localConfigPath = path3.join(
788
- projectDir,
789
- CLAUDE_SRC_DIR,
790
- "config.yaml"
791
- );
792
987
  this.log("Copying skills to local directory...");
793
988
  try {
794
- await ensureDir(localSkillsDir);
795
- await ensureDir(localAgentsDir);
796
- await ensureDir(path3.dirname(localConfigPath));
797
- const copiedSkills = await copySkillsToLocalFlattened(
798
- result.selectedSkills,
799
- localSkillsDir,
800
- matrix,
801
- sourceResult
802
- );
803
- this.log(`Copied ${copiedSkills.length} skills to .claude/skills/
989
+ const installResult = await installLocal({
990
+ wizardResult: result,
991
+ sourceResult,
992
+ projectDir,
993
+ sourceFlag: flags.source
994
+ });
995
+ this.log(`Copied ${installResult.copiedSkills.length} skills to .claude/skills/
804
996
  `);
805
997
  this.log("Generating configuration...");
806
- const cliAgents = await loadAllAgents(PROJECT_ROOT);
807
- const localAgents = await loadAllAgents(sourceResult.sourcePath);
808
- const agents = { ...cliAgents, ...localAgents };
809
- const localSkillsForResolution = {};
810
- for (const copiedSkill of copiedSkills) {
811
- const skill = matrix.skills[copiedSkill.skillId];
812
- if (skill) {
813
- localSkillsForResolution[copiedSkill.skillId] = {
814
- id: copiedSkill.skillId,
815
- name: skill.name,
816
- description: skill.description || "",
817
- canonicalId: copiedSkill.skillId,
818
- path: copiedSkill.destPath,
819
- content: ""
820
- // Content not needed for skill references
821
- };
822
- }
823
- }
824
- const skillAliases = matrix.aliases || {};
825
- let localConfig;
826
- const loadedStack = result.selectedStackId ? await loadStackById(result.selectedStackId, PROJECT_ROOT) : null;
827
- if (result.selectedStackId) {
828
- if (loadedStack) {
829
- const agentIds = Object.keys(loadedStack.agents);
830
- const stackProperty = buildStackProperty(loadedStack, skillAliases);
831
- localConfig = {
832
- name: PLUGIN_NAME,
833
- installMode: result.installMode,
834
- description: loadedStack.description,
835
- skills: result.selectedSkills.map((id) => id),
836
- agents: agentIds,
837
- philosophy: loadedStack.philosophy,
838
- stack: stackProperty
839
- };
840
- } else {
841
- throw new Error(
842
- `Stack '${result.selectedStackId}' not found in config/stacks.yaml. Available stacks are defined in the CLI's config/stacks.yaml file.`
843
- );
844
- }
845
- } else {
846
- localConfig = generateProjectConfigFromSkills(
847
- PLUGIN_NAME,
848
- result.selectedSkills,
849
- sourceResult.matrix
850
- );
851
- }
852
- localConfig.installMode = result.installMode;
853
- if (flags.source) {
854
- localConfig.source = flags.source;
855
- } else if (sourceResult.sourceConfig.source) {
856
- localConfig.source = sourceResult.sourceConfig.source;
998
+ if (installResult.wasMerged) {
999
+ this.log(`Merged with existing config at ${installResult.mergedConfigPath}`);
857
1000
  }
858
- if (sourceResult.marketplace) {
859
- localConfig.marketplace = sourceResult.marketplace;
860
- }
861
- const existingFullConfig = await loadProjectConfig2(projectDir);
862
- if (existingFullConfig) {
863
- const existingConfig = existingFullConfig.config;
864
- if (existingConfig.name) {
865
- localConfig.name = existingConfig.name;
866
- }
867
- if (existingConfig.description) {
868
- localConfig.description = existingConfig.description;
869
- }
870
- if (existingConfig.source) {
871
- localConfig.source = existingConfig.source;
872
- }
873
- if (existingConfig.skills && existingConfig.skills.length > 0) {
874
- const existingSkillIds = new Set(
875
- existingConfig.skills.map(
876
- (s) => typeof s === "string" ? s : s.id
877
- )
878
- );
879
- const newSkillIds = localConfig.skills?.filter(
880
- (s) => !existingSkillIds.has(typeof s === "string" ? s : s.id)
881
- ) || [];
882
- localConfig.skills = [...existingConfig.skills, ...newSkillIds];
883
- }
884
- if (existingConfig.agents && existingConfig.agents.length > 0) {
885
- const existingAgentIds = new Set(existingConfig.agents);
886
- const newAgentIds = localConfig.agents.filter(
887
- (a) => !existingAgentIds.has(a)
888
- );
889
- localConfig.agents = [...existingConfig.agents, ...newAgentIds];
890
- }
891
- if (existingConfig.stack) {
892
- const mergedStack = { ...localConfig.stack };
893
- for (const [agentId, agentConfig] of Object.entries(
894
- existingConfig.stack
895
- )) {
896
- mergedStack[agentId] = { ...mergedStack[agentId], ...agentConfig };
897
- }
898
- localConfig.stack = mergedStack;
899
- }
900
- if (existingConfig.author) {
901
- localConfig.author = existingConfig.author;
902
- }
903
- if (existingConfig.agents_source) {
904
- localConfig.agents_source = existingConfig.agents_source;
905
- }
906
- if (existingConfig.marketplace) {
907
- localConfig.marketplace = existingConfig.marketplace;
908
- }
909
- if (existingConfig.philosophy) {
910
- localConfig.philosophy = existingConfig.philosophy;
911
- }
912
- if (existingConfig.framework) {
913
- localConfig.framework = existingConfig.framework;
914
- }
915
- if (existingConfig.principles) {
916
- localConfig.principles = existingConfig.principles;
917
- }
918
- if (existingConfig.tags) {
919
- localConfig.tags = existingConfig.tags;
920
- }
921
- if (existingConfig.agent_skills) {
922
- localConfig.agent_skills = existingConfig.agent_skills;
923
- }
924
- if (existingConfig.preload_patterns) {
925
- localConfig.preload_patterns = existingConfig.preload_patterns;
926
- }
927
- if (existingConfig.custom_agents) {
928
- localConfig.custom_agents = existingConfig.custom_agents;
929
- }
930
- if (existingConfig.hooks) {
931
- localConfig.hooks = existingConfig.hooks;
932
- }
933
- this.log(
934
- `Merged with existing config at ${existingFullConfig.configPath}`
935
- );
936
- } else {
937
- const existingProjectConfig = await loadProjectConfig(projectDir);
938
- if (existingProjectConfig?.author) {
939
- localConfig.author = existingProjectConfig.author;
940
- }
941
- if (existingProjectConfig?.agents_source) {
942
- localConfig.agents_source = existingProjectConfig.agents_source;
943
- }
944
- }
945
- const configYaml = stringifyYaml(localConfig, {
946
- indent: 2,
947
- lineWidth: 120
948
- });
949
- await writeFile(localConfigPath, configYaml);
950
- this.log(`Configuration saved (${localConfig.agents.length} agents)
1001
+ this.log(`Configuration saved (${installResult.config.agents.length} agents)
951
1002
  `);
952
1003
  this.log("Compiling agents...");
953
- const compileAgents = {};
954
- for (const agentId of localConfig.agents) {
955
- if (agents[agentId]) {
956
- if (loadedStack) {
957
- const skillRefs = resolveAgentSkillsFromStack(
958
- agentId,
959
- loadedStack,
960
- skillAliases
961
- );
962
- compileAgents[agentId] = { skills: skillRefs };
963
- } else if (localConfig.agent_skills?.[agentId]) {
964
- const skillRefs = resolveStackSkills(
965
- localConfig,
966
- agentId,
967
- localSkillsForResolution
968
- );
969
- compileAgents[agentId] = { skills: skillRefs };
970
- } else {
971
- compileAgents[agentId] = {};
972
- }
973
- }
974
- }
975
- const compileConfig = {
976
- name: PLUGIN_NAME,
977
- description: localConfig.description || `Local setup with ${result.selectedSkills.length} skills`,
978
- claude_md: "",
979
- agents: compileAgents
980
- };
981
- const engine = await createLiquidEngine(projectDir);
982
- const resolvedAgents = await resolveAgents(
983
- agents,
984
- localSkillsForResolution,
985
- compileConfig,
986
- sourceResult.sourcePath,
987
- loadedStack ?? void 0,
988
- skillAliases
989
- );
990
- const compiledAgentNames = [];
991
- for (const [name, agent] of Object.entries(resolvedAgents)) {
992
- const output = await compileAgentForPlugin(
993
- name,
994
- agent,
995
- sourceResult.sourcePath,
996
- engine
997
- );
998
- await writeFile(path3.join(localAgentsDir, `${name}.md`), output);
999
- compiledAgentNames.push(name);
1000
- }
1001
- this.log(
1002
- `Compiled ${compiledAgentNames.length} agents to .claude/agents/
1003
- `
1004
- );
1004
+ this.log(`Compiled ${installResult.compiledAgents.length} agents to .claude/agents/
1005
+ `);
1005
1006
  this.log("Claude Collective initialized successfully!\n");
1006
1007
  this.log("Skills copied to:");
1007
- this.log(` ${localSkillsDir}`);
1008
- for (const copiedSkill of copiedSkills) {
1008
+ this.log(` ${installResult.skillsDir}`);
1009
+ for (const copiedSkill of installResult.copiedSkills) {
1009
1010
  const skill = matrix.skills[copiedSkill.skillId];
1010
1011
  const displayName = skill?.alias || copiedSkill.skillId;
1011
1012
  this.log(` ${displayName}/`);
1012
1013
  }
1013
1014
  this.log("");
1014
1015
  this.log("Agents compiled to:");
1015
- this.log(` ${localAgentsDir}`);
1016
- for (const agentName of compiledAgentNames) {
1016
+ this.log(` ${installResult.agentsDir}`);
1017
+ for (const agentName of installResult.compiledAgents) {
1017
1018
  this.log(` ${agentName}.md`);
1018
1019
  }
1019
1020
  this.log("");
1020
1021
  this.log("Configuration:");
1021
- this.log(` ${localConfigPath}`);
1022
+ this.log(` ${installResult.configPath}`);
1022
1023
  this.log("");
1023
1024
  this.log("To customize agent-skill assignments:");
1024
1025
  this.log(` 1. Edit .claude-src/config.yaml`);