@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,607 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ DIRS
4
+ } from "./chunk-A3J6IAXK.js";
5
+ import {
6
+ verbose
7
+ } from "./chunk-TOPAIL5W.js";
8
+ import {
9
+ directoryExists,
10
+ fileExists,
11
+ glob,
12
+ readFile
13
+ } from "./chunk-MMDXNZPF.js";
14
+ import {
15
+ init_esm_shims
16
+ } from "./chunk-DHET7RCE.js";
17
+
18
+ // src/cli-v2/lib/loader.ts
19
+ init_esm_shims();
20
+ import { parse as parseYaml } from "yaml";
21
+ import path from "path";
22
+ var FRONTMATTER_REGEX = /^---\n([\s\S]*?)\n---/;
23
+ function parseFrontmatter(content) {
24
+ const match = content.match(FRONTMATTER_REGEX);
25
+ if (!match) return null;
26
+ const yamlContent = match[1];
27
+ const frontmatter = parseYaml(yamlContent);
28
+ if (!frontmatter.name || !frontmatter.description) return null;
29
+ return frontmatter;
30
+ }
31
+ function extractDisplayName(skillId) {
32
+ const withoutCategory = skillId.split("/").pop() || skillId;
33
+ const withoutAuthor = withoutCategory.replace(/\s*\(@\w+\)$/, "").trim();
34
+ return withoutAuthor.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
35
+ }
36
+ async function loadAllAgents(projectRoot) {
37
+ const agents = {};
38
+ const agentSourcesDir = path.join(projectRoot, DIRS.agents);
39
+ const files = await glob("**/agent.yaml", agentSourcesDir);
40
+ for (const file of files) {
41
+ const fullPath = path.join(agentSourcesDir, file);
42
+ const content = await readFile(fullPath);
43
+ const config = parseYaml(content);
44
+ const agentPath = path.dirname(file);
45
+ agents[config.id] = {
46
+ title: config.title,
47
+ description: config.description,
48
+ model: config.model,
49
+ tools: config.tools,
50
+ path: agentPath,
51
+ sourceRoot: projectRoot,
52
+ skills: config.skills
53
+ };
54
+ verbose(`Loaded agent: ${config.id} from ${file}`);
55
+ }
56
+ return agents;
57
+ }
58
+ async function buildIdToDirectoryPathMap(skillsDir) {
59
+ const map = {};
60
+ const files = await glob("**/SKILL.md", skillsDir);
61
+ for (const file of files) {
62
+ const fullPath = path.join(skillsDir, file);
63
+ const content = await readFile(fullPath);
64
+ const frontmatter = parseFrontmatter(content);
65
+ if (frontmatter?.name) {
66
+ const directoryPath = file.replace("/SKILL.md", "");
67
+ map[frontmatter.name] = directoryPath;
68
+ map[directoryPath] = directoryPath;
69
+ }
70
+ }
71
+ return map;
72
+ }
73
+ async function loadSkillsByIds(skillIds, projectRoot) {
74
+ const skills = {};
75
+ const skillsDir = path.join(projectRoot, DIRS.skills);
76
+ const idToDirectoryPath = await buildIdToDirectoryPathMap(skillsDir);
77
+ const allSkillIds = Object.keys(idToDirectoryPath);
78
+ const expandedSkillIds = [];
79
+ for (const { id: skillId } of skillIds) {
80
+ if (idToDirectoryPath[skillId]) {
81
+ expandedSkillIds.push(skillId);
82
+ } else {
83
+ const childSkills = allSkillIds.filter((id) => {
84
+ const dirPath = idToDirectoryPath[id];
85
+ return dirPath.startsWith(skillId + "/");
86
+ });
87
+ if (childSkills.length > 0) {
88
+ expandedSkillIds.push(...childSkills);
89
+ verbose(
90
+ `Expanded directory '${skillId}' to ${childSkills.length} skills`
91
+ );
92
+ } else {
93
+ console.warn(` Warning: Unknown skill reference '${skillId}'`);
94
+ }
95
+ }
96
+ }
97
+ const uniqueSkillIds = [...new Set(expandedSkillIds)];
98
+ for (const skillId of uniqueSkillIds) {
99
+ const directoryPath = idToDirectoryPath[skillId];
100
+ if (!directoryPath) {
101
+ console.warn(
102
+ ` Warning: Could not find skill ${skillId}: No matching skill found`
103
+ );
104
+ continue;
105
+ }
106
+ const skillPath = path.join(skillsDir, directoryPath);
107
+ const skillMdPath = path.join(skillPath, "SKILL.md");
108
+ try {
109
+ const content = await readFile(skillMdPath);
110
+ const frontmatter = parseFrontmatter(content);
111
+ if (!frontmatter) {
112
+ console.warn(
113
+ ` Warning: Skipping ${skillId}: Missing or invalid frontmatter`
114
+ );
115
+ continue;
116
+ }
117
+ const canonicalId = frontmatter.name;
118
+ const skillDef = {
119
+ path: `${DIRS.skills}/${directoryPath}/`,
120
+ name: extractDisplayName(frontmatter.name),
121
+ description: frontmatter.description,
122
+ canonicalId
123
+ };
124
+ skills[canonicalId] = skillDef;
125
+ if (directoryPath !== canonicalId) {
126
+ skills[directoryPath] = skillDef;
127
+ }
128
+ verbose(`Loaded skill: ${canonicalId} (from ${directoryPath})`);
129
+ } catch (error) {
130
+ console.warn(` Warning: Could not load skill ${skillId}: ${error}`);
131
+ }
132
+ }
133
+ return skills;
134
+ }
135
+ async function loadPluginSkills(pluginDir) {
136
+ const skills = {};
137
+ const pluginSkillsDir = path.join(pluginDir, "skills");
138
+ if (!await directoryExists(pluginSkillsDir)) {
139
+ return skills;
140
+ }
141
+ const files = await glob("**/SKILL.md", pluginSkillsDir);
142
+ for (const file of files) {
143
+ const fullPath = path.join(pluginSkillsDir, file);
144
+ const content = await readFile(fullPath);
145
+ const frontmatter = parseFrontmatter(content);
146
+ if (!frontmatter) {
147
+ console.warn(
148
+ ` Warning: Skipping ${file}: Missing or invalid frontmatter`
149
+ );
150
+ continue;
151
+ }
152
+ const folderPath = file.replace("/SKILL.md", "");
153
+ const skillPath = `skills/${folderPath}/`;
154
+ const skillId = frontmatter.name;
155
+ skills[skillId] = {
156
+ path: skillPath,
157
+ name: extractDisplayName(frontmatter.name),
158
+ description: frontmatter.description,
159
+ canonicalId: skillId
160
+ };
161
+ verbose(`Loaded plugin skill: ${skillId} from ${file}`);
162
+ }
163
+ return skills;
164
+ }
165
+
166
+ // src/cli-v2/lib/stacks-loader.ts
167
+ init_esm_shims();
168
+ import { parse as parseYaml2 } from "yaml";
169
+ import path2 from "path";
170
+ var STACKS_FILE = "config/stacks.yaml";
171
+ var stacksCache = /* @__PURE__ */ new Map();
172
+ async function loadStacks(configDir) {
173
+ const cacheKey = configDir;
174
+ const cached = stacksCache.get(cacheKey);
175
+ if (cached) return cached;
176
+ const stacksPath = path2.join(configDir, STACKS_FILE);
177
+ if (!await fileExists(stacksPath)) {
178
+ verbose(`No stacks file found at ${stacksPath}`);
179
+ return [];
180
+ }
181
+ try {
182
+ const content = await readFile(stacksPath);
183
+ const config = parseYaml2(content);
184
+ if (!config.stacks || !Array.isArray(config.stacks)) {
185
+ verbose(`Invalid stacks.yaml format: missing stacks array`);
186
+ return [];
187
+ }
188
+ stacksCache.set(cacheKey, config.stacks);
189
+ verbose(`Loaded ${config.stacks.length} stacks from ${stacksPath}`);
190
+ return config.stacks;
191
+ } catch (error) {
192
+ const errorMessage = error instanceof Error ? error.message : String(error);
193
+ throw new Error(
194
+ `Failed to load stacks from '${stacksPath}': ${errorMessage}`
195
+ );
196
+ }
197
+ }
198
+ async function loadStackById(stackId, configDir) {
199
+ const stacks = await loadStacks(configDir);
200
+ const stack = stacks.find((s) => s.id === stackId);
201
+ if (!stack) {
202
+ verbose(`Stack '${stackId}' not found`);
203
+ return null;
204
+ }
205
+ verbose(`Found stack: ${stack.name} (${stackId})`);
206
+ return stack;
207
+ }
208
+ var KEY_SUBCATEGORIES = /* @__PURE__ */ new Set([
209
+ "framework",
210
+ "api",
211
+ "database",
212
+ "meta-framework",
213
+ "base-framework",
214
+ "platform"
215
+ ]);
216
+ function resolveAgentConfigToSkills(agentConfig, skillAliases) {
217
+ const skillRefs = [];
218
+ for (const [subcategory, technologyAlias] of Object.entries(agentConfig)) {
219
+ const fullSkillId = skillAliases[technologyAlias];
220
+ if (!fullSkillId) {
221
+ verbose(
222
+ `Warning: No skill alias found for '${technologyAlias}' (subcategory: ${subcategory}). Skipping.`
223
+ );
224
+ continue;
225
+ }
226
+ const isKeySkill = KEY_SUBCATEGORIES.has(subcategory);
227
+ skillRefs.push({
228
+ id: fullSkillId,
229
+ usage: `when working with ${subcategory}`,
230
+ preloaded: isKeySkill
231
+ });
232
+ }
233
+ return skillRefs;
234
+ }
235
+
236
+ // src/cli-v2/lib/matrix-loader.ts
237
+ init_esm_shims();
238
+ import { parse as parseYaml3 } from "yaml";
239
+ import path3 from "path";
240
+ async function loadSkillsMatrix(configPath) {
241
+ const content = await readFile(configPath);
242
+ const config = parseYaml3(content);
243
+ validateMatrixStructure(config, configPath);
244
+ verbose(`Loaded skills matrix: ${configPath}`);
245
+ return config;
246
+ }
247
+ function validateMatrixStructure(config, configPath) {
248
+ const requiredFields = [
249
+ "version",
250
+ "categories",
251
+ "relationships",
252
+ "skill_aliases"
253
+ ];
254
+ const missing = requiredFields.filter((field) => !(field in config));
255
+ if (missing.length > 0) {
256
+ throw new Error(
257
+ `Skills matrix at ${configPath} is missing required fields: ${missing.join(", ")}`
258
+ );
259
+ }
260
+ const relationshipFields = [
261
+ "conflicts",
262
+ "recommends",
263
+ "requires",
264
+ "alternatives"
265
+ ];
266
+ const missingRelationships = relationshipFields.filter(
267
+ (field) => !config.relationships || !(field in config.relationships)
268
+ );
269
+ if (missingRelationships.length > 0) {
270
+ throw new Error(
271
+ `Skills matrix relationships missing required fields: ${missingRelationships.join(", ")}`
272
+ );
273
+ }
274
+ for (const [categoryId, category] of Object.entries(config.categories)) {
275
+ const requiredCategoryFields = [
276
+ "id",
277
+ "name",
278
+ "description",
279
+ "exclusive",
280
+ "required",
281
+ "order"
282
+ ];
283
+ const missingCategoryFields = requiredCategoryFields.filter(
284
+ (field) => !(field in category)
285
+ );
286
+ if (missingCategoryFields.length > 0) {
287
+ throw new Error(
288
+ `Category "${categoryId}" missing required fields: ${missingCategoryFields.join(", ")}`
289
+ );
290
+ }
291
+ }
292
+ }
293
+ async function extractAllSkills(skillsDir) {
294
+ const skills = [];
295
+ const metadataFiles = await glob("**/metadata.yaml", skillsDir);
296
+ for (const metadataFile of metadataFiles) {
297
+ const skillDir = path3.dirname(metadataFile);
298
+ const skillMdPath = path3.join(skillsDir, skillDir, "SKILL.md");
299
+ const metadataPath = path3.join(skillsDir, metadataFile);
300
+ if (!await fileExists(skillMdPath)) {
301
+ verbose(`Skipping ${metadataFile}: No SKILL.md found`);
302
+ continue;
303
+ }
304
+ const metadataContent = await readFile(metadataPath);
305
+ const metadata = parseYaml3(metadataContent);
306
+ const skillMdContent = await readFile(skillMdPath);
307
+ const frontmatter = parseFrontmatter(skillMdContent);
308
+ if (!frontmatter) {
309
+ verbose(`Skipping ${metadataFile}: Invalid SKILL.md frontmatter`);
310
+ continue;
311
+ }
312
+ if (!metadata.cli_name) {
313
+ throw new Error(
314
+ `Skill at ${metadataFile} is missing required 'cli_name' field in metadata.yaml`
315
+ );
316
+ }
317
+ const skillId = frontmatter.name;
318
+ const extracted = {
319
+ id: skillId,
320
+ directoryPath: skillDir,
321
+ name: metadata.cli_name,
322
+ description: metadata.cli_description || frontmatter.description,
323
+ usageGuidance: metadata.usage_guidance,
324
+ category: metadata.category,
325
+ categoryExclusive: metadata.category_exclusive ?? true,
326
+ author: metadata.author,
327
+ tags: metadata.tags ?? [],
328
+ compatibleWith: metadata.compatible_with ?? [],
329
+ conflictsWith: metadata.conflicts_with ?? [],
330
+ requires: metadata.requires ?? [],
331
+ requiresSetup: metadata.requires_setup ?? [],
332
+ providesSetupFor: metadata.provides_setup_for ?? [],
333
+ path: `skills/${skillDir}/`
334
+ };
335
+ skills.push(extracted);
336
+ verbose(`Extracted skill: ${skillId}`);
337
+ }
338
+ return skills;
339
+ }
340
+ function buildReverseAliases(aliases) {
341
+ const reverse = {};
342
+ for (const [alias, fullId] of Object.entries(aliases)) {
343
+ reverse[fullId] = alias;
344
+ }
345
+ return reverse;
346
+ }
347
+ function buildAliasTargetToSkillIdMap(aliases, skills) {
348
+ const map = {};
349
+ for (const skill of skills) {
350
+ const parts = skill.id.split("/");
351
+ const shortForm = parts[parts.length - 1];
352
+ if (shortForm && shortForm !== skill.id) {
353
+ map[shortForm] = skill.id;
354
+ }
355
+ if (skill.directoryPath && skill.directoryPath !== skill.id) {
356
+ map[skill.directoryPath] = skill.id;
357
+ }
358
+ }
359
+ const aliasTargets = new Set(Object.values(aliases));
360
+ for (const skill of skills) {
361
+ for (const aliasTarget of aliasTargets) {
362
+ if (aliasTarget !== skill.id && (skill.id.endsWith(`/${aliasTarget}`) || skill.id === aliasTarget)) {
363
+ map[aliasTarget] = skill.id;
364
+ }
365
+ }
366
+ }
367
+ return map;
368
+ }
369
+ function buildDirectoryPathToIdMap(skills) {
370
+ const map = {};
371
+ for (const skill of skills) {
372
+ if (skill.directoryPath && skill.directoryPath !== skill.id) {
373
+ map[skill.directoryPath] = skill.id;
374
+ }
375
+ }
376
+ return map;
377
+ }
378
+ function resolveToCanonicalId(aliasOrId, aliases, directoryPathToId = {}, aliasTargetToSkillId = {}) {
379
+ if (aliases[aliasOrId]) {
380
+ return aliases[aliasOrId];
381
+ }
382
+ if (directoryPathToId[aliasOrId]) {
383
+ return directoryPathToId[aliasOrId];
384
+ }
385
+ if (aliasTargetToSkillId[aliasOrId]) {
386
+ return aliasTargetToSkillId[aliasOrId];
387
+ }
388
+ return aliasOrId;
389
+ }
390
+ async function mergeMatrixWithSkills(matrix, skills) {
391
+ const aliases = matrix.skill_aliases;
392
+ const aliasesReverse = buildReverseAliases(aliases);
393
+ const directoryPathToId = buildDirectoryPathToIdMap(skills);
394
+ const aliasTargetToSkillId = buildAliasTargetToSkillIdMap(aliases, skills);
395
+ const resolvedSkills = {};
396
+ for (const skill of skills) {
397
+ const resolved = buildResolvedSkill(
398
+ skill,
399
+ matrix,
400
+ aliases,
401
+ aliasesReverse,
402
+ directoryPathToId,
403
+ aliasTargetToSkillId
404
+ );
405
+ resolvedSkills[skill.id] = resolved;
406
+ }
407
+ computeInverseRelationships(resolvedSkills);
408
+ const suggestedStacks = resolveSuggestedStacks(
409
+ matrix,
410
+ aliases,
411
+ aliasTargetToSkillId
412
+ );
413
+ const merged = {
414
+ version: matrix.version,
415
+ categories: matrix.categories,
416
+ skills: resolvedSkills,
417
+ suggestedStacks,
418
+ aliases,
419
+ aliasesReverse,
420
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString()
421
+ };
422
+ return merged;
423
+ }
424
+ function buildResolvedSkill(skill, matrix, aliases, aliasesReverse, directoryPathToId, aliasTargetToSkillId) {
425
+ const conflictsWith = [];
426
+ const recommends = [];
427
+ const requires = [];
428
+ const alternatives = [];
429
+ const discourages = [];
430
+ const resolve = (id) => resolveToCanonicalId(id, aliases, directoryPathToId, aliasTargetToSkillId);
431
+ for (const conflictRef of skill.conflictsWith) {
432
+ const canonicalId = resolve(conflictRef);
433
+ conflictsWith.push({
434
+ skillId: canonicalId,
435
+ reason: "Defined in skill metadata"
436
+ });
437
+ }
438
+ for (const conflictRule of matrix.relationships.conflicts) {
439
+ const resolvedSkills = conflictRule.skills.map(resolve);
440
+ if (resolvedSkills.includes(skill.id)) {
441
+ for (const otherSkill of resolvedSkills) {
442
+ if (otherSkill !== skill.id) {
443
+ if (!conflictsWith.some((c) => c.skillId === otherSkill)) {
444
+ conflictsWith.push({
445
+ skillId: otherSkill,
446
+ reason: conflictRule.reason
447
+ });
448
+ }
449
+ }
450
+ }
451
+ }
452
+ }
453
+ for (const compatRef of skill.compatibleWith) {
454
+ const canonicalId = resolve(compatRef);
455
+ recommends.push({
456
+ skillId: canonicalId,
457
+ reason: "Compatible with this skill"
458
+ });
459
+ }
460
+ for (const recommendRule of matrix.relationships.recommends) {
461
+ const whenCanonicalId = resolve(recommendRule.when);
462
+ if (whenCanonicalId === skill.id) {
463
+ for (const suggested of recommendRule.suggest) {
464
+ const canonicalId = resolve(suggested);
465
+ if (!recommends.some((r) => r.skillId === canonicalId)) {
466
+ recommends.push({
467
+ skillId: canonicalId,
468
+ reason: recommendRule.reason
469
+ });
470
+ }
471
+ }
472
+ }
473
+ }
474
+ if (skill.requires.length > 0) {
475
+ requires.push({
476
+ skillIds: skill.requires.map(resolve),
477
+ needsAny: false,
478
+ reason: "Defined in skill metadata"
479
+ });
480
+ }
481
+ for (const requireRule of matrix.relationships.requires) {
482
+ const skillCanonicalId = resolve(requireRule.skill);
483
+ if (skillCanonicalId === skill.id) {
484
+ requires.push({
485
+ skillIds: requireRule.needs.map(resolve),
486
+ needsAny: requireRule.needs_any ?? false,
487
+ reason: requireRule.reason
488
+ });
489
+ }
490
+ }
491
+ for (const altGroup of matrix.relationships.alternatives) {
492
+ const resolvedAlts = altGroup.skills.map(resolve);
493
+ if (resolvedAlts.includes(skill.id)) {
494
+ for (const altSkill of resolvedAlts) {
495
+ if (altSkill !== skill.id) {
496
+ alternatives.push({
497
+ skillId: altSkill,
498
+ purpose: altGroup.purpose
499
+ });
500
+ }
501
+ }
502
+ }
503
+ }
504
+ if (matrix.relationships.discourages) {
505
+ for (const discourageRule of matrix.relationships.discourages) {
506
+ const resolvedSkills = discourageRule.skills.map(resolve);
507
+ if (resolvedSkills.includes(skill.id)) {
508
+ for (const otherSkill of resolvedSkills) {
509
+ if (otherSkill !== skill.id) {
510
+ if (!discourages.some((d) => d.skillId === otherSkill)) {
511
+ discourages.push({
512
+ skillId: otherSkill,
513
+ reason: discourageRule.reason
514
+ });
515
+ }
516
+ }
517
+ }
518
+ }
519
+ }
520
+ }
521
+ return {
522
+ id: skill.id,
523
+ alias: aliasesReverse[skill.id],
524
+ name: skill.name,
525
+ description: skill.description,
526
+ usageGuidance: skill.usageGuidance,
527
+ category: skill.category,
528
+ categoryExclusive: skill.categoryExclusive,
529
+ tags: skill.tags,
530
+ author: skill.author,
531
+ conflictsWith,
532
+ recommends,
533
+ recommendedBy: [],
534
+ requires,
535
+ requiredBy: [],
536
+ alternatives,
537
+ discourages,
538
+ requiresSetup: skill.requiresSetup.map(resolve),
539
+ providesSetupFor: skill.providesSetupFor.map(resolve),
540
+ path: skill.path
541
+ };
542
+ }
543
+ function computeInverseRelationships(skills) {
544
+ for (const skill of Object.values(skills)) {
545
+ for (const recommend of skill.recommends) {
546
+ const targetSkill = skills[recommend.skillId];
547
+ if (targetSkill) {
548
+ targetSkill.recommendedBy.push({
549
+ skillId: skill.id,
550
+ reason: recommend.reason
551
+ });
552
+ }
553
+ }
554
+ for (const requirement of skill.requires) {
555
+ for (const requiredId of requirement.skillIds) {
556
+ const targetSkill = skills[requiredId];
557
+ if (targetSkill) {
558
+ targetSkill.requiredBy.push({
559
+ skillId: skill.id,
560
+ reason: requirement.reason
561
+ });
562
+ }
563
+ }
564
+ }
565
+ }
566
+ }
567
+ function resolveSuggestedStacks(matrix, aliases, aliasTargetToSkillId) {
568
+ if (!matrix.suggested_stacks) {
569
+ return [];
570
+ }
571
+ return matrix.suggested_stacks.map((stack) => {
572
+ const resolvedSkillsMap = {};
573
+ const allSkillIds = [];
574
+ for (const [category, subcategories] of Object.entries(stack.skills)) {
575
+ resolvedSkillsMap[category] = {};
576
+ for (const [subcategory, alias] of Object.entries(subcategories)) {
577
+ const aliasTarget = resolveToCanonicalId(alias, aliases);
578
+ const canonicalId = aliasTargetToSkillId[aliasTarget] || aliasTarget;
579
+ resolvedSkillsMap[category][subcategory] = canonicalId;
580
+ allSkillIds.push(canonicalId);
581
+ }
582
+ }
583
+ return {
584
+ id: stack.id,
585
+ name: stack.name,
586
+ description: stack.description,
587
+ audience: stack.audience,
588
+ skills: resolvedSkillsMap,
589
+ allSkillIds,
590
+ philosophy: stack.philosophy
591
+ };
592
+ });
593
+ }
594
+
595
+ export {
596
+ parseFrontmatter,
597
+ loadAllAgents,
598
+ loadSkillsByIds,
599
+ loadPluginSkills,
600
+ loadStacks,
601
+ loadStackById,
602
+ resolveAgentConfigToSkills,
603
+ loadSkillsMatrix,
604
+ extractAllSkills,
605
+ mergeMatrixWithSkills
606
+ };
607
+ //# sourceMappingURL=chunk-QGGSLMO3.js.map