@agents-inc/cli 0.46.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 (169) hide show
  1. package/CHANGELOG.md +26 -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-LFZXMQOH.js → chunk-2BVZOYJP.js} +2 -2
  6. package/dist/{chunk-4C7PDDLY.js → chunk-2DNDAXF6.js} +5 -5
  7. package/dist/{chunk-C7BO2ASM.js → chunk-34BP5BC4.js} +2 -2
  8. package/dist/{chunk-TOWP4T5L.js → chunk-37QYD33C.js} +2 -2
  9. package/dist/{chunk-YT7UHV67.js → chunk-5MN5S3DV.js} +11 -9
  10. package/dist/chunk-5MN5S3DV.js.map +1 -0
  11. package/dist/{chunk-72GS6PIH.js → chunk-5O6GKXAN.js} +7 -7
  12. package/dist/{chunk-KWQ2BQXF.js → chunk-7IAKVZL5.js} +3 -3
  13. package/dist/{chunk-CTQHZELA.js → chunk-AMNCCZSG.js} +14 -14
  14. package/dist/{chunk-PZLUO4OY.js → chunk-AXV7NFFJ.js} +4 -4
  15. package/dist/{chunk-ODQ2BKWU.js → chunk-AXZNJ5PN.js} +3 -3
  16. package/dist/{chunk-J64CA4V6.js → chunk-C7DLY64D.js} +2 -2
  17. package/dist/{chunk-G2WNOT3R.js → chunk-DG2U2WY3.js} +2 -2
  18. package/dist/{chunk-3WKFSTG6.js → chunk-F7KTUFGU.js} +2 -2
  19. package/dist/{chunk-5M6JI76P.js → chunk-FHKNG3UA.js} +2 -2
  20. package/dist/{chunk-I26YP2Q3.js → chunk-FPTUCWBY.js} +5 -5
  21. package/dist/{chunk-VH3PI43B.js → chunk-G5OZQ376.js} +4 -4
  22. package/dist/{chunk-RWR56UVK.js → chunk-GSPPOXMG.js} +11 -2
  23. package/dist/chunk-GSPPOXMG.js.map +1 -0
  24. package/dist/{chunk-YVMYQSED.js → chunk-I52THVF6.js} +2 -2
  25. package/dist/{chunk-FKBCYT7B.js → chunk-IS7GP6XC.js} +5 -5
  26. package/dist/{chunk-UK3AMBR7.js → chunk-KPJJOLAQ.js} +13 -6
  27. package/dist/{chunk-UK3AMBR7.js.map → chunk-KPJJOLAQ.js.map} +1 -1
  28. package/dist/{chunk-74HSA7C4.js → chunk-LESHL6SM.js} +9 -5
  29. package/dist/chunk-LESHL6SM.js.map +1 -0
  30. package/dist/{chunk-NMXNHRAK.js → chunk-NJVJ7VO5.js} +3 -3
  31. package/dist/{chunk-GVLYNP2I.js → chunk-OHDEJEYB.js} +4 -4
  32. package/dist/{chunk-CD64ZNYI.js → chunk-OTTITQ7C.js} +11 -3
  33. package/dist/chunk-OTTITQ7C.js.map +1 -0
  34. package/dist/{chunk-RT6IBH37.js → chunk-P2SFRDWI.js} +191 -109
  35. package/dist/chunk-P2SFRDWI.js.map +1 -0
  36. package/dist/{chunk-FUEZQ2H6.js → chunk-PY2XZUBF.js} +4 -4
  37. package/dist/{chunk-CDGHSTB6.js → chunk-SPVSWDFM.js} +7 -5
  38. package/dist/chunk-SPVSWDFM.js.map +1 -0
  39. package/dist/{chunk-DO5OZHSS.js → chunk-U2AEK4ZL.js} +2 -2
  40. package/dist/{chunk-HM3DHMW7.js → chunk-VBAAATPU.js} +8 -8
  41. package/dist/chunk-VBAAATPU.js.map +1 -0
  42. package/dist/{chunk-7LDSHHKN.js → chunk-W62XVWXB.js} +3 -3
  43. package/dist/{chunk-D7JTL3DJ.js → chunk-WSGKCBY5.js} +2 -2
  44. package/dist/{chunk-XE6RTHUD.js → chunk-X3SZIBVW.js} +34 -4
  45. package/dist/chunk-X3SZIBVW.js.map +1 -0
  46. package/dist/{chunk-QBUOZVNZ.js → chunk-YDASDMTH.js} +2 -2
  47. package/dist/{chunk-5QRJUBK7.js → chunk-YMUWTPOM.js} +41 -29
  48. package/dist/chunk-YMUWTPOM.js.map +1 -0
  49. package/dist/{chunk-SGXUMZWL.js → chunk-ZML3OCYA.js} +2 -2
  50. package/dist/commands/build/marketplace.js +4 -4
  51. package/dist/commands/build/plugins.js +5 -5
  52. package/dist/commands/build/stack.js +5 -5
  53. package/dist/commands/compile.js +6 -6
  54. package/dist/commands/config/get.js +4 -4
  55. package/dist/commands/config/index.js +5 -5
  56. package/dist/commands/config/path.js +4 -4
  57. package/dist/commands/config/set-project.js +4 -4
  58. package/dist/commands/config/show.js +5 -5
  59. package/dist/commands/config/unset-project.js +4 -4
  60. package/dist/commands/diff.js +4 -4
  61. package/dist/commands/doctor.js +4 -4
  62. package/dist/commands/edit.js +29 -29
  63. package/dist/commands/eject.js +4 -4
  64. package/dist/commands/import/skill.js +7 -8
  65. package/dist/commands/import/skill.js.map +1 -1
  66. package/dist/commands/info.js +5 -5
  67. package/dist/commands/init.js +28 -28
  68. package/dist/commands/list.js +4 -4
  69. package/dist/commands/new/agent.js +6 -6
  70. package/dist/commands/new/marketplace.js +5 -5
  71. package/dist/commands/new/skill.js +10 -8
  72. package/dist/commands/new/skill.js.map +1 -1
  73. package/dist/commands/outdated.js +4 -4
  74. package/dist/commands/search.js +7 -8
  75. package/dist/commands/search.js.map +1 -1
  76. package/dist/commands/uninstall.js +6 -6
  77. package/dist/commands/update.js +6 -6
  78. package/dist/commands/validate.js +267 -24
  79. package/dist/commands/validate.js.map +1 -1
  80. package/dist/components/skill-search/skill-search.js +3 -3
  81. package/dist/components/wizard/category-grid.js +2 -2
  82. package/dist/components/wizard/category-grid.test.js +122 -2
  83. package/dist/components/wizard/category-grid.test.js.map +1 -1
  84. package/dist/components/wizard/checkbox-grid.js +3 -3
  85. package/dist/components/wizard/checkbox-grid.test.js +3 -3
  86. package/dist/components/wizard/domain-selection.js +9 -9
  87. package/dist/components/wizard/help-modal.js +2 -2
  88. package/dist/components/wizard/menu-item.js +1 -1
  89. package/dist/components/wizard/search-modal.js +2 -2
  90. package/dist/components/wizard/search-modal.test.js +2 -2
  91. package/dist/components/wizard/section-progress.js +2 -2
  92. package/dist/components/wizard/section-progress.test.js +2 -2
  93. package/dist/components/wizard/selection-card.js +2 -2
  94. package/dist/components/wizard/source-grid.js +3 -3
  95. package/dist/components/wizard/source-grid.test.js +3 -3
  96. package/dist/components/wizard/stack-selection.js +8 -8
  97. package/dist/components/wizard/step-agents.js +8 -8
  98. package/dist/components/wizard/step-agents.test.js +9 -9
  99. package/dist/components/wizard/step-build.js +8 -8
  100. package/dist/components/wizard/step-build.test.js +74 -46
  101. package/dist/components/wizard/step-build.test.js.map +1 -1
  102. package/dist/components/wizard/step-confirm.js +4 -4
  103. package/dist/components/wizard/step-confirm.test.js +8 -8
  104. package/dist/components/wizard/step-refine.js +2 -2
  105. package/dist/components/wizard/step-refine.test.js +2 -2
  106. package/dist/components/wizard/step-settings.js +5 -5
  107. package/dist/components/wizard/step-settings.test.js +8 -8
  108. package/dist/components/wizard/step-sources.js +10 -10
  109. package/dist/components/wizard/step-sources.test.js +11 -11
  110. package/dist/components/wizard/step-stack.js +12 -12
  111. package/dist/components/wizard/step-stack.test.js +13 -13
  112. package/dist/components/wizard/view-title.js +2 -2
  113. package/dist/components/wizard/wizard-layout.js +8 -8
  114. package/dist/components/wizard/wizard-tabs.js +2 -2
  115. package/dist/components/wizard/wizard-tabs.test.js +2 -2
  116. package/dist/components/wizard/wizard.js +25 -25
  117. package/dist/config/skill-categories.yaml +344 -0
  118. package/dist/config/skill-rules.yaml +740 -0
  119. package/dist/hooks/init.js +3 -3
  120. package/dist/{source-manager-6QZ2GDUA.js → source-manager-Y7R6WPOW.js} +4 -4
  121. package/dist/src/agents/meta/documentor/examples.md +35 -36
  122. package/dist/src/agents/meta/documentor/workflow.md +91 -105
  123. package/dist/stores/wizard-store.js +5 -5
  124. package/dist/stores/wizard-store.test.js +48 -6
  125. package/dist/stores/wizard-store.test.js.map +1 -1
  126. package/package.json +5 -1
  127. package/src/agents/meta/documentor/examples.md +35 -36
  128. package/src/agents/meta/documentor/workflow.md +91 -105
  129. package/src/schemas/agent.schema.json +3 -0
  130. package/src/schemas/metadata.schema.json +5 -5
  131. package/src/schemas/project-source-config.schema.json +4 -1
  132. package/config/skills-matrix.yaml +0 -918
  133. package/dist/chunk-5QRJUBK7.js.map +0 -1
  134. package/dist/chunk-74HSA7C4.js.map +0 -1
  135. package/dist/chunk-CD64ZNYI.js.map +0 -1
  136. package/dist/chunk-CDGHSTB6.js.map +0 -1
  137. package/dist/chunk-HM3DHMW7.js.map +0 -1
  138. package/dist/chunk-RT6IBH37.js.map +0 -1
  139. package/dist/chunk-RWR56UVK.js.map +0 -1
  140. package/dist/chunk-XE6RTHUD.js.map +0 -1
  141. package/dist/chunk-YT7UHV67.js.map +0 -1
  142. package/dist/config/skills-matrix.yaml +0 -918
  143. package/src/schemas/skills-matrix.schema.json +0 -179
  144. /package/dist/{chunk-LFZXMQOH.js.map → chunk-2BVZOYJP.js.map} +0 -0
  145. /package/dist/{chunk-4C7PDDLY.js.map → chunk-2DNDAXF6.js.map} +0 -0
  146. /package/dist/{chunk-C7BO2ASM.js.map → chunk-34BP5BC4.js.map} +0 -0
  147. /package/dist/{chunk-TOWP4T5L.js.map → chunk-37QYD33C.js.map} +0 -0
  148. /package/dist/{chunk-72GS6PIH.js.map → chunk-5O6GKXAN.js.map} +0 -0
  149. /package/dist/{chunk-KWQ2BQXF.js.map → chunk-7IAKVZL5.js.map} +0 -0
  150. /package/dist/{chunk-CTQHZELA.js.map → chunk-AMNCCZSG.js.map} +0 -0
  151. /package/dist/{chunk-PZLUO4OY.js.map → chunk-AXV7NFFJ.js.map} +0 -0
  152. /package/dist/{chunk-ODQ2BKWU.js.map → chunk-AXZNJ5PN.js.map} +0 -0
  153. /package/dist/{chunk-J64CA4V6.js.map → chunk-C7DLY64D.js.map} +0 -0
  154. /package/dist/{chunk-G2WNOT3R.js.map → chunk-DG2U2WY3.js.map} +0 -0
  155. /package/dist/{chunk-3WKFSTG6.js.map → chunk-F7KTUFGU.js.map} +0 -0
  156. /package/dist/{chunk-5M6JI76P.js.map → chunk-FHKNG3UA.js.map} +0 -0
  157. /package/dist/{chunk-I26YP2Q3.js.map → chunk-FPTUCWBY.js.map} +0 -0
  158. /package/dist/{chunk-VH3PI43B.js.map → chunk-G5OZQ376.js.map} +0 -0
  159. /package/dist/{chunk-YVMYQSED.js.map → chunk-I52THVF6.js.map} +0 -0
  160. /package/dist/{chunk-FKBCYT7B.js.map → chunk-IS7GP6XC.js.map} +0 -0
  161. /package/dist/{chunk-NMXNHRAK.js.map → chunk-NJVJ7VO5.js.map} +0 -0
  162. /package/dist/{chunk-GVLYNP2I.js.map → chunk-OHDEJEYB.js.map} +0 -0
  163. /package/dist/{chunk-FUEZQ2H6.js.map → chunk-PY2XZUBF.js.map} +0 -0
  164. /package/dist/{chunk-DO5OZHSS.js.map → chunk-U2AEK4ZL.js.map} +0 -0
  165. /package/dist/{chunk-7LDSHHKN.js.map → chunk-W62XVWXB.js.map} +0 -0
  166. /package/dist/{chunk-D7JTL3DJ.js.map → chunk-WSGKCBY5.js.map} +0 -0
  167. /package/dist/{chunk-QBUOZVNZ.js.map → chunk-YDASDMTH.js.map} +0 -0
  168. /package/dist/{chunk-SGXUMZWL.js.map → chunk-ZML3OCYA.js.map} +0 -0
  169. /package/dist/{source-manager-6QZ2GDUA.js.map → source-manager-Y7R6WPOW.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  typedKeys
5
5
  } from "./chunk-T4EXUIBY.js";
