@claude-collective/cli 0.2.0 → 0.8.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 (190) hide show
  1. package/CHANGELOG.md +178 -0
  2. package/README.md +1 -1
  3. package/dist/chunk-3HBTELJN.js +114 -0
  4. package/dist/chunk-3HBTELJN.js.map +1 -0
  5. package/dist/chunk-3ZCB5K33.js +54 -0
  6. package/dist/chunk-3ZCB5K33.js.map +1 -0
  7. package/dist/chunk-66UDJBF6.js +96 -0
  8. package/dist/chunk-66UDJBF6.js.map +1 -0
  9. package/dist/chunk-6LS7XO3H.js +31 -0
  10. package/dist/chunk-6LS7XO3H.js.map +1 -0
  11. package/dist/chunk-A3J6IAXK.js +57 -0
  12. package/dist/chunk-A3J6IAXK.js.map +1 -0
  13. package/dist/chunk-A65SBAAJ.js +69 -0
  14. package/dist/chunk-A65SBAAJ.js.map +1 -0
  15. package/dist/chunk-ALEPJ6YN.js +80 -0
  16. package/dist/chunk-ALEPJ6YN.js.map +1 -0
  17. package/dist/chunk-C4ZTIYFR.js +84 -0
  18. package/dist/chunk-C4ZTIYFR.js.map +1 -0
  19. package/dist/chunk-CIY5UBRB.js +453 -0
  20. package/dist/chunk-CIY5UBRB.js.map +1 -0
  21. package/dist/chunk-DHET7RCE.js +50 -0
  22. package/dist/chunk-DHET7RCE.js.map +1 -0
  23. package/dist/chunk-DHFFRMF6.js +31 -0
  24. package/dist/chunk-DHFFRMF6.js.map +1 -0
  25. package/dist/chunk-DKGL77IY.js +307 -0
  26. package/dist/chunk-DKGL77IY.js.map +1 -0
  27. package/dist/chunk-ED73HCW2.js +315 -0
  28. package/dist/chunk-ED73HCW2.js.map +1 -0
  29. package/dist/chunk-FNOYEXUE.js +308 -0
  30. package/dist/chunk-FNOYEXUE.js.map +1 -0
  31. package/dist/chunk-G2FBJOZG.js +141 -0
  32. package/dist/chunk-G2FBJOZG.js.map +1 -0
  33. package/dist/chunk-HNDT5QRB.js +120 -0
  34. package/dist/chunk-HNDT5QRB.js.map +1 -0
  35. package/dist/chunk-K7PTOVX4.js +158 -0
  36. package/dist/chunk-K7PTOVX4.js.map +1 -0
  37. package/dist/chunk-LQTST4WY.js +91 -0
  38. package/dist/chunk-LQTST4WY.js.map +1 -0
  39. package/dist/chunk-LVKRVFYR.js +54 -0
  40. package/dist/chunk-LVKRVFYR.js.map +1 -0
  41. package/dist/chunk-M7YCPFIX.js +108 -0
  42. package/dist/chunk-M7YCPFIX.js.map +1 -0
  43. package/dist/chunk-MJSFR562.js +57 -0
  44. package/dist/chunk-MJSFR562.js.map +1 -0
  45. package/dist/chunk-MMDXNZPF.js +69 -0
  46. package/dist/chunk-MMDXNZPF.js.map +1 -0
  47. package/dist/chunk-MYAVQ23U.js +356 -0
  48. package/dist/chunk-MYAVQ23U.js.map +1 -0
  49. package/dist/chunk-NGBFJJ7Q.js +124 -0
  50. package/dist/chunk-NGBFJJ7Q.js.map +1 -0
  51. package/dist/chunk-OLBOTK3O.js +64 -0
  52. package/dist/chunk-OLBOTK3O.js.map +1 -0
  53. package/dist/chunk-PPNTD5LO.js +330 -0
  54. package/dist/chunk-PPNTD5LO.js.map +1 -0
  55. package/dist/chunk-Q2LH2DAB.js +392 -0
  56. package/dist/chunk-Q2LH2DAB.js.map +1 -0
  57. package/dist/chunk-Q6DR5QUH.js +547 -0
  58. package/dist/chunk-Q6DR5QUH.js.map +1 -0
  59. package/dist/chunk-QESUUPOE.js +241 -0
  60. package/dist/chunk-QESUUPOE.js.map +1 -0
  61. package/dist/chunk-QGGSLMO3.js +607 -0
  62. package/dist/chunk-QGGSLMO3.js.map +1 -0
  63. package/dist/chunk-SEBPPFUW.js +478 -0
  64. package/dist/chunk-SEBPPFUW.js.map +1 -0
  65. package/dist/chunk-SYQ7R2JO.js +95 -0
  66. package/dist/chunk-SYQ7R2JO.js.map +1 -0
  67. package/dist/chunk-TOPAIL5W.js +22 -0
  68. package/dist/chunk-TOPAIL5W.js.map +1 -0
  69. package/dist/chunk-U4VYHKPM.js +110 -0
  70. package/dist/chunk-U4VYHKPM.js.map +1 -0
  71. package/dist/chunk-UOWHJ6BE.js +83 -0
  72. package/dist/chunk-UOWHJ6BE.js.map +1 -0
  73. package/dist/chunk-XKEG3SCV.js +86 -0
  74. package/dist/chunk-XKEG3SCV.js.map +1 -0
  75. package/dist/chunk-XY3XDVMI.js +15599 -0
  76. package/dist/chunk-XY3XDVMI.js.map +1 -0
  77. package/dist/chunk-Y3V43XCU.js +76 -0
  78. package/dist/chunk-Y3V43XCU.js.map +1 -0
  79. package/dist/chunk-YKXBGCFD.js +129 -0
  80. package/dist/chunk-YKXBGCFD.js.map +1 -0
  81. package/dist/cli-v2/defaults/agent-mappings.yaml +185 -0
  82. package/dist/commands/build/marketplace.js +254 -0
  83. package/dist/commands/build/marketplace.js.map +1 -0
  84. package/dist/commands/build/plugins.js +324 -0
  85. package/dist/commands/build/plugins.js.map +1 -0
  86. package/dist/commands/build/stack.js +169 -0
  87. package/dist/commands/build/stack.js.map +1 -0
  88. package/dist/commands/compile.js +461 -0
  89. package/dist/commands/compile.js.map +1 -0
  90. package/dist/commands/config/get.js +60 -0
  91. package/dist/commands/config/get.js.map +1 -0
  92. package/dist/commands/config/index.js +22 -0
  93. package/dist/commands/config/index.js.map +1 -0
  94. package/dist/commands/config/path.js +35 -0
  95. package/dist/commands/config/path.js.map +1 -0
  96. package/dist/commands/config/set-project.js +61 -0
  97. package/dist/commands/config/set-project.js.map +1 -0
  98. package/dist/commands/config/set.js +60 -0
  99. package/dist/commands/config/set.js.map +1 -0
  100. package/dist/commands/config/show.js +13 -0
  101. package/dist/commands/config/show.js.map +1 -0
  102. package/dist/commands/config/unset-project.js +57 -0
  103. package/dist/commands/config/unset-project.js.map +1 -0
  104. package/dist/commands/config/unset.js +56 -0
  105. package/dist/commands/config/unset.js.map +1 -0
  106. package/dist/commands/diff.js +755 -0
  107. package/dist/commands/diff.js.map +1 -0
  108. package/dist/commands/doctor.js +413 -0
  109. package/dist/commands/doctor.js.map +1 -0
  110. package/dist/commands/edit.js +254 -0
  111. package/dist/commands/edit.js.map +1 -0
  112. package/dist/commands/eject.js +208 -0
  113. package/dist/commands/eject.js.map +1 -0
  114. package/dist/commands/info.js +205 -0
  115. package/dist/commands/info.js.map +1 -0
  116. package/dist/commands/init.js +915 -0
  117. package/dist/commands/init.js.map +1 -0
  118. package/dist/commands/list.js +44 -0
  119. package/dist/commands/list.js.map +1 -0
  120. package/dist/commands/new/agent.js +230 -0
  121. package/dist/commands/new/agent.js.map +1 -0
  122. package/dist/commands/new/skill.js +204 -0
  123. package/dist/commands/new/skill.js.map +1 -0
  124. package/dist/commands/outdated.js +242 -0
  125. package/dist/commands/outdated.js.map +1 -0
  126. package/dist/commands/search.js +115 -0
  127. package/dist/commands/search.js.map +1 -0
  128. package/dist/commands/test-imports.js +92 -0
  129. package/dist/commands/test-imports.js.map +1 -0
  130. package/dist/commands/uninstall.js +309 -0
  131. package/dist/commands/uninstall.js.map +1 -0
  132. package/dist/commands/update.js +428 -0
  133. package/dist/commands/update.js.map +1 -0
  134. package/dist/commands/validate.js +375 -0
  135. package/dist/commands/validate.js.map +1 -0
  136. package/dist/commands/version/bump.js +95 -0
  137. package/dist/commands/version/bump.js.map +1 -0
  138. package/dist/commands/version/index.js +70 -0
  139. package/dist/commands/version/index.js.map +1 -0
  140. package/dist/commands/version/set.js +101 -0
  141. package/dist/commands/version/set.js.map +1 -0
  142. package/dist/commands/version/show.js +70 -0
  143. package/dist/commands/version/show.js.map +1 -0
  144. package/dist/components/common/confirm.js +9 -0
  145. package/dist/components/common/confirm.js.map +1 -0
  146. package/dist/components/common/message.js +24 -0
  147. package/dist/components/common/message.js.map +1 -0
  148. package/dist/components/common/spinner.js +14 -0
  149. package/dist/components/common/spinner.js.map +1 -0
  150. package/dist/components/wizard/category-grid.js +9 -0
  151. package/dist/components/wizard/category-grid.js.map +1 -0
  152. package/dist/components/wizard/category-grid.test.js +728 -0
  153. package/dist/components/wizard/category-grid.test.js.map +1 -0
  154. package/dist/components/wizard/section-progress.js +9 -0
  155. package/dist/components/wizard/section-progress.js.map +1 -0
  156. package/dist/components/wizard/section-progress.test.js +281 -0
  157. package/dist/components/wizard/section-progress.test.js.map +1 -0
  158. package/dist/components/wizard/step-approach.js +11 -0
  159. package/dist/components/wizard/step-approach.js.map +1 -0
  160. package/dist/components/wizard/step-build.js +15 -0
  161. package/dist/components/wizard/step-build.js.map +1 -0
  162. package/dist/components/wizard/step-build.test.js +729 -0
  163. package/dist/components/wizard/step-build.test.js.map +1 -0
  164. package/dist/components/wizard/step-confirm.js +9 -0
  165. package/dist/components/wizard/step-confirm.js.map +1 -0
  166. package/dist/components/wizard/step-refine.js +9 -0
  167. package/dist/components/wizard/step-refine.js.map +1 -0
  168. package/dist/components/wizard/step-refine.test.js +235 -0
  169. package/dist/components/wizard/step-refine.test.js.map +1 -0
  170. package/dist/components/wizard/step-stack-options.js +11 -0
  171. package/dist/components/wizard/step-stack-options.js.map +1 -0
  172. package/dist/components/wizard/step-stack.js +11 -0
  173. package/dist/components/wizard/step-stack.js.map +1 -0
  174. package/dist/components/wizard/wizard-tabs.js +11 -0
  175. package/dist/components/wizard/wizard-tabs.js.map +1 -0
  176. package/dist/components/wizard/wizard.js +20 -0
  177. package/dist/components/wizard/wizard.js.map +1 -0
  178. package/dist/hooks/init.js +41 -0
  179. package/dist/hooks/init.js.map +1 -0
  180. package/dist/index.js +10 -0
  181. package/dist/index.js.map +1 -0
  182. package/dist/magic-string.es-RGXYGAW3.js +1316 -0
  183. package/dist/magic-string.es-RGXYGAW3.js.map +1 -0
  184. package/dist/stores/wizard-store.js +10 -0
  185. package/dist/stores/wizard-store.js.map +1 -0
  186. package/dist/stores/wizard-store.test.js +405 -0
  187. package/dist/stores/wizard-store.test.js.map +1 -0
  188. package/package.json +44 -25
  189. package/dist/cli/index.js +0 -6314
  190. package/dist/cli/index.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli-v2/lib/loader.ts","../src/cli-v2/lib/stacks-loader.ts","../src/cli-v2/lib/matrix-loader.ts"],"sourcesContent":["import { parse as parseYaml } from \"yaml\";\nimport path from \"path\";\nimport { glob, readFile, directoryExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport { DIRS } from \"../consts\";\nimport type {\n AgentDefinition,\n AgentYamlConfig,\n SkillDefinition,\n SkillFrontmatter,\n StackConfig,\n} from \"../types\";\n\nexport type CompileMode = \"dev\";\n\nexport function getDirs(_mode: CompileMode) {\n return DIRS;\n}\n\nconst FRONTMATTER_REGEX = /^---\\n([\\s\\S]*?)\\n---/;\n\nexport function parseFrontmatter(content: string): SkillFrontmatter | null {\n const match = content.match(FRONTMATTER_REGEX);\n if (!match) return null;\n\n const yamlContent = match[1];\n const frontmatter = parseYaml(yamlContent) as SkillFrontmatter;\n\n if (!frontmatter.name || !frontmatter.description) return null;\n return frontmatter;\n}\n\nfunction extractDisplayName(skillId: string): string {\n const withoutCategory = skillId.split(\"/\").pop() || skillId;\n const withoutAuthor = withoutCategory.replace(/\\s*\\(@\\w+\\)$/, \"\").trim();\n return withoutAuthor\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\nexport async function loadAllAgents(\n projectRoot: string,\n): Promise<Record<string, AgentDefinition>> {\n const agents: Record<string, AgentDefinition> = {};\n const agentSourcesDir = path.join(projectRoot, DIRS.agents);\n\n const files = await glob(\"**/agent.yaml\", agentSourcesDir);\n\n for (const file of files) {\n const fullPath = path.join(agentSourcesDir, file);\n const content = await readFile(fullPath);\n const config = parseYaml(content) as AgentYamlConfig;\n const agentPath = path.dirname(file);\n\n agents[config.id] = {\n title: config.title,\n description: config.description,\n model: config.model,\n tools: config.tools,\n path: agentPath,\n sourceRoot: projectRoot,\n skills: config.skills,\n };\n\n verbose(`Loaded agent: ${config.id} from ${file}`);\n }\n\n return agents;\n}\n\n/** @deprecated Use loadSkillsByIds instead - stacks no longer embed skills */\nexport async function loadStackSkills(\n stackId: string,\n projectRoot: string,\n _mode: CompileMode = \"dev\",\n): Promise<Record<string, SkillDefinition>> {\n const skills: Record<string, SkillDefinition> = {};\n const stackSkillsDir = path.join(projectRoot, DIRS.stacks, stackId, \"skills\");\n\n if (!(await directoryExists(stackSkillsDir))) {\n verbose(`No embedded skills directory for stack ${stackId}`);\n return skills;\n }\n\n const files = await glob(\"**/SKILL.md\", stackSkillsDir);\n\n for (const file of files) {\n const fullPath = path.join(stackSkillsDir, file);\n const content = await readFile(fullPath);\n\n const frontmatter = parseFrontmatter(content);\n if (!frontmatter) {\n console.warn(\n ` Warning: Skipping ${file}: Missing or invalid frontmatter`,\n );\n continue;\n }\n\n const folderPath = file.replace(\"/SKILL.md\", \"\");\n const skillPath = `src/stacks/${stackId}/skills/${folderPath}/`;\n const skillId = frontmatter.name;\n\n skills[skillId] = {\n path: skillPath,\n name: extractDisplayName(frontmatter.name),\n description: frontmatter.description,\n canonicalId: skillId,\n };\n\n verbose(`Loaded stack skill: ${skillId} from ${file}`);\n }\n\n return skills;\n}\n\nasync function buildIdToDirectoryPathMap(\n skillsDir: string,\n): Promise<Record<string, string>> {\n const map: Record<string, string> = {};\n const files = await glob(\"**/SKILL.md\", skillsDir);\n\n for (const file of files) {\n const fullPath = path.join(skillsDir, file);\n const content = await readFile(fullPath);\n const frontmatter = parseFrontmatter(content);\n\n if (frontmatter?.name) {\n const directoryPath = file.replace(\"/SKILL.md\", \"\");\n map[frontmatter.name] = directoryPath;\n map[directoryPath] = directoryPath;\n }\n }\n\n return map;\n}\n\nexport async function loadSkillsByIds(\n skillIds: Array<{ id: string }>,\n projectRoot: string,\n): Promise<Record<string, SkillDefinition>> {\n const skills: Record<string, SkillDefinition> = {};\n const skillsDir = path.join(projectRoot, DIRS.skills);\n\n const idToDirectoryPath = await buildIdToDirectoryPathMap(skillsDir);\n const allSkillIds = Object.keys(idToDirectoryPath);\n const expandedSkillIds: string[] = [];\n\n for (const { id: skillId } of skillIds) {\n if (idToDirectoryPath[skillId]) {\n expandedSkillIds.push(skillId);\n } else {\n const childSkills = allSkillIds.filter((id) => {\n const dirPath = idToDirectoryPath[id];\n return dirPath.startsWith(skillId + \"/\");\n });\n\n if (childSkills.length > 0) {\n expandedSkillIds.push(...childSkills);\n verbose(\n `Expanded directory '${skillId}' to ${childSkills.length} skills`,\n );\n } else {\n console.warn(` Warning: Unknown skill reference '${skillId}'`);\n }\n }\n }\n\n const uniqueSkillIds = [...new Set(expandedSkillIds)];\n\n for (const skillId of uniqueSkillIds) {\n const directoryPath = idToDirectoryPath[skillId];\n if (!directoryPath) {\n console.warn(\n ` Warning: Could not find skill ${skillId}: No matching skill found`,\n );\n continue;\n }\n\n const skillPath = path.join(skillsDir, directoryPath);\n const skillMdPath = path.join(skillPath, \"SKILL.md\");\n\n try {\n const content = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(content);\n\n if (!frontmatter) {\n console.warn(\n ` Warning: Skipping ${skillId}: Missing or invalid frontmatter`,\n );\n continue;\n }\n\n const canonicalId = frontmatter.name;\n const skillDef: SkillDefinition = {\n path: `${DIRS.skills}/${directoryPath}/`,\n name: extractDisplayName(frontmatter.name),\n description: frontmatter.description,\n canonicalId,\n };\n\n skills[canonicalId] = skillDef;\n\n if (directoryPath !== canonicalId) {\n skills[directoryPath] = skillDef;\n }\n\n verbose(`Loaded skill: ${canonicalId} (from ${directoryPath})`);\n } catch (error) {\n console.warn(` Warning: Could not load skill ${skillId}: ${error}`);\n }\n }\n\n return skills;\n}\n\nexport async function loadPluginSkills(\n pluginDir: string,\n): Promise<Record<string, SkillDefinition>> {\n const skills: Record<string, SkillDefinition> = {};\n const pluginSkillsDir = path.join(pluginDir, \"skills\");\n\n if (!(await directoryExists(pluginSkillsDir))) {\n return skills;\n }\n\n const files = await glob(\"**/SKILL.md\", pluginSkillsDir);\n\n for (const file of files) {\n const fullPath = path.join(pluginSkillsDir, file);\n const content = await readFile(fullPath);\n\n const frontmatter = parseFrontmatter(content);\n if (!frontmatter) {\n console.warn(\n ` Warning: Skipping ${file}: Missing or invalid frontmatter`,\n );\n continue;\n }\n\n const folderPath = file.replace(\"/SKILL.md\", \"\");\n const skillPath = `skills/${folderPath}/`;\n const skillId = frontmatter.name;\n\n skills[skillId] = {\n path: skillPath,\n name: extractDisplayName(frontmatter.name),\n description: frontmatter.description,\n canonicalId: skillId,\n };\n\n verbose(`Loaded plugin skill: ${skillId} from ${file}`);\n }\n\n return skills;\n}\n\nconst stackCache = new Map<string, StackConfig>();\n\n/**\n * @deprecated Use loadStackById from stacks-loader.ts instead.\n * This function loads legacy stack configs from src/stacks/{stackId}/config.yaml.\n * The new system uses config/stacks.yaml with agent-centric configuration\n * where skills are defined in each agent's agent.yaml file.\n *\n * Migration path:\n * 1. Use loadStackById() to get stack metadata (agents list)\n * 2. Skills come from agent.yaml files, not stack config\n *\n * @see src/cli-v2/lib/stacks-loader.ts\n */\nexport async function loadStack(\n stackId: string,\n projectRoot: string,\n mode: CompileMode = \"dev\",\n): Promise<StackConfig> {\n const cacheKey = `${mode}:${stackId}`;\n const cached = stackCache.get(cacheKey);\n if (cached) return cached;\n\n const dirs = getDirs(mode);\n const stackPath = path.join(projectRoot, dirs.stacks, stackId, \"config.yaml\");\n\n try {\n const content = await readFile(stackPath);\n const stack = parseYaml(content) as StackConfig;\n stackCache.set(cacheKey, stack);\n verbose(`Loaded stack: ${stack.name} (${stackId})`);\n return stack;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(\n `Failed to load stack '${stackId}': ${errorMessage}. Expected config at: ${stackPath}`,\n );\n }\n}\n","import { parse as parseYaml } from \"yaml\";\nimport path from \"path\";\nimport { readFile, fileExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport type { Stack, StacksConfig, StackAgentConfig } from \"../types-stacks\";\nimport type { SkillReference } from \"../types\";\n\nconst STACKS_FILE = \"config/stacks.yaml\";\n\nconst stacksCache = new Map<string, Stack[]>();\n\n/**\n * Load all stacks from config/stacks.yaml\n * Stacks are simple agent groupings without skill mappings\n */\nexport async function loadStacks(configDir: string): Promise<Stack[]> {\n const cacheKey = configDir;\n const cached = stacksCache.get(cacheKey);\n if (cached) return cached;\n\n const stacksPath = path.join(configDir, STACKS_FILE);\n\n if (!(await fileExists(stacksPath))) {\n verbose(`No stacks file found at ${stacksPath}`);\n return [];\n }\n\n try {\n const content = await readFile(stacksPath);\n const config = parseYaml(content) as StacksConfig;\n\n if (!config.stacks || !Array.isArray(config.stacks)) {\n verbose(`Invalid stacks.yaml format: missing stacks array`);\n return [];\n }\n\n stacksCache.set(cacheKey, config.stacks);\n verbose(`Loaded ${config.stacks.length} stacks from ${stacksPath}`);\n\n return config.stacks;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(\n `Failed to load stacks from '${stacksPath}': ${errorMessage}`,\n );\n }\n}\n\n/**\n * Load a specific stack by ID\n * Returns null if stack not found\n */\nexport async function loadStackById(\n stackId: string,\n configDir: string,\n): Promise<Stack | null> {\n const stacks = await loadStacks(configDir);\n const stack = stacks.find((s) => s.id === stackId);\n\n if (!stack) {\n verbose(`Stack '${stackId}' not found`);\n return null;\n }\n\n verbose(`Found stack: ${stack.name} (${stackId})`);\n return stack;\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 a single agent's technology config to skill references.\n * Looks up each technology alias in skill_aliases to get full skill ID.\n *\n * @param agentConfig - The agent's technology selections (subcategory -> alias)\n * @param skillAliases - Mapping from technology aliases to full skill IDs\n * @returns Array of SkillReference objects\n */\nexport function resolveAgentConfigToSkills(\n agentConfig: StackAgentConfig,\n skillAliases: Record<string, string>,\n): SkillReference[] {\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}' (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 return skillRefs;\n}\n\n/**\n * Resolve all agents in a stack to their skill references.\n * Takes a Stack and skill_aliases, returns a mapping of agent IDs to their resolved skills.\n *\n * @param stack - The stack definition with agent technology selections\n * @param skillAliases - Mapping from technology aliases to full skill IDs\n * @returns Record mapping agent IDs to their SkillReference arrays\n *\n * @example\n * ```typescript\n * const stack = {\n * id: 'nextjs-fullstack',\n * name: 'Next.js Fullstack',\n * agents: {\n * 'web-developer': { framework: 'react', styling: 'scss-modules' },\n * 'api-developer': { api: 'hono', database: 'drizzle' }\n * }\n * };\n *\n * const aliases = {\n * react: 'web/framework/react (@vince)',\n * hono: 'api/framework/hono (@vince)',\n * // ...\n * };\n *\n * const result = resolveStackSkillsFromAliases(stack, aliases);\n * // Returns:\n * // {\n * // 'web-developer': [{ id: 'web/framework/react (@vince)', usage: '...', preloaded: true }, ...],\n * // 'api-developer': [{ id: 'api/framework/hono (@vince)', usage: '...', preloaded: true }, ...]\n * // }\n * ```\n */\nexport function resolveStackSkillsFromAliases(\n stack: Stack,\n skillAliases: Record<string, string>,\n): Record<string, SkillReference[]> {\n const result: Record<string, SkillReference[]> = {};\n\n for (const [agentId, agentConfig] of Object.entries(stack.agents)) {\n // Empty config {} means agent has no technology-specific skills\n if (Object.keys(agentConfig).length === 0) {\n result[agentId] = [];\n continue;\n }\n\n result[agentId] = resolveAgentConfigToSkills(agentConfig, skillAliases);\n }\n\n verbose(\n `Resolved skills for ${Object.keys(result).length} agents in stack '${stack.id}'`,\n );\n\n return result;\n}\n","import { parse as parseYaml } from \"yaml\";\nimport path from \"path\";\nimport { glob, readFile, fileExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport { DIRS } from \"../consts\";\nimport { parseFrontmatter } from \"./loader\";\nimport type {\n SkillsMatrixConfig,\n ExtractedSkillMetadata,\n MergedSkillsMatrix,\n ResolvedSkill,\n ResolvedStack,\n SkillRelation,\n SkillRequirement,\n SkillAlternative,\n} from \"../types-matrix\";\n\ninterface RawMetadata {\n category: string;\n category_exclusive?: boolean;\n author: string;\n version: string;\n cli_name?: string;\n cli_description?: string;\n usage_guidance?: string;\n tags?: string[];\n compatible_with?: string[];\n conflicts_with?: string[];\n requires?: string[];\n requires_setup?: string[];\n provides_setup_for?: string[];\n}\n\nexport async function loadSkillsMatrix(\n configPath: string,\n): Promise<SkillsMatrixConfig> {\n const content = await readFile(configPath);\n const config = parseYaml(content) as SkillsMatrixConfig;\n\n validateMatrixStructure(config, configPath);\n\n verbose(`Loaded skills matrix: ${configPath}`);\n return config;\n}\n\nfunction validateMatrixStructure(\n config: SkillsMatrixConfig,\n configPath: string,\n): void {\n // Note: suggested_stacks removed from required - stacks now defined in config/stacks.yaml (Phase 6)\n const requiredFields = [\n \"version\",\n \"categories\",\n \"relationships\",\n \"skill_aliases\",\n ];\n const missing = requiredFields.filter((field) => !(field in config));\n\n if (missing.length > 0) {\n throw new Error(\n `Skills matrix at ${configPath} is missing required fields: ${missing.join(\", \")}`,\n );\n }\n\n const relationshipFields = [\n \"conflicts\",\n \"recommends\",\n \"requires\",\n \"alternatives\",\n ];\n const missingRelationships = relationshipFields.filter(\n (field) => !config.relationships || !(field in config.relationships),\n );\n\n if (missingRelationships.length > 0) {\n throw new Error(\n `Skills matrix relationships missing required fields: ${missingRelationships.join(\", \")}`,\n );\n }\n\n for (const [categoryId, category] of Object.entries(config.categories)) {\n const requiredCategoryFields = [\n \"id\",\n \"name\",\n \"description\",\n \"exclusive\",\n \"required\",\n \"order\",\n ];\n const missingCategoryFields = requiredCategoryFields.filter(\n (field) => !(field in category),\n );\n\n if (missingCategoryFields.length > 0) {\n throw new Error(\n `Category \"${categoryId}\" missing required fields: ${missingCategoryFields.join(\", \")}`,\n );\n }\n }\n}\n\nexport async function extractAllSkills(\n skillsDir: string,\n): Promise<ExtractedSkillMetadata[]> {\n const skills: ExtractedSkillMetadata[] = [];\n const metadataFiles = await glob(\"**/metadata.yaml\", skillsDir);\n\n for (const metadataFile of metadataFiles) {\n const skillDir = path.dirname(metadataFile);\n const skillMdPath = path.join(skillsDir, skillDir, \"SKILL.md\");\n const metadataPath = path.join(skillsDir, metadataFile);\n\n if (!(await fileExists(skillMdPath))) {\n verbose(`Skipping ${metadataFile}: No SKILL.md found`);\n continue;\n }\n\n const metadataContent = await readFile(metadataPath);\n const metadata = parseYaml(metadataContent) as RawMetadata;\n const skillMdContent = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(skillMdContent);\n\n if (!frontmatter) {\n verbose(`Skipping ${metadataFile}: Invalid SKILL.md frontmatter`);\n continue;\n }\n\n if (!metadata.cli_name) {\n throw new Error(\n `Skill at ${metadataFile} is missing required 'cli_name' field in metadata.yaml`,\n );\n }\n\n const skillId = frontmatter.name;\n\n const extracted: ExtractedSkillMetadata = {\n id: skillId,\n directoryPath: skillDir,\n name: metadata.cli_name,\n description: metadata.cli_description || frontmatter.description,\n usageGuidance: metadata.usage_guidance,\n category: metadata.category,\n categoryExclusive: metadata.category_exclusive ?? true,\n author: metadata.author,\n tags: metadata.tags ?? [],\n compatibleWith: metadata.compatible_with ?? [],\n conflictsWith: metadata.conflicts_with ?? [],\n requires: metadata.requires ?? [],\n requiresSetup: metadata.requires_setup ?? [],\n providesSetupFor: metadata.provides_setup_for ?? [],\n path: `skills/${skillDir}/`,\n };\n\n skills.push(extracted);\n verbose(`Extracted skill: ${skillId}`);\n }\n\n return skills;\n}\n\nfunction buildReverseAliases(\n aliases: Record<string, string>,\n): Record<string, string> {\n const reverse: Record<string, string> = {};\n for (const [alias, fullId] of Object.entries(aliases)) {\n reverse[fullId] = alias;\n }\n return reverse;\n}\n\n/**\n * Build a map from short names to actual skill IDs.\n *\n * This handles multiple formats used in skill metadata:\n * - \"react (@vince)\" -> \"web/framework/react (@vince)\"\n * - \"react\" -> \"web/framework/react (@vince)\"\n * - Old alias targets that may still exist in metadata files\n */\nfunction buildAliasTargetToSkillIdMap(\n aliases: Record<string, string>,\n skills: ExtractedSkillMetadata[],\n): Record<string, string> {\n const map: Record<string, string> = {};\n\n for (const skill of skills) {\n // Extract the \"short author\" form: last path segment with author\n // e.g., \"web/framework/react (@vince)\" -> \"react (@vince)\"\n const parts = skill.id.split(\"/\");\n const shortForm = parts[parts.length - 1];\n\n if (shortForm && shortForm !== skill.id) {\n map[shortForm] = skill.id;\n }\n\n // Also map directory name without author if different\n // e.g., \"web/framework/react\" -> \"web/framework/react (@vince)\"\n if (skill.directoryPath && skill.directoryPath !== skill.id) {\n map[skill.directoryPath] = skill.id;\n }\n }\n\n // Also include any old-style alias targets that might still be referenced\n const aliasTargets = new Set(Object.values(aliases));\n for (const skill of skills) {\n for (const aliasTarget of aliasTargets) {\n if (\n aliasTarget !== skill.id &&\n (skill.id.endsWith(`/${aliasTarget}`) || skill.id === aliasTarget)\n ) {\n map[aliasTarget] = skill.id;\n }\n }\n }\n\n return map;\n}\n\nfunction buildDirectoryPathToIdMap(\n skills: ExtractedSkillMetadata[],\n): Record<string, string> {\n const map: Record<string, string> = {};\n for (const skill of skills) {\n if (skill.directoryPath && skill.directoryPath !== skill.id) {\n map[skill.directoryPath] = skill.id;\n }\n }\n return map;\n}\n\nfunction resolveToCanonicalId(\n aliasOrId: string,\n aliases: Record<string, string>,\n directoryPathToId: Record<string, string> = {},\n aliasTargetToSkillId: Record<string, string> = {},\n): string {\n if (aliases[aliasOrId]) {\n return aliases[aliasOrId];\n }\n if (directoryPathToId[aliasOrId]) {\n return directoryPathToId[aliasOrId];\n }\n // Handle \"short author\" format like \"react (@vince)\" that maps to full ID\n if (aliasTargetToSkillId[aliasOrId]) {\n return aliasTargetToSkillId[aliasOrId];\n }\n return aliasOrId;\n}\n\nexport async function mergeMatrixWithSkills(\n matrix: SkillsMatrixConfig,\n skills: ExtractedSkillMetadata[],\n): Promise<MergedSkillsMatrix> {\n const aliases = matrix.skill_aliases;\n const aliasesReverse = buildReverseAliases(aliases);\n const directoryPathToId = buildDirectoryPathToIdMap(skills);\n const aliasTargetToSkillId = buildAliasTargetToSkillIdMap(aliases, skills);\n const resolvedSkills: Record<string, ResolvedSkill> = {};\n\n for (const skill of skills) {\n const resolved = buildResolvedSkill(\n skill,\n matrix,\n aliases,\n aliasesReverse,\n directoryPathToId,\n aliasTargetToSkillId,\n );\n resolvedSkills[skill.id] = resolved;\n }\n\n computeInverseRelationships(resolvedSkills);\n const suggestedStacks = resolveSuggestedStacks(\n matrix,\n aliases,\n aliasTargetToSkillId,\n );\n\n const merged: MergedSkillsMatrix = {\n version: matrix.version,\n categories: matrix.categories,\n skills: resolvedSkills,\n suggestedStacks,\n aliases,\n aliasesReverse,\n generatedAt: new Date().toISOString(),\n };\n\n return merged;\n}\n\nfunction buildResolvedSkill(\n skill: ExtractedSkillMetadata,\n matrix: SkillsMatrixConfig,\n aliases: Record<string, string>,\n aliasesReverse: Record<string, string>,\n directoryPathToId: Record<string, string>,\n aliasTargetToSkillId: Record<string, string>,\n): ResolvedSkill {\n const conflictsWith: SkillRelation[] = [];\n const recommends: SkillRelation[] = [];\n const requires: SkillRequirement[] = [];\n const alternatives: SkillAlternative[] = [];\n const discourages: SkillRelation[] = [];\n\n // Helper to resolve with all maps\n const resolve = (id: string) =>\n resolveToCanonicalId(id, aliases, directoryPathToId, aliasTargetToSkillId);\n\n for (const conflictRef of skill.conflictsWith) {\n const canonicalId = resolve(conflictRef);\n conflictsWith.push({\n skillId: canonicalId,\n reason: \"Defined in skill metadata\",\n });\n }\n\n for (const conflictRule of matrix.relationships.conflicts) {\n const resolvedSkills = conflictRule.skills.map(resolve);\n if (resolvedSkills.includes(skill.id)) {\n for (const otherSkill of resolvedSkills) {\n if (otherSkill !== skill.id) {\n if (!conflictsWith.some((c) => c.skillId === otherSkill)) {\n conflictsWith.push({\n skillId: otherSkill,\n reason: conflictRule.reason,\n });\n }\n }\n }\n }\n }\n\n for (const compatRef of skill.compatibleWith) {\n const canonicalId = resolve(compatRef);\n recommends.push({\n skillId: canonicalId,\n reason: \"Compatible with this skill\",\n });\n }\n\n for (const recommendRule of matrix.relationships.recommends) {\n const whenCanonicalId = resolve(recommendRule.when);\n if (whenCanonicalId === skill.id) {\n for (const suggested of recommendRule.suggest) {\n const canonicalId = resolve(suggested);\n if (!recommends.some((r) => r.skillId === canonicalId)) {\n recommends.push({\n skillId: canonicalId,\n reason: recommendRule.reason,\n });\n }\n }\n }\n }\n\n if (skill.requires.length > 0) {\n requires.push({\n skillIds: skill.requires.map(resolve),\n needsAny: false,\n reason: \"Defined in skill metadata\",\n });\n }\n\n for (const requireRule of matrix.relationships.requires) {\n const skillCanonicalId = resolve(requireRule.skill);\n if (skillCanonicalId === skill.id) {\n requires.push({\n skillIds: requireRule.needs.map(resolve),\n needsAny: requireRule.needs_any ?? false,\n reason: requireRule.reason,\n });\n }\n }\n\n for (const altGroup of matrix.relationships.alternatives) {\n const resolvedAlts = altGroup.skills.map(resolve);\n if (resolvedAlts.includes(skill.id)) {\n for (const altSkill of resolvedAlts) {\n if (altSkill !== skill.id) {\n alternatives.push({\n skillId: altSkill,\n purpose: altGroup.purpose,\n });\n }\n }\n }\n }\n\n if (matrix.relationships.discourages) {\n for (const discourageRule of matrix.relationships.discourages) {\n const resolvedSkills = discourageRule.skills.map(resolve);\n if (resolvedSkills.includes(skill.id)) {\n for (const otherSkill of resolvedSkills) {\n if (otherSkill !== skill.id) {\n if (!discourages.some((d) => d.skillId === otherSkill)) {\n discourages.push({\n skillId: otherSkill,\n reason: discourageRule.reason,\n });\n }\n }\n }\n }\n }\n }\n\n return {\n id: skill.id,\n alias: aliasesReverse[skill.id],\n name: skill.name,\n description: skill.description,\n usageGuidance: skill.usageGuidance,\n category: skill.category,\n categoryExclusive: skill.categoryExclusive,\n tags: skill.tags,\n author: skill.author,\n conflictsWith,\n recommends,\n recommendedBy: [],\n requires,\n requiredBy: [],\n alternatives,\n discourages,\n requiresSetup: skill.requiresSetup.map(resolve),\n providesSetupFor: skill.providesSetupFor.map(resolve),\n path: skill.path,\n };\n}\n\nfunction computeInverseRelationships(\n skills: Record<string, ResolvedSkill>,\n): void {\n for (const skill of Object.values(skills)) {\n for (const recommend of skill.recommends) {\n const targetSkill = skills[recommend.skillId];\n if (targetSkill) {\n targetSkill.recommendedBy.push({\n skillId: skill.id,\n reason: recommend.reason,\n });\n }\n }\n\n for (const requirement of skill.requires) {\n for (const requiredId of requirement.skillIds) {\n const targetSkill = skills[requiredId];\n if (targetSkill) {\n targetSkill.requiredBy.push({\n skillId: skill.id,\n reason: requirement.reason,\n });\n }\n }\n }\n }\n}\n\nfunction resolveSuggestedStacks(\n matrix: SkillsMatrixConfig,\n aliases: Record<string, string>,\n aliasTargetToSkillId: Record<string, string>,\n): ResolvedStack[] {\n // Phase 6: suggested_stacks is now optional (stacks moved to config/stacks.yaml)\n if (!matrix.suggested_stacks) {\n return [];\n }\n return matrix.suggested_stacks.map((stack) => {\n const resolvedSkillsMap: Record<string, Record<string, string>> = {};\n const allSkillIds: string[] = [];\n\n for (const [category, subcategories] of Object.entries(stack.skills)) {\n resolvedSkillsMap[category] = {};\n for (const [subcategory, alias] of Object.entries(subcategories)) {\n // First resolve the alias to its target (e.g., \"react\" -> \"react (@vince)\")\n const aliasTarget = resolveToCanonicalId(alias, aliases);\n // Then check if the alias target needs to be mapped to a full skill ID\n // (e.g., \"react (@vince)\" -> \"web/framework/react (@vince)\")\n const canonicalId = aliasTargetToSkillId[aliasTarget] || aliasTarget;\n resolvedSkillsMap[category][subcategory] = canonicalId;\n allSkillIds.push(canonicalId);\n }\n }\n\n return {\n id: stack.id,\n name: stack.name,\n description: stack.description,\n audience: stack.audience,\n skills: resolvedSkillsMap,\n allSkillIds,\n philosophy: stack.philosophy,\n };\n });\n}\n\nexport async function loadAndMergeSkillsMatrix(\n matrixPath: string,\n projectRoot: string,\n): Promise<MergedSkillsMatrix> {\n const matrix = await loadSkillsMatrix(matrixPath);\n const skillsDir = path.join(projectRoot, DIRS.skills);\n const skills = await extractAllSkills(skillsDir);\n return mergeMatrixWithSkills(matrix, skills);\n}\n"],"mappings":"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","names":["parseYaml","path","path","parseYaml","parseYaml","path","parseYaml","path"]}
@@ -0,0 +1,478 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ DIRS,
4
+ PROJECT_ROOT
5
+ } from "./chunk-A3J6IAXK.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-SEBPPFUW.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', ... };\n *\n * const skills = resolveAgentSkillsFromStack('web-developer', stack, aliases);\n * // Returns: [{ id: 'web-framework-react', 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":[]}