@claude-collective/cli 0.26.1 → 0.29.4

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 (233) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/README.md +47 -13
  3. package/config/stacks.yaml +330 -93
  4. package/dist/chunk-56ERY7H7.js +29 -0
  5. package/dist/chunk-56ERY7H7.js.map +1 -0
  6. package/dist/{chunk-OBXAY23Y.js → chunk-5I6VY2E7.js} +5 -5
  7. package/dist/chunk-5I6VY2E7.js.map +1 -0
  8. package/dist/{chunk-324DM2L6.js → chunk-5WIHSJRO.js} +230 -65
  9. package/dist/chunk-5WIHSJRO.js.map +1 -0
  10. package/dist/{chunk-GGFOD5PK.js → chunk-6F3ZKDVE.js} +122 -66
  11. package/dist/chunk-6F3ZKDVE.js.map +1 -0
  12. package/dist/{chunk-DBRUQQUF.js → chunk-7GHTQSWI.js} +5 -1
  13. package/dist/{chunk-DBRUQQUF.js.map → chunk-7GHTQSWI.js.map} +1 -1
  14. package/dist/chunk-7ICBJZV2.js +63 -0
  15. package/dist/chunk-7ICBJZV2.js.map +1 -0
  16. package/dist/{chunk-3X5D7RM5.js → chunk-7UKQZSWT.js} +15 -4
  17. package/dist/chunk-7UKQZSWT.js.map +1 -0
  18. package/dist/{chunk-F4RD5FYM.js → chunk-A4T4YSV4.js} +5 -2
  19. package/dist/chunk-A4T4YSV4.js.map +1 -0
  20. package/dist/{chunk-VVYNZZUX.js → chunk-AG5YGYJT.js} +9 -5
  21. package/dist/chunk-AG5YGYJT.js.map +1 -0
  22. package/dist/chunk-AJFSCLJ7.js +81 -0
  23. package/dist/chunk-AJFSCLJ7.js.map +1 -0
  24. package/dist/{chunk-NQJ47R4N.js → chunk-CQZAKMPJ.js} +66 -14
  25. package/dist/chunk-CQZAKMPJ.js.map +1 -0
  26. package/dist/chunk-DIRH4PDF.js +24 -0
  27. package/dist/chunk-DIRH4PDF.js.map +1 -0
  28. package/dist/{chunk-HIQGK5XJ.js → chunk-DUIYVKFK.js} +123 -86
  29. package/dist/chunk-DUIYVKFK.js.map +1 -0
  30. package/dist/chunk-EP6J44I4.js +142 -0
  31. package/dist/chunk-EP6J44I4.js.map +1 -0
  32. package/dist/{chunk-2YMMJP4Z.js → chunk-EUPMWSM3.js} +92 -29
  33. package/dist/chunk-EUPMWSM3.js.map +1 -0
  34. package/dist/chunk-FUPBGSRA.js +66 -0
  35. package/dist/chunk-FUPBGSRA.js.map +1 -0
  36. package/dist/{chunk-U7HFKR74.js → chunk-FY5D4KIC.js} +5 -2
  37. package/dist/chunk-FY5D4KIC.js.map +1 -0
  38. package/dist/chunk-G5WXKKQM.js +233 -0
  39. package/dist/chunk-G5WXKKQM.js.map +1 -0
  40. package/dist/{chunk-KWYO3M5Q.js → chunk-GVVEPVR7.js} +25 -24
  41. package/dist/chunk-GVVEPVR7.js.map +1 -0
  42. package/dist/chunk-IFODQTCX.js +162 -0
  43. package/dist/chunk-IFODQTCX.js.map +1 -0
  44. package/dist/chunk-IQUBOWWU.js +366 -0
  45. package/dist/chunk-IQUBOWWU.js.map +1 -0
  46. package/dist/{chunk-ETCVEV3S.js → chunk-IRG52AN5.js} +242 -155
  47. package/dist/chunk-IRG52AN5.js.map +1 -0
  48. package/dist/chunk-MQAYAISQ.js +88 -0
  49. package/dist/chunk-MQAYAISQ.js.map +1 -0
  50. package/dist/{chunk-G35SYE6Z.js → chunk-N73GQTCK.js} +37 -104
  51. package/dist/chunk-N73GQTCK.js.map +1 -0
  52. package/dist/{chunk-H7SSBSPR.js → chunk-OA5RCL2L.js} +8 -5
  53. package/dist/chunk-OA5RCL2L.js.map +1 -0
  54. package/dist/{chunk-CZBNDP5B.js → chunk-PNXFJPXF.js} +3 -3
  55. package/dist/{chunk-MCTSHLAF.js → chunk-RI5QEK5W.js} +41 -14
  56. package/dist/chunk-RI5QEK5W.js.map +1 -0
  57. package/dist/chunk-RXC7AF7N.js +31 -0
  58. package/dist/chunk-RXC7AF7N.js.map +1 -0
  59. package/dist/{chunk-CQ7657GA.js → chunk-SSHG7MEE.js} +1248 -735
  60. package/dist/chunk-SSHG7MEE.js.map +1 -0
  61. package/dist/{chunk-4S4FCAA2.js → chunk-VTUPUKFD.js} +26 -31
  62. package/dist/chunk-VTUPUKFD.js.map +1 -0
  63. package/dist/{chunk-XENOESJZ.js → chunk-WLQUQXWO.js} +10 -67
  64. package/dist/chunk-WLQUQXWO.js.map +1 -0
  65. package/dist/chunk-WPED6CL3.js +105 -0
  66. package/dist/chunk-WPED6CL3.js.map +1 -0
  67. package/dist/{chunk-NT4K647L.js → chunk-XPMEGGJK.js} +97 -76
  68. package/dist/chunk-XPMEGGJK.js.map +1 -0
  69. package/dist/chunk-XZKVOPCR.js +75 -0
  70. package/dist/chunk-XZKVOPCR.js.map +1 -0
  71. package/dist/{chunk-ZW2PELOH.js → chunk-ZX5DM4D5.js} +106 -69
  72. package/dist/chunk-ZX5DM4D5.js.map +1 -0
  73. package/dist/commands/build/marketplace.js +21 -20
  74. package/dist/commands/build/marketplace.js.map +1 -1
  75. package/dist/commands/build/plugins.js +7 -11
  76. package/dist/commands/build/plugins.js.map +1 -1
  77. package/dist/commands/build/stack.js +8 -13
  78. package/dist/commands/build/stack.js.map +1 -1
  79. package/dist/commands/compile.js +109 -135
  80. package/dist/commands/compile.js.map +1 -1
  81. package/dist/commands/config/get.js +4 -5
  82. package/dist/commands/config/get.js.map +1 -1
  83. package/dist/commands/config/index.js +5 -6
  84. package/dist/commands/config/index.js.map +1 -1
  85. package/dist/commands/config/path.js +4 -5
  86. package/dist/commands/config/path.js.map +1 -1
  87. package/dist/commands/config/set-project.js +4 -5
  88. package/dist/commands/config/set-project.js.map +1 -1
  89. package/dist/commands/config/show.js +5 -6
  90. package/dist/commands/config/unset-project.js +4 -5
  91. package/dist/commands/config/unset-project.js.map +1 -1
  92. package/dist/commands/diff.js +26 -11
  93. package/dist/commands/diff.js.map +1 -1
  94. package/dist/commands/doctor.js +13 -16
  95. package/dist/commands/doctor.js.map +1 -1
  96. package/dist/commands/edit.js +71 -42
  97. package/dist/commands/edit.js.map +1 -1
  98. package/dist/commands/eject.js +34 -14
  99. package/dist/commands/eject.js.map +1 -1
  100. package/dist/commands/import/skill.js +93 -52
  101. package/dist/commands/import/skill.js.map +1 -1
  102. package/dist/commands/info.js +27 -9
  103. package/dist/commands/info.js.map +1 -1
  104. package/dist/commands/init.js +98 -48
  105. package/dist/commands/init.js.map +1 -1
  106. package/dist/commands/list.js +10 -5
  107. package/dist/commands/list.js.map +1 -1
  108. package/dist/commands/new/agent.js +8 -11
  109. package/dist/commands/new/agent.js.map +1 -1
  110. package/dist/commands/new/skill.js +17 -18
  111. package/dist/commands/new/skill.js.map +1 -1
  112. package/dist/commands/outdated.js +23 -9
  113. package/dist/commands/outdated.js.map +1 -1
  114. package/dist/commands/search.js +23 -20
  115. package/dist/commands/search.js.map +1 -1
  116. package/dist/commands/uninstall.js +28 -21
  117. package/dist/commands/uninstall.js.map +1 -1
  118. package/dist/commands/update.js +30 -22
  119. package/dist/commands/update.js.map +1 -1
  120. package/dist/commands/validate.js +103 -39
  121. package/dist/commands/validate.js.map +1 -1
  122. package/dist/commands/version/bump.js +4 -5
  123. package/dist/commands/version/bump.js.map +1 -1
  124. package/dist/commands/version/index.js +4 -5
  125. package/dist/commands/version/index.js.map +1 -1
  126. package/dist/commands/version/set.js +4 -5
  127. package/dist/commands/version/set.js.map +1 -1
  128. package/dist/commands/version/show.js +4 -5
  129. package/dist/commands/version/show.js.map +1 -1
  130. package/dist/components/common/confirm.test.js +2 -2
  131. package/dist/components/common/confirm.test.js.map +1 -1
  132. package/dist/components/skill-search/skill-search.js +4 -2
  133. package/dist/components/wizard/category-grid.js +3 -1
  134. package/dist/components/wizard/category-grid.test.js +63 -64
  135. package/dist/components/wizard/category-grid.test.js.map +1 -1
  136. package/dist/components/wizard/domain-selection.js +13 -0
  137. package/dist/components/wizard/help-modal.js +10 -0
  138. package/dist/components/wizard/help-modal.js.map +1 -0
  139. package/dist/components/wizard/menu-item.js +2 -1
  140. package/dist/components/wizard/search-modal.js +3 -1
  141. package/dist/components/wizard/search-modal.test.js +4 -2
  142. package/dist/components/wizard/search-modal.test.js.map +1 -1
  143. package/dist/components/wizard/section-progress.js +2 -1
  144. package/dist/components/wizard/section-progress.test.js +2 -1
  145. package/dist/components/wizard/section-progress.test.js.map +1 -1
  146. package/dist/components/wizard/source-grid.js +6 -2
  147. package/dist/components/wizard/source-grid.test.js +49 -45
  148. package/dist/components/wizard/source-grid.test.js.map +1 -1
  149. package/dist/components/wizard/stack-selection.js +15 -0
  150. package/dist/components/wizard/stack-selection.js.map +1 -0
  151. package/dist/components/wizard/step-approach.js +8 -6
  152. package/dist/components/wizard/step-approach.test.js +11 -9
  153. package/dist/components/wizard/step-approach.test.js.map +1 -1
  154. package/dist/components/wizard/step-build.js +9 -13
  155. package/dist/components/wizard/step-build.test.js +27 -45
  156. package/dist/components/wizard/step-build.test.js.map +1 -1
  157. package/dist/components/wizard/step-confirm.js +2 -1
  158. package/dist/components/wizard/step-confirm.test.js +6 -5
  159. package/dist/components/wizard/step-confirm.test.js.map +1 -1
  160. package/dist/components/wizard/step-refine.js +2 -1
  161. package/dist/components/wizard/step-refine.test.js +3 -2
  162. package/dist/components/wizard/step-refine.test.js.map +1 -1
  163. package/dist/components/wizard/step-settings.js +8 -6
  164. package/dist/components/wizard/step-settings.test.js +12 -10
  165. package/dist/components/wizard/step-settings.test.js.map +1 -1
  166. package/dist/components/wizard/step-sources.js +11 -9
  167. package/dist/components/wizard/step-sources.test.js +16 -15
  168. package/dist/components/wizard/step-sources.test.js.map +1 -1
  169. package/dist/components/wizard/step-stack.js +9 -6
  170. package/dist/components/wizard/step-stack.test.js +15 -12
  171. package/dist/components/wizard/step-stack.test.js.map +1 -1
  172. package/dist/components/wizard/view-title.js +2 -1
  173. package/dist/components/wizard/wizard-layout.js +7 -9
  174. package/dist/components/wizard/wizard-tabs.js +2 -1
  175. package/dist/components/wizard/wizard-tabs.test.js +2 -1
  176. package/dist/components/wizard/wizard-tabs.test.js.map +1 -1
  177. package/dist/components/wizard/wizard.js +26 -20
  178. package/dist/config/stacks.yaml +330 -93
  179. package/dist/hooks/init.js +3 -4
  180. package/dist/hooks/init.js.map +1 -1
  181. package/dist/source-manager-TV2YGPAN.js +15 -0
  182. package/dist/source-manager-TV2YGPAN.js.map +1 -0
  183. package/dist/stores/wizard-store.js +4 -3
  184. package/dist/stores/wizard-store.test.js +272 -25
  185. package/dist/stores/wizard-store.test.js.map +1 -1
  186. package/package.json +2 -1
  187. package/src/schemas/agent-frontmatter.schema.json +84 -0
  188. package/src/schemas/agent.schema.json +93 -0
  189. package/src/schemas/hooks.schema.json +47 -0
  190. package/src/schemas/marketplace.schema.json +119 -0
  191. package/src/schemas/metadata.schema.json +113 -0
  192. package/src/schemas/plugin.schema.json +130 -0
  193. package/src/schemas/project-config.schema.json +125 -0
  194. package/src/schemas/project-source-config.schema.json +81 -0
  195. package/src/schemas/skill-frontmatter.schema.json +42 -0
  196. package/src/schemas/skills-matrix.schema.json +467 -0
  197. package/src/schemas/stack.schema.json +191 -0
  198. package/src/schemas/stacks.schema.json +111 -0
  199. package/dist/chunk-2OW7FCIF.js +0 -197
  200. package/dist/chunk-2OW7FCIF.js.map +0 -1
  201. package/dist/chunk-2YMMJP4Z.js.map +0 -1
  202. package/dist/chunk-324DM2L6.js.map +0 -1
  203. package/dist/chunk-3X5D7RM5.js.map +0 -1
  204. package/dist/chunk-4S4FCAA2.js.map +0 -1
  205. package/dist/chunk-CQ7657GA.js.map +0 -1
  206. package/dist/chunk-ETCVEV3S.js.map +0 -1
  207. package/dist/chunk-F4RD5FYM.js.map +0 -1
  208. package/dist/chunk-G35SYE6Z.js.map +0 -1
  209. package/dist/chunk-GGFOD5PK.js.map +0 -1
  210. package/dist/chunk-H7SSBSPR.js.map +0 -1
  211. package/dist/chunk-HIQGK5XJ.js.map +0 -1
  212. package/dist/chunk-HWD32NP7.js +0 -19
  213. package/dist/chunk-HWD32NP7.js.map +0 -1
  214. package/dist/chunk-KWYO3M5Q.js.map +0 -1
  215. package/dist/chunk-MCTSHLAF.js.map +0 -1
  216. package/dist/chunk-NQJ47R4N.js.map +0 -1
  217. package/dist/chunk-NT4K647L.js.map +0 -1
  218. package/dist/chunk-O6ZTD7ZI.js +0 -70
  219. package/dist/chunk-O6ZTD7ZI.js.map +0 -1
  220. package/dist/chunk-OBXAY23Y.js.map +0 -1
  221. package/dist/chunk-TMED5DQ2.js +0 -210
  222. package/dist/chunk-TMED5DQ2.js.map +0 -1
  223. package/dist/chunk-U7HFKR74.js.map +0 -1
  224. package/dist/chunk-UEMRJI2K.js +0 -146
  225. package/dist/chunk-UEMRJI2K.js.map +0 -1
  226. package/dist/chunk-UNN7523L.js +0 -78
  227. package/dist/chunk-UNN7523L.js.map +0 -1
  228. package/dist/chunk-VVYNZZUX.js.map +0 -1
  229. package/dist/chunk-XENOESJZ.js.map +0 -1
  230. package/dist/chunk-ZW2PELOH.js.map +0 -1
  231. package/dist/source-manager-VWIIDTK5.js +0 -16
  232. /package/dist/{chunk-CZBNDP5B.js.map → chunk-PNXFJPXF.js.map} +0 -0
  233. /package/dist/{source-manager-VWIIDTK5.js.map → components/wizard/domain-selection.js.map} +0 -0