6
6
  import {
7
- SKILL_ID_PATTERN,
7
+ DOMAIN_VALUES,
8
8
  SUBCATEGORY_VALUES,
9
9
  agentFrontmatterValidationSchema,
10
10
  agentNameSchema,
@@ -14,6 +14,7 @@ import {
14
14
  directoryExists,
15
15
  ensureDir,
16
16
  extendSchemasWithCustomValues,
17
+ extensibleDomainSchema,
17
18
  fileExists,
18
19
  formatZodErrors,
19
20
  getErrorMessage,
@@ -33,19 +34,20 @@ import {
33
34
  readFileOptional,
34
35
  readFileSafe,
35
36
  remove,
37
+ skillCategoriesFileSchema,
36
38
  skillDisplayNameSchema,
37
39
  skillFrontmatterLoaderSchema,
38
40
  skillFrontmatterValidationSchema,
39
41
  skillIdSchema,
40
42
  skillMetadataLoaderSchema,
41
- skillsMatrixConfigSchema,
43
+ skillRulesFileSchema,
42
44
  stacksConfigSchema,
43
45
  validateNestingDepth,
44
46
  verbose,
45
47
  warn,
46
48
  warnUnknownFields,
47
49
  writeFile
48
- } from "./chunk-5QRJUBK7.js";
50
+ } from "./chunk-YMUWTPOM.js";
49
51
  import {
50
52
  ARCHIVED_SKILLS_DIR_NAME,
51
53
  CACHE_DIR,
@@ -73,13 +75,14 @@ import {
73
75
  PROJECT_ROOT,
74
76
  SCHEMA_PATHS,
75
77
  SKILLS_DIR_PATH,
76
- SKILLS_MATRIX_PATH,
78
+ SKILL_CATEGORIES_YAML_PATH,
79
+ SKILL_RULES_YAML_PATH,
77
80
  STACKS_FILE_PATH,
78
81
  STANDARD_DIRS,
79
82
  STANDARD_FILES,
80
83
  YAML_FORMATTING,
81
84
  yamlSchemaComment
82
- } from "./chunk-74HSA7C4.js";
85
+ } from "./chunk-LESHL6SM.js";
83
86
  import {
84
87
  init_esm_shims
85
88
  } from "./chunk-DHET7RCE.js";
@@ -1016,7 +1019,8 @@ async function loadAllAgents(projectRoot) {
1016
1019
  model: config.model,
1017
1020
  tools: config.tools,
1018
1021
  path: agentPath,
1019
- sourceRoot: projectRoot
1022
+ sourceRoot: projectRoot,
1023
+ ...config.domain ? { domain: config.domain } : {}
1020
1024
  };
1021
1025
  verbose(`Loaded agent: ${config.id} from ${file}`);
1022
1026
  } catch (error) {
@@ -1046,8 +1050,9 @@ async function loadProjectAgents(projectRoot) {
1046
1050
  tools: config.tools,
1047
1051
  path: agentPath,
1048
1052
  sourceRoot: projectRoot,
1049
- agentBaseDir: `${CLAUDE_SRC_DIR}/agents`
1053
+ agentBaseDir: `${CLAUDE_SRC_DIR}/agents`,
1050
1054
  // Project agents are in .claude-src/agents/
1055
+ ...config.domain ? { domain: config.domain } : {}
1051
1056
  };
1052
1057
  verbose(`Loaded project agent: ${config.id} from ${file}`);
1053
1058
  } catch (error) {
@@ -1162,7 +1167,7 @@ import { unique as unique4 } from "remeda";
1162
1167
  // src/cli/lib/metadata-keys.ts
1163
1168
  init_esm_shims();
1164
1169
  var METADATA_KEYS = {
1165
- CLI_NAME: "cliName",
1170
+ DISPLAY_NAME: "displayName",
1166
1171
  CLI_DESCRIPTION: "cliDescription",
1167
1172
  CATEGORY: "category",
1168
1173
  FORKED_FROM: "forkedFrom",
@@ -1558,7 +1563,7 @@ async function writePluginManifest(outputDir, manifest) {
1558
1563
  // src/cli/lib/plugins/plugin-finder.ts
1559
1564
  init_esm_shims();
1560
1565
  import path10 from "path";
1561
- import { last, zip } from "remeda";
1566
+ import { zip } from "remeda";
1562
1567
  function getProjectPluginsDir(projectDir) {
1563
1568
  const dir = projectDir ?? process.cwd();
1564
1569
  return path10.join(dir, CLAUDE_DIR, PLUGINS_SUBDIR);
@@ -2222,7 +2227,8 @@ var PATH_OVERRIDES_COMMENT = [
2222
2227
  `# skillsDir: ${SKILLS_DIR_PATH}`,
2223
2228
  `# agentsDir: ${DIRS.agents}`,
2224
2229
  `# stacksFile: ${STACKS_FILE_PATH}`,
2225
- `# matrixFile: ${SKILLS_MATRIX_PATH}`,
2230
+ `# categoriesFile: ${SKILL_CATEGORIES_YAML_PATH}`,
2231
+ `# rulesFile: ${SKILL_RULES_YAML_PATH}`,
2226
2232
  ""
2227
2233
  ].join("\n");
2228
2234
  async function writeConfigFile(config, configPath) {
@@ -3135,33 +3141,56 @@ import path19 from "path";
3135
3141
  import { z as z3 } from "zod";
3136
3142
  var rawMetadataSchema = z3.object({
3137
3143
  category: categoryPathSchema,
3138
- categoryExclusive: z3.boolean().optional(),
3139
3144
  author: z3.string(),
3140
- cliName: z3.string().optional(),
3145
+ displayName: z3.string().optional(),
3141
3146
  cliDescription: z3.string().optional(),
3142
3147
  usageGuidance: z3.string().optional(),
3143
3148
  tags: z3.array(z3.string()).optional(),
3144
- // Lenient: accepts display names and skill IDs from YAML, resolved to canonical IDs during matrix merge
3145
- compatibleWith: z3.array(z3.string()).optional(),
3146
- conflictsWith: z3.array(z3.string()).optional(),
3147
- requires: z3.array(z3.string()).optional(),
3148
- requiresSetup: z3.array(z3.string()).optional(),
3149
- providesSetupFor: z3.array(z3.string()).optional(),
3149
+ domain: extensibleDomainSchema.optional(),
3150
3150
  custom: z3.boolean().optional()
3151
3151
  });
3152
- 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) {
3153
3182
  const content = await readFile(configPath);
3154
3183
  const raw = parseYaml7(content);
3155
- const result = skillsMatrixConfigSchema.safeParse(raw);
3184
+ const result = skillRulesFileSchema.safeParse(raw);
3156
3185
  if (!result.success) {
3157
3186
  throw new Error(
3158
- `Invalid skills matrix at '${configPath}': ${formatZodErrors(result.error.issues)}`
3187
+ `Invalid skill rules at '${configPath}': ${formatZodErrors(result.error.issues)}`
3159
3188
  );
3160
3189
  }
3161
3190
  const data = result.data;
3162
- const matrix = {
3191
+ const config = {
3163
3192
  version: data.version,
3164
- categories: data.categories,
3193
+ aliases: data.aliases ?? {},
3165
3194
  relationships: data.relationships ?? {
3166
3195
  conflicts: [],
3167
3196
  discourages: [],
@@ -3169,10 +3198,10 @@ async function loadSkillsMatrix(configPath) {
3169
3198
  requires: [],
3170
3199
  alternatives: []
3171
3200
  },
3172
- skillAliases: data.skillAliases ?? {}
3201
+ perSkill: data["per-skill"] ?? {}
3173
3202
  };
3174
- verbose(`Loaded skills matrix: ${configPath}`);
3175
- return matrix;
3203
+ verbose(`Loaded skill rules: ${configPath}`);
3204
+ return config;
3176
3205
  }
3177
3206
  async function extractAllSkills(skillsDir) {
3178
3207
  const skills = [];
@@ -3201,9 +3230,9 @@ async function extractAllSkills(skillsDir) {
3201
3230
  verbose(`Skipping ${metadataFile}: Invalid SKILL.md frontmatter`);
3202
3231
  continue;
3203
3232
  }
3204
- if (!metadata.cliName) {
3233
+ if (!metadata.displayName) {
3205
3234
  throw new Error(
3206
- `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`
3207
3236
  );
3208
3237
  }
3209
3238
  const skillId = frontmatter.name;
@@ -3213,15 +3242,10 @@ async function extractAllSkills(skillsDir) {
3213
3242
  description: metadata.cliDescription || frontmatter.description,
3214
3243
  usageGuidance: metadata.usageGuidance,
3215
3244
  category: metadata.category,
3216
- categoryExclusive: metadata.categoryExclusive ?? true,
3217
3245
  author: metadata.author,
3218
3246
  tags: metadata.tags ?? [],
3219
- compatibleWith: metadata.compatibleWith ?? [],
3220
- conflictsWith: metadata.conflictsWith ?? [],
3221
- requires: metadata.requires ?? [],
3222
- requiresSetup: metadata.requiresSetup ?? [],
3223
- providesSetupFor: metadata.providesSetupFor ?? [],
3224
3247
  path: `skills/${skillDir}/`,
3248
+ ...metadata.domain ? { domain: metadata.domain } : {},
3225
3249
  ...metadata.custom === true ? { custom: true } : {}
3226
3250
  };
3227
3251
  skills.push(extracted);
@@ -3266,25 +3290,36 @@ function resolveToCanonicalId(nameOrId, displayNameToId, directoryPathToId = {},
3266
3290
  }
3267
3291
  return nameOrId;
3268
3292
  }
3269
- async function mergeMatrixWithSkills(matrix, skills) {
3270
- const displayNameToId = matrix.skillAliases;
3293
+ async function mergeMatrixWithSkills(categories, relationships, aliases, skills, perSkillRules) {
3294
+ const displayNameToId = aliases;
3271
3295
  const displayNames = buildReverseDisplayNames(displayNameToId);
3272
3296
  const directoryPathToId = buildDirectoryPathToIdMap(skills);
3273
3297
  const resolvedSkills = {};
3274
3298
  for (const skill of skills) {
3275
3299
  const resolved = buildResolvedSkill(
3276
3300
  skill,
3277
- matrix,
3301
+ categories,
3302
+ relationships,
3278
3303
  displayNameToId,
3279
3304
  displayNames,
3280
- directoryPathToId
3305
+ directoryPathToId,
3306
+ perSkillRules
3281
3307
  );
3282
3308
  resolvedSkills[skill.id] = resolved;
3283
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
+ }
3284
3319
  const suggestedStacks = resolveSuggestedStacks();
3285
3320
  const merged = {
3286
- version: matrix.version,
3287
- categories: matrix.categories,
3321
+ version: "1.0.0",
3322
+ categories: synthesizedCategories,
3288
3323
  skills: resolvedSkills,
3289
3324
  suggestedStacks,
3290
3325
  displayNameToId,
@@ -3377,41 +3412,48 @@ function resolveDiscourages(skillId, discourageRules, resolve) {
3377
3412
  }
3378
3413
  return discourages;
3379
3414
  }
3380
- function buildResolvedSkill(skill, matrix, displayNameToId, displayNames, directoryPathToId) {
3415
+ function buildResolvedSkill(skill, _categories, relationships, displayNameToId, displayNames, directoryPathToId, perSkillRules) {
3381
3416
  const resolve = (id, context) => resolveToCanonicalId(
3382
3417
  id,
3383
3418
  displayNameToId,
3384
3419
  directoryPathToId,
3385
3420
  context ? `${skill.id} ${context}` : void 0
3386
3421
  );
3387
- const { relationships } = matrix;
3422
+ const skillAlias = displayNames[skill.id];
3423
+ const perSkill = skillAlias ? perSkillRules?.[skillAlias] : void 0;
3388
3424
  return {
3389
3425
  id: skill.id,
3390
3426
  displayName: displayNames[skill.id],
3391
3427
  description: skill.description,
3392
3428
  usageGuidance: skill.usageGuidance,
3393
3429
  category: skill.category,
3394
- categoryExclusive: skill.categoryExclusive,
3395
3430
  tags: skill.tags,
3396
3431
  author: skill.author,
3397
3432
  conflictsWith: resolveConflicts(
3398
3433
  skill.id,
3399
- skill.conflictsWith,
3434
+ perSkill?.conflictsWith ?? [],
3400
3435
  relationships.conflicts,
3401
3436
  resolve
3402
3437
  ),
3403
3438
  recommends: resolveRecommends(
3404
3439
  skill.id,
3405
- skill.compatibleWith,
3440
+ perSkill?.compatibleWith ?? [],
3406
3441
  relationships.recommends,
3407
3442
  resolve
3408
3443
  ),
3409
- requires: resolveRequirements(skill.id, skill.requires, relationships.requires, resolve),
3444
+ requires: resolveRequirements(
3445
+ skill.id,
3446
+ perSkill?.requires ?? [],
3447
+ relationships.requires,
3448
+ resolve
3449
+ ),
3410
3450
  alternatives: resolveAlternatives(skill.id, relationships.alternatives, resolve),
3411
3451
  discourages: resolveDiscourages(skill.id, relationships.discourages, resolve),
3412
- compatibleWith: skill.compatibleWith.map((id) => resolve(id, "compatibleWith")),
3413
- requiresSetup: skill.requiresSetup.map((id) => resolve(id, "requiresSetup")),
3414
- 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
+ ),
3415
3457
  path: skill.path
3416
3458
  };
3417
3459
  }
@@ -3763,12 +3805,15 @@ function checkSubcategoryDomains(matrix, issues) {
3763
3805
  function checkSkillCategories(matrix, issues) {
3764
3806
  for (const [skillId, skill] of typedEntries(matrix.skills)) {
3765
3807
  if (!skill) continue;
3766
- if (!matrix.categories[skill.category]) {
3808
+ const category = matrix.categories[skill.category];
3809
+ if (!category) {
3767
3810
  issues.push({
3768
3811
  severity: "warning",
3769
3812
  finding: "skill-unknown-category",
3770
3813
  details: `Skill '${skillId}' references category '${skill.category}' which does not exist in the matrix`
3771
3814
  });
3815
+ } else if (category.custom) {
3816
+ verbose(`Skill '${skillId}' uses auto-synthesized category '${skill.category}'`);
3772
3817
  }
3773
3818
  }
3774
3819
  }
@@ -4083,47 +4128,62 @@ async function loadFromRemote(source, sourceConfig, forceRefresh) {
4083
4128
  }
4084
4129
  async function loadAndMergeFromBasePath(basePath) {
4085
4130
  const sourceProjectConfig = await loadProjectSourceConfig(basePath);
4086
- const matrixRelPath = sourceProjectConfig?.matrixFile ?? SKILLS_MATRIX_PATH;
4087
4131
  const skillsDirRelPath = sourceProjectConfig?.skillsDir ?? SKILLS_DIR_PATH;
4088
4132
  const stacksRelFile = sourceProjectConfig?.stacksFile;
4089
- const cliMatrixPath = path21.join(PROJECT_ROOT, SKILLS_MATRIX_PATH);
4090
- const cliMatrix = await loadSkillsMatrix(cliMatrixPath);
4091
- 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;
4092
4141
  await discoverAndExtendFromSource(basePath);
4093
- const sourceMatrixPath = path21.join(basePath, matrixRelPath);
4094
- if (await fileExists(sourceMatrixPath)) {
4095
- const sourceMatrix = await loadSkillsMatrix(sourceMatrixPath);
4096
- const mergedCategories = { ...cliMatrix.categories, ...sourceMatrix.categories };
4097
- const mergedRelationships = {
4098
- conflicts: [...cliMatrix.relationships.conflicts, ...sourceMatrix.relationships.conflicts],
4099
- discourages: [
4100
- ...cliMatrix.relationships.discourages,
4101
- ...sourceMatrix.relationships.discourages
4102
- ],
4103
- recommends: [...cliMatrix.relationships.recommends, ...sourceMatrix.relationships.recommends],
4104
- requires: [...cliMatrix.relationships.requires, ...sourceMatrix.relationships.requires],
4105
- alternatives: [
4106
- ...cliMatrix.relationships.alternatives,
4107
- ...sourceMatrix.relationships.alternatives
4108
- ]
4109
- };
4110
- const mergedAliases = { ...cliMatrix.skillAliases, ...sourceMatrix.skillAliases };
4111
- matrix = {
4112
- version: cliMatrix.version,
4113
- categories: mergedCategories,
4114
- relationships: mergedRelationships,
4115
- skillAliases: mergedAliases
4116
- };
4117
- verbose(
4118
- `Matrix merged: CLI (${typedKeys(cliMatrix.categories).length} categories) + source (${typedKeys(sourceMatrix.categories).length} categories)`
4119
- );
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`);
4120
4174
  } else {
4121
- verbose(`Matrix from CLI only (source has no matrix): ${cliMatrixPath}`);
4175
+ verbose(`Matrix from CLI only (source has no categories/rules files)`);
4122
4176
  }
4123
4177
  const skillsDir = path21.join(basePath, skillsDirRelPath);
4124
4178
  verbose(`Skills from source: ${skillsDir}`);
4125
4179
  const skills = await extractAllSkills(skillsDir);
4126
- const mergedMatrix = await mergeMatrixWithSkills(matrix, skills);
4180
+ const mergedMatrix = await mergeMatrixWithSkills(
4181
+ categories,
4182
+ relationships,
4183
+ aliases,
4184
+ skills,
4185
+ perSkillRules
4186
+ );
4127
4187
  const sourceStacks = await loadStacks(basePath, stacksRelFile);
4128
4188
  const stacks = sourceStacks.length > 0 ? sourceStacks : await loadStacks(PROJECT_ROOT);
4129
4189
  if (stacks.length > 0) {
@@ -4131,6 +4191,17 @@ async function loadAndMergeFromBasePath(basePath) {
4131
4191
  const stackSource = sourceStacks.length > 0 ? "source" : "CLI";
4132
4192
  verbose(`Loaded ${stacks.length} stacks from ${stackSource}`);
4133
4193
  }
4194
+ const agents = await loadAllAgents(basePath);
4195
+ const agentDefinedDomains = {};
4196
+ for (const [agentId, agentDef] of typedEntries(agents)) {
4197
+ if (agentDef.domain) {
4198
+ agentDefinedDomains[agentId] = agentDef.domain;
4199
+ }
4200
+ }
4201
+ if (Object.keys(agentDefinedDomains).length > 0) {
4202
+ mergedMatrix.agentDefinedDomains = agentDefinedDomains;
4203
+ verbose(`Loaded ${Object.keys(agentDefinedDomains).length} agent domain definition(s)`);
4204
+ }
4134
4205
  return mergedMatrix;
4135
4206
  }
4136
4207
  function convertStackToResolvedStack(stack) {
@@ -4190,15 +4261,20 @@ function getMarketplaceLabel(sourceResult) {
4190
4261
  }
4191
4262
  return marketplace;
4192
4263
  }
4193
- async function discoverCustomAgentName(agentsDir, file, parseYaml9) {
4264
+ async function discoverCustomAgentValues(agentsDir, file, parseYaml9, builtinDomains) {
4194
4265
  const content = await readFile(path21.join(agentsDir, file));
4195
4266
  const raw = parseYaml9(content);
4196
- if (raw?.custom !== true) return void 0;
4197
- if (typeof raw?.id !== "string") return void 0;
4198
- if (agentNameSchema.safeParse(raw.id).success) return void 0;
4199
- return raw.id;
4267
+ if (raw?.custom !== true) return {};
4268
+ const result = {};
4269
+ if (typeof raw?.id === "string" && !agentNameSchema.safeParse(raw.id).success) {
4270
+ result.agentName = raw.id;
4271
+ }
4272
+ if (typeof raw?.domain === "string" && !builtinDomains.has(raw.domain)) {
4273
+ result.domain = raw.domain;
4274
+ }
4275
+ return result;
4200
4276
  }
4201
- async function discoverCustomSkillValues(skillsDir, file, parseYaml9, builtinSubcategories) {
4277
+ async function discoverCustomSkillValues(skillsDir, file, parseYaml9, builtinSubcategories, builtinDomains) {
4202
4278
  const content = await readFile(path21.join(skillsDir, file));
4203
4279
  const frontmatter = parseFrontmatter(content);
4204
4280
  if (!frontmatter) return {};
@@ -4210,19 +4286,23 @@ async function discoverCustomSkillValues(skillsDir, file, parseYaml9, builtinSub
4210
4286
  const metadataRaw = parseYaml9(metadataContent);
4211
4287
  if (metadataRaw?.custom !== true) return {};
4212
4288
  const result = {};
4213
- if (!SKILL_ID_PATTERN.test(skillId)) {
4214
- result.skillId = skillId;
4215
- }
4289
+ result.skillId = skillId;
4216
4290
  const category = metadataRaw.category;
4217
4291
  if (typeof category === "string" && !builtinSubcategories.has(category)) {
4218
4292
  result.category = category;
4219
4293
  }
4294
+ const domain = metadataRaw.domain;
4295
+ if (typeof domain === "string" && !builtinDomains.has(domain)) {
4296
+ result.domain = domain;
4297
+ }
4220
4298
  return result;
4221
4299
  }
4222
4300
  async function discoverAndExtendFromSource(basePath) {
4223
4301
  const { parse: parseYaml9 } = await import("yaml");
4224
4302
  const builtinSubcategories = new Set(SUBCATEGORY_VALUES);
4303
+ const builtinDomains = new Set(DOMAIN_VALUES);
4225
4304
  const customCategories = [];
4305
+ const customDomains = [];
4226
4306
  const customAgentNames = [];
4227
4307
  const customSkillIds = [];
4228
4308
  const agentsDir = path21.join(basePath, DIRS.agents);
@@ -4230,8 +4310,9 @@ async function discoverAndExtendFromSource(basePath) {
4230
4310
  const agentFiles = await glob(`**/${STANDARD_FILES.AGENT_YAML}`, agentsDir);
4231
4311
  for (const file of agentFiles) {
4232
4312
  try {
4233
- const name = await discoverCustomAgentName(agentsDir, file, parseYaml9);
4234
- if (name) customAgentNames.push(name);
4313
+ const result = await discoverCustomAgentValues(agentsDir, file, parseYaml9, builtinDomains);
4314
+ if (result.agentName) customAgentNames.push(result.agentName);
4315
+ if (result.domain) customDomains.push(result.domain);
4235
4316
  } catch {
4236
4317
  }
4237
4318
  }
@@ -4245,23 +4326,26 @@ async function discoverAndExtendFromSource(basePath) {
4245
4326
  skillsDir,
4246
4327
  file,
4247
4328
  parseYaml9,
4248
- builtinSubcategories
4329
+ builtinSubcategories,
4330
+ builtinDomains
4249
4331
  );
4250
4332
  if (result.skillId) customSkillIds.push(result.skillId);
4251
4333
  if (result.category) customCategories.push(result.category);
4334
+ if (result.domain) customDomains.push(result.domain);
4252
4335
  } catch {
4253
4336
  }
4254
4337
  }
4255
4338
  }
4256
- const hasCustomValues = customCategories.length > 0 || customAgentNames.length > 0 || customSkillIds.length > 0;
4339
+ const hasCustomValues = customCategories.length > 0 || customDomains.length > 0 || customAgentNames.length > 0 || customSkillIds.length > 0;
4257
4340
  if (hasCustomValues) {
4258
4341
  extendSchemasWithCustomValues({
4259
4342
  categories: unique4(customCategories),
4343
+ domains: unique4(customDomains),
4260
4344
  agentNames: customAgentNames,
4261
4345
  skillIds: customSkillIds
4262
4346
  });
4263
4347
  verbose(
4264
- `Extended schemas with ${unique4(customCategories).length} custom categories, ${customAgentNames.length} custom agents, ${customSkillIds.length} custom skill IDs`
4348
+ `Extended schemas with ${unique4(customCategories).length} custom categories, ${unique4(customDomains).length} custom domains, ${customAgentNames.length} custom agents, ${customSkillIds.length} custom skill IDs`
4265
4349
  );
4266
4350
  }
4267
4351
  }
@@ -4276,7 +4360,6 @@ function mergeLocalSkillsIntoMatrix(matrix, localResult) {
4276
4360
  description: metadata.description,
4277
4361
  usageGuidance: metadata.usageGuidance,
4278
4362
  category,
4279
- categoryExclusive: metadata.categoryExclusive,
4280
4363
  tags: metadata.tags ?? [],
4281
4364
  author: LOCAL_DEFAULTS.AUTHOR,
4282
4365
  conflictsWith: existingSkill?.conflictsWith ?? [],
@@ -4339,11 +4422,10 @@ async function extractLocalSkill(localSkillsPath, skillDirName) {
4339
4422
  return null;
4340
4423
  }
4341
4424
  const metadata = parsed.data;
4342
- if (!metadata.cliName) {
4343
- warn(
4344
- `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`
4345
4428
  );
4346
- return null;
4347
4429
  }
4348
4430
  const skillMdContent = await readFile(skillMdPath);
4349
4431
  const frontmatter = parseFrontmatter(skillMdContent, skillMdPath);
@@ -4365,14 +4447,8 @@ async function extractLocalSkill(localSkillsPath, skillDirName) {
4365
4447
  description: metadata.cliDescription || frontmatter.description,
4366
4448
  usageGuidance: metadata.usageGuidance,
4367
4449
  category,
4368
- categoryExclusive: metadata.categoryExclusive ?? false,
4369
4450
  author: LOCAL_DEFAULTS.AUTHOR,
4370
4451
  tags: metadata.tags ?? [],
4371
- compatibleWith: metadata.compatibleWith ?? [],
4372
- conflictsWith: metadata.conflictsWith ?? [],
4373
- requires: metadata.requires ?? [],
4374
- requiresSetup: metadata.requiresSetup ?? [],
4375
- providesSetupFor: metadata.providesSetupFor ?? [],
4376
4452
  path: relativePath,
4377
4453
  local: true,
4378
4454
  localPath: relativePath
@@ -4477,6 +4553,7 @@ export {
4477
4553
  getCurrentDate,
4478
4554
  computeStringHash,
4479
4555
  computeFileHash,
4556
+ computeSkillFolderHash,
4480
4557
  determinePluginVersion,
4481
4558
  writeContentHash,
4482
4559
  readForkedFromMetadata,
@@ -4488,9 +4565,14 @@ export {
4488
4565
  printCompilationSummary,
4489
4566
  archiveLocalSkill,
4490
4567
  restoreArchivedSkill,
4568
+ loadSkillCategories,
4569
+ loadSkillRules,
4570
+ extractAllSkills,
4571
+ mergeMatrixWithSkills,
4491
4572
  resolveAlias,
4492
4573
  validateSelection,
4493
4574
  getAvailableSkills,
4575
+ checkMatrixHealth,
4494
4576
  searchExtraSources,
4495
4577
  buildSkillRefsFromConfig,
4496
4578
  resolveAgents,
@@ -4517,4 +4599,4 @@ export {
4517
4599
  validateAllPlugins,
4518
4600
  printPluginValidationResult
4519
4601
  };
4520
- //# sourceMappingURL=chunk-RT6IBH37.js.map
4602
+ //# sourceMappingURL=chunk-P2SFRDWI.js.map