@agents-inc/cli 0.47.0 → 0.48.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 (157) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +114 -118
  3. package/config/skill-categories.yaml +344 -0
  4. package/config/skill-rules.yaml +740 -0
  5. package/dist/{chunk-LNA6M2IE.js → chunk-2BVZOYJP.js} +2 -2
  6. package/dist/{chunk-JZHIF3K7.js → chunk-2DNDAXF6.js} +5 -5
  7. package/dist/{chunk-VSZ5GDET.js → chunk-34BP5BC4.js} +2 -2
  8. package/dist/{chunk-MVEYK55V.js → chunk-37QYD33C.js} +2 -2
  9. package/dist/{chunk-VAQJLHUW.js → chunk-5MN5S3DV.js} +6 -6
  10. package/dist/{chunk-HPJP3HFD.js → chunk-5O6GKXAN.js} +7 -7
  11. package/dist/{chunk-FXQYEXLS.js → chunk-7IAKVZL5.js} +3 -3
  12. package/dist/{chunk-XTRPYUWK.js → chunk-AMNCCZSG.js} +14 -14
  13. package/dist/{chunk-JTTTXGHX.js → chunk-AXV7NFFJ.js} +4 -4
  14. package/dist/{chunk-M4P5YJ45.js → chunk-AXZNJ5PN.js} +3 -3
  15. package/dist/{chunk-INKJBMPJ.js → chunk-C7DLY64D.js} +2 -2
  16. package/dist/{chunk-2RQYJFKA.js → chunk-DG2U2WY3.js} +2 -2
  17. package/dist/{chunk-ZWAL2ZY7.js → chunk-F7KTUFGU.js} +2 -2
  18. package/dist/{chunk-N5OCAAXY.js → chunk-FHKNG3UA.js} +2 -2
  19. package/dist/{chunk-QR2TM4OY.js → chunk-FPTUCWBY.js} +5 -5
  20. package/dist/{chunk-DC333ZDC.js → chunk-G5OZQ376.js} +4 -4
  21. package/dist/{chunk-NRCKIHND.js → chunk-GSPPOXMG.js} +2 -2
  22. package/dist/{chunk-IRJADQM7.js → chunk-I52THVF6.js} +2 -2
  23. package/dist/{chunk-OEJDFGAF.js → chunk-IS7GP6XC.js} +5 -5
  24. package/dist/{chunk-SPSGZWTZ.js → chunk-KPJJOLAQ.js} +5 -5
  25. package/dist/{chunk-FTD5Z6QD.js → chunk-LESHL6SM.js} +7 -5
  26. package/dist/chunk-LESHL6SM.js.map +1 -0
  27. package/dist/{chunk-EZ46ZTAQ.js → chunk-NJVJ7VO5.js} +3 -3
  28. package/dist/{chunk-DVW6ASTO.js → chunk-OHDEJEYB.js} +4 -4
  29. package/dist/{chunk-3APMMQUA.js → chunk-OTTITQ7C.js} +2 -2
  30. package/dist/{chunk-GFDGYQ6M.js → chunk-P2SFRDWI.js} +140 -92
  31. package/dist/chunk-P2SFRDWI.js.map +1 -0
  32. package/dist/{chunk-FMQ3A7W4.js → chunk-PY2XZUBF.js} +4 -4
  33. package/dist/{chunk-HLTJK3XB.js → chunk-SPVSWDFM.js} +5 -5
  34. package/dist/{chunk-B4QYXVPZ.js → chunk-U2AEK4ZL.js} +2 -2
  35. package/dist/{chunk-YTRFL3MR.js → chunk-VBAAATPU.js} +5 -5
  36. package/dist/{chunk-TWDVLTU6.js → chunk-W62XVWXB.js} +3 -3
  37. package/dist/{chunk-KQ27IDYL.js → chunk-WSGKCBY5.js} +2 -2
  38. package/dist/{chunk-TBB3THSL.js → chunk-X3SZIBVW.js} +8 -13
  39. package/dist/chunk-X3SZIBVW.js.map +1 -0
  40. package/dist/{chunk-CJFWO46A.js → chunk-YDASDMTH.js} +2 -2
  41. package/dist/{chunk-C4QI54PN.js → chunk-YMUWTPOM.js} +28 -25
  42. package/dist/chunk-YMUWTPOM.js.map +1 -0
  43. package/dist/{chunk-LJ5E4GXC.js → chunk-ZML3OCYA.js} +2 -2
  44. package/dist/commands/build/marketplace.js +4 -4
  45. package/dist/commands/build/plugins.js +5 -5
  46. package/dist/commands/build/stack.js +5 -5
  47. package/dist/commands/compile.js +6 -6
  48. package/dist/commands/config/get.js +4 -4
  49. package/dist/commands/config/index.js +5 -5
  50. package/dist/commands/config/path.js +4 -4
  51. package/dist/commands/config/set-project.js +4 -4
  52. package/dist/commands/config/show.js +5 -5
  53. package/dist/commands/config/unset-project.js +4 -4
  54. package/dist/commands/diff.js +4 -4
  55. package/dist/commands/doctor.js +4 -4
  56. package/dist/commands/edit.js +29 -29
  57. package/dist/commands/eject.js +4 -4
  58. package/dist/commands/import/skill.js +7 -8
  59. package/dist/commands/import/skill.js.map +1 -1
  60. package/dist/commands/info.js +5 -5
  61. package/dist/commands/init.js +28 -28
  62. package/dist/commands/list.js +4 -4
  63. package/dist/commands/new/agent.js +6 -6
  64. package/dist/commands/new/marketplace.js +5 -5
  65. package/dist/commands/new/skill.js +5 -6
  66. package/dist/commands/new/skill.js.map +1 -1
  67. package/dist/commands/outdated.js +4 -4
  68. package/dist/commands/search.js +7 -8
  69. package/dist/commands/search.js.map +1 -1
  70. package/dist/commands/uninstall.js +6 -6
  71. package/dist/commands/update.js +6 -6
  72. package/dist/commands/validate.js +55 -22
  73. package/dist/commands/validate.js.map +1 -1
  74. package/dist/components/skill-search/skill-search.js +3 -3
  75. package/dist/components/wizard/category-grid.js +2 -2
  76. package/dist/components/wizard/category-grid.test.js +2 -2
  77. package/dist/components/wizard/checkbox-grid.js +3 -3
  78. package/dist/components/wizard/checkbox-grid.test.js +3 -3
  79. package/dist/components/wizard/domain-selection.js +9 -9
  80. package/dist/components/wizard/help-modal.js +2 -2
  81. package/dist/components/wizard/menu-item.js +1 -1
  82. package/dist/components/wizard/search-modal.js +2 -2
  83. package/dist/components/wizard/search-modal.test.js +2 -2
  84. package/dist/components/wizard/section-progress.js +2 -2
  85. package/dist/components/wizard/section-progress.test.js +2 -2
  86. package/dist/components/wizard/selection-card.js +2 -2
  87. package/dist/components/wizard/source-grid.js +3 -3
  88. package/dist/components/wizard/source-grid.test.js +3 -3
  89. package/dist/components/wizard/stack-selection.js +8 -8
  90. package/dist/components/wizard/step-agents.js +8 -8
  91. package/dist/components/wizard/step-agents.test.js +9 -9
  92. package/dist/components/wizard/step-build.js +8 -8
  93. package/dist/components/wizard/step-build.test.js +16 -20
  94. package/dist/components/wizard/step-build.test.js.map +1 -1
  95. package/dist/components/wizard/step-confirm.js +4 -4
  96. package/dist/components/wizard/step-confirm.test.js +8 -8
  97. package/dist/components/wizard/step-refine.js +2 -2
  98. package/dist/components/wizard/step-refine.test.js +2 -2
  99. package/dist/components/wizard/step-settings.js +5 -5
  100. package/dist/components/wizard/step-settings.test.js +8 -8
  101. package/dist/components/wizard/step-sources.js +10 -10
  102. package/dist/components/wizard/step-sources.test.js +11 -11
  103. package/dist/components/wizard/step-stack.js +12 -12
  104. package/dist/components/wizard/step-stack.test.js +13 -13
  105. package/dist/components/wizard/view-title.js +2 -2
  106. package/dist/components/wizard/wizard-layout.js +8 -8
  107. package/dist/components/wizard/wizard-tabs.js +2 -2
  108. package/dist/components/wizard/wizard-tabs.test.js +2 -2
  109. package/dist/components/wizard/wizard.js +25 -25
  110. package/dist/config/skill-categories.yaml +344 -0
  111. package/dist/config/skill-rules.yaml +740 -0
  112. package/dist/hooks/init.js +3 -3
  113. package/dist/{source-manager-Q34LTUVM.js → source-manager-Y7R6WPOW.js} +4 -4
  114. package/dist/stores/wizard-store.js +5 -5
  115. package/dist/stores/wizard-store.test.js +6 -6
  116. package/package.json +5 -1
  117. package/src/schemas/metadata.schema.json +2 -5
  118. package/src/schemas/project-source-config.schema.json +4 -1
  119. package/config/skills-matrix.yaml +0 -918
  120. package/dist/chunk-C4QI54PN.js.map +0 -1
  121. package/dist/chunk-FTD5Z6QD.js.map +0 -1
  122. package/dist/chunk-GFDGYQ6M.js.map +0 -1
  123. package/dist/chunk-TBB3THSL.js.map +0 -1
  124. package/dist/config/skills-matrix.yaml +0 -918
  125. package/src/schemas/skills-matrix.schema.json +0 -179
  126. /package/dist/{chunk-LNA6M2IE.js.map → chunk-2BVZOYJP.js.map} +0 -0
  127. /package/dist/{chunk-JZHIF3K7.js.map → chunk-2DNDAXF6.js.map} +0 -0
  128. /package/dist/{chunk-VSZ5GDET.js.map → chunk-34BP5BC4.js.map} +0 -0
  129. /package/dist/{chunk-MVEYK55V.js.map → chunk-37QYD33C.js.map} +0 -0
  130. /package/dist/{chunk-VAQJLHUW.js.map → chunk-5MN5S3DV.js.map} +0 -0
  131. /package/dist/{chunk-HPJP3HFD.js.map → chunk-5O6GKXAN.js.map} +0 -0
  132. /package/dist/{chunk-FXQYEXLS.js.map → chunk-7IAKVZL5.js.map} +0 -0
  133. /package/dist/{chunk-XTRPYUWK.js.map → chunk-AMNCCZSG.js.map} +0 -0
  134. /package/dist/{chunk-JTTTXGHX.js.map → chunk-AXV7NFFJ.js.map} +0 -0
  135. /package/dist/{chunk-M4P5YJ45.js.map → chunk-AXZNJ5PN.js.map} +0 -0
  136. /package/dist/{chunk-INKJBMPJ.js.map → chunk-C7DLY64D.js.map} +0 -0
  137. /package/dist/{chunk-2RQYJFKA.js.map → chunk-DG2U2WY3.js.map} +0 -0
  138. /package/dist/{chunk-ZWAL2ZY7.js.map → chunk-F7KTUFGU.js.map} +0 -0
  139. /package/dist/{chunk-N5OCAAXY.js.map → chunk-FHKNG3UA.js.map} +0 -0
  140. /package/dist/{chunk-QR2TM4OY.js.map → chunk-FPTUCWBY.js.map} +0 -0
  141. /package/dist/{chunk-DC333ZDC.js.map → chunk-G5OZQ376.js.map} +0 -0
  142. /package/dist/{chunk-NRCKIHND.js.map → chunk-GSPPOXMG.js.map} +0 -0
  143. /package/dist/{chunk-IRJADQM7.js.map → chunk-I52THVF6.js.map} +0 -0
  144. /package/dist/{chunk-OEJDFGAF.js.map → chunk-IS7GP6XC.js.map} +0 -0
  145. /package/dist/{chunk-SPSGZWTZ.js.map → chunk-KPJJOLAQ.js.map} +0 -0
  146. /package/dist/{chunk-EZ46ZTAQ.js.map → chunk-NJVJ7VO5.js.map} +0 -0
  147. /package/dist/{chunk-DVW6ASTO.js.map → chunk-OHDEJEYB.js.map} +0 -0
  148. /package/dist/{chunk-3APMMQUA.js.map → chunk-OTTITQ7C.js.map} +0 -0
  149. /package/dist/{chunk-FMQ3A7W4.js.map → chunk-PY2XZUBF.js.map} +0 -0
  150. /package/dist/{chunk-HLTJK3XB.js.map → chunk-SPVSWDFM.js.map} +0 -0
  151. /package/dist/{chunk-B4QYXVPZ.js.map → chunk-U2AEK4ZL.js.map} +0 -0
  152. /package/dist/{chunk-YTRFL3MR.js.map → chunk-VBAAATPU.js.map} +0 -0
  153. /package/dist/{chunk-TWDVLTU6.js.map → chunk-W62XVWXB.js.map} +0 -0
  154. /package/dist/{chunk-KQ27IDYL.js.map → chunk-WSGKCBY5.js.map} +0 -0
  155. /package/dist/{chunk-CJFWO46A.js.map → chunk-YDASDMTH.js.map} +0 -0
  156. /package/dist/{chunk-LJ5E4GXC.js.map → chunk-ZML3OCYA.js.map} +0 -0
  157. /package/dist/{source-manager-Q34LTUVM.js.map → source-manager-Y7R6WPOW.js.map} +0 -0