@@ -1,17 +1,21 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ ViewTitle
4
+ } from "./chunk-FY5D4KIC.js";
2
5
  import {
3
6
  getDomainDisplayName
4
7
  } from "./chunk-V2ZIH7HV.js";
5
- import {
6
- ViewTitle
7
- } from "./chunk-U7HFKR74.js";
8
8
  import {
9
9
  CategoryGrid
10
- } from "./chunk-ETCVEV3S.js";
10
+ } from "./chunk-IRG52AN5.js";
11
11
  import {
12
12
  getAvailableSkills,
13
13
  resolveAlias
14
- } from "./chunk-CQ7657GA.js";
14
+ } from "./chunk-SSHG7MEE.js";
15
+ import {
16
+ CLI_COLORS,
17
+ UI_SYMBOLS
18
+ } from "./chunk-IFODQTCX.js";
15
19
  import {
16
20
  init_esm_shims
17
21
  } from "./chunk-AWKZ5BDL.js";
@@ -20,8 +24,13 @@ import {
20
24
  init_esm_shims();
21
25
  import { useState } from "react";
22
26
  import { Box, Text, useInput } from "ink";
27
+
28
+ // src/cli/lib/wizard/index.ts
29
+ init_esm_shims();
30
+
31
+ // src/cli/lib/wizard/build-step-logic.ts
32
+ init_esm_shims();
23
33
  import { sortBy } from "remeda";
24
- import { jsx, jsxs } from "react/jsx-runtime";
25
34
  var FRAMEWORK_SUBCATEGORY_ID = "framework";
26
35
  var WEB_DOMAIN_ID = "web";
27
36
  function validateBuildStep(categories, selections) {
@@ -31,7 +40,7 @@ function validateBuildStep(categories, selections) {
31
40
  if (categorySelections.length === 0) {
32
41
  return {
33
42
  valid: false,
34
- message: `Please select a ${category.displayName}`
43
+ message: `Select at least one skill from the ${category.displayName} category. Use arrow keys to navigate, then SPACE to select.`
35
44
  };
36
45
  }
37
46
  }
@@ -50,7 +59,7 @@ function computeOptionState(skill) {
50
59
  }
51
60
  return "normal";
52
61
  }
53
- function getDisplayLabel(skill) {
62
+ function getSkillDisplayLabel(skill) {
54
63
  return skill.displayName || skill.id;
55
64
  }
56
65
  function getStateReason(skill) {
@@ -99,7 +108,7 @@ function buildCategoriesForDomain(domain, allSelections, matrix, expertMode, sel
99
108
  ) : skillOptions;
100
109
  const options = filteredSkillOptions.map((skill) => ({
101
110
  id: skill.id,
102
- label: getDisplayLabel(skill),
111
+ label: getSkillDisplayLabel(skill),
103
112
  state: computeOptionState(skill),
104
113
  stateReason: getStateReason(skill),
105
114
  selected: skill.selected,
@@ -116,15 +125,67 @@ function buildCategoriesForDomain(domain, allSelections, matrix, expertMode, sel
116
125
  });
117
126
  return categoryRows.filter((row) => row.options.length > 0);
118
127
  }
128
+
129
+ // src/cli/components/hooks/use-framework-filtering.ts
130
+ init_esm_shims();
131
+ import { useMemo } from "react";
132
+ function useFrameworkFiltering({
133
+ domain,
134
+ allSelections,
135
+ matrix,
136
+ expertMode,
137
+ selections,
138
+ parentDomainSelections,
139
+ installedSkillIds
140
+ }) {
141
+ return useMemo(
142
+ () => buildCategoriesForDomain(
143
+ domain,
144
+ allSelections,
145
+ matrix,
146
+ expertMode,
147
+ selections,
148
+ parentDomainSelections,
149
+ installedSkillIds
150
+ ),
151
+ [
152
+ domain,
153
+ allSelections,
154
+ matrix,
155
+ expertMode,
156
+ selections,
157
+ parentDomainSelections,
158
+ installedSkillIds
159
+ ]
160
+ );
161
+ }
162
+
163
+ // src/cli/components/wizard/step-build.tsx
164
+ import { jsx, jsxs } from "react/jsx-runtime";
119
165
  var Footer = ({ validationError }) => {
120
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 1, children: validationError && /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { color: "yellow", children: validationError }) }) });
166
+ return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 1, children: validationError && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
167
+ /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, children: validationError }),
168
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press ESC to go back, or select a skill and press ENTER to continue." })
169
+ ] }) });
121
170
  };
