@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.
- package/CHANGELOG.md +113 -0
- package/README.md +1 -1
- package/dist/chunk-367K3JB3.js +84 -0
- package/dist/chunk-367K3JB3.js.map +1 -0
- package/dist/chunk-6ESUJMM7.js +54 -0
- package/dist/chunk-6ESUJMM7.js.map +1 -0
- package/dist/chunk-6OY6ZYQF.js +93 -0
- package/dist/chunk-6OY6ZYQF.js.map +1 -0
- package/dist/chunk-6WEQADPL.js +307 -0
- package/dist/chunk-6WEQADPL.js.map +1 -0
- package/dist/chunk-AU7XVCLO.js +91 -0
- package/dist/chunk-AU7XVCLO.js.map +1 -0
- package/dist/chunk-AZP2AA5M.js +425 -0
- package/dist/chunk-AZP2AA5M.js.map +1 -0
- package/dist/chunk-D4IQAT27.js +114 -0
- package/dist/chunk-D4IQAT27.js.map +1 -0
- package/dist/chunk-DHET7RCE.js +50 -0
- package/dist/chunk-DHET7RCE.js.map +1 -0
- package/dist/chunk-DHFFRMF6.js +31 -0
- package/dist/chunk-DHFFRMF6.js.map +1 -0
- package/dist/chunk-FKU7VSUD.js +453 -0
- package/dist/chunk-FKU7VSUD.js.map +1 -0
- package/dist/chunk-J2Y4A3LP.js +478 -0
- package/dist/chunk-J2Y4A3LP.js.map +1 -0
- package/dist/chunk-JMQGWQZU.js +607 -0
- package/dist/chunk-JMQGWQZU.js.map +1 -0
- package/dist/chunk-JY4RO76L.js +73 -0
- package/dist/chunk-JY4RO76L.js.map +1 -0
- package/dist/chunk-M7YCPFIX.js +108 -0
- package/dist/chunk-M7YCPFIX.js.map +1 -0
- package/dist/chunk-MJSFR562.js +57 -0
- package/dist/chunk-MJSFR562.js.map +1 -0
- package/dist/chunk-MMDXNZPF.js +69 -0
- package/dist/chunk-MMDXNZPF.js.map +1 -0
- package/dist/chunk-MYAVQ23U.js +356 -0
- package/dist/chunk-MYAVQ23U.js.map +1 -0
- package/dist/chunk-OSQDDJXX.js +146 -0
- package/dist/chunk-OSQDDJXX.js.map +1 -0
- package/dist/chunk-QESUUPOE.js +241 -0
- package/dist/chunk-QESUUPOE.js.map +1 -0
- package/dist/chunk-SJYG4EJZ.js +57 -0
- package/dist/chunk-SJYG4EJZ.js.map +1 -0
- package/dist/chunk-SYQ7R2JO.js +95 -0
- package/dist/chunk-SYQ7R2JO.js.map +1 -0
- package/dist/chunk-TD643KB3.js +245 -0
- package/dist/chunk-TD643KB3.js.map +1 -0
- package/dist/chunk-TFV6Z7F7.js +129 -0
- package/dist/chunk-TFV6Z7F7.js.map +1 -0
- package/dist/chunk-TGOHJCQ4.js +83 -0
- package/dist/chunk-TGOHJCQ4.js.map +1 -0
- package/dist/chunk-TOPAIL5W.js +22 -0
- package/dist/chunk-TOPAIL5W.js.map +1 -0
- package/dist/chunk-U4VYHKPM.js +110 -0
- package/dist/chunk-U4VYHKPM.js.map +1 -0
- package/dist/chunk-UFWNMW3G.js +392 -0
- package/dist/chunk-UFWNMW3G.js.map +1 -0
- package/dist/chunk-UNHCZRO4.js +64 -0
- package/dist/chunk-UNHCZRO4.js.map +1 -0
- package/dist/chunk-URDV4OCP.js +308 -0
- package/dist/chunk-URDV4OCP.js.map +1 -0
- package/dist/chunk-YI6JVSFO.js +43 -0
- package/dist/chunk-YI6JVSFO.js.map +1 -0
- package/dist/chunk-YNSNRR5D.js +184 -0
- package/dist/chunk-YNSNRR5D.js.map +1 -0
- package/dist/chunk-Z6DLWTBY.js +46 -0
- package/dist/chunk-Z6DLWTBY.js.map +1 -0
- package/dist/chunk-ZDQIUHAM.js +89 -0
- package/dist/chunk-ZDQIUHAM.js.map +1 -0
- package/dist/chunk-ZSKHDU5P.js +124 -0
- package/dist/chunk-ZSKHDU5P.js.map +1 -0
- package/dist/cli-v2/defaults/agent-mappings.yaml +185 -0
- package/dist/commands/build/marketplace.js +295 -0
- package/dist/commands/build/marketplace.js.map +1 -0
- package/dist/commands/build/plugins.js +362 -0
- package/dist/commands/build/plugins.js.map +1 -0
- package/dist/commands/build/stack.js +169 -0
- package/dist/commands/build/stack.js.map +1 -0
- package/dist/commands/compile.js +461 -0
- package/dist/commands/compile.js.map +1 -0
- package/dist/commands/config/get.js +60 -0
- package/dist/commands/config/get.js.map +1 -0
- package/dist/commands/config/index.js +22 -0
- package/dist/commands/config/index.js.map +1 -0
- package/dist/commands/config/path.js +35 -0
- package/dist/commands/config/path.js.map +1 -0
- package/dist/commands/config/set-project.js +61 -0
- package/dist/commands/config/set-project.js.map +1 -0
- package/dist/commands/config/set.js +60 -0
- package/dist/commands/config/set.js.map +1 -0
- package/dist/commands/config/show.js +13 -0
- package/dist/commands/config/show.js.map +1 -0
- package/dist/commands/config/unset-project.js +57 -0
- package/dist/commands/config/unset-project.js.map +1 -0
- package/dist/commands/config/unset.js +56 -0
- package/dist/commands/config/unset.js.map +1 -0
- package/dist/commands/diff.js +755 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/doctor.js +413 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/edit.js +253 -0
- package/dist/commands/edit.js.map +1 -0
- package/dist/commands/eject.js +208 -0
- package/dist/commands/eject.js.map +1 -0
- package/dist/commands/info.js +205 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/init.js +914 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.js +44 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/new/agent.js +230 -0
- package/dist/commands/new/agent.js.map +1 -0
- package/dist/commands/new/skill.js +204 -0
- package/dist/commands/new/skill.js.map +1 -0
- package/dist/commands/outdated.js +242 -0
- package/dist/commands/outdated.js.map +1 -0
- package/dist/commands/search.js +115 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/test-imports.js +92 -0
- package/dist/commands/test-imports.js.map +1 -0
- package/dist/commands/uninstall.js +302 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.js +428 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/validate.js +375 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/version/bump.js +95 -0
- package/dist/commands/version/bump.js.map +1 -0
- package/dist/commands/version/index.js +70 -0
- package/dist/commands/version/index.js.map +1 -0
- package/dist/commands/version/set.js +101 -0
- package/dist/commands/version/set.js.map +1 -0
- package/dist/commands/version/show.js +70 -0
- package/dist/commands/version/show.js.map +1 -0
- package/dist/components/common/confirm.js +9 -0
- package/dist/components/common/confirm.js.map +1 -0
- package/dist/components/common/message.js +24 -0
- package/dist/components/common/message.js.map +1 -0
- package/dist/components/common/spinner.js +14 -0
- package/dist/components/common/spinner.js.map +1 -0
- package/dist/components/wizard/selection-header.js +11 -0
- package/dist/components/wizard/selection-header.js.map +1 -0
- package/dist/components/wizard/step-approach.js +11 -0
- package/dist/components/wizard/step-approach.js.map +1 -0
- package/dist/components/wizard/step-category.js +12 -0
- package/dist/components/wizard/step-category.js.map +1 -0
- package/dist/components/wizard/step-confirm.js +12 -0
- package/dist/components/wizard/step-confirm.js.map +1 -0
- package/dist/components/wizard/step-stack.js +11 -0
- package/dist/components/wizard/step-stack.js.map +1 -0
- package/dist/components/wizard/step-subcategory.js +13 -0
- package/dist/components/wizard/step-subcategory.js.map +1 -0
- package/dist/components/wizard/wizard.js +19 -0
- package/dist/components/wizard/wizard.js.map +1 -0
- package/dist/hooks/init.js +41 -0
- package/dist/hooks/init.js.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/magic-string.es-RGXYGAW3.js +1316 -0
- package/dist/magic-string.es-RGXYGAW3.js.map +1 -0
- package/dist/stores/wizard-store.js +10 -0
- package/dist/stores/wizard-store.js.map +1 -0
- package/dist/stores/wizard-store.test.js +15991 -0
- package/dist/stores/wizard-store.test.js.map +1 -0
- package/package.json +44 -25
- package/dist/cli/index.js +0 -6314
- 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,OAAO,UAAU;;;ACAjB;AAGA,IAAM,gBAAgB,CAAC,QAAQ,QAAQ,MAAM;AAG7C,IAAM,oBAAoB;AAYnB,SAAS,mBACd,SACA,cACA,eACiB;AACjB,MAAI,YAAsC,CAAC;AAE3C,MAAI,aAAa,SAAS;AACxB,UAAM,OAAO,cAAc,aAAa,OAAO;AAC/C,QAAI,CAAC,MAAM;AACT,YAAM,kBAAkB,OAAO,KAAK,aAAa;AACjD,YAAM,YACJ,gBAAgB,SAAS,IACrB,qBAAqB,gBAAgB,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG,gBAAgB,SAAS,IAAI,SAAS,gBAAgB,SAAS,CAAC,WAAW,EAAE,KAC3I;AACN,YAAM,IAAI;AAAA,QACR,iBAAiB,OAAO,4BAA4B,aAAa,OAAO,MAAM,SAAS;AAAA,MACzF;AAAA,IACF;AACA,gBAAY,EAAE,GAAG,KAAK;AAAA,EACxB;AAGA,MAAI;AACJ,MAAI,aAAa,oBAAoB,UAAU,kBAAkB;AAC/D,UAAM,SAAS,oBAAI,IAAY;AAAA,MAC7B,GAAI,UAAU,oBAAoB,CAAC;AAAA,MACnC,GAAI,aAAa,oBAAoB,CAAC;AAAA,IACxC,CAAC;AACD,sBAAkB,CAAC,GAAG,MAAM;AAAA,EAC9B;AAGA,MAAI;AACJ,MAAI,aAAa,SAAS,UAAU,OAAO;AACzC,YAAQ,EAAE,GAAG,UAAU,MAAM;AAC7B,QAAI,aAAa,OAAO;AACtB,iBAAW,CAAC,UAAU,QAAQ,KAAK,OAAO,QAAQ,aAAa,KAAK,GAAG;AACrE,YAAI,MAAM,QAAQ,GAAG;AACnB,gBAAM,QAAQ,IAAI,CAAC,GAAG,MAAM,QAAQ,GAAG,GAAG,QAAQ;AAAA,QACpD,OAAO;AACL,gBAAM,QAAQ,IAAI;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,aAAa;AAAA,IACpB,aAAa,aAAa;AAAA,IAC1B,OAAO,aAAa,SAAS,UAAU;AAAA,IACvC,OAAO,aAAa,SAAS,UAAU,SAAS;AAAA,IAChD,kBAAkB;AAAA,IAClB,iBAAiB,aAAa,mBAAmB,UAAU;AAAA,IAC3D;AAAA;AAAA,IAEA,MAAM,UAAU,QAAQ;AAAA,IACxB,YAAY,UAAU;AAAA,EACxB;AACF;AASO,SAAS,oBACd,cACA,eACiC;AACjC,QAAM,WAA4C,CAAC;AAEnD,aAAW,CAAC,IAAI,MAAM,KAAK,OAAO,QAAQ,YAAY,GAAG;AACvD,aAAS,EAAE,IAAI,mBAAmB,IAAI,QAAQ,aAAa;AAAA,EAC7D;AAEA,SAAO;AACT;AASO,SAAS,mBACd,eACA,eACS;AACT,SAAO,iBAAiB;AAC1B;AASO,SAAS,uBACd,cACA,eACU;AACV,QAAM,SAAmB,CAAC;AAE1B,aAAW,YAAY,OAAO,KAAK,YAAY,GAAG;AAChD,QAAI,mBAAmB,UAAU,aAAa,GAAG;AAC/C,aAAO;AAAA,QACL,iBAAiB,QAAQ;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ADrHA,SAAS,SAAS,iBAAiB;AA0BnC,eAAe,sBAAsB,WAAsC;AACzE,QAAM,YAAY,mBAAmB,SAAS;AAC9C,QAAM,QAAQ,MAAM,KAAK,QAAQ,SAAS;AAC1C,SAAO,MAAM,IAAI,CAAC,MAAM,KAAK,SAAS,GAAG,KAAK,CAAC;AACjD;AASA,eAAe,uBACb,WACqC;AAErC,QAAM,mBAAmB,KAAK,KAAK,WAAW,aAAa;AAC3D,MAAI,MAAM,WAAW,gBAAgB,GAAG;AACtC,QAAI;AACF,YAAM,UAAU,MAAM,SAAS,gBAAgB;AAC/C,YAAM,SAAS,UAAU,OAAO;AAEhC,UAAI,UAAU,OAAO,WAAW,UAAU;AACxC,gBAAQ,2BAA2B,gBAAgB,EAAE;AAGrD,YAAI,oBAAoB,MAAM,GAAG;AAC/B,gBAAM,aAAa,qBAAqB,MAAqB;AAC7D,iBAAO;AAAA,YACL,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,UAAU;AAAA,UACZ;AAAA,QACF;AAEA,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,YAAY;AAAA,UACZ,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,gCAAgC,KAAK,EAAE;AAAA,IACjD;AAAA,EACF;AAGA,SAAO,kBAAkB,SAAS;AACpC;AAMA,SAAS,yBAAyB,QAAoC;AACpE,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,SAAS;AAAA,IACT,QAAQ,OAAO,UAAU;AAAA,IACzB,aAAa,OAAO;AAAA,IACpB,QACE,OAAO,QAAQ,IAAI,CAAC,MAAO,OAAO,MAAM,WAAW,EAAE,IAAI,EAAE,IAAI,CAAE,KAAK,CAAC;AAAA,IACzE,QAAQ,OAAO;AAAA,IACf,cAAc,OAAO;AAAA,IACrB,OAAO,OAAO;AAAA,IACd,WAAW,OAAO;AAAA,IAClB,YAAY,OAAO;AAAA,IACnB,YAAY,OAAO;AAAA,IACnB,MAAM,OAAO;AAAA,EACf;AACF;AAEA,eAAsB,gBACpB,SACgC;AAChC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,SAAgC;AAAA,IACpC,UAAU,CAAC;AAAA,IACX,QAAQ,CAAC;AAAA,IACT,UAAU,CAAC;AAAA,EACb;AAGA,QAAM,eAAe,MAAM,uBAAuB,SAAS;AAC3D,QAAM,gBAAgB,cAAc,UAAU;AAG9C,QAAM,gBAAgB,MAAM,cAAc,UAAU;AAGpD,MAAI,YAA6C,EAAE,GAAG,cAAc;AACpE,MAAI,eAAe,eAAe;AAEhC,UAAM,cAAc;AAAA,MAClB,cAAc;AAAA,MACd;AAAA,IACF;AACA,QAAI,YAAY,SAAS,GAAG;AAC1B,iBAAW,SAAS,aAAa;AAC/B,eAAO,SAAS,KAAK,KAAK;AAAA,MAC5B;AAAA,IACF;AAGA,QAAI;AACF,YAAM,uBAAuB;AAAA,QAC3B,cAAc;AAAA,QACd;AAAA,MACF;AAEA,kBAAY,EAAE,GAAG,eAAe,GAAG,qBAAqB;AACxD;AAAA,QACE,YAAY,OAAO,KAAK,oBAAoB,EAAE,MAAM;AAAA,MACtD;AAAA,IACF,SAAS,OAAO;AACd,aAAO,SAAS;AAAA,QACd,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC5F;AAAA,IACF;AAAA,EACF;AAGA,QAAM,eAAe,gBACjB,yBAAyB,aAAa,IACtC;AAEJ,MAAI;AACJ,MAAI,iBAAiB;AACnB,iBAAa;AAAA,EACf,WAAW,cAAc,QAAQ;AAC/B,iBAAa,aAAa;AAC1B,YAAQ,kCAAkC,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,EACnE,WAAW,WAAW;AACpB,iBAAa,OAAO,KAAK,SAAS;AAClC,YAAQ,2CAA2C,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,EAC5E,OAAO;AACL,iBAAa,MAAM,sBAAsB,SAAS;AAAA,EACpD;AAEA,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO,SAAS,KAAK,8BAA8B;AACnD,WAAO;AAAA,EACT;AAEA;AAAA,IACE,eAAe,WAAW,MAAM,cAAc,aAAa,SAAS;AAAA,EACtE;AAEA,QAAM,eAAe,kBAAmB,MAAM,iBAAiB,SAAS;AAExE,QAAM,gBAAoD,CAAC;AAC3D,aAAW,aAAa,YAAY;AAClC,QAAI,UAAU,SAAS,GAAG;AAExB,YAAM,oBAAoB,eAAe,gBAAgB,SAAS;AAClE,UAAI,mBAAmB,UAAU,kBAAkB,OAAO,SAAS,GAAG;AAEpE,cAAM,YAA8B,kBAAkB,OAAO;AAAA,UAC3D,CAAC,OAAO;AAAA,YACN,IAAI,OAAO,MAAM,WAAW,IAAI,EAAE;AAAA,YAClC,OAAO,sBAAsB,OAAO,MAAM,WAAW,IAAI,EAAE,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,YAC5E,YACG,OAAO,MAAM,YAAY,eAAe,KAAK,EAAE,cAChD;AAAA,UACJ;AAAA,QACF;AACA,sBAAc,SAAS,IAAI,EAAE,QAAQ,UAAU;AAC/C;AAAA,UACE,WAAW,SAAS,KAAK,UAAU,MAAM;AAAA,QAC3C;AAAA,MACF,WAAW,cAAc,eAAe,SAAS,GAAG;AAClD,cAAM,YAAY;AAAA,UAChB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,sBAAc,SAAS,IAAI,EAAE,QAAQ,UAAU;AAC/C,gBAAQ,WAAW,SAAS,KAAK,UAAU,MAAM,qBAAqB;AAAA,MACxE,WAAW,cAAc,QAAQ;AAE/B,cAAM,YAA8B,aAAa,OAAO,IAAI,CAAC,OAAO;AAAA,UAClE,IAAI,EAAE;AAAA,UACN,OAAO,qBAAqB,EAAE,GAAG,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,UAC9C,WAAW,EAAE,aAAa;AAAA,QAC5B,EAAE;AACF,sBAAc,SAAS,IAAI,EAAE,QAAQ,UAAU;AAC/C,gBAAQ,WAAW,SAAS,KAAK,UAAU,MAAM,eAAe;AAAA,MAClE,OAAO;AACL,sBAAc,SAAS,IAAI,CAAC;AAAA,MAC9B;AAAA,IACF,OAAO;AACL,aAAO,SAAS;AAAA,QACd,UAAU,SAAS;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAA+B;AAAA,IACnC,MAAM,cAAc,QAAQ,KAAK,SAAS,SAAS;AAAA,IACnD,aAAa,cAAc,eAAe;AAAA,IAC1C,WAAW;AAAA,IACX,QAAQ;AAAA,EACV;AAEA,QAAM,SAAS,MAAM,mBAAmB,UAAU;AAClD,QAAM,iBAAiB,MAAM;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,YAAY,aAAa,mBAAmB,SAAS;AAC3D,QAAM,UAAU,SAAS;AAEzB,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AAC1D,QAAI;AACF,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,UAAU,KAAK,KAAK,WAAW,GAAG,IAAI,KAAK,GAAG,MAAM;AAC1D,aAAO,SAAS,KAAK,IAAI;AACzB,cAAQ,iBAAiB,IAAI,EAAE;AAAA,IACjC,SAAS,OAAO;AACd,aAAO,OAAO,KAAK,IAAI;AACvB,aAAO,SAAS;AAAA,QACd,qBAAqB,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACtF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","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":[]}
|