@@ -34,19 +34,20 @@ import {
34
34
  readFileOptional,
35
35
  readFileSafe,
36
36
  remove,
37
+ skillCategoriesFileSchema,
37
38
  skillDisplayNameSchema,
38
39
  skillFrontmatterLoaderSchema,
39
40
  skillFrontmatterValidationSchema,
40
41
  skillIdSchema,
41
42
  skillMetadataLoaderSchema,
42
- skillsMatrixConfigSchema,
43
+ skillRulesFileSchema,
43
44
  stacksConfigSchema,
44
45
  validateNestingDepth,
45
46
  verbose,
46
47
  warn,
47
48
  warnUnknownFields,
48
49
  writeFile
49
- } from "./chunk-C4QI54PN.js";
50
+ } from "./chunk-YMUWTPOM.js";
50
51
  import {
51
52
  ARCHIVED_SKILLS_DIR_NAME,
52
53
  CACHE_DIR,
@@ -74,13 +75,14 @@ import {
74
75
  PROJECT_ROOT,
75
76
  SCHEMA_PATHS,
76
77
  SKILLS_DIR_PATH,
77
- SKILLS_MATRIX_PATH,
78
+ SKILL_CATEGORIES_YAML_PATH,
79
+ SKILL_RULES_YAML_PATH,
78
80
  STACKS_FILE_PATH,
79
81
  STANDARD_DIRS,
80
82
  STANDARD_FILES,
81
83
  YAML_FORMATTING,
82
84
  yamlSchemaComment
83
- } from "./chunk-FTD5Z6QD.js";
85
+ } from "./chunk-LESHL6SM.js";
84
86
  import {
85
87
  init_esm_shims
86
88
  } from "./chunk-DHET7RCE.js";