122
171
  var LegendRow = () => {
123
172
  return /* @__PURE__ */ jsxs(Box, { paddingLeft: 1, columnGap: 2, children: [
124
- /* @__PURE__ */ jsx(Text, { color: "cyan", children: "active" }),
125
- /* @__PURE__ */ jsx(Text, { color: "#fff", children: "recommended" }),
126
- /* @__PURE__ */ jsx(Text, { color: "yellow", children: "discouraged" }),
127
- /* @__PURE__ */ jsx(Text, { color: "gray", children: "disabled" })
173
+ /* @__PURE__ */ jsxs(Text, { color: CLI_COLORS.PRIMARY, children: [
174
+ UI_SYMBOLS.SELECTED,
175
+ " active"
176
+ ] }),
177
+ /* @__PURE__ */ jsxs(Text, { color: CLI_COLORS.UNFOCUSED, children: [
178
+ UI_SYMBOLS.UNSELECTED,
179
+ " recommended"
180
+ ] }),
181
+ /* @__PURE__ */ jsxs(Text, { color: CLI_COLORS.WARNING, children: [
182
+ UI_SYMBOLS.DISCOURAGED,
183
+ " discouraged"
184
+ ] }),
185
+ /* @__PURE__ */ jsxs(Text, { color: CLI_COLORS.NEUTRAL, children: [
186
+ UI_SYMBOLS.DISABLED,
187
+ " disabled"
188
+ ] })
128
189
  ] });
129
190
  };
