@claude-collective/cli 0.2.0 → 0.6.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 (166) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/README.md +1 -1
  3. package/dist/chunk-367K3JB3.js +84 -0
  4. package/dist/chunk-367K3JB3.js.map +1 -0
  5. package/dist/chunk-6ESUJMM7.js +54 -0
  6. package/dist/chunk-6ESUJMM7.js.map +1 -0
  7. package/dist/chunk-6OY6ZYQF.js +93 -0
  8. package/dist/chunk-6OY6ZYQF.js.map +1 -0
  9. package/dist/chunk-6WEQADPL.js +307 -0
  10. package/dist/chunk-6WEQADPL.js.map +1 -0
  11. package/dist/chunk-AU7XVCLO.js +91 -0
  12. package/dist/chunk-AU7XVCLO.js.map +1 -0
  13. package/dist/chunk-AZP2AA5M.js +425 -0
  14. package/dist/chunk-AZP2AA5M.js.map +1 -0
  15. package/dist/chunk-D4IQAT27.js +114 -0
  16. package/dist/chunk-D4IQAT27.js.map +1 -0
  17. package/dist/chunk-DHET7RCE.js +50 -0
  18. package/dist/chunk-DHET7RCE.js.map +1 -0
  19. package/dist/chunk-DHFFRMF6.js +31 -0
  20. package/dist/chunk-DHFFRMF6.js.map +1 -0
  21. package/dist/chunk-FKU7VSUD.js +453 -0
  22. package/dist/chunk-FKU7VSUD.js.map +1 -0
  23. package/dist/chunk-J2Y4A3LP.js +478 -0
  24. package/dist/chunk-J2Y4A3LP.js.map +1 -0
  25. package/dist/chunk-JMQGWQZU.js +607 -0
  26. package/dist/chunk-JMQGWQZU.js.map +1 -0
  27. package/dist/chunk-JY4RO76L.js +73 -0
  28. package/dist/chunk-JY4RO76L.js.map +1 -0
  29. package/dist/chunk-M7YCPFIX.js +108 -0
  30. package/dist/chunk-M7YCPFIX.js.map +1 -0
  31. package/dist/chunk-MJSFR562.js +57 -0
  32. package/dist/chunk-MJSFR562.js.map +1 -0
  33. package/dist/chunk-MMDXNZPF.js +69 -0
  34. package/dist/chunk-MMDXNZPF.js.map +1 -0
  35. package/dist/chunk-MYAVQ23U.js +356 -0
  36. package/dist/chunk-MYAVQ23U.js.map +1 -0
  37. package/dist/chunk-OSQDDJXX.js +146 -0
  38. package/dist/chunk-OSQDDJXX.js.map +1 -0
  39. package/dist/chunk-QESUUPOE.js +241 -0
  40. package/dist/chunk-QESUUPOE.js.map +1 -0
  41. package/dist/chunk-SJYG4EJZ.js +57 -0
  42. package/dist/chunk-SJYG4EJZ.js.map +1 -0
  43. package/dist/chunk-SYQ7R2JO.js +95 -0
  44. package/dist/chunk-SYQ7R2JO.js.map +1 -0
  45. package/dist/chunk-TD643KB3.js +245 -0
  46. package/dist/chunk-TD643KB3.js.map +1 -0
  47. package/dist/chunk-TFV6Z7F7.js +129 -0
  48. package/dist/chunk-TFV6Z7F7.js.map +1 -0
  49. package/dist/chunk-TGOHJCQ4.js +83 -0
  50. package/dist/chunk-TGOHJCQ4.js.map +1 -0
  51. package/dist/chunk-TOPAIL5W.js +22 -0
  52. package/dist/chunk-TOPAIL5W.js.map +1 -0
  53. package/dist/chunk-U4VYHKPM.js +110 -0
  54. package/dist/chunk-U4VYHKPM.js.map +1 -0
  55. package/dist/chunk-UFWNMW3G.js +392 -0
  56. package/dist/chunk-UFWNMW3G.js.map +1 -0
  57. package/dist/chunk-UNHCZRO4.js +64 -0
  58. package/dist/chunk-UNHCZRO4.js.map +1 -0
  59. package/dist/chunk-URDV4OCP.js +308 -0
  60. package/dist/chunk-URDV4OCP.js.map +1 -0
  61. package/dist/chunk-YI6JVSFO.js +43 -0
  62. package/dist/chunk-YI6JVSFO.js.map +1 -0
  63. package/dist/chunk-YNSNRR5D.js +184 -0
  64. package/dist/chunk-YNSNRR5D.js.map +1 -0
  65. package/dist/chunk-Z6DLWTBY.js +46 -0
  66. package/dist/chunk-Z6DLWTBY.js.map +1 -0
  67. package/dist/chunk-ZDQIUHAM.js +89 -0
  68. package/dist/chunk-ZDQIUHAM.js.map +1 -0
  69. package/dist/chunk-ZSKHDU5P.js +124 -0
  70. package/dist/chunk-ZSKHDU5P.js.map +1 -0
  71. package/dist/cli-v2/defaults/agent-mappings.yaml +185 -0
  72. package/dist/commands/build/marketplace.js +295 -0
  73. package/dist/commands/build/marketplace.js.map +1 -0
  74. package/dist/commands/build/plugins.js +362 -0
  75. package/dist/commands/build/plugins.js.map +1 -0
  76. package/dist/commands/build/stack.js +169 -0
  77. package/dist/commands/build/stack.js.map +1 -0
  78. package/dist/commands/compile.js +461 -0
  79. package/dist/commands/compile.js.map +1 -0
  80. package/dist/commands/config/get.js +60 -0
  81. package/dist/commands/config/get.js.map +1 -0
  82. package/dist/commands/config/index.js +22 -0
  83. package/dist/commands/config/index.js.map +1 -0
  84. package/dist/commands/config/path.js +35 -0
  85. package/dist/commands/config/path.js.map +1 -0
  86. package/dist/commands/config/set-project.js +61 -0
  87. package/dist/commands/config/set-project.js.map +1 -0
  88. package/dist/commands/config/set.js +60 -0
  89. package/dist/commands/config/set.js.map +1 -0
  90. package/dist/commands/config/show.js +13 -0
  91. package/dist/commands/config/show.js.map +1 -0
  92. package/dist/commands/config/unset-project.js +57 -0
  93. package/dist/commands/config/unset-project.js.map +1 -0
  94. package/dist/commands/config/unset.js +56 -0
  95. package/dist/commands/config/unset.js.map +1 -0
  96. package/dist/commands/diff.js +755 -0
  97. package/dist/commands/diff.js.map +1 -0
  98. package/dist/commands/doctor.js +413 -0
  99. package/dist/commands/doctor.js.map +1 -0
  100. package/dist/commands/edit.js +253 -0
  101. package/dist/commands/edit.js.map +1 -0
  102. package/dist/commands/eject.js +208 -0
  103. package/dist/commands/eject.js.map +1 -0
  104. package/dist/commands/info.js +205 -0
  105. package/dist/commands/info.js.map +1 -0
  106. package/dist/commands/init.js +914 -0
  107. package/dist/commands/init.js.map +1 -0
  108. package/dist/commands/list.js +44 -0
  109. package/dist/commands/list.js.map +1 -0
  110. package/dist/commands/new/agent.js +230 -0
  111. package/dist/commands/new/agent.js.map +1 -0
  112. package/dist/commands/new/skill.js +204 -0
  113. package/dist/commands/new/skill.js.map +1 -0
  114. package/dist/commands/outdated.js +242 -0
  115. package/dist/commands/outdated.js.map +1 -0
  116. package/dist/commands/search.js +115 -0
  117. package/dist/commands/search.js.map +1 -0
  118. package/dist/commands/test-imports.js +92 -0
  119. package/dist/commands/test-imports.js.map +1 -0
  120. package/dist/commands/uninstall.js +302 -0
  121. package/dist/commands/uninstall.js.map +1 -0
  122. package/dist/commands/update.js +428 -0
  123. package/dist/commands/update.js.map +1 -0
  124. package/dist/commands/validate.js +375 -0
  125. package/dist/commands/validate.js.map +1 -0
  126. package/dist/commands/version/bump.js +95 -0
  127. package/dist/commands/version/bump.js.map +1 -0
  128. package/dist/commands/version/index.js +70 -0
  129. package/dist/commands/version/index.js.map +1 -0
  130. package/dist/commands/version/set.js +101 -0
  131. package/dist/commands/version/set.js.map +1 -0
  132. package/dist/commands/version/show.js +70 -0
  133. package/dist/commands/version/show.js.map +1 -0
  134. package/dist/components/common/confirm.js +9 -0
  135. package/dist/components/common/confirm.js.map +1 -0
  136. package/dist/components/common/message.js +24 -0
  137. package/dist/components/common/message.js.map +1 -0
  138. package/dist/components/common/spinner.js +14 -0
  139. package/dist/components/common/spinner.js.map +1 -0
  140. package/dist/components/wizard/selection-header.js +11 -0
  141. package/dist/components/wizard/selection-header.js.map +1 -0
  142. package/dist/components/wizard/step-approach.js +11 -0
  143. package/dist/components/wizard/step-approach.js.map +1 -0
  144. package/dist/components/wizard/step-category.js +12 -0
  145. package/dist/components/wizard/step-category.js.map +1 -0
  146. package/dist/components/wizard/step-confirm.js +12 -0
  147. package/dist/components/wizard/step-confirm.js.map +1 -0
  148. package/dist/components/wizard/step-stack.js +11 -0
  149. package/dist/components/wizard/step-stack.js.map +1 -0
  150. package/dist/components/wizard/step-subcategory.js +13 -0
  151. package/dist/components/wizard/step-subcategory.js.map +1 -0
  152. package/dist/components/wizard/wizard.js +19 -0
  153. package/dist/components/wizard/wizard.js.map +1 -0
  154. package/dist/hooks/init.js +41 -0
  155. package/dist/hooks/init.js.map +1 -0
  156. package/dist/index.js +10 -0
  157. package/dist/index.js.map +1 -0
  158. package/dist/magic-string.es-RGXYGAW3.js +1316 -0
  159. package/dist/magic-string.es-RGXYGAW3.js.map +1 -0
  160. package/dist/stores/wizard-store.js +10 -0
  161. package/dist/stores/wizard-store.js.map +1 -0
  162. package/dist/stores/wizard-store.test.js +15991 -0
  163. package/dist/stores/wizard-store.test.js.map +1 -0
  164. package/package.json +44 -25
  165. package/dist/cli/index.js +0 -6314
  166. package/dist/cli/index.js.map +0 -1