@@ -1165,7 +1167,7 @@ import { unique as unique4 } from "remeda";
1165
1167
  // src/cli/lib/metadata-keys.ts
1166
1168
  init_esm_shims();
1167
1169
  var METADATA_KEYS = {
1168
- CLI_NAME: "cliName",
1170
+ DISPLAY_NAME: "displayName",
1169
1171
  CLI_DESCRIPTION: "cliDescription",
1170
1172
  CATEGORY: "category",
1171
1173
  FORKED_FROM: "forkedFrom",
@@ -2225,7 +2227,8 @@ var PATH_OVERRIDES_COMMENT = [
2225
2227
  `# skillsDir: ${SKILLS_DIR_PATH}`,
2226
2228
  `# agentsDir: ${DIRS.agents}`,
2227
2229
  `# stacksFile: ${STACKS_FILE_PATH}`,
2228
- `# matrixFile: ${SKILLS_MATRIX_PATH}`,
2230
+ `# categoriesFile: ${SKILL_CATEGORIES_YAML_PATH}`,
2231
+ `# rulesFile: ${SKILL_RULES_YAML_PATH}`,
2229
2232
  ""
2230
2233
  ].join("\n");
2231
2234
  async function writeConfigFile(config, configPath) {
@@ -3138,34 +3141,56 @@ import path19 from "path";
3138
3141
  import { z as z3 } from "zod";
3139
3142
  var rawMetadataSchema = z3.object({
3140
3143
  category: categoryPathSchema,
3141
- categoryExclusive: z3.boolean().optional(),
3142
3144
  author: z3.string(),
3143
- cliName: z3.string().optional(),
3145
+ displayName: z3.string().optional(),
3144
3146
  cliDescription: z3.string().optional(),
3145
3147
  usageGuidance: z3.string().optional(),
3146
3148
  tags: z3.array(z3.string()).optional(),
3147
- // Lenient: accepts display names and skill IDs from YAML, resolved to canonical IDs during matrix merge
3148
- compatibleWith: z3.array(z3.string()).optional(),
3149
- conflictsWith: z3.array(z3.string()).optional(),
3150
- requires: z3.array(z3.string()).optional(),
3151
- requiresSetup: z3.array(z3.string()).optional(),
3152
- providesSetupFor: z3.array(z3.string()).optional(),
3153
3149
  domain: extensibleDomainSchema.optional(),
3154
3150
  custom: z3.boolean().optional()
3155
3151
  });
3156
- async function loadSkillsMatrix(configPath) {
3152
+ var KNOWN_DOMAINS = new Set(DOMAIN_VALUES);
3153
+ var AUTO_SYNTH_ORDER = 999;
3154
+ function synthesizeCategory(categoryPath, skillDomain) {
3155
+ const prefix = categoryPath.split("-")[0];
3156
+ const domain = skillDomain ?? (KNOWN_DOMAINS.has(prefix) ? prefix : void 0);
3157
+ const displayName = categoryPath.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
3158
+ return {
3159
+ id: categoryPath,
3160
+ displayName,
3161
+ description: `Auto-generated category for ${categoryPath}`,
3162
+ domain,
3163
+ exclusive: true,
3164
+ required: false,
3165
+ order: AUTO_SYNTH_ORDER,
3166
+ custom: true
3167
+ };
3168
+ }
3169
+ async function loadSkillCategories(configPath) {
3170
+ const content = await readFile(configPath);
3171
+ const raw = parseYaml7(content);
3172
+ const result = skillCategoriesFileSchema.safeParse(raw);
3173
+ if (!result.success) {
3174
+ throw new Error(
3175
+ `Invalid skill categories at '${configPath}': ${formatZodErrors(result.error.issues)}`
3176
+ );
3177
+ }
3178
+ verbose(`Loaded skill categories: ${configPath}`);
3179
+ return result.data.categories;
3180
+ }
3181
+ async function loadSkillRules(configPath) {
3157
3182
  const content = await readFile(configPath);
3158
3183
  const raw = parseYaml7(content);
3159
- const result = skillsMatrixConfigSchema.safeParse(raw);
3184
+ const result = skillRulesFileSchema.safeParse(raw);
3160
3185
  if (!result.success) {
3161
3186
  throw new Error(
3162
- `Invalid skills matrix at '${configPath}': ${formatZodErrors(result.error.issues)}`
3187
+ `Invalid skill rules at '${configPath}': ${formatZodErrors(result.error.issues)}`
3163
3188
  );
3164
3189
  }
3165
3190
  const data = result.data;
3166
- const matrix = {
3191
+ const config = {
3167
3192
  version: data.version,
3168
- categories: data.categories,
3193
+ aliases: data.aliases ?? {},
3169
3194
  relationships: data.relationships ?? {
3170
3195
  conflicts: [],
3171
3196
  discourages: [],
@@ -3173,10 +3198,10 @@ async function loadSkillsMatrix(configPath) {
3173
3198
  requires: [],
3174
3199
  alternatives: []
3175
3200
  },
3176
- skillAliases: data.skillAliases ?? {}
3201
+ perSkill: data["per-skill"] ?? {}
3177
3202
  };
3178
- verbose(`Loaded skills matrix: ${configPath}`);
3179
- return matrix;
3203
+ verbose(`Loaded skill rules: ${configPath}`);
3204
+ return config;
3180
3205
  }
3181
3206
  async function extractAllSkills(skillsDir) {
3182
3207
  const skills = [];
@@ -3205,9 +3230,9 @@ async function extractAllSkills(skillsDir) {
3205
3230
  verbose(`Skipping ${metadataFile}: Invalid SKILL.md frontmatter`);
3206
3231
  continue;
3207
3232
  }
3208
- if (!metadata.cliName) {
3233
+ if (!metadata.displayName) {
3209
3234
  throw new Error(
3210
- `Skill at ${metadataFile} is missing required '${METADATA_KEYS.CLI_NAME}' field in metadata.yaml`
3235
+ `Skill at ${metadataFile} is missing required '${METADATA_KEYS.DISPLAY_NAME}' field in metadata.yaml`
3211
3236
  );
3212
3237
  }
3213
3238
  const skillId = frontmatter.name;
@@ -3217,14 +3242,8 @@ async function extractAllSkills(skillsDir) {
3217
3242
  description: metadata.cliDescription || frontmatter.description,
3218
3243
  usageGuidance: metadata.usageGuidance,
3219
3244
  category: metadata.category,
3220
- categoryExclusive: metadata.categoryExclusive ?? true,
3221
3245
  author: metadata.author,
3222
3246
  tags: metadata.tags ?? [],
3223
- compatibleWith: metadata.compatibleWith ?? [],
3224
- conflictsWith: metadata.conflictsWith ?? [],
3225
- requires: metadata.requires ?? [],
3226
- requiresSetup: metadata.requiresSetup ?? [],
3227
- providesSetupFor: metadata.providesSetupFor ?? [],
3228
3247
  path: `skills/${skillDir}/`,
3229
3248
  ...metadata.domain ? { domain: metadata.domain } : {},
3230
3249
  ...metadata.custom === true ? { custom: true } : {}
@@ -3271,25 +3290,36 @@ function resolveToCanonicalId(nameOrId, displayNameToId, directoryPathToId = {},
3271
3290
  }
3272
3291
  return nameOrId;
3273
3292
  }
3274
- async function mergeMatrixWithSkills(matrix, skills) {
3275
- const displayNameToId = matrix.skillAliases;
3293
+ async function mergeMatrixWithSkills(categories, relationships, aliases, skills, perSkillRules) {
3294
+ const displayNameToId = aliases;
3276
3295
  const displayNames = buildReverseDisplayNames(displayNameToId);
3277
3296
  const directoryPathToId = buildDirectoryPathToIdMap(skills);
3278
3297
  const resolvedSkills = {};
3279
3298
  for (const skill of skills) {
3280
3299
  const resolved = buildResolvedSkill(
3281
3300
  skill,
3282
- matrix,
3301
+ categories,
3302
+ relationships,
3283
3303
  displayNameToId,
3284
3304
  displayNames,
3285
- directoryPathToId
3305
+ directoryPathToId,
3306
+ perSkillRules
3286
3307
  );
3287
3308
  resolvedSkills[skill.id] = resolved;
3288
3309
  }
3310
+ const synthesizedCategories = { ...categories };
3311
+ for (const skill of skills) {
3312
+ const subcategory = skill.category;
3313
+ if (!synthesizedCategories[subcategory]) {
3314
+ const synthesized = synthesizeCategory(skill.category, skill.domain);
3315
+ synthesizedCategories[subcategory] = synthesized;
3316
+ verbose(`Auto-synthesized category '${skill.category}' for skill '${skill.id}'`);
3317
+ }
3318
+ }
3289
3319
  const suggestedStacks = resolveSuggestedStacks();
3290
3320
  const merged = {
3291
- version: matrix.version,
3292
- categories: matrix.categories,
3321
+ version: "1.0.0",
3322
+ categories: synthesizedCategories,
3293
3323
  skills: resolvedSkills,
3294
3324
  suggestedStacks,
3295
3325
  displayNameToId,
@@ -3382,41 +3412,48 @@ function resolveDiscourages(skillId, discourageRules, resolve) {
3382
3412
  }
3383
3413
  return discourages;
3384
3414
  }
3385
- function buildResolvedSkill(skill, matrix, displayNameToId, displayNames, directoryPathToId) {
3415
+ function buildResolvedSkill(skill, _categories, relationships, displayNameToId, displayNames, directoryPathToId, perSkillRules) {
3386
3416
  const resolve = (id, context) => resolveToCanonicalId(
3387
3417
  id,
3388
3418
  displayNameToId,
3389
3419
  directoryPathToId,
3390
3420
  context ? `${skill.id} ${context}` : void 0
3391
3421
  );
3392
- const { relationships } = matrix;
3422
+ const skillAlias = displayNames[skill.id];
3423
+ const perSkill = skillAlias ? perSkillRules?.[skillAlias] : void 0;
3393
3424
  return {
3394
3425
  id: skill.id,
3395
3426
  displayName: displayNames[skill.id],
3396
3427
  description: skill.description,
3397
3428
  usageGuidance: skill.usageGuidance,
3398
3429
  category: skill.category,
3399
- categoryExclusive: skill.categoryExclusive,
3400
3430
  tags: skill.tags,
3401
3431
  author: skill.author,
3402
3432
  conflictsWith: resolveConflicts(
3403
3433
  skill.id,
3404
- skill.conflictsWith,
3434
+ perSkill?.conflictsWith ?? [],
3405
3435
  relationships.conflicts,
3406
3436
  resolve
3407
3437
  ),
3408
3438
  recommends: resolveRecommends(
3409
3439
  skill.id,
3410
- skill.compatibleWith,
3440
+ perSkill?.compatibleWith ?? [],
3411
3441
  relationships.recommends,
3412
3442
  resolve
3413
3443
  ),
3414
- requires: resolveRequirements(skill.id, skill.requires, relationships.requires, resolve),
3444
+ requires: resolveRequirements(
3445
+ skill.id,
3446
+ perSkill?.requires ?? [],
3447
+ relationships.requires,
3448
+ resolve
3449
+ ),
3415
3450
  alternatives: resolveAlternatives(skill.id, relationships.alternatives, resolve),
3416
3451
  discourages: resolveDiscourages(skill.id, relationships.discourages, resolve),
3417
- compatibleWith: skill.compatibleWith.map((id) => resolve(id, "compatibleWith")),
3418
- requiresSetup: skill.requiresSetup.map((id) => resolve(id, "requiresSetup")),
3419
- providesSetupFor: skill.providesSetupFor.map((id) => resolve(id, "providesSetupFor")),
3452
+ compatibleWith: (perSkill?.compatibleWith ?? []).map((id) => resolve(id, "compatibleWith")),
3453
+ requiresSetup: (perSkill?.requiresSetup ?? []).map((id) => resolve(id, "requiresSetup")),
3454
+ providesSetupFor: (perSkill?.providesSetupFor ?? []).map(
3455
+ (id) => resolve(id, "providesSetupFor")
3456
+ ),
3420
3457
  path: skill.path
3421
3458
  };
3422
3459
  }
@@ -3768,12 +3805,15 @@ function checkSubcategoryDomains(matrix, issues) {
3768
3805
  function checkSkillCategories(matrix, issues) {
3769
3806
  for (const [skillId, skill] of typedEntries(matrix.skills)) {
3770
3807
  if (!skill) continue;
3771
- if (!matrix.categories[skill.category]) {
3808
+ const category = matrix.categories[skill.category];
3809
+ if (!category) {
3772
3810
  issues.push({
3773
3811
  severity: "warning",
3774
3812
  finding: "skill-unknown-category",
3775
3813
  details: `Skill '${skillId}' references category '${skill.category}' which does not exist in the matrix`
3776
3814
  });
3815
+ } else if (category.custom) {
3816
+ verbose(`Skill '${skillId}' uses auto-synthesized category '${skill.category}'`);
3777
3817
  }
3778
3818
  }
3779
3819
  }
@@ -4088,47 +4128,62 @@ async function loadFromRemote(source, sourceConfig, forceRefresh) {
4088
4128
  }
4089
4129
  async function loadAndMergeFromBasePath(basePath) {
4090
4130
  const sourceProjectConfig = await loadProjectSourceConfig(basePath);
4091
- const matrixRelPath = sourceProjectConfig?.matrixFile ?? SKILLS_MATRIX_PATH;
4092
4131
  const skillsDirRelPath = sourceProjectConfig?.skillsDir ?? SKILLS_DIR_PATH;
4093
4132
  const stacksRelFile = sourceProjectConfig?.stacksFile;
4094
- const cliMatrixPath = path21.join(PROJECT_ROOT, SKILLS_MATRIX_PATH);
4095
- const cliMatrix = await loadSkillsMatrix(cliMatrixPath);
4096
- let matrix = cliMatrix;
4133
+ const cliCategoriesPath = path21.join(PROJECT_ROOT, SKILL_CATEGORIES_YAML_PATH);
4134
+ const cliRulesPath = path21.join(PROJECT_ROOT, SKILL_RULES_YAML_PATH);
4135
+ const cliCategories = await loadSkillCategories(cliCategoriesPath);
4136
+ const cliRules = await loadSkillRules(cliRulesPath);
4137
+ let categories = cliCategories;
4138
+ let relationships = cliRules.relationships;
4139
+ let aliases = cliRules.aliases;
4140
+ let perSkillRules = cliRules.perSkill;
4097
4141
  await discoverAndExtendFromSource(basePath);
4098
- const sourceMatrixPath = path21.join(basePath, matrixRelPath);
4099
- if (await fileExists(sourceMatrixPath)) {
4100
- const sourceMatrix = await loadSkillsMatrix(sourceMatrixPath);
4101
- const mergedCategories = { ...cliMatrix.categories, ...sourceMatrix.categories };
4102
- const mergedRelationships = {
4103
- conflicts: [...cliMatrix.relationships.conflicts, ...sourceMatrix.relationships.conflicts],
4104
- discourages: [
4105
- ...cliMatrix.relationships.discourages,
4106
- ...sourceMatrix.relationships.discourages
4107
- ],
4108
- recommends: [...cliMatrix.relationships.recommends, ...sourceMatrix.relationships.recommends],
4109
- requires: [...cliMatrix.relationships.requires, ...sourceMatrix.relationships.requires],
4110
- alternatives: [
4111
- ...cliMatrix.relationships.alternatives,
4112
- ...sourceMatrix.relationships.alternatives
4113
- ]
4114
- };
4115
- const mergedAliases = { ...cliMatrix.skillAliases, ...sourceMatrix.skillAliases };
4116
- matrix = {
4117
- version: cliMatrix.version,
4118
- categories: mergedCategories,
4119
- relationships: mergedRelationships,
4120
- skillAliases: mergedAliases
4121
- };
4122
- verbose(
4123
- `Matrix merged: CLI (${typedKeys(cliMatrix.categories).length} categories) + source (${typedKeys(sourceMatrix.categories).length} categories)`
4124
- );
4142
+ const sourceCategoriesPath = path21.join(basePath, SKILL_CATEGORIES_YAML_PATH);
4143
+ const sourceRulesPath = path21.join(basePath, SKILL_RULES_YAML_PATH);
4144
+ const hasSourceCategories = await fileExists(sourceCategoriesPath);
4145
+ const hasSourceRules = await fileExists(sourceRulesPath);
4146
+ if (hasSourceCategories || hasSourceRules) {
4147
+ if (hasSourceCategories) {
4148
+ const sourceCategories = await loadSkillCategories(sourceCategoriesPath);
4149
+ categories = { ...cliCategories, ...sourceCategories };
4150
+ verbose(
4151
+ `Loaded source categories: ${sourceCategoriesPath} (${typedKeys(sourceCategories).length} categories)`
4152
+ );
4153
+ }
4154
+ if (hasSourceRules) {
4155
+ const sourceRules = await loadSkillRules(sourceRulesPath);
4156
+ relationships = {
4157
+ conflicts: [...cliRules.relationships.conflicts, ...sourceRules.relationships.conflicts],
4158
+ discourages: [
4159
+ ...cliRules.relationships.discourages,
4160
+ ...sourceRules.relationships.discourages
4161
+ ],
4162
+ recommends: [...cliRules.relationships.recommends, ...sourceRules.relationships.recommends],
4163
+ requires: [...cliRules.relationships.requires, ...sourceRules.relationships.requires],
4164
+ alternatives: [
4165
+ ...cliRules.relationships.alternatives,
4166
+ ...sourceRules.relationships.alternatives
4167
+ ]
4168
+ };
4169
+ aliases = { ...cliRules.aliases, ...sourceRules.aliases };
4170
+ perSkillRules = { ...cliRules.perSkill, ...sourceRules.perSkill };
4171
+ verbose(`Loaded source rules: ${sourceRulesPath}`);
4172
+ }
4173
+ verbose(`Matrix merged: CLI (${typedKeys(cliCategories).length} categories) + source`);
4125
4174
  } else {
4126
- verbose(`Matrix from CLI only (source has no matrix): ${cliMatrixPath}`);
4175
+ verbose(`Matrix from CLI only (source has no categories/rules files)`);
4127
4176
  }
4128
4177
  const skillsDir = path21.join(basePath, skillsDirRelPath);
4129
4178
  verbose(`Skills from source: ${skillsDir}`);
4130
4179
  const skills = await extractAllSkills(skillsDir);
4131
- const mergedMatrix = await mergeMatrixWithSkills(matrix, skills);
4180
+ const mergedMatrix = await mergeMatrixWithSkills(
4181
+ categories,
4182
+ relationships,
4183
+ aliases,
4184
+ skills,
4185
+ perSkillRules
4186
+ );
4132
4187
  const sourceStacks = await loadStacks(basePath, stacksRelFile);
4133
4188
  const stacks = sourceStacks.length > 0 ? sourceStacks : await loadStacks(PROJECT_ROOT);
4134
4189
  if (stacks.length > 0) {
@@ -4305,7 +4360,6 @@ function mergeLocalSkillsIntoMatrix(matrix, localResult) {
4305
4360
  description: metadata.description,
4306
4361
  usageGuidance: metadata.usageGuidance,
4307
4362
  category,
4308
- categoryExclusive: metadata.categoryExclusive,
4309
4363
  tags: metadata.tags ?? [],
4310
4364
  author: LOCAL_DEFAULTS.AUTHOR,
4311
4365
  conflictsWith: existingSkill?.conflictsWith ?? [],
@@ -4368,11 +4422,10 @@ async function extractLocalSkill(localSkillsPath, skillDirName) {
4368
4422
  return null;
4369
4423
  }
4370
4424
  const metadata = parsed.data;
4371
- if (!metadata.cliName) {
4372
- warn(
4373
- `Skipping local skill '${skillDirName}': missing required '${METADATA_KEYS.CLI_NAME}' in metadata.yaml`
4425
+ if (!metadata.displayName) {
4426
+ throw new Error(
4427
+ `Local skill '${skillDirName}' is missing required '${METADATA_KEYS.DISPLAY_NAME}' field in metadata.yaml`
4374
4428
  );
4375
- return null;
4376
4429
  }
4377
4430
  const skillMdContent = await readFile(skillMdPath);
4378
4431
  const frontmatter = parseFrontmatter(skillMdContent, skillMdPath);
@@ -4394,14 +4447,8 @@ async function extractLocalSkill(localSkillsPath, skillDirName) {
4394
4447
  description: metadata.cliDescription || frontmatter.description,
4395
4448
  usageGuidance: metadata.usageGuidance,
4396
4449
  category,
4397
- categoryExclusive: metadata.categoryExclusive ?? false,
4398
4450
  author: LOCAL_DEFAULTS.AUTHOR,
4399
4451
  tags: metadata.tags ?? [],
4400
- compatibleWith: metadata.compatibleWith ?? [],
4401
- conflictsWith: metadata.conflictsWith ?? [],
4402
- requires: metadata.requires ?? [],
4403
- requiresSetup: metadata.requiresSetup ?? [],
4404
- providesSetupFor: metadata.providesSetupFor ?? [],
4405
4452
  path: relativePath,
4406
4453
  local: true,
4407
4454
  localPath: relativePath
@@ -4518,7 +4565,8 @@ export {
4518
4565
  printCompilationSummary,
4519
4566
  archiveLocalSkill,
4520
4567
  restoreArchivedSkill,
4521
- loadSkillsMatrix,
4568
+ loadSkillCategories,
4569
+ loadSkillRules,
4522
4570
  extractAllSkills,
4523
4571
  mergeMatrixWithSkills,
4524
4572
  resolveAlias,
@@ -4551,4 +4599,4 @@ export {
4551
4599
  validateAllPlugins,
4552
4600
  printPluginValidationResult
4553
4601
  };
4554
- //# sourceMappingURL=chunk-GFDGYQ6M.js.map
4602
+ //# sourceMappingURL=chunk-P2SFRDWI.js.map