130
191
  var StepBuild = ({
@@ -133,28 +194,25 @@ var StepBuild = ({
133
194
  selectedDomains,
134
195
  selections,
135
196
  allSelections,
136
- focusedRow,
137
- focusedCol,
138
197
  showDescriptions,
139
198
  expertMode,
140
199
  parentDomainSelections,
141
200
  installedSkillIds,
142
201
  onToggle,
143
- onFocusChange,
144
202
  onToggleDescriptions,
145
203
  onContinue,
146
204
  onBack
147
205
  }) => {
148
206
  const [validationError, setValidationError] = useState(void 0);
149
- const categories = buildCategoriesForDomain(
150
- activeDomain,
207
+ const categories = useFrameworkFiltering({
208
+ domain: activeDomain,
151
209
  allSelections,
152
210
  matrix,
153
211
  expertMode,
154
212
  selections,
155
213
  parentDomainSelections,
156
214
  installedSkillIds
157
- );
215
+ });
158
216
  useInput((_input, key) => {
159
217
  if (key.return) {
160
218
  const validation = validateBuildStep(categories, selections);
@@ -182,16 +240,23 @@ var StepBuild = ({
182
240
  borderTop: false,
183
241
  borderRight: false,
184
242
  borderLeft: false,
185
- borderColor: "gray",
243
+ borderColor: CLI_COLORS.NEUTRAL,
186
244
  borderStyle: "single",
187
245
  children: [
188
- /* @__PURE__ */ jsx(Box, { columnGap: 2, flexDirection: "row", children: selectedDomains.map((domain) => /* @__PURE__ */ jsx(Text, { color: domain === activeDomain ? "cyan" : void 0, children: getDomainDisplayName(domain) }, domain)) }),
246
+ /* @__PURE__ */ jsx(Box, { columnGap: 2, flexDirection: "row", children: selectedDomains.map((domain) => {
247
+ const isActive = domain === activeDomain;
248
+ return /* @__PURE__ */ jsxs(Text, { color: isActive ? CLI_COLORS.PRIMARY : void 0, children: [
249
+ isActive ? UI_SYMBOLS.CURRENT : UI_SYMBOLS.UNSELECTED,
250
+ " ",
251
+ getDomainDisplayName(domain)
252
+ ] }, domain);
253
+ }) }),
189
254
  /* @__PURE__ */ jsx(LegendRow, {})
190
255
  ]
191
256
  }
192
257
  ),
193
258
  /* @__PURE__ */ jsxs(ViewTitle, { children: [
194
- "Customise your ",
259
+ "Customize your ",
195
260
  getDomainDisplayName(activeDomain),
196
261
  " stack"
197
262
  ] }),
@@ -199,14 +264,12 @@ var StepBuild = ({
199
264
  CategoryGrid,
200
265
  {
201
266
  categories,
202
- focusedRow,
203
- focusedCol,
204
267
  expertMode,
205
268
  showDescriptions,
206
269
  onToggle,
207
- onFocusChange,
208
270
  onToggleDescriptions
209
- }
271
+ },
272
+ activeDomain
210
273
  ),
211
274
  /* @__PURE__ */ jsx(Footer, { validationError })
212
275
  ] });
@@ -214,7 +277,7 @@ var StepBuild = ({
214
277
 
215
278
  export {
216
279
  validateBuildStep,
217
- getDisplayLabel,
280
+ getSkillDisplayLabel,
218
281
  StepBuild
219
282
  };
220
- //# sourceMappingURL=chunk-2YMMJP4Z.js.map
283
+ //# sourceMappingURL=chunk-EUPMWSM3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/step-build.tsx","../src/cli/lib/wizard/index.ts","../src/cli/lib/wizard/build-step-logic.ts","../src/cli/components/hooks/use-framework-filtering.ts"],"sourcesContent":["import React, { useState } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport type {\n Domain,\n MergedSkillsMatrix,\n SkillId,\n Subcategory,\n SubcategorySelections,\n} from \"../../types/index.js\";\nimport { validateBuildStep } from \"../../lib/wizard/index.js\";\nimport { CLI_COLORS, UI_SYMBOLS } from \"../../consts.js\";\nimport { useFrameworkFiltering } from \"../hooks/use-framework-filtering.js\";\nimport { CategoryGrid } from \"./category-grid.js\";\nimport { ViewTitle } from \"./view-title.js\";\nimport { getDomainDisplayName } from \"./utils.js\";\n\nexport type StepBuildProps = {\n matrix: MergedSkillsMatrix;\n domain: Domain;\n selectedDomains: Domain[];\n selections: SubcategorySelections;\n allSelections: SkillId[];\n showDescriptions: boolean;\n expertMode: boolean;\n /** For framework-first filtering on sub-domains (e.g., web-extras inherits from web) */\n parentDomainSelections?: SubcategorySelections;\n /** Skill IDs already installed on disk, shown with a dimmed checkmark */\n installedSkillIds?: SkillId[];\n onToggle: (subcategoryId: Subcategory, technologyId: SkillId) => void;\n onToggleDescriptions: () => void;\n onContinue: () => void;\n onBack: () => void;\n};\n\ntype FooterProps = {\n validationError?: string;\n};\n\nconst Footer: React.FC<FooterProps> = ({ validationError }) => {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n {validationError && (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color={CLI_COLORS.WARNING}>{validationError}</Text>\n <Text dimColor>Press ESC to go back, or select a skill and press ENTER to continue.</Text>\n </Box>\n )}\n </Box>\n );\n};\n\nconst LegendRow: React.FC = () => {\n return (\n <Box paddingLeft={1} columnGap={2}>\n <Text color={CLI_COLORS.PRIMARY}>{UI_SYMBOLS.SELECTED} active</Text>\n <Text color={CLI_COLORS.UNFOCUSED}>{UI_SYMBOLS.UNSELECTED} recommended</Text>\n <Text color={CLI_COLORS.WARNING}>{UI_SYMBOLS.DISCOURAGED} discouraged</Text>\n <Text color={CLI_COLORS.NEUTRAL}>{UI_SYMBOLS.DISABLED} disabled</Text>\n </Box>\n );\n};\n\nexport const StepBuild: React.FC<StepBuildProps> = ({\n matrix,\n domain: activeDomain,\n selectedDomains,\n selections,\n allSelections,\n showDescriptions,\n expertMode,\n parentDomainSelections,\n installedSkillIds,\n onToggle,\n onToggleDescriptions,\n onContinue,\n onBack,\n}) => {\n const [validationError, setValidationError] = useState<string | undefined>(undefined);\n\n const categories = useFrameworkFiltering({\n domain: activeDomain,\n allSelections,\n matrix,\n expertMode,\n selections,\n parentDomainSelections,\n installedSkillIds,\n });\n\n useInput((_input, key) => {\n if (key.return) {\n const validation = validateBuildStep(categories, selections);\n if (validation.valid) {\n setValidationError(undefined);\n onContinue();\n } else {\n setValidationError(validation.message);\n }\n } else if (key.escape) {\n setValidationError(undefined);\n onBack();\n }\n });\n\n return (\n <Box flexDirection=\"column\" width=\"100%\">\n <Box\n columnGap={2}\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n marginBottom={1}\n paddingRight={1}\n marginTop={-1}\n borderTop={false}\n borderRight={false}\n borderLeft={false}\n borderColor={CLI_COLORS.NEUTRAL}\n borderStyle=\"single\"\n >\n <Box columnGap={2} flexDirection=\"row\">\n {selectedDomains.map((domain) => {\n const isActive = domain === activeDomain;\n return (\n <Text key={domain} color={isActive ? CLI_COLORS.PRIMARY : undefined}>\n {isActive ? UI_SYMBOLS.CURRENT : UI_SYMBOLS.UNSELECTED}{\" \"}\n {getDomainDisplayName(domain)}\n </Text>\n );\n })}\n </Box>\n <LegendRow />\n </Box>\n <ViewTitle>Customize your {getDomainDisplayName(activeDomain)} stack</ViewTitle>\n\n <CategoryGrid\n key={activeDomain}\n categories={categories}\n expertMode={expertMode}\n showDescriptions={showDescriptions}\n onToggle={onToggle}\n onToggleDescriptions={onToggleDescriptions}\n />\n\n <Footer validationError={validationError} />\n </Box>\n );\n};\n","export {\n type BuildStepValidation,\n validateBuildStep,\n computeOptionState,\n getSkillDisplayLabel,\n buildCategoriesForDomain,\n} from \"./build-step-logic\";\n","import { sortBy } from \"remeda\";\nimport type {\n Domain,\n MergedSkillsMatrix,\n SkillId,\n SubcategorySelections,\n} from \"../../types/index.js\";\nimport { getAvailableSkills, resolveAlias } from \"../matrix/index.js\";\nimport type {\n CategoryRow,\n CategoryOption,\n OptionState,\n} from \"../../components/wizard/category-grid.js\";\n\nconst FRAMEWORK_SUBCATEGORY_ID = \"framework\";\nconst WEB_DOMAIN_ID = \"web\";\n\nexport type BuildStepValidation = {\n valid: boolean;\n message?: string;\n};\n\nexport function validateBuildStep(\n categories: CategoryRow[],\n selections: SubcategorySelections,\n): BuildStepValidation {\n for (const category of categories) {\n if (category.required) {\n const categorySelections = selections[category.id] || [];\n if (categorySelections.length === 0) {\n return {\n valid: false,\n message: `Select at least one skill from the ${category.displayName} category. Use arrow keys to navigate, then SPACE to select.`,\n };\n }\n }\n }\n return { valid: true };\n}\n\nexport function computeOptionState(skill: {\n disabled: boolean;\n discouraged: boolean;\n recommended: boolean;\n}): OptionState {\n if (skill.disabled) {\n return \"disabled\";\n }\n if (skill.discouraged) {\n return \"discouraged\";\n }\n if (skill.recommended) {\n return \"recommended\";\n }\n return \"normal\";\n}\n\nexport function getSkillDisplayLabel(skill: { displayName?: string; id: string }): string {\n return skill.displayName || skill.id;\n}\n\nfunction getStateReason(skill: {\n disabled: boolean;\n disabledReason?: string;\n discouraged: boolean;\n discouragedReason?: string;\n recommended: boolean;\n recommendedReason?: string;\n}): string | undefined {\n if (skill.disabled && skill.disabledReason) {\n return skill.disabledReason;\n }\n if (skill.discouraged && skill.discouragedReason) {\n return skill.discouragedReason;\n }\n if (skill.recommended && skill.recommendedReason) {\n return skill.recommendedReason;\n }\n return undefined;\n}\n\nfunction isFrameworkSelected(selections: SubcategorySelections): boolean {\n const frameworkSelections = selections[FRAMEWORK_SUBCATEGORY_ID] ?? [];\n return frameworkSelections.length > 0;\n}\n\nfunction getSelectedFrameworks(\n selections: SubcategorySelections,\n matrix: MergedSkillsMatrix,\n): SkillId[] {\n const frameworkSelections = selections[FRAMEWORK_SUBCATEGORY_ID] ?? [];\n return frameworkSelections.map((alias) => resolveAlias(alias, matrix));\n}\n\nfunction isCompatibleWithSelectedFrameworks(\n skillId: SkillId,\n selectedFrameworkIds: SkillId[],\n matrix: MergedSkillsMatrix,\n): boolean {\n const skill = matrix.skills[skillId];\n if (!skill) return false;\n\n // No compatibleWith = compatible with all (allows legacy skills to appear)\n if (skill.compatibleWith.length === 0) {\n return true;\n }\n\n return selectedFrameworkIds.some((frameworkId) => skill.compatibleWith.includes(frameworkId));\n}\n\n// Build CategoryRow[] from matrix for a domain, with framework-first filtering for web\nexport function buildCategoriesForDomain(\n domain: Domain,\n allSelections: SkillId[],\n matrix: MergedSkillsMatrix,\n expertMode: boolean,\n selections: SubcategorySelections,\n parentDomainSelections?: SubcategorySelections,\n installedSkillIds?: SkillId[],\n): CategoryRow[] {\n const frameworkSource = parentDomainSelections ?? selections;\n const frameworkSelected = isFrameworkSelected(frameworkSource);\n const selectedFrameworkIds = frameworkSelected\n ? getSelectedFrameworks(frameworkSource, matrix)\n : [];\n\n const subcategories = sortBy(\n Object.values(matrix.categories).filter((cat) => cat.domain === domain),\n (cat) => cat.order ?? 0,\n );\n\n const categoryRows: CategoryRow[] = subcategories.map((cat) => {\n const skillOptions = getAvailableSkills(cat.id, allSelections, matrix, {\n expertMode,\n });\n\n const useFrameworkFilter =\n (domain === WEB_DOMAIN_ID || parentDomainSelections !== undefined) &&\n cat.id !== FRAMEWORK_SUBCATEGORY_ID &&\n frameworkSelected;\n const filteredSkillOptions = useFrameworkFilter\n ? skillOptions.filter((skill) =>\n isCompatibleWithSelectedFrameworks(skill.id, selectedFrameworkIds, matrix),\n )\n : skillOptions;\n\n const options: CategoryOption[] = filteredSkillOptions.map((skill) => ({\n id: skill.id,\n label: getSkillDisplayLabel(skill),\n state: computeOptionState(skill),\n stateReason: getStateReason(skill),\n selected: skill.selected,\n local: matrix.skills[skill.id]?.local,\n installed: installedSkillIds?.includes(skill.id) || false,\n }));\n\n return {\n id: cat.id,\n displayName: cat.displayName,\n required: cat.required ?? false,\n exclusive: cat.exclusive ?? true,\n options,\n };\n });\n\n return categoryRows.filter((row) => row.options.length > 0);\n}\n","import { useMemo } from \"react\";\nimport type {\n Domain,\n MergedSkillsMatrix,\n SkillId,\n SubcategorySelections,\n} from \"../../types/index.js\";\nimport { buildCategoriesForDomain } from \"../../lib/wizard/index.js\";\nimport type { CategoryRow } from \"../wizard/category-grid.js\";\n\ntype UseFrameworkFilteringOptions = {\n domain: Domain;\n allSelections: SkillId[];\n matrix: MergedSkillsMatrix;\n expertMode: boolean;\n selections: SubcategorySelections;\n parentDomainSelections?: SubcategorySelections;\n installedSkillIds?: SkillId[];\n};\n\nexport function useFrameworkFiltering({\n domain,\n allSelections,\n matrix,\n expertMode,\n selections,\n parentDomainSelections,\n installedSkillIds,\n}: UseFrameworkFilteringOptions): CategoryRow[] {\n return useMemo(\n () =>\n buildCategoriesForDomain(\n domain,\n allSelections,\n matrix,\n expertMode,\n selections,\n parentDomainSelections,\n installedSkillIds,\n ),\n [\n domain,\n allSelections,\n matrix,\n expertMode,\n selections,\n parentDomainSelections,\n installedSkillIds,\n ],\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ init_esm_shims
4
+ } from "./chunk-AWKZ5BDL.js";
5
+
6
+ // src/cli/utils/messages.ts
7
+ init_esm_shims();
8
+ var ERROR_MESSAGES = {
9
+ UNKNOWN_ERROR: "Unknown error occurred",
10
+ UNKNOWN_ERROR_SHORT: "Unknown error",
11
+ NO_INSTALLATION: "No installation found. Run 'cc init' first to set up Claude Collective.",
12
+ NO_LOCAL_SKILLS: "No local skills found. Run `cc init` or `cc edit` first.",
13
+ NO_SKILLS_FOUND: "No skills found",
14
+ VALIDATION_FAILED: "Validation failed",
15
+ FAILED_RESOLVE_SOURCE: "Failed to resolve source",
16
+ FAILED_LOAD_AGENT_PARTIALS: "Failed to load agent partials",
17
+ FAILED_COMPILE_AGENTS: "Failed to compile agents",
18
+ SKILL_NOT_FOUND: "Skill not found"
19
+ };
20
+ var SUCCESS_MESSAGES = {
21
+ IMPORT_COMPLETE: "Import complete!",
22
+ UNINSTALL_COMPLETE: "Uninstall complete!",
23
+ INIT_SUCCESS: "Claude Collective initialized successfully!",
24
+ PLUGIN_COMPILE_COMPLETE: "Plugin compile complete!",
25
+ CUSTOM_COMPILE_COMPLETE: "Custom output compile complete!",
26
+ ALL_SKILLS_UP_TO_DATE: "All skills are up to date."
27
+ };
28
+ var STATUS_MESSAGES = {
29
+ LOADING_SKILLS: "Loading skills...",
30
+ LOADING_MARKETPLACE_SOURCE: "Loading marketplace source...",
31
+ RECOMPILING_AGENTS: "Recompiling agents...",
32
+ COMPILING_AGENTS: "Compiling agents...",
33
+ DISCOVERING_SKILLS: "Discovering skills...",
34
+ RESOLVING_SOURCE: "Resolving source...",
35
+ RESOLVING_MARKETPLACE_SOURCE: "Resolving marketplace source...",
36
+ FETCHING_AGENT_PARTIALS: "Fetching agent partials...",
37
+ LOADING_AGENT_PARTIALS: "Loading agent partials...",
38
+ FETCHING_REPOSITORY: "Fetching repository...",
39
+ COPYING_SKILLS: "Copying skills...",
40
+ UPDATING_PLUGIN_SKILLS: "Updating plugin skills..."
41
+ };
42
+ var INFO_MESSAGES = {
43
+ NO_CHANGES_MADE: "No changes made.",
44
+ RUN_COMPILE: "Run 'cc compile' to include imported skills in your agents.",
45
+ NO_AGENTS_TO_RECOMPILE: "No agents to recompile",
46
+ NO_AGENTS_TO_COMPILE: "No agents to compile",
47
+ NO_PLUGIN_INSTALLATION: "No plugin installation found.",
48
+ NO_LOCAL_INSTALLATION: "No local installation found.",
49
+ NOT_INSTALLED: "Claude Collective is not installed in this project."
50
+ };
51
+ var DRY_RUN_MESSAGES = {
52
+ PREVIEW_NO_FILES_REMOVED: "[dry-run] Preview mode - no files will be removed",
53
+ PREVIEW_NO_FILES_CREATED: "[dry-run] Preview mode - no files will be created",
54
+ COMPLETE_NO_FILES_REMOVED: "[dry-run] Preview complete - no files were removed",
55
+ COMPLETE_NO_FILES_WRITTEN: "[dry-run] Preview complete - no files were written",
56
+ COMPLETE_NO_FILES_CREATED: "[dry-run] Preview complete - no files were created"
57
+ };
58
+
59
+ export {
60
+ ERROR_MESSAGES,
61
+ SUCCESS_MESSAGES,
62
+ STATUS_MESSAGES,
63
+ INFO_MESSAGES,
64
+ DRY_RUN_MESSAGES
65
+ };
66
+ //# sourceMappingURL=chunk-FUPBGSRA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/utils/messages.ts"],"sourcesContent":["export const ERROR_MESSAGES = {\n UNKNOWN_ERROR: \"Unknown error occurred\",\n UNKNOWN_ERROR_SHORT: \"Unknown error\",\n NO_INSTALLATION: \"No installation found. Run 'cc init' first to set up Claude Collective.\",\n NO_LOCAL_SKILLS: \"No local skills found. Run `cc init` or `cc edit` first.\",\n NO_SKILLS_FOUND: \"No skills found\",\n VALIDATION_FAILED: \"Validation failed\",\n FAILED_RESOLVE_SOURCE: \"Failed to resolve source\",\n FAILED_LOAD_AGENT_PARTIALS: \"Failed to load agent partials\",\n FAILED_COMPILE_AGENTS: \"Failed to compile agents\",\n SKILL_NOT_FOUND: \"Skill not found\",\n} as const;\n\nexport const SUCCESS_MESSAGES = {\n IMPORT_COMPLETE: \"Import complete!\",\n UNINSTALL_COMPLETE: \"Uninstall complete!\",\n INIT_SUCCESS: \"Claude Collective initialized successfully!\",\n PLUGIN_COMPILE_COMPLETE: \"Plugin compile complete!\",\n CUSTOM_COMPILE_COMPLETE: \"Custom output compile complete!\",\n ALL_SKILLS_UP_TO_DATE: \"All skills are up to date.\",\n} as const;\n\nexport const STATUS_MESSAGES = {\n LOADING_SKILLS: \"Loading skills...\",\n LOADING_MARKETPLACE_SOURCE: \"Loading marketplace source...\",\n RECOMPILING_AGENTS: \"Recompiling agents...\",\n COMPILING_AGENTS: \"Compiling agents...\",\n DISCOVERING_SKILLS: \"Discovering skills...\",\n RESOLVING_SOURCE: \"Resolving source...\",\n RESOLVING_MARKETPLACE_SOURCE: \"Resolving marketplace source...\",\n FETCHING_AGENT_PARTIALS: \"Fetching agent partials...\",\n LOADING_AGENT_PARTIALS: \"Loading agent partials...\",\n FETCHING_REPOSITORY: \"Fetching repository...\",\n COPYING_SKILLS: \"Copying skills...\",\n UPDATING_PLUGIN_SKILLS: \"Updating plugin skills...\",\n} as const;\n\nexport const INFO_MESSAGES = {\n NO_CHANGES_MADE: \"No changes made.\",\n RUN_COMPILE: \"Run 'cc compile' to include imported skills in your agents.\",\n NO_AGENTS_TO_RECOMPILE: \"No agents to recompile\",\n NO_AGENTS_TO_COMPILE: \"No agents to compile\",\n NO_PLUGIN_INSTALLATION: \"No plugin installation found.\",\n NO_LOCAL_INSTALLATION: \"No local installation found.\",\n NOT_INSTALLED: \"Claude Collective is not installed in this project.\",\n} as const;\n\nexport const DRY_RUN_MESSAGES = {\n PREVIEW_NO_FILES_REMOVED: \"[dry-run] Preview mode - no files will be removed\",\n PREVIEW_NO_FILES_CREATED: \"[dry-run] Preview mode - no files will be created\",\n COMPLETE_NO_FILES_REMOVED: \"[dry-run] Preview complete - no files were removed\",\n COMPLETE_NO_FILES_WRITTEN: \"[dry-run] Preview complete - no files were written\",\n COMPLETE_NO_FILES_CREATED: \"[dry-run] Preview complete - no files were created\",\n} as const;\n"],"mappings":";;;;;;AAAA;AAAO,IAAM,iBAAiB;AAAA,EAC5B,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,iBAAiB;AACnB;AAEO,IAAM,mBAAmB;AAAA,EAC9B,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,uBAAuB;AACzB;AAEO,IAAM,kBAAkB;AAAA,EAC7B,gBAAgB;AAAA,EAChB,4BAA4B;AAAA,EAC5B,oBAAoB;AAAA,EACpB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,kBAAkB;AAAA,EAClB,8BAA8B;AAAA,EAC9B,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,gBAAgB;AAAA,EAChB,wBAAwB;AAC1B;AAEO,IAAM,gBAAgB;AAAA,EAC3B,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,eAAe;AACjB;AAEO,IAAM,mBAAmB;AAAA,EAC9B,0BAA0B;AAAA,EAC1B,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,2BAA2B;AAC7B;","names":[]}
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ CLI_COLORS
4
+ } from "./chunk-IFODQTCX.js";
2
5
  import {
3
6
  init_esm_shims
4
7
  } from "./chunk-AWKZ5BDL.js";
@@ -8,7 +11,7 @@ init_esm_shims();
8
11
  import { Text } from "ink";
9
12
  import { jsxs } from "react/jsx-runtime";
10
13
  var ViewTitle = ({ children }) => {
11
- return /* @__PURE__ */ jsxs(Text, { backgroundColor: "yellow", bold: true, color: "#000", children: [
14
+ return /* @__PURE__ */ jsxs(Text, { backgroundColor: CLI_COLORS.WARNING, bold: true, color: "#000", children: [
12
15
  " ",
13
16
  children,
14
17
  " "
@@ -18,4 +21,4 @@ var ViewTitle = ({ children }) => {
18
21
  export {
19
22
  ViewTitle
20
23
  };
21
- //# sourceMappingURL=chunk-U7HFKR74.js.map
24
+ //# sourceMappingURL=chunk-FY5D4KIC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/view-title.tsx"],"sourcesContent":["import React from \"react\";\nimport { Text } from \"ink\";\nimport { CLI_COLORS } from \"../../consts.js\";\n\ntype ViewTitleProps = {\n children: React.ReactNode;\n};\n\nexport const ViewTitle: React.FC<ViewTitleProps> = ({ children }) => {\n return (\n <Text backgroundColor={CLI_COLORS.WARNING} bold color=\"#000\">\n {\" \"}\n {children}{\" \"}\n </Text>\n );\n};\n"],"mappings":";;;;;;;;;AAAA;AACA,SAAS,YAAY;AASjB;AAFG,IAAM,YAAsC,CAAC,EAAE,SAAS,MAAM;AACnE,SACE,qBAAC,QAAK,iBAAiB,WAAW,SAAS,MAAI,MAAC,OAAM,QACnD;AAAA;AAAA,IACA;AAAA,IAAU;AAAA,KACb;AAEJ;","names":[]}
@@ -0,0 +1,233 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ViewTitle
4
+ } from "./chunk-FY5D4KIC.js";
5
+ import {
6
+ useModalState
7
+ } from "./chunk-DIRH4PDF.js";
8
+ import {
9
+ useKeyboardNavigation
10
+ } from "./chunk-7ICBJZV2.js";
11
+ import {
12
+ useTextInput
13
+ } from "./chunk-RXC7AF7N.js";
14
+ import {
15
+ DEFAULT_SOURCE,
16
+ addSource,
17
+ getSourceSummary,
18
+ removeSource
19
+ } from "./chunk-SSHG7MEE.js";
20
+ import {
21
+ getErrorMessage
22
+ } from "./chunk-5WIHSJRO.js";
23
+ import {
24
+ CLI_COLORS
25
+ } from "./chunk-IFODQTCX.js";
26
+ import {
27
+ init_esm_shims
28
+ } from "./chunk-AWKZ5BDL.js";
29
+
30
+ // src/cli/components/wizard/step-settings.tsx
31
+ init_esm_shims();
32
+ import { useState as useState2, useEffect, useCallback as useCallback2 } from "react";
33
+ import { Box, Text, useInput } from "ink";
34
+
35
+ // src/cli/components/hooks/use-source-operations.ts
36
+ init_esm_shims();
37
+ import { useState, useCallback } from "react";
38
+ function useSourceOperations(projectDir, onReload) {
39
+ const [statusMessage, setStatusMessage] = useState(null);
40
+ const handleAdd = useCallback(
41
+ async (url) => {
42
+ try {
43
+ const result = await addSource(projectDir, url);
44
+ setStatusMessage({
45
+ text: `Added "${result.name}" (${result.skillCount} skills)`,
46
+ color: CLI_COLORS.SUCCESS
47
+ });
48
+ await onReload();
49
+ } catch (error) {
50
+ const message = getErrorMessage(error);
51
+ setStatusMessage({ text: `Failed to add source: ${message}`, color: CLI_COLORS.ERROR });
52
+ }
53
+ },
54
+ [projectDir, onReload]
55
+ );
56
+ const handleRemove = useCallback(
57
+ async (name) => {
58
+ try {
59
+ await removeSource(projectDir, name);
60
+ setStatusMessage({ text: `Removed "${name}"`, color: CLI_COLORS.SUCCESS });
61
+ await onReload();
62
+ return true;
63
+ } catch (error) {
64
+ const message = getErrorMessage(error);
65
+ setStatusMessage({ text: `Failed to remove: ${message}`, color: CLI_COLORS.ERROR });
66
+ return false;
67
+ }
68
+ },
69
+ [projectDir, onReload]
70
+ );
71
+ const clearStatus = useCallback(() => {
72
+ setStatusMessage(null);
73
+ }, []);
74
+ return { handleAdd, handleRemove, statusMessage, clearStatus };
75
+ }
76
+
77
+ // src/cli/components/wizard/step-settings.tsx
78
+ import { jsx, jsxs } from "react/jsx-runtime";
79
+ var DEFAULT_SOURCE_NAME = "public";
80
+ var StepSettings = ({ projectDir, onClose }) => {
81
+ const [summary, setSummary] = useState2(null);
82
+ const addModal = useModalState();
83
+ const {
84
+ value: addSourceInput,
85
+ setValue: setAddSourceInput,
86
+ handleInput: handleTextInput
87
+ } = useTextInput("");
88
+ const [isLoading, setIsLoading] = useState2(true);
89
+ const loadSummary = useCallback2(async () => {
90
+ try {
91
+ const result = await getSourceSummary(projectDir);
92
+ setSummary(result);
93
+ } catch {
94
+ setSummary({
95
+ sources: [{ name: DEFAULT_SOURCE_NAME, url: DEFAULT_SOURCE, enabled: true }],
96
+ localSkillCount: 0,
97
+ pluginSkillCount: 0
98
+ });
99
+ }
100
+ setIsLoading(false);
101
+ }, [projectDir]);
102
+ useEffect(() => {
103
+ void loadSummary();
104
+ }, [loadSummary]);
105
+ const { handleAdd, handleRemove, statusMessage, clearStatus } = useSourceOperations(
106
+ projectDir,
107
+ loadSummary
108
+ );
109
+ const sourceCount = summary?.sources.length ?? 0;
110
+ const { focusedIndex, setFocusedIndex } = useKeyboardNavigation(
111
+ sourceCount,
112
+ { onEscape: onClose },
113
+ { wrap: false, vimKeys: false, active: !addModal.isOpen }
114
+ );
115
+ useInput((input, key) => {
116
+ if (statusMessage) {
117
+ clearStatus();
118
+ }
119
+ if (addModal.isOpen) {
120
+ if (key.escape) {
121
+ addModal.close();
122
+ setAddSourceInput("");
123
+ return;
124
+ }
125
+ if (key.return) {
126
+ if (addSourceInput.trim()) {
127
+ addModal.close();
128
+ setAddSourceInput("");
129
+ void handleAdd(addSourceInput.trim());
130
+ }
131
+ return;
132
+ }
133
+ handleTextInput(input, key);
134
+ return;
135
+ }
136
+ if (key.return) {
137
+ return;
138
+ }
139
+ if (key.backspace || key.delete) {
140
+ if (summary?.sources[focusedIndex]) {
141
+ const source = summary.sources[focusedIndex];
142
+ if (source.name !== DEFAULT_SOURCE_NAME) {
143
+ void handleRemove(source.name).then((success) => {
144
+ if (success) {
145
+ setFocusedIndex((prev) => Math.max(0, prev - 1));
146
+ }
147
+ });
148
+ }
149
+ }
150
+ return;
151
+ }
152
+ if (input === "a" || input === "A") {
153
+ addModal.open(true);
154
+ setAddSourceInput("");
155
+ }
156
+ });
157
+ if (isLoading) {
158
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 2, children: [
159
+ /* @__PURE__ */ jsx(ViewTitle, { children: "Skill Sources" }),
160
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Loading sources..." })
161
+ ] });
162
+ }
163
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 2, children: [
164
+ /* @__PURE__ */ jsx(ViewTitle, { children: "Skill Sources" }),
165
+ /* @__PURE__ */ jsx(Box, { marginTop: 1 }),
166
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Configured marketplaces:" }),
167
+ /* @__PURE__ */ jsx(
168
+ Box,
169
+ {
170
+ flexDirection: "column",
171
+ borderStyle: "round",
172
+ borderColor: CLI_COLORS.NEUTRAL,
173
+ paddingX: 1,
174
+ marginTop: 1,
175
+ children: summary?.sources.map((source, index) => {
176
+ const isFocused = index === focusedIndex && !addModal.isOpen;
177
+ const isDefault = source.name === DEFAULT_SOURCE_NAME;
178
+ const checkmark = source.enabled ? "\u2713" : " ";
179
+ const displayName = isDefault ? "Public" : source.name;
180
+ const suffix = isDefault ? " (default)" : "";
181
+ return /* @__PURE__ */ jsxs(Box, { children: [
182
+ /* @__PURE__ */ jsxs(Text, { color: isFocused ? CLI_COLORS.PRIMARY : void 0, bold: isFocused, children: [
183
+ isFocused ? ">" : " ",
184
+ " ",
185
+ checkmark,
186
+ " ",
187
+ displayName
188
+ ] }),
189
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
190
+ " ",
191
+ source.url,
192
+ suffix
193
+ ] })
194
+ ] }, source.name);
195
+ })
196
+ }
197
+ ),
198
+ /* @__PURE__ */ jsx(
199
+ Box,
200
+ {
201
+ flexDirection: "column",
202
+ borderStyle: "round",
203
+ borderColor: addModal.isOpen ? CLI_COLORS.PRIMARY : CLI_COLORS.NEUTRAL,
204
+ paddingX: 1,
205
+ marginTop: 1,
206
+ children: /* @__PURE__ */ jsxs(Text, { color: addModal.isOpen ? CLI_COLORS.PRIMARY : void 0, children: [
207
+ "+ Add source: ",
208
+ addModal.isOpen ? addSourceInput : "",
209
+ addModal.isOpen ? "\u2588" : ""
210
+ ] })
211
+ }
212
+ ),
213
+ statusMessage && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { color: statusMessage.color, children: statusMessage.text }) }),
214
+ /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
215
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
216
+ "Local skills: ",
217
+ summary?.localSkillCount ?? 0,
218
+ " in .claude/skills/"
219
+ ] }),
220
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
221
+ "Plugins: ",
222
+ summary?.pluginSkillCount ?? 0,
223
+ " in .claude/plugins/"
224
+ ] })
225
+ ] }),
226
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: addModal.isOpen ? "ENTER submit ESC cancel" : "A add DEL remove ESC close" }) })
227
+ ] });
228
+ };
229
+
230
+ export {
231
+ StepSettings
232
+ };
233
+ //# sourceMappingURL=chunk-G5WXKKQM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/step-settings.tsx","../src/cli/components/hooks/use-source-operations.ts"],"sourcesContent":["import React, { useState, useEffect, useCallback } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { CLI_COLORS } from \"../../consts.js\";\nimport { ViewTitle } from \"./view-title.js\";\nimport { getSourceSummary, type SourceSummary } from \"../../lib/configuration/source-manager.js\";\nimport { DEFAULT_SOURCE } from \"../../lib/configuration/config.js\";\nimport { useKeyboardNavigation } from \"../hooks/use-keyboard-navigation.js\";\nimport { useModalState } from \"../hooks/use-modal-state.js\";\nimport { useSourceOperations } from \"../hooks/use-source-operations.js\";\nimport { useTextInput } from \"../hooks/use-text-input.js\";\n\nconst DEFAULT_SOURCE_NAME = \"public\";\n\nexport type StepSettingsProps = {\n projectDir: string;\n onClose: () => void;\n};\n\nexport const StepSettings: React.FC<StepSettingsProps> = ({ projectDir, onClose }) => {\n const [summary, setSummary] = useState<SourceSummary | null>(null);\n const addModal = useModalState();\n const {\n value: addSourceInput,\n setValue: setAddSourceInput,\n handleInput: handleTextInput,\n } = useTextInput(\"\");\n const [isLoading, setIsLoading] = useState(true);\n\n const loadSummary = useCallback(async () => {\n try {\n const result = await getSourceSummary(projectDir);\n setSummary(result);\n } catch {\n setSummary({\n sources: [{ name: DEFAULT_SOURCE_NAME, url: DEFAULT_SOURCE, enabled: true }],\n localSkillCount: 0,\n pluginSkillCount: 0,\n });\n }\n setIsLoading(false);\n }, [projectDir]);\n\n useEffect(() => {\n void loadSummary();\n }, [loadSummary]);\n\n const { handleAdd, handleRemove, statusMessage, clearStatus } = useSourceOperations(\n projectDir,\n loadSummary,\n );\n\n const sourceCount = summary?.sources.length ?? 0;\n\n const { focusedIndex, setFocusedIndex } = useKeyboardNavigation(\n sourceCount,\n { onEscape: onClose },\n { wrap: false, vimKeys: false, active: !addModal.isOpen },\n );\n\n useInput((input, key) => {\n if (statusMessage) {\n clearStatus();\n }\n\n if (addModal.isOpen) {\n if (key.escape) {\n addModal.close();\n setAddSourceInput(\"\");\n return;\n }\n\n if (key.return) {\n if (addSourceInput.trim()) {\n addModal.close();\n setAddSourceInput(\"\");\n void handleAdd(addSourceInput.trim());\n }\n return;\n }\n\n handleTextInput(input, key);\n return;\n }\n\n // Non-adding mode: up/down/escape handled by useKeyboardNavigation hook\n\n if (key.return) {\n // Toggle enabled/disabled is a placeholder for future enabledSources store integration\n return;\n }\n\n if (key.backspace || key.delete) {\n if (summary?.sources[focusedIndex]) {\n const source = summary.sources[focusedIndex];\n if (source.name !== DEFAULT_SOURCE_NAME) {\n void handleRemove(source.name).then((success) => {\n if (success) {\n setFocusedIndex((prev) => Math.max(0, prev - 1));\n }\n });\n }\n }\n return;\n }\n\n if (input === \"a\" || input === \"A\") {\n addModal.open(true);\n setAddSourceInput(\"\");\n }\n });\n\n if (isLoading) {\n return (\n <Box flexDirection=\"column\" paddingX={2}>\n <ViewTitle>Skill Sources</ViewTitle>\n <Text dimColor>Loading sources...</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" paddingX={2}>\n <ViewTitle>Skill Sources</ViewTitle>\n <Box marginTop={1} />\n\n <Text bold>Configured marketplaces:</Text>\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={CLI_COLORS.NEUTRAL}\n paddingX={1}\n marginTop={1}\n >\n {summary?.sources.map((source, index) => {\n const isFocused = index === focusedIndex && !addModal.isOpen;\n const isDefault = source.name === DEFAULT_SOURCE_NAME;\n const checkmark = source.enabled ? \"\\u2713\" : \" \";\n const displayName = isDefault ? \"Public\" : source.name;\n const suffix = isDefault ? \" (default)\" : \"\";\n\n return (\n <Box key={source.name}>\n <Text color={isFocused ? CLI_COLORS.PRIMARY : undefined} bold={isFocused}>\n {isFocused ? \">\" : \" \"} {checkmark} {displayName}\n </Text>\n <Text dimColor>\n {\" \"}\n {source.url}\n {suffix}\n </Text>\n </Box>\n );\n })}\n </Box>\n\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={addModal.isOpen ? CLI_COLORS.PRIMARY : CLI_COLORS.NEUTRAL}\n paddingX={1}\n marginTop={1}\n >\n <Text color={addModal.isOpen ? CLI_COLORS.PRIMARY : undefined}>\n + Add source: {addModal.isOpen ? addSourceInput : \"\"}\n {addModal.isOpen ? \"\\u2588\" : \"\"}\n </Text>\n </Box>\n\n {statusMessage && (\n <Box marginTop={1}>\n <Text color={statusMessage.color as \"red\" | \"green\"}>{statusMessage.text}</Text>\n </Box>\n )}\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>Local skills: {summary?.localSkillCount ?? 0} in .claude/skills/</Text>\n <Text dimColor>Plugins: {summary?.pluginSkillCount ?? 0} in .claude/plugins/</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n {addModal.isOpen ? \"ENTER submit ESC cancel\" : \"A add DEL remove ESC close\"}\n </Text>\n </Box>\n </Box>\n );\n};\n","import { useState, useCallback } from \"react\";\nimport { CLI_COLORS } from \"../../consts.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { addSource, removeSource } from \"../../lib/configuration/source-manager.js\";\n\ntype StatusMessage = { text: string; color: string } | null;\n\ntype UseSourceOperationsResult = {\n handleAdd: (url: string) => Promise<void>;\n handleRemove: (name: string) => Promise<boolean>;\n statusMessage: StatusMessage;\n clearStatus: () => void;\n};\n\nexport function useSourceOperations(\n projectDir: string,\n onReload: () => Promise<void>,\n): UseSourceOperationsResult {\n const [statusMessage, setStatusMessage] = useState<StatusMessage>(null);\n\n const handleAdd = useCallback(\n async (url: string) => {\n try {\n const result = await addSource(projectDir, url);\n setStatusMessage({\n text: `Added \"${result.name}\" (${result.skillCount} skills)`,\n color: CLI_COLORS.SUCCESS,\n });\n await onReload();\n } catch (error) {\n const message = getErrorMessage(error);\n setStatusMessage({ text: `Failed to add source: ${message}`, color: CLI_COLORS.ERROR });\n }\n },\n [projectDir, onReload],\n );\n\n const handleRemove = useCallback(\n async (name: string): Promise<boolean> => {\n try {\n await removeSource(projectDir, name);\n setStatusMessage({ text: `Removed \"${name}\"`, color: CLI_COLORS.SUCCESS });\n await onReload();\n return true;\n } catch (error) {\n const message = getErrorMessage(error);\n setStatusMessage({ text: `Failed to remove: ${message}`, color: CLI_COLORS.ERROR });\n return false;\n }\n },\n [projectDir, onReload],\n );\n\n const clearStatus = useCallback(() => {\n setStatusMessage(null);\n }, []);\n\n return { handleAdd, handleRemove, statusMessage, clearStatus };\n}\n"],"mappings":"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","names":["useState","useCallback","useState","useCallback"]}