@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,478 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ DIRS,
4
+ PROJECT_ROOT
5
+ } from "./chunk-SJYG4EJZ.js";
6
+ import {
7
+ verbose
8
+ } from "./chunk-TOPAIL5W.js";
9
+ import {
10
+ directoryExists,
11
+ ensureDir,
12
+ readFile,
13
+ readFileOptional,
14
+ writeFile
15
+ } from "./chunk-MMDXNZPF.js";
16
+ import {
17
+ init_esm_shims
18
+ } from "./chunk-DHET7RCE.js";
19
+
20
+ // src/cli-v2/lib/resolver.ts
21
+ init_esm_shims();
22
+ function resolveSkillReference(ref, skills) {
23
+ const definition = skills[ref.id];
24
+ if (!definition) {
25
+ const availableSkills = Object.keys(skills);
26
+ const skillList = availableSkills.length > 0 ? `Available skills: ${availableSkills.slice(0, 5).join(", ")}${availableSkills.length > 5 ? ` (and ${availableSkills.length - 5} more)` : ""}` : "No skills found in scanned directories";
27
+ throw new Error(
28
+ `Skill '${ref.id}' not found in scanned skills. ${skillList}`
29
+ );
30
+ }
31
+ return {
32
+ id: ref.id,
33
+ path: definition.path,
34
+ name: definition.name,
35
+ description: definition.description,
36
+ usage: ref.usage,
37
+ preloaded: ref.preloaded ?? false
38
+ };
39
+ }
40
+ function resolveSkillReferences(skillRefs, skills) {
41
+ return skillRefs.map((ref) => resolveSkillReference(ref, skills));
42
+ }
43
+ function flattenAgentSkills(categorizedSkills) {
44
+ const assignments = [];
45
+ for (const category of Object.keys(categorizedSkills)) {
46
+ assignments.push(...categorizedSkills[category]);
47
+ }
48
+ return assignments;
49
+ }
50
+ function expandSkillIdIfDirectory(skillId, skills) {
51
+ if (skills[skillId]) {
52
+ return [skillId];
53
+ }
54
+ const allSkillIds = Object.keys(skills);
55
+ const seenPaths = /* @__PURE__ */ new Set();
56
+ const matchingSkills = [];
57
+ for (const id of allSkillIds) {
58
+ const skillDef = skills[id];
59
+ if (skillDef.path.startsWith(`src/skills/${skillId}/`)) {
60
+ if (!seenPaths.has(skillDef.path)) {
61
+ seenPaths.add(skillDef.path);
62
+ matchingSkills.push(id);
63
+ }
64
+ }
65
+ }
66
+ if (matchingSkills.length > 0) {
67
+ return matchingSkills;
68
+ }
69
+ return [skillId];
70
+ }
71
+ function resolveAgentSkills(agentDef) {
72
+ if (!agentDef.skills) return [];
73
+ return Object.entries(agentDef.skills).map(([category, entry]) => ({
74
+ id: entry.id,
75
+ usage: `when working with ${category}`,
76
+ preloaded: entry.preloaded
77
+ }));
78
+ }
79
+ var KEY_SUBCATEGORIES = /* @__PURE__ */ new Set([
80
+ "framework",
81
+ "api",
82
+ "database",
83
+ "meta-framework",
84
+ "base-framework",
85
+ "platform"
86
+ ]);
87
+ function resolveAgentSkillsFromStack(agentName, stack, skillAliases) {
88
+ const agentConfig = stack.agents[agentName];
89
+ if (!agentConfig) {
90
+ verbose(`Agent '${agentName}' not found in stack '${stack.id}'`);
91
+ return [];
92
+ }
93
+ if (Object.keys(agentConfig).length === 0) {
94
+ verbose(
95
+ `Agent '${agentName}' has no technology config in stack '${stack.id}'`
96
+ );
97
+ return [];
98
+ }
99
+ const skillRefs = [];
100
+ for (const [subcategory, technologyAlias] of Object.entries(agentConfig)) {
101
+ const fullSkillId = skillAliases[technologyAlias];
102
+ if (!fullSkillId) {
103
+ verbose(
104
+ `Warning: No skill alias found for '${technologyAlias}' (agent: ${agentName}, subcategory: ${subcategory}). Skipping.`
105
+ );
106
+ continue;
107
+ }
108
+ const isKeySkill = KEY_SUBCATEGORIES.has(subcategory);
109
+ skillRefs.push({
110
+ id: fullSkillId,
111
+ usage: `when working with ${subcategory}`,
112
+ preloaded: isKeySkill
113
+ });
114
+ }
115
+ verbose(
116
+ `Resolved ${skillRefs.length} skills for agent '${agentName}' from stack '${stack.id}'`
117
+ );
118
+ return skillRefs;
119
+ }
120
+ function resolveStackSkills(stack, agentName, skills) {
121
+ const skillRefs = [];
122
+ const agentSkillCategories = stack.agent_skills?.[agentName];
123
+ const assignments = agentSkillCategories ? flattenAgentSkills(agentSkillCategories) : stack.skills;
124
+ const validSkillIds = /* @__PURE__ */ new Set();
125
+ for (const s of stack.skills) {
126
+ const expandedIds = expandSkillIdIfDirectory(s.id, skills);
127
+ for (const id of expandedIds) {
128
+ validSkillIds.add(id);
129
+ }
130
+ }
131
+ const addedSkills = /* @__PURE__ */ new Set();
132
+ for (const assignment of assignments) {
133
+ const skillId = assignment.id;
134
+ const expandedSkillIds = expandSkillIdIfDirectory(skillId, skills);
135
+ for (const expandedId of expandedSkillIds) {
136
+ if (addedSkills.has(expandedId)) {
137
+ continue;
138
+ }
139
+ if (!skills[expandedId]) {
140
+ throw new Error(
141
+ `Stack "${stack.name}" references skill "${expandedId}" for agent "${agentName}" not found in scanned skills`
142
+ );
143
+ }
144
+ if (agentSkillCategories && !validSkillIds.has(expandedId)) {
145
+ throw new Error(
146
+ `Stack "${stack.name}" agent_skills for "${agentName}" includes skill "${expandedId}" not in stack's skills array`
147
+ );
148
+ }
149
+ const skillDef = skills[expandedId];
150
+ skillRefs.push({
151
+ id: expandedId,
152
+ usage: `when working with ${skillDef.name.toLowerCase()}`,
153
+ preloaded: assignment.preloaded ?? false
154
+ });
155
+ addedSkills.add(expandedId);
156
+ }
157
+ }
158
+ return skillRefs;
159
+ }
160
+ async function getAgentSkills(agentName, agentConfig, _compileConfig, _skills, _projectRoot, agentDef, stack, skillAliases) {
161
+ if (agentConfig.skills && agentConfig.skills.length > 0) {
162
+ return agentConfig.skills;
163
+ }
164
+ if (stack && skillAliases) {
165
+ const stackSkills = resolveAgentSkillsFromStack(
166
+ agentName,
167
+ stack,
168
+ skillAliases
169
+ );
170
+ if (stackSkills.length > 0) {
171
+ verbose(
172
+ `Resolved ${stackSkills.length} skills from stack for ${agentName}`
173
+ );
174
+ return stackSkills;
175
+ }
176
+ }
177
+ if (agentDef?.skills && Object.keys(agentDef.skills).length > 0) {
178
+ verbose(`Resolving skills from agent definition for ${agentName}`);
179
+ return resolveAgentSkills(agentDef);
180
+ }
181
+ return [];
182
+ }
183
+ async function resolveAgents(agents, skills, compileConfig, projectRoot, stack, skillAliases) {
184
+ const resolved = {};
185
+ const agentNames = Object.keys(compileConfig.agents);
186
+ for (const agentName of agentNames) {
187
+ const definition = agents[agentName];
188
+ if (!definition) {
189
+ const availableAgents = Object.keys(agents);
190
+ const agentList = availableAgents.length > 0 ? `Available agents: ${availableAgents.slice(0, 5).join(", ")}${availableAgents.length > 5 ? ` (and ${availableAgents.length - 5} more)` : ""}` : "No agents found in scanned directories";
191
+ throw new Error(
192
+ `Agent '${agentName}' referenced in compile config but not found in scanned agents. ${agentList}. Check that src/agents/${agentName}/agent.yaml exists.`
193
+ );
194
+ }
195
+ const agentConfig = compileConfig.agents[agentName];
196
+ const skillRefs = await getAgentSkills(
197
+ agentName,
198
+ agentConfig,
199
+ compileConfig,
200
+ skills,
201
+ projectRoot,
202
+ definition,
203
+ stack,
204
+ skillAliases
205
+ );
206
+ const resolvedSkills = resolveSkillReferences(skillRefs, skills);
207
+ resolved[agentName] = {
208
+ name: agentName,
209
+ title: definition.title,
210
+ description: definition.description,
211
+ model: definition.model,
212
+ tools: definition.tools,
213
+ skills: resolvedSkills,
214
+ path: definition.path,
215
+ sourceRoot: definition.sourceRoot
216
+ };
217
+ }
218
+ return resolved;
219
+ }
220
+ function stackToCompileConfig(stackId, stack) {
221
+ const agents = {};
222
+ for (const agentId of stack.agents) {
223
+ agents[agentId] = {};
224
+ }
225
+ return {
226
+ name: stack.name,
227
+ description: stack.description || "",
228
+ claude_md: "",
229
+ stack: stackId,
230
+ agents
231
+ };
232
+ }
233
+
234
+ // src/cli-v2/lib/compiler.ts
235
+ init_esm_shims();
236
+ import { Liquid } from "liquidjs";
237
+ import path from "path";
238
+
239
+ // src/cli-v2/lib/output-validator.ts
240
+ init_esm_shims();
241
+ import { parse as parseYaml } from "yaml";
242
+ function extractFrontmatter(content) {
243
+ const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---/;
244
+ const match = content.match(frontmatterRegex);
245
+ if (!match || !match[1]) {
246
+ return null;
247
+ }
248
+ try {
249
+ return parseYaml(match[1]);
250
+ } catch {
251
+ return null;
252
+ }
253
+ }
254
+ function checkXmlTagBalance(content) {
255
+ const errors = [];
256
+ const tagRegex = /<\/?([a-z_][a-z0-9_-]*)\s*>/gi;
257
+ const tagCounts = /* @__PURE__ */ new Map();
258
+ let match;
259
+ while ((match = tagRegex.exec(content)) !== null) {
260
+ const fullTag = match[0];
261
+ const tagName = match[1].toLowerCase();
262
+ const before = content.slice(Math.max(0, match.index - 10), match.index);
263
+ const after = content.slice(
264
+ match.index + fullTag.length,
265
+ match.index + fullTag.length + 10
266
+ );
267
+ if (before.includes("`") || after.includes("`")) {
268
+ continue;
269
+ }
270
+ const isClosing = fullTag.startsWith("</");
271
+ const current = tagCounts.get(tagName) || 0;
272
+ tagCounts.set(tagName, isClosing ? current - 1 : current + 1);
273
+ }
274
+ for (const [tag, count] of tagCounts) {
275
+ if (count > 0) {
276
+ errors.push(`Unclosed XML tag: <${tag}> (${count} unclosed)`);
277
+ } else if (count < 0) {
278
+ errors.push(`Extra closing tag: </${tag}> (${Math.abs(count)} extra)`);
279
+ }
280
+ }
281
+ return errors;
282
+ }
283
+ function checkTemplateArtifacts(content) {
284
+ const warnings = [];
285
+ const variableMatches = content.match(/\{\{[^}]*\}\}/g);
286
+ if (variableMatches) {
287
+ warnings.push(
288
+ `Template artifacts found: ${variableMatches.length} unprocessed {{ }} tags`
289
+ );
290
+ }
291
+ const controlMatches = content.match(/\{%[^%]*%\}/g);
292
+ if (controlMatches) {
293
+ warnings.push(
294
+ `Template artifacts found: ${controlMatches.length} unprocessed {% %} tags`
295
+ );
296
+ }
297
+ return warnings;
298
+ }
299
+ function checkRequiredPatterns(content) {
300
+ const warnings = [];
301
+ if (!content.startsWith("---")) {
302
+ warnings.push("Missing YAML frontmatter at start of file");
303
+ }
304
+ if (!content.includes("<role>")) {
305
+ warnings.push("Missing <role> section");
306
+ }
307
+ if (!content.includes("Core Principles") && !content.includes("core_principles")) {
308
+ warnings.push("Missing Core Principles section");
309
+ }
310
+ const lines = content.trim().split("\n");
311
+ if (lines.length < 50) {
312
+ warnings.push(`Suspiciously short output: only ${lines.length} lines`);
313
+ }
314
+ return warnings;
315
+ }
316
+ function validateFrontmatter(content) {
317
+ const errors = [];
318
+ const warnings = [];
319
+ const frontmatter = extractFrontmatter(content);
320
+ if (frontmatter === null) {
321
+ errors.push("Failed to parse YAML frontmatter");
322
+ return { errors, warnings };
323
+ }
324
+ const fm = frontmatter;
325
+ if (!fm.name || typeof fm.name !== "string") {
326
+ errors.push("Frontmatter missing required field: name");
327
+ }
328
+ if (!fm.description || typeof fm.description !== "string") {
329
+ warnings.push("Frontmatter missing field: description");
330
+ }
331
+ if (!fm.tools || typeof fm.tools !== "string") {
332
+ warnings.push("Frontmatter missing field: tools");
333
+ }
334
+ return { errors, warnings };
335
+ }
336
+ function validateCompiledAgent(content) {
337
+ const errors = [];
338
+ const warnings = [];
339
+ if (!content || content.trim().length === 0) {
340
+ return {
341
+ valid: false,
342
+ errors: ["Compiled output is empty"],
343
+ warnings: []
344
+ };
345
+ }
346
+ const fmResult = validateFrontmatter(content);
347
+ errors.push(...fmResult.errors);
348
+ warnings.push(...fmResult.warnings);
349
+ const xmlErrors = checkXmlTagBalance(content);
350
+ errors.push(...xmlErrors);
351
+ const artifactWarnings = checkTemplateArtifacts(content);
352
+ warnings.push(...artifactWarnings);
353
+ const patternWarnings = checkRequiredPatterns(content);
354
+ warnings.push(...patternWarnings);
355
+ return {
356
+ valid: errors.length === 0,
357
+ errors,
358
+ warnings
359
+ };
360
+ }
361
+ function printOutputValidationResult(agentName, result) {
362
+ if (result.errors.length > 0) {
363
+ console.log(` Validation errors for ${agentName}:`);
364
+ result.errors.forEach((e) => console.log(` - ${e}`));
365
+ }
366
+ if (result.warnings.length > 0) {
367
+ console.log(` Validation warnings for ${agentName}:`);
368
+ result.warnings.forEach((w) => console.log(` - ${w}`));
369
+ }
370
+ }
371
+
372
+ // src/cli-v2/lib/compiler.ts
373
+ async function compileAgent(name, agent, projectRoot, engine) {
374
+ verbose(`Reading agent files for ${name}...`);
375
+ const agentDir = path.join(projectRoot, DIRS.agents, agent.path || name);
376
+ const intro = await readFile(path.join(agentDir, "intro.md"));
377
+ const workflow = await readFile(path.join(agentDir, "workflow.md"));
378
+ const examples = await readFileOptional(
379
+ path.join(agentDir, "examples.md"),
380
+ "## Examples\n\n_No examples defined._"
381
+ );
382
+ const criticalRequirementsTop = await readFileOptional(
383
+ path.join(agentDir, "critical-requirements.md"),
384
+ ""
385
+ );
386
+ const criticalReminders = await readFileOptional(
387
+ path.join(agentDir, "critical-reminders.md"),
388
+ ""
389
+ );
390
+ const agentPath = agent.path || name;
391
+ const category = agentPath.split("/")[0];
392
+ const categoryDir = path.join(projectRoot, DIRS.agents, category);
393
+ let outputFormat = await readFileOptional(
394
+ path.join(agentDir, "output-format.md"),
395
+ ""
396
+ );
397
+ if (!outputFormat) {
398
+ outputFormat = await readFileOptional(
399
+ path.join(categoryDir, "output-format.md"),
400
+ ""
401
+ );
402
+ }
403
+ const preloadedSkills = agent.skills.filter((s) => s.preloaded);
404
+ const dynamicSkills = agent.skills.filter((s) => !s.preloaded);
405
+ const preloadedSkillIds = preloadedSkills.map((s) => s.id);
406
+ verbose(
407
+ `Skills for ${name}: ${preloadedSkills.length} preloaded, ${dynamicSkills.length} dynamic`
408
+ );
409
+ const data = {
410
+ agent,
411
+ intro,
412
+ workflow,
413
+ examples,
414
+ criticalRequirementsTop,
415
+ criticalReminders,
416
+ outputFormat,
417
+ skills: agent.skills,
418
+ preloadedSkills,
419
+ dynamicSkills,
420
+ preloadedSkillIds
421
+ };
422
+ verbose(`Rendering template for ${name}...`);
423
+ return engine.renderFile("agent", data);
424
+ }
425
+ async function compileAllAgents(resolvedAgents, config, ctx, engine) {
426
+ const outDir = path.join(ctx.outputDir, "agents");
427
+ await ensureDir(outDir);
428
+ let hasValidationIssues = false;
429
+ for (const [name, agent] of Object.entries(resolvedAgents)) {
430
+ try {
431
+ const output = await compileAgent(name, agent, ctx.projectRoot, engine);
432
+ await writeFile(path.join(outDir, `${name}.md`), output);
433
+ console.log(` \u2713 ${name}.md`);
434
+ const validationResult = validateCompiledAgent(output);
435
+ if (!validationResult.valid || validationResult.warnings.length > 0) {
436
+ hasValidationIssues = true;
437
+ printOutputValidationResult(name, validationResult);
438
+ }
439
+ } catch (error) {
440
+ const errorMessage = error instanceof Error ? error.message : String(error);
441
+ console.error(` \u2717 ${name}.md - ${errorMessage}`);
442
+ throw new Error(
443
+ `Failed to compile agent '${name}': ${errorMessage}. Check that all required files exist in src/agents/${agent.path || name}/`
444
+ );
445
+ }
446
+ }
447
+ if (hasValidationIssues) {
448
+ console.log("");
449
+ }
450
+ }
451
+ async function createLiquidEngine(projectDir) {
452
+ const roots = [];
453
+ if (projectDir) {
454
+ const localTemplatesDir = path.join(projectDir, ".claude", "templates");
455
+ if (await directoryExists(localTemplatesDir)) {
456
+ roots.push(localTemplatesDir);
457
+ verbose(`Using local templates from: ${localTemplatesDir}`);
458
+ }
459
+ }
460
+ roots.push(path.join(PROJECT_ROOT, DIRS.templates));
461
+ return new Liquid({
462
+ root: roots,
463
+ extname: ".liquid",
464
+ strictVariables: false,
465
+ strictFilters: true
466
+ });
467
+ }
468
+
469
+ export {
470
+ resolveSkillReference,
471
+ resolveAgentSkillsFromStack,
472
+ resolveStackSkills,
473
+ resolveAgents,
474
+ stackToCompileConfig,
475
+ compileAllAgents,
476
+ createLiquidEngine
477
+ };
478
+ //# sourceMappingURL=chunk-J2Y4A3LP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli-v2/lib/resolver.ts","../src/cli-v2/lib/compiler.ts","../src/cli-v2/lib/output-validator.ts"],"sourcesContent":["import path from \"path\";\nimport { fileExists } from \"../utils/fs\";\nimport { getDirs, type CompileMode } from \"./loader\";\nimport { verbose } from \"../utils/logger\";\nimport type {\n AgentConfig,\n AgentDefinition,\n CompileAgentConfig,\n CompileConfig,\n Skill,\n SkillAssignment,\n SkillDefinition,\n SkillReference,\n StackConfig,\n} from \"../types\";\nimport type { Stack, StackAgentConfig } from \"../types-stacks\";\n\nexport async function resolveTemplate(\n projectRoot: string,\n stackId: string,\n mode: CompileMode = \"dev\",\n): Promise<string> {\n const dirs = getDirs(mode);\n const stackTemplate = path.join(\n projectRoot,\n dirs.stacks,\n stackId,\n \"agent.liquid\",\n );\n if (await fileExists(stackTemplate)) return stackTemplate;\n\n return path.join(projectRoot, dirs.templates, \"agent.liquid\");\n}\n\nexport async function resolveClaudeMd(\n projectRoot: string,\n stackId: string,\n mode: CompileMode = \"dev\",\n): Promise<string> {\n const dirs = getDirs(mode);\n const stackClaude = path.join(projectRoot, dirs.stacks, stackId, \"CLAUDE.md\");\n if (await fileExists(stackClaude)) return stackClaude;\n\n throw new Error(\n `Stack '${stackId}' is missing required CLAUDE.md file. Expected at: ${stackClaude}`,\n );\n}\n\nexport function resolveSkillReference(\n ref: SkillReference,\n skills: Record<string, SkillDefinition>,\n): Skill {\n const definition = skills[ref.id];\n if (!definition) {\n const availableSkills = Object.keys(skills);\n const skillList =\n availableSkills.length > 0\n ? `Available skills: ${availableSkills.slice(0, 5).join(\", \")}${availableSkills.length > 5 ? ` (and ${availableSkills.length - 5} more)` : \"\"}`\n : \"No skills found in scanned directories\";\n throw new Error(\n `Skill '${ref.id}' not found in scanned skills. ${skillList}`,\n );\n }\n return {\n id: ref.id,\n path: definition.path,\n name: definition.name,\n description: definition.description,\n usage: ref.usage,\n preloaded: ref.preloaded ?? false,\n };\n}\n\nexport function resolveSkillReferences(\n skillRefs: SkillReference[],\n skills: Record<string, SkillDefinition>,\n): Skill[] {\n return skillRefs.map((ref) => resolveSkillReference(ref, skills));\n}\n\nfunction getStackSkillIds(stackSkills: SkillAssignment[]): string[] {\n return stackSkills.map((s) => s.id);\n}\n\nfunction flattenAgentSkills(\n categorizedSkills: Record<string, SkillAssignment[]>,\n): SkillAssignment[] {\n const assignments: SkillAssignment[] = [];\n for (const category of Object.keys(categorizedSkills)) {\n assignments.push(...categorizedSkills[category]);\n }\n return assignments;\n}\n\nfunction expandSkillIdIfDirectory(\n skillId: string,\n skills: Record<string, SkillDefinition>,\n): string[] {\n if (skills[skillId]) {\n return [skillId];\n }\n\n // Use path as unique key to deduplicate (both frontmatter name and directory path map to same skill)\n const allSkillIds = Object.keys(skills);\n const seenPaths = new Set<string>();\n const matchingSkills: string[] = [];\n\n for (const id of allSkillIds) {\n const skillDef = skills[id];\n if (skillDef.path.startsWith(`src/skills/${skillId}/`)) {\n if (!seenPaths.has(skillDef.path)) {\n seenPaths.add(skillDef.path);\n matchingSkills.push(id);\n }\n }\n }\n\n if (matchingSkills.length > 0) {\n return matchingSkills;\n }\n\n return [skillId];\n}\n\n/**\n * Resolve skills from agent's skills field (Phase 6: agent-centric configuration)\n * Converts agent's skills Record to SkillReference array\n *\n * @deprecated Use resolveAgentSkillsFromStack for Phase 7 agent-centric configuration\n */\nexport function resolveAgentSkills(\n agentDef: AgentDefinition,\n): SkillReference[] {\n if (!agentDef.skills) return [];\n\n return Object.entries(agentDef.skills).map(([category, entry]) => ({\n id: entry.id,\n usage: `when working with ${category}`,\n preloaded: entry.preloaded,\n }));\n}\n\n/**\n * Subcategories considered \"key\" skills that should be preloaded.\n * These are primary technology choices that define the stack's core.\n */\nconst KEY_SUBCATEGORIES = new Set([\n \"framework\",\n \"api\",\n \"database\",\n \"meta-framework\",\n \"base-framework\",\n \"platform\",\n]);\n\n/**\n * Resolve skills for an agent from a Stack definition (Phase 7 format).\n * Takes a stack and skill aliases, returns skill references for the specified agent.\n *\n * @param agentName - The agent ID to resolve skills for\n * @param stack - The stack definition with agent technology selections\n * @param skillAliases - Mapping from technology aliases to full skill IDs\n * @returns Array of SkillReference objects for the agent\n *\n * @example\n * ```typescript\n * const stack = {\n * id: 'nextjs-fullstack',\n * agents: {\n * 'web-developer': { framework: 'react', styling: 'scss-modules' }\n * }\n * };\n *\n * const aliases = { react: 'web/framework/react (@vince)', ... };\n *\n * const skills = resolveAgentSkillsFromStack('web-developer', stack, aliases);\n * // Returns: [{ id: 'web/framework/react (@vince)', usage: '...', preloaded: true }, ...]\n * ```\n */\nexport function resolveAgentSkillsFromStack(\n agentName: string,\n stack: Stack,\n skillAliases: Record<string, string>,\n): SkillReference[] {\n const agentConfig = stack.agents[agentName];\n\n // Agent not in this stack\n if (!agentConfig) {\n verbose(`Agent '${agentName}' not found in stack '${stack.id}'`);\n return [];\n }\n\n // Empty config {} means agent has no technology-specific skills\n if (Object.keys(agentConfig).length === 0) {\n verbose(\n `Agent '${agentName}' has no technology config in stack '${stack.id}'`,\n );\n return [];\n }\n\n const skillRefs: SkillReference[] = [];\n\n for (const [subcategory, technologyAlias] of Object.entries(agentConfig)) {\n const fullSkillId = skillAliases[technologyAlias];\n\n if (!fullSkillId) {\n verbose(\n `Warning: No skill alias found for '${technologyAlias}' (agent: ${agentName}, subcategory: ${subcategory}). Skipping.`,\n );\n continue;\n }\n\n const isKeySkill = KEY_SUBCATEGORIES.has(subcategory);\n\n skillRefs.push({\n id: fullSkillId,\n usage: `when working with ${subcategory}`,\n preloaded: isKeySkill,\n });\n }\n\n verbose(\n `Resolved ${skillRefs.length} skills for agent '${agentName}' from stack '${stack.id}'`,\n );\n\n return skillRefs;\n}\n\nexport function resolveStackSkills(\n stack: StackConfig,\n agentName: string,\n skills: Record<string, SkillDefinition>,\n): SkillReference[] {\n const skillRefs: SkillReference[] = [];\n\n const agentSkillCategories = stack.agent_skills?.[agentName];\n const assignments: SkillAssignment[] = agentSkillCategories\n ? flattenAgentSkills(agentSkillCategories)\n : stack.skills;\n\n const validSkillIds = new Set<string>();\n for (const s of stack.skills) {\n const expandedIds = expandSkillIdIfDirectory(s.id, skills);\n for (const id of expandedIds) {\n validSkillIds.add(id);\n }\n }\n\n const addedSkills = new Set<string>();\n\n for (const assignment of assignments) {\n const skillId = assignment.id;\n const expandedSkillIds = expandSkillIdIfDirectory(skillId, skills);\n\n for (const expandedId of expandedSkillIds) {\n if (addedSkills.has(expandedId)) {\n continue;\n }\n\n if (!skills[expandedId]) {\n throw new Error(\n `Stack \"${stack.name}\" references skill \"${expandedId}\" for agent \"${agentName}\" not found in scanned skills`,\n );\n }\n\n if (agentSkillCategories && !validSkillIds.has(expandedId)) {\n throw new Error(\n `Stack \"${stack.name}\" agent_skills for \"${agentName}\" includes skill \"${expandedId}\" not in stack's skills array`,\n );\n }\n\n const skillDef = skills[expandedId];\n skillRefs.push({\n id: expandedId,\n usage: `when working with ${skillDef.name.toLowerCase()}`,\n preloaded: assignment.preloaded ?? false,\n });\n\n addedSkills.add(expandedId);\n }\n }\n\n return skillRefs;\n}\n\n/**\n * Options for getAgentSkills function.\n * Supports both Phase 6 (agent-centric) and Phase 7 (stack-based) configurations.\n */\nexport interface GetAgentSkillsOptions {\n /** The agent name/ID */\n agentName: string;\n /** Per-agent compile config (may have explicit skills) */\n agentConfig: CompileAgentConfig;\n /** Overall compile config */\n compileConfig: CompileConfig;\n /** All available skill definitions */\n skills: Record<string, SkillDefinition>;\n /** Project root path */\n projectRoot: string;\n /** Agent definition (Phase 6) */\n agentDef?: AgentDefinition;\n /** Stack definition (Phase 7) */\n stack?: Stack;\n /** Skill aliases mapping (Phase 7) */\n skillAliases?: Record<string, string>;\n}\n\n/**\n * Get skill references for an agent.\n * Supports multiple resolution strategies with the following priority:\n *\n * 1. Explicit skills in compile config (agentConfig.skills)\n * 2. Stack-based skills (Phase 7) if stack and skillAliases provided\n * 3. Agent definition skills (Phase 6) if agentDef.skills provided\n *\n * @param options - Configuration options for skill resolution\n * @returns Array of SkillReference objects\n */\nexport async function getAgentSkills(\n agentName: string,\n agentConfig: CompileAgentConfig,\n _compileConfig: CompileConfig,\n _skills: Record<string, SkillDefinition>,\n _projectRoot: string,\n agentDef?: AgentDefinition,\n stack?: Stack,\n skillAliases?: Record<string, string>,\n): Promise<SkillReference[]> {\n // Priority 1: Explicit skills in compile config\n if (agentConfig.skills && agentConfig.skills.length > 0) {\n return agentConfig.skills;\n }\n\n // Priority 2: Stack-based skills (Phase 7)\n if (stack && skillAliases) {\n const stackSkills = resolveAgentSkillsFromStack(\n agentName,\n stack,\n skillAliases,\n );\n if (stackSkills.length > 0) {\n verbose(\n `Resolved ${stackSkills.length} skills from stack for ${agentName}`,\n );\n return stackSkills;\n }\n }\n\n // Priority 3: Agent's own skills field (Phase 6: agent-centric configuration)\n if (agentDef?.skills && Object.keys(agentDef.skills).length > 0) {\n verbose(`Resolving skills from agent definition for ${agentName}`);\n return resolveAgentSkills(agentDef);\n }\n\n // No skills defined for this agent\n return [];\n}\n\n/**\n * Options for resolveAgents function.\n */\nexport interface ResolveAgentsOptions {\n /** All loaded agent definitions */\n agents: Record<string, AgentDefinition>;\n /** All loaded skill definitions */\n skills: Record<string, SkillDefinition>;\n /** Compile configuration */\n compileConfig: CompileConfig;\n /** Project root path */\n projectRoot: string;\n /** Stack definition (Phase 7) - optional */\n stack?: Stack;\n /** Skill aliases mapping (Phase 7) - optional */\n skillAliases?: Record<string, string>;\n}\n\nexport async function resolveAgents(\n agents: Record<string, AgentDefinition>,\n skills: Record<string, SkillDefinition>,\n compileConfig: CompileConfig,\n projectRoot: string,\n stack?: Stack,\n skillAliases?: Record<string, string>,\n): Promise<Record<string, AgentConfig>> {\n const resolved: Record<string, AgentConfig> = {};\n const agentNames = Object.keys(compileConfig.agents);\n\n for (const agentName of agentNames) {\n const definition = agents[agentName];\n if (!definition) {\n const availableAgents = Object.keys(agents);\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 agents found in scanned directories\";\n throw new Error(\n `Agent '${agentName}' referenced in compile config but not found in scanned agents. ${agentList}. Check that src/agents/${agentName}/agent.yaml exists.`,\n );\n }\n\n const agentConfig = compileConfig.agents[agentName];\n\n const skillRefs = await getAgentSkills(\n agentName,\n agentConfig,\n compileConfig,\n skills,\n projectRoot,\n definition,\n stack,\n skillAliases,\n );\n\n const resolvedSkills = resolveSkillReferences(skillRefs, skills);\n\n resolved[agentName] = {\n name: agentName,\n title: definition.title,\n description: definition.description,\n model: definition.model,\n tools: definition.tools,\n skills: resolvedSkills,\n path: definition.path,\n sourceRoot: definition.sourceRoot,\n };\n }\n\n return resolved;\n}\n\nexport function stackToCompileConfig(\n stackId: string,\n stack: StackConfig,\n): CompileConfig {\n const agents: Record<string, CompileAgentConfig> = {};\n\n for (const agentId of stack.agents) {\n agents[agentId] = {};\n }\n\n return {\n name: stack.name,\n description: stack.description || \"\",\n claude_md: \"\",\n stack: stackId,\n agents,\n };\n}\n","import { Liquid } from \"liquidjs\";\nimport path from \"path\";\nimport {\n readFile,\n readFileOptional,\n writeFile,\n ensureDir,\n remove,\n copy,\n glob,\n fileExists,\n directoryExists,\n} from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport { DIRS, OUTPUT_DIR, PROJECT_ROOT } from \"../consts\";\nimport { resolveClaudeMd } from \"./resolver\";\nimport {\n validateCompiledAgent,\n printOutputValidationResult,\n} from \"./output-validator\";\nimport type {\n Skill,\n AgentConfig,\n CompiledAgentData,\n CompileConfig,\n CompileContext,\n} from \"../types\";\n\nasync function compileAgent(\n name: string,\n agent: AgentConfig,\n projectRoot: string,\n engine: Liquid,\n): Promise<string> {\n verbose(`Reading agent files for ${name}...`);\n\n const agentDir = path.join(projectRoot, DIRS.agents, agent.path || name);\n\n const intro = await readFile(path.join(agentDir, \"intro.md\"));\n const workflow = await readFile(path.join(agentDir, \"workflow.md\"));\n const examples = await readFileOptional(\n path.join(agentDir, \"examples.md\"),\n \"## Examples\\n\\n_No examples defined._\",\n );\n const criticalRequirementsTop = await readFileOptional(\n path.join(agentDir, \"critical-requirements.md\"),\n \"\",\n );\n const criticalReminders = await readFileOptional(\n path.join(agentDir, \"critical-reminders.md\"),\n \"\",\n );\n\n const agentPath = agent.path || name;\n const category = agentPath.split(\"/\")[0];\n const categoryDir = path.join(projectRoot, DIRS.agents, category);\n\n let outputFormat = await readFileOptional(\n path.join(agentDir, \"output-format.md\"),\n \"\",\n );\n if (!outputFormat) {\n outputFormat = await readFileOptional(\n path.join(categoryDir, \"output-format.md\"),\n \"\",\n );\n }\n\n const preloadedSkills = agent.skills.filter((s) => s.preloaded);\n const dynamicSkills = agent.skills.filter((s) => !s.preloaded);\n const preloadedSkillIds = preloadedSkills.map((s) => s.id);\n\n verbose(\n `Skills for ${name}: ${preloadedSkills.length} preloaded, ${dynamicSkills.length} dynamic`,\n );\n\n const data: CompiledAgentData = {\n agent,\n intro,\n workflow,\n examples,\n criticalRequirementsTop,\n criticalReminders,\n outputFormat,\n skills: agent.skills,\n preloadedSkills,\n dynamicSkills,\n preloadedSkillIds,\n };\n\n verbose(`Rendering template for ${name}...`);\n return engine.renderFile(\"agent\", data);\n}\n\nexport async function compileAllAgents(\n resolvedAgents: Record<string, AgentConfig>,\n config: CompileConfig,\n ctx: CompileContext,\n engine: Liquid,\n): Promise<void> {\n const outDir = path.join(ctx.outputDir, \"agents\");\n await ensureDir(outDir);\n\n let hasValidationIssues = false;\n\n for (const [name, agent] of Object.entries(resolvedAgents)) {\n try {\n const output = await compileAgent(name, agent, ctx.projectRoot, engine);\n await writeFile(path.join(outDir, `${name}.md`), output);\n console.log(` ✓ ${name}.md`);\n\n const validationResult = validateCompiledAgent(output);\n if (!validationResult.valid || validationResult.warnings.length > 0) {\n hasValidationIssues = true;\n printOutputValidationResult(name, validationResult);\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n console.error(` ✗ ${name}.md - ${errorMessage}`);\n throw new Error(\n `Failed to compile agent '${name}': ${errorMessage}. Check that all required files exist in src/agents/${agent.path || name}/`,\n );\n }\n }\n\n if (hasValidationIssues) {\n console.log(\"\");\n }\n}\n\nexport async function compileAllSkills(\n resolvedAgents: Record<string, AgentConfig>,\n ctx: CompileContext,\n): Promise<void> {\n const allSkills = Object.values(resolvedAgents)\n .flatMap((a) => a.skills)\n .filter((s) => s.path);\n\n const uniqueSkills = [...new Map(allSkills.map((s) => [s.id, s])).values()];\n\n for (const skill of uniqueSkills) {\n const id = skill.id.replace(\"/\", \"-\");\n const outDir = path.join(ctx.outputDir, \"skills\", id);\n await ensureDir(outDir);\n\n const sourcePath = path.join(ctx.projectRoot, skill.path);\n const isFolder = skill.path.endsWith(\"/\");\n\n try {\n if (isFolder) {\n const mainContent = await readFile(path.join(sourcePath, \"SKILL.md\"));\n await writeFile(path.join(outDir, \"SKILL.md\"), mainContent);\n console.log(` ✓ skills/${id}/SKILL.md`);\n\n const referenceContent = await readFileOptional(\n path.join(sourcePath, \"reference.md\"),\n );\n if (referenceContent) {\n await writeFile(path.join(outDir, \"reference.md\"), referenceContent);\n console.log(` ✓ skills/${id}/reference.md`);\n }\n\n const examplesDir = path.join(sourcePath, \"examples\");\n if (await fileExists(examplesDir)) {\n await copy(examplesDir, path.join(outDir, \"examples\"));\n console.log(` ✓ skills/${id}/examples/`);\n }\n\n const scriptsDir = path.join(sourcePath, \"scripts\");\n if (await fileExists(scriptsDir)) {\n await copy(scriptsDir, path.join(outDir, \"scripts\"));\n console.log(` ✓ skills/${id}/scripts/`);\n }\n } else {\n const content = await readFile(sourcePath);\n await writeFile(path.join(outDir, \"SKILL.md\"), content);\n console.log(` ✓ skills/${id}/SKILL.md`);\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n console.error(` ✗ skills/${id}/SKILL.md - ${errorMessage}`);\n throw new Error(\n `Failed to compile skill '${skill.id}': ${errorMessage}. Expected skill at: ${sourcePath}`,\n );\n }\n }\n}\n\nexport async function copyClaude(ctx: CompileContext): Promise<void> {\n const claudePath = await resolveClaudeMd(\n ctx.projectRoot,\n ctx.stackId,\n ctx.mode,\n );\n\n const content = await readFile(claudePath);\n const outputPath = path.join(ctx.outputDir, \"..\", \"CLAUDE.md\");\n await writeFile(outputPath, content);\n console.log(` ✓ CLAUDE.md (from stack)`);\n}\n\nexport async function compileAllCommands(ctx: CompileContext): Promise<void> {\n const commandsDir = path.join(ctx.projectRoot, DIRS.commands);\n const outDir = path.join(ctx.outputDir, \"commands\");\n\n if (!(await fileExists(commandsDir))) {\n console.log(\" - No commands directory found, skipping...\");\n return;\n }\n\n const files = await glob(\"*.md\", commandsDir);\n\n if (files.length === 0) {\n console.log(\" - No commands found, skipping...\");\n return;\n }\n\n await ensureDir(outDir);\n\n for (const file of files) {\n try {\n const content = await readFile(path.join(commandsDir, file));\n await writeFile(path.join(outDir, file), content);\n console.log(` ✓ ${file}`);\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n console.error(` ✗ ${file} - ${errorMessage}`);\n throw new Error(\n `Failed to compile command '${file}': ${errorMessage}. Expected at: ${path.join(commandsDir, file)}`,\n );\n }\n }\n}\n\nexport async function createLiquidEngine(projectDir?: string): Promise<Liquid> {\n const roots: string[] = [];\n\n if (projectDir) {\n const localTemplatesDir = path.join(projectDir, \".claude\", \"templates\");\n if (await directoryExists(localTemplatesDir)) {\n roots.push(localTemplatesDir);\n verbose(`Using local templates from: ${localTemplatesDir}`);\n }\n }\n\n roots.push(path.join(PROJECT_ROOT, DIRS.templates));\n\n return new Liquid({\n root: roots,\n extname: \".liquid\",\n strictVariables: false,\n strictFilters: true,\n });\n}\n\nexport async function cleanOutputDir(outputDir: string): Promise<void> {\n await remove(path.join(outputDir, \"agents\"));\n await remove(path.join(outputDir, \"skills\"));\n await remove(path.join(outputDir, \"commands\"));\n}\n","import { parse as parseYaml } from \"yaml\";\n\nexport interface OutputValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n}\n\nfunction extractFrontmatter(content: string): unknown | null {\n const frontmatterRegex = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/;\n const match = content.match(frontmatterRegex);\n\n if (!match || !match[1]) {\n return null;\n }\n\n try {\n return parseYaml(match[1]);\n } catch {\n return null;\n }\n}\n\nfunction checkXmlTagBalance(content: string): string[] {\n const errors: string[] = [];\n const tagRegex = /<\\/?([a-z_][a-z0-9_-]*)\\s*>/gi;\n const tagCounts = new Map<string, number>();\n\n let match;\n while ((match = tagRegex.exec(content)) !== null) {\n const fullTag = match[0];\n const tagName = match[1].toLowerCase();\n\n const before = content.slice(Math.max(0, match.index - 10), match.index);\n const after = content.slice(\n match.index + fullTag.length,\n match.index + fullTag.length + 10,\n );\n if (before.includes(\"`\") || after.includes(\"`\")) {\n continue;\n }\n\n const isClosing = fullTag.startsWith(\"</\");\n const current = tagCounts.get(tagName) || 0;\n tagCounts.set(tagName, isClosing ? current - 1 : current + 1);\n }\n\n for (const [tag, count] of tagCounts) {\n if (count > 0) {\n errors.push(`Unclosed XML tag: <${tag}> (${count} unclosed)`);\n } else if (count < 0) {\n errors.push(`Extra closing tag: </${tag}> (${Math.abs(count)} extra)`);\n }\n }\n\n return errors;\n}\n\nfunction checkTemplateArtifacts(content: string): string[] {\n const warnings: string[] = [];\n\n const variableMatches = content.match(/\\{\\{[^}]*\\}\\}/g);\n if (variableMatches) {\n warnings.push(\n `Template artifacts found: ${variableMatches.length} unprocessed {{ }} tags`,\n );\n }\n\n const controlMatches = content.match(/\\{%[^%]*%\\}/g);\n if (controlMatches) {\n warnings.push(\n `Template artifacts found: ${controlMatches.length} unprocessed {% %} tags`,\n );\n }\n\n return warnings;\n}\n\nfunction checkRequiredPatterns(content: string): string[] {\n const warnings: string[] = [];\n\n if (!content.startsWith(\"---\")) {\n warnings.push(\"Missing YAML frontmatter at start of file\");\n }\n\n if (!content.includes(\"<role>\")) {\n warnings.push(\"Missing <role> section\");\n }\n\n if (\n !content.includes(\"Core Principles\") &&\n !content.includes(\"core_principles\")\n ) {\n warnings.push(\"Missing Core Principles section\");\n }\n\n const lines = content.trim().split(\"\\n\");\n if (lines.length < 50) {\n warnings.push(`Suspiciously short output: only ${lines.length} lines`);\n }\n\n return warnings;\n}\n\nfunction validateFrontmatter(content: string): {\n errors: string[];\n warnings: string[];\n} {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n const frontmatter = extractFrontmatter(content);\n\n if (frontmatter === null) {\n errors.push(\"Failed to parse YAML frontmatter\");\n return { errors, warnings };\n }\n\n const fm = frontmatter as Record<string, unknown>;\n\n if (!fm.name || typeof fm.name !== \"string\") {\n errors.push(\"Frontmatter missing required field: name\");\n }\n\n if (!fm.description || typeof fm.description !== \"string\") {\n warnings.push(\"Frontmatter missing field: description\");\n }\n\n if (!fm.tools || typeof fm.tools !== \"string\") {\n warnings.push(\"Frontmatter missing field: tools\");\n }\n\n return { errors, warnings };\n}\n\nexport function validateCompiledAgent(content: string): OutputValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!content || content.trim().length === 0) {\n return {\n valid: false,\n errors: [\"Compiled output is empty\"],\n warnings: [],\n };\n }\n\n const fmResult = validateFrontmatter(content);\n errors.push(...fmResult.errors);\n warnings.push(...fmResult.warnings);\n\n const xmlErrors = checkXmlTagBalance(content);\n errors.push(...xmlErrors);\n\n const artifactWarnings = checkTemplateArtifacts(content);\n warnings.push(...artifactWarnings);\n\n const patternWarnings = checkRequiredPatterns(content);\n warnings.push(...patternWarnings);\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nexport function printOutputValidationResult(\n agentName: string,\n result: OutputValidationResult,\n): void {\n if (result.errors.length > 0) {\n console.log(` Validation errors for ${agentName}:`);\n result.errors.forEach((e) => console.log(` - ${e}`));\n }\n\n if (result.warnings.length > 0) {\n console.log(` Validation warnings for ${agentName}:`);\n result.warnings.forEach((w) => console.log(` - ${w}`));\n }\n}\n"],"mappings":"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","names":[]}