@@ -0,0 +1,308 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ isLegacyStackConfig,
4
+ loadProjectConfig,
5
+ normalizeStackConfig
6
+ } from "./chunk-MYAVQ23U.js";
7
+ import {
8
+ compileAgentForPlugin
9
+ } from "./chunk-UFWNMW3G.js";
10
+ import {
11
+ createLiquidEngine,
12
+ resolveAgents,
13
+ resolveStackSkills
14
+ } from "./chunk-J2Y4A3LP.js";
15
+ import {
16
+ getPluginAgentsDir
17
+ } from "./chunk-D4IQAT27.js";
18
+ import {
19
+ loadAllAgents,
20
+ loadPluginSkills
21
+ } from "./chunk-JMQGWQZU.js";
22
+ import {
23
+ verbose
24
+ } from "./chunk-TOPAIL5W.js";
25
+ import {
26
+ ensureDir,
27
+ fileExists,
28
+ glob,
29
+ readFile,
30
+ writeFile
31
+ } from "./chunk-MMDXNZPF.js";
32
+ import {
33
+ init_esm_shims
34
+ } from "./chunk-DHET7RCE.js";
35
+
36
+ // src/cli-v2/lib/agent-recompiler.ts
37
+ init_esm_shims();
38
+ import path from "path";
39
+
40
+ // src/cli-v2/lib/custom-agent-resolver.ts
41
+ init_esm_shims();
42
+ var DEFAULT_TOOLS = ["Read", "Grep", "Glob"];
43
+ var CUSTOM_AGENT_PATH = "_custom";
44
+ function resolveCustomAgent(agentId, customConfig, builtinAgents) {
45
+ let baseAgent = {};
46
+ if (customConfig.extends) {
47
+ const base = builtinAgents[customConfig.extends];
48
+ if (!base) {
49
+ const availableAgents = Object.keys(builtinAgents);
50
+ const agentList = availableAgents.length > 0 ? `Available agents: ${availableAgents.slice(0, 5).join(", ")}${availableAgents.length > 5 ? ` (and ${availableAgents.length - 5} more)` : ""}` : "No built-in agents found";
51
+ throw new Error(
52
+ `Custom agent "${agentId}" extends unknown agent "${customConfig.extends}". ${agentList}`
53
+ );
54
+ }
55
+ baseAgent = { ...base };
56
+ }
57
+ let disallowedTools;
58
+ if (customConfig.disallowed_tools || baseAgent.disallowed_tools) {
59
+ const merged = /* @__PURE__ */ new Set([
60
+ ...baseAgent.disallowed_tools || [],
61
+ ...customConfig.disallowed_tools || []
62
+ ]);
63
+ disallowedTools = [...merged];
64
+ }
65
+ let hooks;
66
+ if (customConfig.hooks || baseAgent.hooks) {
67
+ hooks = { ...baseAgent.hooks };
68
+ if (customConfig.hooks) {
69
+ for (const [hookType, hookDefs] of Object.entries(customConfig.hooks)) {
70
+ if (hooks[hookType]) {
71
+ hooks[hookType] = [...hooks[hookType], ...hookDefs];
72
+ } else {
73
+ hooks[hookType] = hookDefs;
74
+ }
75
+ }
76
+ }
77
+ }
78
+ return {
79
+ title: customConfig.title,
80
+ description: customConfig.description,
81
+ model: customConfig.model || baseAgent.model,
82
+ tools: customConfig.tools || baseAgent.tools || DEFAULT_TOOLS,
83
+ disallowed_tools: disallowedTools,
84
+ permission_mode: customConfig.permission_mode || baseAgent.permission_mode,
85
+ hooks,
86
+ // Use extended agent's path for template resolution, or _custom for standalone
87
+ path: baseAgent.path || CUSTOM_AGENT_PATH,
88
+ sourceRoot: baseAgent.sourceRoot
89
+ };
90
+ }
91
+ function resolveCustomAgents(customAgents, builtinAgents) {
92
+ const resolved = {};
93
+ for (const [id, config] of Object.entries(customAgents)) {
94
+ resolved[id] = resolveCustomAgent(id, config, builtinAgents);
95
+ }
96
+ return resolved;
97
+ }
98
+ function hasAgentIdConflict(customAgentId, builtinAgents) {
99
+ return customAgentId in builtinAgents;
100
+ }
101
+ function validateCustomAgentIds(customAgents, builtinAgents) {
102
+ const errors = [];
103
+ for (const customId of Object.keys(customAgents)) {
104
+ if (hasAgentIdConflict(customId, builtinAgents)) {
105
+ errors.push(
106
+ `Custom agent "${customId}" conflicts with built-in agent of the same name. Choose a unique name.`
107
+ );
108
+ }
109
+ }
110
+ return errors;
111
+ }
112
+
113
+ // src/cli-v2/lib/agent-recompiler.ts
114
+ import { parse as parseYaml } from "yaml";
115
+ async function getExistingAgentNames(pluginDir) {
116
+ const agentsDir = getPluginAgentsDir(pluginDir);
117
+ const files = await glob("*.md", agentsDir);
118
+ return files.map((f) => path.basename(f, ".md"));
119
+ }
120
+ async function loadConfigWithFallback(pluginDir) {
121
+ const legacyConfigPath = path.join(pluginDir, "config.yaml");
122
+ if (await fileExists(legacyConfigPath)) {
123
+ try {
124
+ const content = await readFile(legacyConfigPath);
125
+ const parsed = parseYaml(content);
126
+ if (parsed && typeof parsed === "object") {
127
+ verbose(`Loaded config.yaml from ${legacyConfigPath}`);
128
+ if (isLegacyStackConfig(parsed)) {
129
+ const normalized = normalizeStackConfig(parsed);
130
+ return {
131
+ config: normalized,
132
+ configPath: legacyConfigPath,
133
+ isLegacy: true
134
+ };
135
+ }
136
+ return {
137
+ config: parsed,
138
+ configPath: legacyConfigPath,
139
+ isLegacy: false
140
+ };
141
+ }
142
+ } catch (error) {
143
+ verbose(`Failed to parse config.yaml: ${error}`);
144
+ }
145
+ }
146
+ return loadProjectConfig(pluginDir);
147
+ }
148
+ function projectConfigToStackLike(config) {
149
+ return {
150
+ name: config.name,
151
+ version: "1.0.0",
152
+ author: config.author ?? "@unknown",
153
+ description: config.description,
154
+ skills: config.skills?.map((s) => typeof s === "string" ? { id: s } : s) ?? [],
155
+ agents: config.agents,
156
+ agent_skills: config.agent_skills,
157
+ hooks: config.hooks,
158
+ framework: config.framework,
159
+ philosophy: config.philosophy,
160
+ principles: config.principles,
161
+ tags: config.tags
162
+ };
163
+ }
164
+ async function recompileAgents(options) {
165
+ const {
166
+ pluginDir,
167
+ sourcePath,
168
+ agents: specifiedAgents,
169
+ skills: providedSkills,
170
+ projectDir,
171
+ outputDir
172
+ } = options;
173
+ const result = {
174
+ compiled: [],
175
+ failed: [],
176
+ warnings: []
177
+ };
178
+ const loadedConfig = await loadConfigWithFallback(pluginDir);
179
+ const projectConfig = loadedConfig?.config ?? null;
180
+ const builtinAgents = await loadAllAgents(sourcePath);
181
+ let allAgents = { ...builtinAgents };
182
+ if (projectConfig?.custom_agents) {
183
+ const idConflicts = validateCustomAgentIds(
184
+ projectConfig.custom_agents,
185
+ builtinAgents
186
+ );
187
+ if (idConflicts.length > 0) {
188
+ for (const error of idConflicts) {
189
+ result.warnings.push(error);
190
+ }
191
+ }
192
+ try {
193
+ const resolvedCustomAgents = resolveCustomAgents(
194
+ projectConfig.custom_agents,
195
+ builtinAgents
196
+ );
197
+ allAgents = { ...builtinAgents, ...resolvedCustomAgents };
198
+ verbose(
199
+ `Resolved ${Object.keys(resolvedCustomAgents).length} custom agents`
200
+ );
201
+ } catch (error) {
202
+ result.warnings.push(
203
+ `Failed to resolve custom agents: ${error instanceof Error ? error.message : String(error)}`
204
+ );
205
+ }
206
+ }
207
+ const pluginConfig = projectConfig ? projectConfigToStackLike(projectConfig) : null;
208
+ let agentNames;
209
+ if (specifiedAgents) {
210
+ agentNames = specifiedAgents;
211
+ } else if (pluginConfig?.agents) {
212
+ agentNames = pluginConfig.agents;
213
+ verbose(`Using agents from config.yaml: ${agentNames.join(", ")}`);
214
+ } else if (outputDir) {
215
+ agentNames = Object.keys(allAgents);
216
+ verbose(`Using all available agents from source: ${agentNames.join(", ")}`);
217
+ } else {
218
+ agentNames = await getExistingAgentNames(pluginDir);
219
+ }
220
+ if (agentNames.length === 0) {
221
+ result.warnings.push("No agents found to recompile");
222
+ return result;
223
+ }
224
+ verbose(
225
+ `Recompiling ${agentNames.length} agents in ${outputDir ?? pluginDir}`
226
+ );
227
+ const pluginSkills = providedSkills ?? await loadPluginSkills(pluginDir);
228
+ const compileAgents = {};
229
+ for (const agentName of agentNames) {
230
+ if (allAgents[agentName]) {
231
+ const customAgentConfig = projectConfig?.custom_agents?.[agentName];
232
+ if (customAgentConfig?.skills && customAgentConfig.skills.length > 0) {
233
+ const skillRefs = customAgentConfig.skills.map(
234
+ (s) => ({
235
+ id: typeof s === "string" ? s : s.id,
236
+ usage: `when working with ${(typeof s === "string" ? s : s.id).split(" ")[0]}`,
237
+ preloaded: (typeof s === "object" && "preloaded" in s && s.preloaded) ?? false
238
+ })
239
+ );
240
+ compileAgents[agentName] = { skills: skillRefs };
241
+ verbose(
242
+ ` Agent ${agentName}: ${skillRefs.length} skills from custom_agents`
243
+ );
244
+ } else if (pluginConfig?.agent_skills?.[agentName]) {
245
+ const skillRefs = resolveStackSkills(
246
+ pluginConfig,
247
+ agentName,
248
+ pluginSkills
249
+ );
250
+ compileAgents[agentName] = { skills: skillRefs };
251
+ verbose(` Agent ${agentName}: ${skillRefs.length} skills from config`);
252
+ } else if (pluginConfig?.skills) {
253
+ const skillRefs = pluginConfig.skills.map((s) => ({
254
+ id: s.id,
255
+ usage: `when working with ${s.id.split(" ")[0]}`,
256
+ preloaded: s.preloaded ?? false
257
+ }));
258
+ compileAgents[agentName] = { skills: skillRefs };
259
+ verbose(` Agent ${agentName}: ${skillRefs.length} skills (all)`);
260
+ } else {
261
+ compileAgents[agentName] = {};
262
+ }
263
+ } else {
264
+ result.warnings.push(
265
+ `Agent "${agentName}" not found in source definitions`
266
+ );
267
+ }
268
+ }
269
+ const compileConfig = {
270
+ name: pluginConfig?.name || path.basename(pluginDir),
271
+ description: pluginConfig?.description || "Recompiled plugin",
272
+ claude_md: "",
273
+ agents: compileAgents
274
+ };
275
+ const engine = await createLiquidEngine(projectDir);
276
+ const resolvedAgents = await resolveAgents(
277
+ allAgents,
278
+ pluginSkills,
279
+ compileConfig,
280
+ sourcePath
281
+ );
282
+ const agentsDir = outputDir ?? getPluginAgentsDir(pluginDir);
283
+ await ensureDir(agentsDir);
284
+ for (const [name, agent] of Object.entries(resolvedAgents)) {
285
+ try {
286
+ const output = await compileAgentForPlugin(
287
+ name,
288
+ agent,
289
+ sourcePath,
290
+ engine
291
+ );
292
+ await writeFile(path.join(agentsDir, `${name}.md`), output);
293
+ result.compiled.push(name);
294
+ verbose(` Recompiled: ${name}`);
295
+ } catch (error) {
296
+ result.failed.push(name);
297
+ result.warnings.push(
298
+ `Failed to compile ${name}: ${error instanceof Error ? error.message : String(error)}`
299
+ );
300
+ }
301
+ }
302
+ return result;
303
+ }
304
+
305
+ export {
306
+ recompileAgents
307
+ };
308
+ //# sourceMappingURL=chunk-URDV4OCP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli-v2/lib/agent-recompiler.ts","../src/cli-v2/lib/custom-agent-resolver.ts"],"sourcesContent":["import path from \"path\";\nimport { glob, writeFile, ensureDir, readFile, fileExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport { loadAllAgents, loadPluginSkills } from \"./loader\";\nimport { resolveAgents, resolveStackSkills } from \"./resolver\";\nimport { compileAgentForPlugin } from \"./stack-plugin-compiler\";\nimport { getPluginAgentsDir } from \"./plugin-finder\";\nimport { createLiquidEngine } from \"./compiler\";\nimport {\n loadProjectConfig,\n isLegacyStackConfig,\n normalizeStackConfig,\n type LoadedProjectConfig,\n} from \"./project-config\";\nimport {\n resolveCustomAgents,\n validateCustomAgentIds,\n} from \"./custom-agent-resolver\";\nimport { parse as parseYaml } from \"yaml\";\nimport type {\n CompileConfig,\n CompileAgentConfig,\n StackConfig,\n SkillReference,\n SkillDefinition,\n ProjectConfig,\n AgentDefinition,\n} from \"../../types\";\n\nexport interface RecompileAgentsOptions {\n pluginDir: string;\n sourcePath: string;\n agents?: string[];\n skills?: Record<string, SkillDefinition>;\n projectDir?: string;\n outputDir?: string;\n}\n\nexport interface RecompileAgentsResult {\n compiled: string[];\n failed: string[];\n warnings: string[];\n}\n\nasync function getExistingAgentNames(pluginDir: string): Promise<string[]> {\n const agentsDir = getPluginAgentsDir(pluginDir);\n const files = await glob(\"*.md\", agentsDir);\n return files.map((f) => path.basename(f, \".md\"));\n}\n\n/**\n * Load config from either:\n * 1. pluginDir/config.yaml (legacy plugin location)\n * 2. pluginDir/.claude/config.yaml (new project config location)\n *\n * This provides backward compatibility with existing plugins.\n */\nasync function loadConfigWithFallback(\n pluginDir: string,\n): Promise<LoadedProjectConfig | null> {\n // First try the legacy plugin location (pluginDir/config.yaml)\n const legacyConfigPath = path.join(pluginDir, \"config.yaml\");\n if (await fileExists(legacyConfigPath)) {\n try {\n const content = await readFile(legacyConfigPath);\n const parsed = parseYaml(content);\n\n if (parsed && typeof parsed === \"object\") {\n verbose(`Loaded config.yaml from ${legacyConfigPath}`);\n\n // Check if it's legacy StackConfig format\n if (isLegacyStackConfig(parsed)) {\n const normalized = normalizeStackConfig(parsed as StackConfig);\n return {\n config: normalized,\n configPath: legacyConfigPath,\n isLegacy: true,\n };\n }\n\n return {\n config: parsed as ProjectConfig,\n configPath: legacyConfigPath,\n isLegacy: false,\n };\n }\n } catch (error) {\n verbose(`Failed to parse config.yaml: ${error}`);\n }\n }\n\n // Fall back to project config location (.claude/config.yaml)\n return loadProjectConfig(pluginDir);\n}\n\n/**\n * Convert ProjectConfig to StackConfig-like structure for compatibility\n * with existing resolveStackSkills function\n */\nfunction projectConfigToStackLike(config: ProjectConfig): StackConfig {\n return {\n name: config.name,\n version: \"1.0.0\",\n author: config.author ?? \"@unknown\",\n description: config.description,\n skills:\n config.skills?.map((s) => (typeof s === \"string\" ? { id: s } : s)) ?? [],\n agents: config.agents,\n agent_skills: config.agent_skills as StackConfig[\"agent_skills\"],\n hooks: config.hooks,\n framework: config.framework,\n philosophy: config.philosophy,\n principles: config.principles,\n tags: config.tags,\n };\n}\n\nexport async function recompileAgents(\n options: RecompileAgentsOptions,\n): Promise<RecompileAgentsResult> {\n const {\n pluginDir,\n sourcePath,\n agents: specifiedAgents,\n skills: providedSkills,\n projectDir,\n outputDir,\n } = options;\n\n const result: RecompileAgentsResult = {\n compiled: [],\n failed: [],\n warnings: [],\n };\n\n // Load project config (handles both legacy plugin config and new ProjectConfig)\n const loadedConfig = await loadConfigWithFallback(pluginDir);\n const projectConfig = loadedConfig?.config ?? null;\n\n // Load built-in agents from source\n const builtinAgents = await loadAllAgents(sourcePath);\n\n // Resolve custom agents and merge with built-in agents\n let allAgents: Record<string, AgentDefinition> = { ...builtinAgents };\n if (projectConfig?.custom_agents) {\n // Validate custom agent IDs don't conflict with built-in agents\n const idConflicts = validateCustomAgentIds(\n projectConfig.custom_agents,\n builtinAgents,\n );\n if (idConflicts.length > 0) {\n for (const error of idConflicts) {\n result.warnings.push(error);\n }\n }\n\n // Resolve custom agents to AgentDefinition\n try {\n const resolvedCustomAgents = resolveCustomAgents(\n projectConfig.custom_agents,\n builtinAgents,\n );\n // Merge: custom agents can override built-in if same name (though we warn above)\n allAgents = { ...builtinAgents, ...resolvedCustomAgents };\n verbose(\n `Resolved ${Object.keys(resolvedCustomAgents).length} custom agents`,\n );\n } catch (error) {\n result.warnings.push(\n `Failed to resolve custom agents: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n // Convert to StackConfig-like for compatibility with existing functions\n const pluginConfig = projectConfig\n ? projectConfigToStackLike(projectConfig)\n : null;\n\n let agentNames: string[];\n if (specifiedAgents) {\n agentNames = specifiedAgents;\n } else if (pluginConfig?.agents) {\n agentNames = pluginConfig.agents;\n verbose(`Using agents from config.yaml: ${agentNames.join(\", \")}`);\n } else if (outputDir) {\n agentNames = Object.keys(allAgents);\n verbose(`Using all available agents from source: ${agentNames.join(\", \")}`);\n } else {\n agentNames = await getExistingAgentNames(pluginDir);\n }\n\n if (agentNames.length === 0) {\n result.warnings.push(\"No agents found to recompile\");\n return result;\n }\n\n verbose(\n `Recompiling ${agentNames.length} agents in ${outputDir ?? pluginDir}`,\n );\n\n const pluginSkills = providedSkills ?? (await loadPluginSkills(pluginDir));\n\n const compileAgents: Record<string, CompileAgentConfig> = {};\n for (const agentName of agentNames) {\n if (allAgents[agentName]) {\n // Check if this is a custom agent with its own skills defined\n const customAgentConfig = projectConfig?.custom_agents?.[agentName];\n if (customAgentConfig?.skills && customAgentConfig.skills.length > 0) {\n // Custom agent has explicit skills defined\n const skillRefs: SkillReference[] = customAgentConfig.skills.map(\n (s) => ({\n id: typeof s === \"string\" ? s : s.id,\n usage: `when working with ${(typeof s === \"string\" ? s : s.id).split(\" \")[0]}`,\n preloaded:\n (typeof s === \"object\" && \"preloaded\" in s && s.preloaded) ??\n false,\n }),\n );\n compileAgents[agentName] = { skills: skillRefs };\n verbose(\n ` Agent ${agentName}: ${skillRefs.length} skills from custom_agents`,\n );\n } else if (pluginConfig?.agent_skills?.[agentName]) {\n const skillRefs = resolveStackSkills(\n pluginConfig,\n agentName,\n pluginSkills,\n );\n compileAgents[agentName] = { skills: skillRefs };\n verbose(` Agent ${agentName}: ${skillRefs.length} skills from config`);\n } else if (pluginConfig?.skills) {\n // Fall back to all skills in the config\n const skillRefs: SkillReference[] = pluginConfig.skills.map((s) => ({\n id: s.id,\n usage: `when working with ${s.id.split(\" \")[0]}`,\n preloaded: s.preloaded ?? false,\n }));\n compileAgents[agentName] = { skills: skillRefs };\n verbose(` Agent ${agentName}: ${skillRefs.length} skills (all)`);\n } else {\n compileAgents[agentName] = {};\n }\n } else {\n result.warnings.push(\n `Agent \"${agentName}\" not found in source definitions`,\n );\n }\n }\n\n const compileConfig: CompileConfig = {\n name: pluginConfig?.name || path.basename(pluginDir),\n description: pluginConfig?.description || \"Recompiled plugin\",\n claude_md: \"\",\n agents: compileAgents,\n };\n\n const engine = await createLiquidEngine(projectDir);\n const resolvedAgents = await resolveAgents(\n allAgents,\n pluginSkills,\n compileConfig,\n sourcePath,\n );\n\n const agentsDir = outputDir ?? getPluginAgentsDir(pluginDir);\n await ensureDir(agentsDir);\n\n for (const [name, agent] of Object.entries(resolvedAgents)) {\n try {\n const output = await compileAgentForPlugin(\n name,\n agent,\n sourcePath,\n engine,\n );\n await writeFile(path.join(agentsDir, `${name}.md`), output);\n result.compiled.push(name);\n verbose(` Recompiled: ${name}`);\n } catch (error) {\n result.failed.push(name);\n result.warnings.push(\n `Failed to compile ${name}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n return result;\n}\n","import type { CustomAgentConfig, AgentDefinition } from \"../../types\";\n\n/** Default tools for standalone custom agents (no extends) */\nconst DEFAULT_TOOLS = [\"Read\", \"Grep\", \"Glob\"];\n\n/** Marker path for standalone custom agents (no extends) */\nconst CUSTOM_AGENT_PATH = \"_custom\";\n\n/**\n * Resolve a custom agent config to a full AgentDefinition.\n * If extends is specified, inherit from the base agent.\n *\n * @param agentId - The custom agent's identifier\n * @param customConfig - The custom agent configuration from config.yaml\n * @param builtinAgents - Record of built-in agent definitions to extend from\n * @returns Fully resolved AgentDefinition\n * @throws Error if extends references an unknown agent\n */\nexport function resolveCustomAgent(\n agentId: string,\n customConfig: CustomAgentConfig,\n builtinAgents: Record<string, AgentDefinition>,\n): AgentDefinition {\n let baseAgent: Partial<AgentDefinition> = {};\n\n if (customConfig.extends) {\n const base = builtinAgents[customConfig.extends];\n if (!base) {\n const availableAgents = Object.keys(builtinAgents);\n const agentList =\n availableAgents.length > 0\n ? `Available agents: ${availableAgents.slice(0, 5).join(\", \")}${availableAgents.length > 5 ? ` (and ${availableAgents.length - 5} more)` : \"\"}`\n : \"No built-in agents found\";\n throw new Error(\n `Custom agent \"${agentId}\" extends unknown agent \"${customConfig.extends}\". ${agentList}`,\n );\n }\n baseAgent = { ...base };\n }\n\n // Merge disallowed_tools: custom + inherited\n let disallowedTools: string[] | undefined;\n if (customConfig.disallowed_tools || baseAgent.disallowed_tools) {\n const merged = new Set<string>([\n ...(baseAgent.disallowed_tools || []),\n ...(customConfig.disallowed_tools || []),\n ]);\n disallowedTools = [...merged];\n }\n\n // Merge hooks: custom hooks added to inherited\n let hooks: AgentDefinition[\"hooks\"] | undefined;\n if (customConfig.hooks || baseAgent.hooks) {\n hooks = { ...baseAgent.hooks };\n if (customConfig.hooks) {\n for (const [hookType, hookDefs] of Object.entries(customConfig.hooks)) {\n if (hooks[hookType]) {\n hooks[hookType] = [...hooks[hookType], ...hookDefs];\n } else {\n hooks[hookType] = hookDefs;\n }\n }\n }\n }\n\n return {\n title: customConfig.title,\n description: customConfig.description,\n model: customConfig.model || baseAgent.model,\n tools: customConfig.tools || baseAgent.tools || DEFAULT_TOOLS,\n disallowed_tools: disallowedTools,\n permission_mode: customConfig.permission_mode || baseAgent.permission_mode,\n hooks,\n // Use extended agent's path for template resolution, or _custom for standalone\n path: baseAgent.path || CUSTOM_AGENT_PATH,\n sourceRoot: baseAgent.sourceRoot,\n };\n}\n\n/**\n * Resolve all custom agents from config to AgentDefinition records.\n *\n * @param customAgents - Record of custom agent configs from config.yaml\n * @param builtinAgents - Record of built-in agent definitions\n * @returns Record of resolved AgentDefinitions keyed by custom agent ID\n */\nexport function resolveCustomAgents(\n customAgents: Record<string, CustomAgentConfig>,\n builtinAgents: Record<string, AgentDefinition>,\n): Record<string, AgentDefinition> {\n const resolved: Record<string, AgentDefinition> = {};\n\n for (const [id, config] of Object.entries(customAgents)) {\n resolved[id] = resolveCustomAgent(id, config, builtinAgents);\n }\n\n return resolved;\n}\n\n/**\n * Check if a custom agent ID conflicts with a built-in agent ID.\n *\n * @param customAgentId - The custom agent's identifier\n * @param builtinAgents - Record of built-in agent definitions\n * @returns true if there's a conflict\n */\nexport function hasAgentIdConflict(\n customAgentId: string,\n builtinAgents: Record<string, AgentDefinition>,\n): boolean {\n return customAgentId in builtinAgents;\n}\n\n/**\n * Validate custom agents don't conflict with built-in agents.\n *\n * @param customAgents - Record of custom agent configs\n * @param builtinAgents - Record of built-in agent definitions\n * @returns Array of error messages (empty if no conflicts)\n */\nexport function validateCustomAgentIds(\n customAgents: Record<string, CustomAgentConfig>,\n builtinAgents: Record<string, AgentDefinition>,\n): string[] {\n const errors: string[] = [];\n\n for (const customId of Object.keys(customAgents)) {\n if (hasAgentIdConflict(customId, builtinAgents)) {\n errors.push(\n `Custom agent \"${customId}\" conflicts with built-in agent of the same name. Choose a unique name.`,\n );\n }\n }\n\n return errors;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ useWizardStore
4
+ } from "./chunk-6OY6ZYQF.js";
5
+ import {
6
+ init_esm_shims
7
+ } from "./chunk-DHET7RCE.js";
8
+
9
+ // src/cli-v2/components/wizard/step-stack.tsx
10
+ init_esm_shims();
11
+ import { Box, Text } from "ink";
12
+ import { Select } from "@inkjs/ui";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+ var StepStack = ({ matrix }) => {
15
+ const { selectStack, setStep, goBack } = useWizardStore();
16
+ const options = [
17
+ { value: "_back", label: "\u2190 Back" },
18
+ ...matrix.suggestedStacks.map((stack) => ({
19
+ value: stack.id,
20
+ label: `${stack.name} - ${stack.description}`
21
+ }))
22
+ ];
23
+ const handleSelect = (value) => {
24
+ if (value === "_back") {
25
+ goBack();
26
+ return;
27
+ }
28
+ const stack = matrix.suggestedStacks.find((s) => s.id === value);
29
+ if (stack) {
30
+ selectStack(stack);
31
+ setStep("confirm");
32
+ }
33
+ };
34
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
35
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Select a pre-built template:" }),
36
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Select, { options, onChange: handleSelect }) })
37
+ ] });
38
+ };
39
+
40
+ export {
41
+ StepStack
42
+ };
43
+ //# sourceMappingURL=chunk-YI6JVSFO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli-v2/components/wizard/step-stack.tsx"],"sourcesContent":["import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { Select } from \"@inkjs/ui\";\nimport { useWizardStore } from \"../../stores/wizard-store.js\";\nimport type { MergedSkillsMatrix } from \"../../types-matrix.js\";\n\ninterface StepStackProps {\n matrix: MergedSkillsMatrix;\n}\n\nexport const StepStack: React.FC<StepStackProps> = ({ matrix }) => {\n const { selectStack, setStep, goBack } = useWizardStore();\n\n // Build options from matrix.suggestedStacks\n const options = [\n { value: \"_back\", label: \"← Back\" },\n ...matrix.suggestedStacks.map((stack) => ({\n value: stack.id,\n label: `${stack.name} - ${stack.description}`,\n })),\n ];\n\n const handleSelect = (value: string) => {\n if (value === \"_back\") {\n goBack();\n return;\n }\n\n const stack = matrix.suggestedStacks.find((s) => s.id === value);\n if (stack) {\n selectStack(stack);\n setStep(\"confirm\");\n }\n };\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>Select a pre-built template:</Text>\n <Box marginTop={1}>\n <Select options={options} onChange={handleSelect} />\n </Box>\n </Box>\n );\n};\n"],"mappings":";;;;;;;;;AAAA;AACA,SAAS,KAAK,YAAY;AAC1B,SAAS,cAAc;AAkCnB,SACE,KADF;AA1BG,IAAM,YAAsC,CAAC,EAAE,OAAO,MAAM;AACjE,QAAM,EAAE,aAAa,SAAS,OAAO,IAAI,eAAe;AAGxD,QAAM,UAAU;AAAA,IACd,EAAE,OAAO,SAAS,OAAO,cAAS;AAAA,IAClC,GAAG,OAAO,gBAAgB,IAAI,CAAC,WAAW;AAAA,MACxC,OAAO,MAAM;AAAA,MACb,OAAO,GAAG,MAAM,IAAI,MAAM,MAAM,WAAW;AAAA,IAC7C,EAAE;AAAA,EACJ;AAEA,QAAM,eAAe,CAAC,UAAkB;AACtC,QAAI,UAAU,SAAS;AACrB,aAAO;AACP;AAAA,IACF;AAEA,UAAM,QAAQ,OAAO,gBAAgB,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK;AAC/D,QAAI,OAAO;AACT,kBAAY,KAAK;AACjB,cAAQ,SAAS;AAAA,IACnB;AAAA,EACF;AAEA,SACE,qBAAC,OAAI,eAAc,UACjB;AAAA,wBAAC,QAAK,MAAI,MAAC,0CAA4B;AAAA,IACvC,oBAAC,OAAI,WAAW,GACd,8BAAC,UAAO,SAAkB,UAAU,cAAc,GACpD;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ StepCategory
4
+ } from "./chunk-JY4RO76L.js";
5
+ import {
6
+ StepConfirm
7
+ } from "./chunk-TGOHJCQ4.js";
8
+ import {
9
+ StepStack
10
+ } from "./chunk-YI6JVSFO.js";
11
+ import {
12
+ StepSubcategory
13
+ } from "./chunk-TD643KB3.js";
14
+ import {
15
+ validateSelection
16
+ } from "./chunk-AZP2AA5M.js";
17
+ import {
18
+ SelectionHeader
19
+ } from "./chunk-Z6DLWTBY.js";
20
+ import {
21
+ StepApproach
22
+ } from "./chunk-ZDQIUHAM.js";
23
+ import {
24
+ useWizardStore
25
+ } from "./chunk-6OY6ZYQF.js";
26
+ import {
27
+ init_esm_shims
28
+ } from "./chunk-DHET7RCE.js";
29
+
30
+ // src/cli-v2/components/wizard/wizard.tsx
31
+ init_esm_shims();
32
+ import React, { useCallback } from "react";
33
+ import { Box, Text, useApp, useInput } from "ink";
34
+ import { ThemeProvider } from "@inkjs/ui";
35
+
36
+ // src/cli-v2/components/themes/default.ts
37
+ init_esm_shims();
38
+ import { extendTheme, defaultTheme } from "@inkjs/ui";
39
+ var cliTheme = extendTheme(defaultTheme, {
40
+ components: {
41
+ Spinner: {
42
+ styles: {
43
+ frame: () => ({ color: "cyan" }),
44
+ label: () => ({ color: "gray" })
45
+ }
46
+ },
47
+ Select: {
48
+ styles: {
49
+ focusIndicator: () => ({ color: "cyan" }),
50
+ label: ({ isFocused }) => ({
51
+ color: isFocused ? "cyan" : void 0
52
+ })
53
+ }
54
+ },
55
+ MultiSelect: {
56
+ styles: {
57
+ focusIndicator: () => ({ color: "cyan" }),
58
+ label: ({ isFocused, isSelected }) => ({
59
+ color: isFocused ? "cyan" : isSelected ? "green" : void 0
60
+ }),
61
+ checkboxChecked: () => ({ color: "green" })
62
+ }
63
+ },
64
+ StatusMessage: {
65
+ styles: {
66
+ container: ({ variant }) => ({
67
+ borderStyle: "round",
68
+ borderColor: variant === "error" ? "red" : variant === "warning" ? "yellow" : variant === "success" ? "green" : "blue"
69
+ })
70
+ }
71
+ },
72
+ Alert: {
73
+ styles: {
74
+ container: ({ variant }) => ({
75
+ borderColor: variant === "error" ? "red" : variant === "warning" ? "yellow" : variant === "success" ? "green" : "blue"
76
+ }),
77
+ icon: ({ variant }) => ({
78
+ color: variant === "error" ? "red" : variant === "warning" ? "yellow" : variant === "success" ? "green" : "blue"
79
+ })
80
+ }
81
+ },
82
+ TextInput: {
83
+ styles: {
84
+ container: ({ isFocused }) => ({
85
+ borderColor: isFocused ? "cyan" : "gray"
86
+ }),
87
+ cursor: () => ({ color: "cyan" })
88
+ }
89
+ },
90
+ ConfirmInput: {
91
+ styles: {
92
+ highlightedChoice: () => ({ color: "cyan" })
93
+ }
94
+ },
95
+ Badge: {
96
+ styles: {
97
+ container: ({ variant }) => ({
98
+ color: variant === "error" ? "red" : variant === "warning" ? "yellow" : variant === "success" ? "green" : variant === "info" ? "blue" : "cyan"
99
+ })
100
+ }
101
+ }
102
+ }
103
+ });
104
+
105
+ // src/cli-v2/components/wizard/wizard.tsx
106
+ import { jsx, jsxs } from "react/jsx-runtime";
107
+ var Wizard = ({
108
+ matrix,
109
+ onComplete,
110
+ onCancel,
111
+ initialSkills = []
112
+ }) => {
113
+ const {
114
+ step,
115
+ goBack,
116
+ reset,
117
+ selectedSkills,
118
+ selectedStack,
119
+ expertMode,
120
+ installMode
121
+ } = useWizardStore();
122
+ const { exit } = useApp();
123
+ React.useEffect(() => {
124
+ if (initialSkills.length > 0) {
125
+ reset({ initialSkills });
126
+ }
127
+ }, []);
128
+ useInput((input, key) => {
129
+ if (key.escape) {
130
+ if (step === "approach") {
131
+ onCancel();
132
+ exit();
133
+ } else {
134
+ goBack();
135
+ }
136
+ }
137
+ });
138
+ const handleComplete = useCallback(() => {
139
+ const validation = validateSelection(selectedSkills, matrix);
140
+ onComplete({
141
+ selectedSkills,
142
+ selectedStack,
143
+ expertMode,
144
+ installMode,
145
+ cancelled: false,
146
+ validation
147
+ });
148
+ exit();
149
+ }, [
150
+ selectedSkills,
151
+ selectedStack,
152
+ expertMode,
153
+ installMode,
154
+ matrix,
155
+ onComplete,
156
+ exit
157
+ ]);
158
+ const renderStep = () => {
159
+ switch (step) {
160
+ case "approach":
161
+ return /* @__PURE__ */ jsx(StepApproach, {});
162
+ case "stack":
163
+ return /* @__PURE__ */ jsx(StepStack, { matrix });
164
+ case "category":
165
+ return /* @__PURE__ */ jsx(StepCategory, { matrix });
166
+ case "subcategory":
167
+ return /* @__PURE__ */ jsx(StepSubcategory, { matrix });
168
+ case "confirm":
169
+ return /* @__PURE__ */ jsx(StepConfirm, { matrix, onComplete: handleComplete });
170
+ default:
171
+ return null;
172
+ }
173
+ };
174
+ return /* @__PURE__ */ jsx(ThemeProvider, { theme: cliTheme, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
175
+ /* @__PURE__ */ jsx(SelectionHeader, { matrix }),
176
+ renderStep(),
177
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "ESC to go back, Ctrl+C to cancel" }) })
178
+ ] }) });
179
+ };
180
+
181
+ export {
182
+ Wizard
183
+ };
184
+ //# sourceMappingURL=chunk-YNSNRR5D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli-v2/components/wizard/wizard.tsx","../src/cli-v2/components/themes/default.ts"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { Box, Text, useApp, useInput } from \"ink\";\nimport { ThemeProvider } from \"@inkjs/ui\";\nimport { useWizardStore } from \"../../stores/wizard-store.js\";\nimport { cliTheme } from \"../themes/default.js\";\nimport { SelectionHeader } from \"./selection-header.js\";\nimport { StepApproach } from \"./step-approach.js\";\nimport { StepStack } from \"./step-stack.js\";\nimport { StepCategory } from \"./step-category.js\";\nimport { StepSubcategory } from \"./step-subcategory.js\";\nimport { StepConfirm } from \"./step-confirm.js\";\nimport { validateSelection } from \"../../lib/matrix-resolver.js\";\nimport type { MergedSkillsMatrix, ResolvedStack } from \"../../types-matrix.js\";\n\nexport interface WizardResult {\n selectedSkills: string[];\n selectedStack: ResolvedStack | null;\n expertMode: boolean;\n installMode: \"plugin\" | \"local\";\n cancelled: boolean;\n validation: {\n valid: boolean;\n errors: Array<{ message: string }>;\n warnings: Array<{ message: string }>;\n };\n}\n\ninterface WizardProps {\n matrix: MergedSkillsMatrix;\n onComplete: (result: WizardResult) => void;\n onCancel: () => void;\n initialSkills?: string[];\n}\n\nexport const Wizard: React.FC<WizardProps> = ({\n matrix,\n onComplete,\n onCancel,\n initialSkills = [],\n}) => {\n const {\n step,\n goBack,\n reset,\n selectedSkills,\n selectedStack,\n expertMode,\n installMode,\n } = useWizardStore();\n const { exit } = useApp();\n\n // Initialize store with initial skills if provided\n React.useEffect(() => {\n if (initialSkills.length > 0) {\n reset({ initialSkills });\n }\n }, []);\n\n // Handle ESC key for back navigation\n useInput((input, key) => {\n if (key.escape) {\n if (step === \"approach\") {\n onCancel();\n exit();\n } else {\n goBack();\n }\n }\n });\n\n const handleComplete = useCallback(() => {\n const validation = validateSelection(selectedSkills, matrix);\n onComplete({\n selectedSkills,\n selectedStack,\n expertMode,\n installMode,\n cancelled: false,\n validation,\n });\n exit();\n }, [\n selectedSkills,\n selectedStack,\n expertMode,\n installMode,\n matrix,\n onComplete,\n exit,\n ]);\n\n const renderStep = () => {\n switch (step) {\n case \"approach\":\n return <StepApproach />;\n case \"stack\":\n return <StepStack matrix={matrix} />;\n case \"category\":\n return <StepCategory matrix={matrix} />;\n case \"subcategory\":\n return <StepSubcategory matrix={matrix} />;\n case \"confirm\":\n return <StepConfirm matrix={matrix} onComplete={handleComplete} />;\n default:\n return null;\n }\n };\n\n return (\n <ThemeProvider theme={cliTheme}>\n <Box flexDirection=\"column\" padding={1}>\n <SelectionHeader matrix={matrix} />\n {renderStep()}\n <Box marginTop={1}>\n <Text dimColor>ESC to go back, Ctrl+C to cancel</Text>\n </Box>\n </Box>\n </ThemeProvider>\n );\n};\n","import { extendTheme, defaultTheme } from \"@inkjs/ui\";\n\n/**\n * CLI theme matching existing picocolors styling\n *\n * Color scheme:\n * - Cyan: Focus/primary (headings, prompts, selected items)\n * - Green: Success states\n * - Red: Errors\n * - Yellow: Warnings\n * - Blue: Info messages\n */\nexport const cliTheme = extendTheme(defaultTheme, {\n components: {\n Spinner: {\n styles: {\n frame: () => ({ color: \"cyan\" }),\n label: () => ({ color: \"gray\" }),\n },\n },\n Select: {\n styles: {\n focusIndicator: () => ({ color: \"cyan\" }),\n label: ({ isFocused }) => ({\n color: isFocused ? \"cyan\" : undefined,\n }),\n },\n },\n MultiSelect: {\n styles: {\n focusIndicator: () => ({ color: \"cyan\" }),\n label: ({ isFocused, isSelected }) => ({\n color: isFocused ? \"cyan\" : isSelected ? \"green\" : undefined,\n }),\n checkboxChecked: () => ({ color: \"green\" }),\n },\n },\n StatusMessage: {\n styles: {\n container: ({ variant }) => ({\n borderStyle: \"round\",\n borderColor:\n variant === \"error\"\n ? \"red\"\n : variant === \"warning\"\n ? \"yellow\"\n : variant === \"success\"\n ? \"green\"\n : \"blue\",\n }),\n },\n },\n Alert: {\n styles: {\n container: ({ variant }) => ({\n borderColor:\n variant === \"error\"\n ? \"red\"\n : variant === \"warning\"\n ? \"yellow\"\n : variant === \"success\"\n ? \"green\"\n : \"blue\",\n }),\n icon: ({ variant }) => ({\n color:\n variant === \"error\"\n ? \"red\"\n : variant === \"warning\"\n ? \"yellow\"\n : variant === \"success\"\n ? \"green\"\n : \"blue\",\n }),\n },\n },\n TextInput: {\n styles: {\n container: ({ isFocused }) => ({\n borderColor: isFocused ? \"cyan\" : \"gray\",\n }),\n cursor: () => ({ color: \"cyan\" }),\n },\n },\n ConfirmInput: {\n styles: {\n highlightedChoice: () => ({ color: \"cyan\" }),\n },\n },\n Badge: {\n styles: {\n container: ({ variant }) => ({\n color:\n variant === \"error\"\n ? \"red\"\n : variant === \"warning\"\n ? \"yellow\"\n : variant === \"success\"\n ? \"green\"\n : variant === \"info\"\n ? \"blue\"\n : \"cyan\",\n }),\n },\n },\n },\n});\n"],"mappings":"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","names":[]}
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ useWizardStore
4
+ } from "./chunk-6OY6ZYQF.js";
5
+ import {
6
+ init_esm_shims
7
+ } from "./chunk-DHET7RCE.js";
8
+
9
+ // src/cli-v2/components/wizard/selection-header.tsx
10
+ init_esm_shims();
11
+ import { Box, Text } from "ink";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+ var SelectionHeader = ({ matrix }) => {
14
+ const selectedSkills = useWizardStore((state) => state.selectedSkills);
15
+ if (selectedSkills.length === 0) {
16
+ return null;
17
+ }
18
+ const byCategory = {};
19
+ for (const skillId of selectedSkills) {
20
+ const skill = matrix.skills[skillId];
21
+ if (!skill) continue;
22
+ const category = matrix.categories[skill.category];
23
+ const topCategory = category?.parent || skill.category;
24
+ const categoryName = matrix.categories[topCategory]?.name || topCategory;
25
+ if (!byCategory[categoryName]) {
26
+ byCategory[categoryName] = [];
27
+ }
28
+ byCategory[categoryName].push(skill.alias || skill.name);
29
+ }
30
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginY: 1, children: [
31
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(50) }),
32
+ /* @__PURE__ */ jsx(Text, { bold: true, children: " Selected:" }),
33
+ Object.entries(byCategory).map(([category, skills]) => /* @__PURE__ */ jsxs(Text, { children: [
34
+ " ",
35
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: category }),
36
+ ": ",
37
+ skills.join(", ")
38
+ ] }, category)),
39
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(50) })
40
+ ] });
41
+ };
42
+
43
+ export {
44
+ SelectionHeader
45
+ };
46
+ //# sourceMappingURL=chunk-Z6DLWTBY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli-v2/components/wizard/selection-header.tsx"],"sourcesContent":["import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { useWizardStore } from \"../../stores/wizard-store.js\";\nimport type { MergedSkillsMatrix } from \"../../types-matrix.js\";\n\ninterface SelectionHeaderProps {\n matrix: MergedSkillsMatrix;\n}\n\nexport const SelectionHeader: React.FC<SelectionHeaderProps> = ({ matrix }) => {\n const selectedSkills = useWizardStore((state) => state.selectedSkills);\n\n if (selectedSkills.length === 0) {\n return null;\n }\n\n // Group skills by category (same logic as renderSelectionsHeader)\n const byCategory: Record<string, string[]> = {};\n for (const skillId of selectedSkills) {\n const skill = matrix.skills[skillId];\n if (!skill) continue;\n const category = matrix.categories[skill.category];\n const topCategory = category?.parent || skill.category;\n const categoryName = matrix.categories[topCategory]?.name || topCategory;\n\n if (!byCategory[categoryName]) {\n byCategory[categoryName] = [];\n }\n byCategory[categoryName].push(skill.alias || skill.name);\n }\n\n return (\n <Box flexDirection=\"column\" marginY={1}>\n <Text dimColor>{\"─\".repeat(50)}</Text>\n <Text bold> Selected:</Text>\n {Object.entries(byCategory).map(([category, skills]) => (\n <Text key={category}>\n {\" \"}\n <Text color=\"cyan\">{category}</Text>: {skills.join(\", \")}\n </Text>\n ))}\n <Text dimColor>{\"─\".repeat(50)}</Text>\n </Box>\n );\n};\n"],"mappings":";;;;;;;;;AAAA;AACA,SAAS,KAAK,YAAY;AAgCpB,cAGE,YAHF;AAxBC,IAAM,kBAAkD,CAAC,EAAE,OAAO,MAAM;AAC7E,QAAM,iBAAiB,eAAe,CAAC,UAAU,MAAM,cAAc;AAErE,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAO;AAAA,EACT;AAGA,QAAM,aAAuC,CAAC;AAC9C,aAAW,WAAW,gBAAgB;AACpC,UAAM,QAAQ,OAAO,OAAO,OAAO;AACnC,QAAI,CAAC,MAAO;AACZ,UAAM,WAAW,OAAO,WAAW,MAAM,QAAQ;AACjD,UAAM,cAAc,UAAU,UAAU,MAAM;AAC9C,UAAM,eAAe,OAAO,WAAW,WAAW,GAAG,QAAQ;AAE7D,QAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,iBAAW,YAAY,IAAI,CAAC;AAAA,IAC9B;AACA,eAAW,YAAY,EAAE,KAAK,MAAM,SAAS,MAAM,IAAI;AAAA,EACzD;AAEA,SACE,qBAAC,OAAI,eAAc,UAAS,SAAS,GACnC;AAAA,wBAAC,QAAK,UAAQ,MAAE,mBAAI,OAAO,EAAE,GAAE;AAAA,IAC/B,oBAAC,QAAK,MAAI,MAAC,wBAAU;AAAA,IACpB,OAAO,QAAQ,UAAU,EAAE,IAAI,CAAC,CAAC,UAAU,MAAM,MAChD,qBAAC,QACE;AAAA;AAAA,MACD,oBAAC,QAAK,OAAM,QAAQ,oBAAS;AAAA,MAAO;AAAA,MAAG,OAAO,KAAK,IAAI;AAAA,SAF9C,QAGX,CACD;AAAA,IACD,oBAAC,QAAK,UAAQ,MAAE,mBAAI,OAAO,EAAE,GAAE;AAAA,KACjC;AAEJ;","names":[]}