@codemcp/workflows 6.20.2 → 6.21.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 (133) hide show
  1. package/package.json +2 -2
  2. package/packages/cli/dist/{chunk-4N42FFJE.js → chunk-KWAFQZUI.js} +91 -2670
  3. package/packages/cli/dist/{cli-MFHC7UWY.js → cli-O52P3RVC.js} +468 -33
  4. package/packages/cli/dist/{dist-ISN3FRV4.js → dist-FIUD5G5U.js} +65 -4
  5. package/packages/cli/dist/{dist-TDV3DJ2J.js → dist-ZTAPC4IK.js} +3 -1
  6. package/packages/cli/dist/index.js +2 -2
  7. package/packages/cli/package.json +5 -2
  8. package/packages/cli/resources/templates/opencode-agents/coding.md.tmpl +13 -0
  9. package/packages/cli/resources/templates/opencode-agents/research.md.tmpl +13 -0
  10. package/packages/cli/resources/templates/opencode-agents/thinking.md.tmpl +13 -0
  11. package/packages/cli/resources/workflows/bugfix.yaml +6 -0
  12. package/packages/cli/resources/workflows/epcc.yaml +3 -0
  13. package/packages/cli/resources/workflows/greenfield.yaml +3 -0
  14. package/packages/cli/resources/workflows/pr-review.yaml +2 -0
  15. package/packages/cli/resources/workflows/qrspi.yaml +5 -0
  16. package/packages/cli/resources/workflows/tdd.yaml +3 -0
  17. package/packages/cli/resources/workflows/waterfall.yaml +3 -0
  18. package/packages/core/dist/capability-hint.d.ts +28 -0
  19. package/packages/core/dist/capability-hint.js +52 -0
  20. package/packages/core/dist/capability-hint.js.map +1 -0
  21. package/packages/core/dist/config-manager.d.ts +19 -0
  22. package/packages/core/dist/config-manager.js +26 -0
  23. package/packages/core/dist/config-manager.js.map +1 -1
  24. package/packages/core/dist/index.d.ts +1 -0
  25. package/packages/core/dist/index.js +1 -0
  26. package/packages/core/dist/index.js.map +1 -1
  27. package/packages/core/dist/instruction-generator.js +7 -1
  28. package/packages/core/dist/instruction-generator.js.map +1 -1
  29. package/packages/core/dist/interfaces/instruction-generator.interface.d.ts +14 -0
  30. package/packages/core/dist/state-machine-types.d.ts +7 -0
  31. package/packages/core/package.json +1 -1
  32. package/packages/core/resources/templates/opencode-agents/coding.md.tmpl +13 -0
  33. package/packages/core/resources/templates/opencode-agents/research.md.tmpl +13 -0
  34. package/packages/core/resources/templates/opencode-agents/thinking.md.tmpl +13 -0
  35. package/packages/core/resources/workflows/bugfix.yaml +6 -0
  36. package/packages/core/resources/workflows/epcc.yaml +3 -0
  37. package/packages/core/resources/workflows/greenfield.yaml +3 -0
  38. package/packages/core/resources/workflows/pr-review.yaml +2 -0
  39. package/packages/core/resources/workflows/qrspi.yaml +5 -0
  40. package/packages/core/resources/workflows/tdd.yaml +3 -0
  41. package/packages/core/resources/workflows/waterfall.yaml +3 -0
  42. package/packages/docs/.vitepress/dist/404.html +1 -1
  43. package/packages/docs/.vitepress/dist/assets/user_capability-routing.md.DbNKvMiS.js +15 -0
  44. package/packages/docs/.vitepress/dist/assets/user_capability-routing.md.DbNKvMiS.lean.js +1 -0
  45. package/packages/docs/.vitepress/dist/dev/ARCHITECTURE.html +2 -2
  46. package/packages/docs/.vitepress/dist/dev/DEVELOPMENT.html +2 -2
  47. package/packages/docs/.vitepress/dist/dev/LOGGING.html +2 -2
  48. package/packages/docs/.vitepress/dist/dev/PUBLISHING.html +2 -2
  49. package/packages/docs/.vitepress/dist/hashmap.json +1 -1
  50. package/packages/docs/.vitepress/dist/index.html +2 -2
  51. package/packages/docs/.vitepress/dist/user/advanced-engineering.html +3 -3
  52. package/packages/docs/.vitepress/dist/user/agent-setup.html +3 -3
  53. package/packages/docs/.vitepress/dist/user/beads-integration.html +2 -2
  54. package/packages/docs/.vitepress/dist/user/capability-routing.html +40 -0
  55. package/packages/docs/.vitepress/dist/user/crowd-mcp-integration.html +2 -2
  56. package/packages/docs/.vitepress/dist/user/custom-workflows.html +2 -2
  57. package/packages/docs/.vitepress/dist/user/git-commit-feature.html +2 -2
  58. package/packages/docs/.vitepress/dist/user/how-it-works.html +2 -2
  59. package/packages/docs/.vitepress/dist/user/long-term-memory.html +2 -2
  60. package/packages/docs/.vitepress/dist/user/packaged-workflows.html +2 -2
  61. package/packages/docs/.vitepress/dist/user/tutorial.html +2 -2
  62. package/packages/docs/.vitepress/dist/user/workflow-selection.html +2 -2
  63. package/packages/docs/.vitepress/dist/workflows/adr.html +1 -1
  64. package/packages/docs/.vitepress/dist/workflows/big-bang-conversion.html +1 -1
  65. package/packages/docs/.vitepress/dist/workflows/boundary-testing.html +1 -1
  66. package/packages/docs/.vitepress/dist/workflows/bugfix.html +1 -1
  67. package/packages/docs/.vitepress/dist/workflows/bugfix.yaml +6 -0
  68. package/packages/docs/.vitepress/dist/workflows/business-analysis.html +1 -1
  69. package/packages/docs/.vitepress/dist/workflows/c4-analysis.html +1 -1
  70. package/packages/docs/.vitepress/dist/workflows/epcc.html +1 -1
  71. package/packages/docs/.vitepress/dist/workflows/epcc.yaml +3 -0
  72. package/packages/docs/.vitepress/dist/workflows/game-beginner.html +1 -1
  73. package/packages/docs/.vitepress/dist/workflows/greenfield.html +1 -1
  74. package/packages/docs/.vitepress/dist/workflows/greenfield.yaml +3 -0
  75. package/packages/docs/.vitepress/dist/workflows/minor.html +1 -1
  76. package/packages/docs/.vitepress/dist/workflows/posts.html +1 -1
  77. package/packages/docs/.vitepress/dist/workflows/pr-review.html +1 -1
  78. package/packages/docs/.vitepress/dist/workflows/pr-review.yaml +2 -0
  79. package/packages/docs/.vitepress/dist/workflows/qrspi.html +1 -1
  80. package/packages/docs/.vitepress/dist/workflows/qrspi.yaml +5 -0
  81. package/packages/docs/.vitepress/dist/workflows/sdd-bugfix-crowd.html +1 -1
  82. package/packages/docs/.vitepress/dist/workflows/sdd-bugfix.html +1 -1
  83. package/packages/docs/.vitepress/dist/workflows/sdd-feature-crowd.html +1 -1
  84. package/packages/docs/.vitepress/dist/workflows/sdd-feature.html +1 -1
  85. package/packages/docs/.vitepress/dist/workflows/sdd-greenfield-crowd.html +1 -1
  86. package/packages/docs/.vitepress/dist/workflows/sdd-greenfield.html +1 -1
  87. package/packages/docs/.vitepress/dist/workflows/skilled-bugfix.html +1 -1
  88. package/packages/docs/.vitepress/dist/workflows/skilled-epcc.html +1 -1
  89. package/packages/docs/.vitepress/dist/workflows/skilled-greenfield.html +1 -1
  90. package/packages/docs/.vitepress/dist/workflows/slides.html +1 -1
  91. package/packages/docs/.vitepress/dist/workflows/tdd.html +1 -1
  92. package/packages/docs/.vitepress/dist/workflows/tdd.yaml +3 -0
  93. package/packages/docs/.vitepress/dist/workflows/waterfall.html +1 -1
  94. package/packages/docs/.vitepress/dist/workflows/waterfall.yaml +3 -0
  95. package/packages/docs/.vitepress/dist/workflows.html +1 -1
  96. package/packages/docs/package.json +1 -1
  97. package/packages/mcp-server/dist/index.js +67 -4
  98. package/packages/mcp-server/package.json +1 -1
  99. package/packages/mcp-server/resources/templates/opencode-agents/coding.md.tmpl +13 -0
  100. package/packages/mcp-server/resources/templates/opencode-agents/research.md.tmpl +13 -0
  101. package/packages/mcp-server/resources/templates/opencode-agents/thinking.md.tmpl +13 -0
  102. package/packages/mcp-server/resources/workflows/bugfix.yaml +6 -0
  103. package/packages/mcp-server/resources/workflows/epcc.yaml +3 -0
  104. package/packages/mcp-server/resources/workflows/greenfield.yaml +3 -0
  105. package/packages/mcp-server/resources/workflows/pr-review.yaml +2 -0
  106. package/packages/mcp-server/resources/workflows/qrspi.yaml +5 -0
  107. package/packages/mcp-server/resources/workflows/tdd.yaml +3 -0
  108. package/packages/mcp-server/resources/workflows/waterfall.yaml +3 -0
  109. package/packages/opencode-plugin/dist/index.js +67 -4
  110. package/packages/opencode-plugin/package.json +1 -1
  111. package/packages/opencode-plugin/resources/templates/opencode-agents/coding.md.tmpl +13 -0
  112. package/packages/opencode-plugin/resources/templates/opencode-agents/research.md.tmpl +13 -0
  113. package/packages/opencode-plugin/resources/templates/opencode-agents/thinking.md.tmpl +13 -0
  114. package/packages/opencode-plugin/resources/workflows/bugfix.yaml +6 -0
  115. package/packages/opencode-plugin/resources/workflows/epcc.yaml +3 -0
  116. package/packages/opencode-plugin/resources/workflows/greenfield.yaml +3 -0
  117. package/packages/opencode-plugin/resources/workflows/pr-review.yaml +2 -0
  118. package/packages/opencode-plugin/resources/workflows/qrspi.yaml +5 -0
  119. package/packages/opencode-plugin/resources/workflows/tdd.yaml +3 -0
  120. package/packages/opencode-plugin/resources/workflows/waterfall.yaml +3 -0
  121. package/packages/opencode-tui-plugin/package.json +1 -1
  122. package/packages/visualizer/package.json +1 -1
  123. package/resources/state-machine-schema.json +4 -0
  124. package/resources/templates/opencode-agents/coding.md.tmpl +13 -0
  125. package/resources/templates/opencode-agents/research.md.tmpl +13 -0
  126. package/resources/templates/opencode-agents/thinking.md.tmpl +13 -0
  127. package/resources/workflows/bugfix.yaml +6 -0
  128. package/resources/workflows/epcc.yaml +3 -0
  129. package/resources/workflows/greenfield.yaml +3 -0
  130. package/resources/workflows/pr-review.yaml +2 -0
  131. package/resources/workflows/qrspi.yaml +5 -0
  132. package/resources/workflows/tdd.yaml +3 -0
  133. package/resources/workflows/waterfall.yaml +3 -0
@@ -1,15 +1,16 @@
1
1
  import {
2
+ ConfigManager,
2
3
  StateMachineLoader,
3
4
  WorkflowManager,
4
5
  generateSystemPrompt
5
- } from "./chunk-4N42FFJE.js";
6
+ } from "./chunk-KWAFQZUI.js";
6
7
  import "./chunk-R5U7XKVJ.js";
7
8
 
8
9
  // src/cli.ts
9
- import { fileURLToPath as fileURLToPath3 } from "url";
10
- import { dirname as dirname3, join as join5 } from "path";
10
+ import { fileURLToPath as fileURLToPath4 } from "url";
11
+ import { dirname as dirname4, join as join6 } from "path";
11
12
  import {
12
- existsSync as existsSync3,
13
+ existsSync as existsSync4,
13
14
  mkdirSync,
14
15
  writeFileSync,
15
16
  readFileSync,
@@ -991,18 +992,354 @@ async function generateSkill(platform, outputDir = ".") {
991
992
  console.log(`\u2705 Skill generated successfully for ${platform}`);
992
993
  }
993
994
 
994
- // src/cli.ts
995
+ // src/capability-generator.ts
996
+ import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
997
+ import { existsSync as existsSync3 } from "fs";
998
+ import { join as join5, dirname as dirname3 } from "path";
999
+ import { fileURLToPath as fileURLToPath3 } from "url";
1000
+ import yaml from "js-yaml";
995
1001
  var __filename3 = fileURLToPath3(import.meta.url);
996
1002
  var __dirname3 = dirname3(__filename3);
997
- var isLocal = existsSync3(join5(__dirname3, "../../core/dist/index.js"));
1003
+ var SUPPORTED_CAPABILITIES = [
1004
+ "thinking",
1005
+ "coding",
1006
+ "research"
1007
+ ];
1008
+ var CapabilityGenerator = class {
1009
+ /**
1010
+ * Concrete orchestration: for each provided capability, resolve the output
1011
+ * path, render the file, then write (or skip if it exists and `!force`).
1012
+ * Finally, merge the matching `capability_models` entries into
1013
+ * `.vibe/config.yaml` (target-agnostic; lives in the base).
1014
+ */
1015
+ async generate(opts) {
1016
+ const { projectPath, models, force = false } = opts;
1017
+ const generatedFiles = [];
1018
+ const skippedFiles = [];
1019
+ for (const capability of SUPPORTED_CAPABILITIES) {
1020
+ const model = models[capability];
1021
+ if (!model) {
1022
+ continue;
1023
+ }
1024
+ const targetPath = this.getOutputPath(capability, projectPath);
1025
+ const content = await this.renderCapabilityFile(capability, model);
1026
+ if (existsSync3(targetPath) && !force) {
1027
+ skippedFiles.push(targetPath);
1028
+ continue;
1029
+ }
1030
+ await mkdir3(dirname3(targetPath), { recursive: true });
1031
+ await writeFile3(targetPath, content, "utf-8");
1032
+ generatedFiles.push(targetPath);
1033
+ }
1034
+ const configPath = join5(projectPath, ".vibe", "config.yaml");
1035
+ const configUpdated = await mergeCapabilityModels(configPath, models);
1036
+ return { generatedFiles, skippedFiles, configUpdated, configPath };
1037
+ }
1038
+ };
1039
+ async function mergeCapabilityModels(configPath, models) {
1040
+ const newEntries = {};
1041
+ for (const capability of SUPPORTED_CAPABILITIES) {
1042
+ const model = models[capability];
1043
+ if (model) {
1044
+ newEntries[capability] = { model, agent: capability };
1045
+ }
1046
+ }
1047
+ if (Object.keys(newEntries).length === 0) {
1048
+ return false;
1049
+ }
1050
+ let existingConfig = {};
1051
+ let configExisted = false;
1052
+ if (existsSync3(configPath)) {
1053
+ configExisted = true;
1054
+ const projectRoot = dirname3(dirname3(configPath));
1055
+ const loaded = ConfigManager.loadProjectConfig(projectRoot);
1056
+ if (loaded !== null) {
1057
+ existingConfig = loaded;
1058
+ } else {
1059
+ const existingRaw = await readFile3(configPath, "utf-8");
1060
+ const parsed = yaml.load(existingRaw);
1061
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
1062
+ existingConfig = parsed;
1063
+ }
1064
+ }
1065
+ }
1066
+ const mergedConfig = {
1067
+ ...existingConfig,
1068
+ capability_models: {
1069
+ ...existingConfig.capability_models,
1070
+ ...newEntries
1071
+ }
1072
+ };
1073
+ const serialized = yaml.dump(mergedConfig, { noRefs: true, sortKeys: false });
1074
+ if (configExisted) {
1075
+ const existingSerialized = yaml.dump(existingConfig, {
1076
+ noRefs: true,
1077
+ sortKeys: false
1078
+ });
1079
+ if (existingSerialized === serialized) {
1080
+ return false;
1081
+ }
1082
+ }
1083
+ await mkdir3(dirname3(configPath), { recursive: true });
1084
+ await writeFile3(configPath, serialized, "utf-8");
1085
+ return true;
1086
+ }
1087
+ function resolveOpencodeTemplatePath(capability) {
1088
+ const filename = `${capability}.md.tmpl`;
1089
+ const possiblePaths = [
1090
+ // From src/ in dev (vitest): <cli>/resources/templates/opencode-agents/<file>
1091
+ join5(
1092
+ __dirname3,
1093
+ "..",
1094
+ "resources",
1095
+ "templates",
1096
+ "opencode-agents",
1097
+ filename
1098
+ ),
1099
+ // From dist/ at runtime: <cli>/resources/templates/opencode-agents/<file>
1100
+ join5(
1101
+ __dirname3,
1102
+ "..",
1103
+ "..",
1104
+ "resources",
1105
+ "templates",
1106
+ "opencode-agents",
1107
+ filename
1108
+ ),
1109
+ // From dist/cli/ at runtime (alt bundled layout)
1110
+ join5(
1111
+ __dirname3,
1112
+ "..",
1113
+ "..",
1114
+ "..",
1115
+ "resources",
1116
+ "templates",
1117
+ "opencode-agents",
1118
+ filename
1119
+ ),
1120
+ // Root canonical source of truth
1121
+ join5(
1122
+ __dirname3,
1123
+ "..",
1124
+ "..",
1125
+ "..",
1126
+ "..",
1127
+ "resources",
1128
+ "templates",
1129
+ "opencode-agents",
1130
+ filename
1131
+ ),
1132
+ // From core package resources
1133
+ join5(
1134
+ __dirname3,
1135
+ "..",
1136
+ "..",
1137
+ "core",
1138
+ "resources",
1139
+ "templates",
1140
+ "opencode-agents",
1141
+ filename
1142
+ )
1143
+ ];
1144
+ for (const candidate of possiblePaths) {
1145
+ if (existsSync3(candidate)) {
1146
+ return candidate;
1147
+ }
1148
+ }
1149
+ throw new Error(
1150
+ `Capability template not found: ${filename}. Searched: ${possiblePaths.join(", ")}`
1151
+ );
1152
+ }
1153
+ function renderOpencodeTemplate(content, capability, model) {
1154
+ return content.replace(/\$\{capability\}/g, capability).replace(/\$\{model\}/g, model);
1155
+ }
1156
+ var OpencodeCapabilityGenerator = class extends CapabilityGenerator {
1157
+ name = "opencode";
1158
+ description = "Generate .opencode/agents/<capability>.md (mode: subagent, model pinned)";
1159
+ getOutputPath(capability, projectPath) {
1160
+ return join5(projectPath, ".opencode", "agents", `${capability}.md`);
1161
+ }
1162
+ async renderCapabilityFile(capability, model) {
1163
+ const templatePath = resolveOpencodeTemplatePath(capability);
1164
+ const templateContent = await readFile3(templatePath, "utf-8");
1165
+ return renderOpencodeTemplate(templateContent, capability, model);
1166
+ }
1167
+ };
1168
+ function buildNotYetSupportedError(target) {
1169
+ return new Error(
1170
+ `Capability generation for ${target} is not yet supported \u2014 see \`setup capabilities --help\``
1171
+ );
1172
+ }
1173
+ var KiroCapabilityGenerator = class extends CapabilityGenerator {
1174
+ name = "kiro";
1175
+ description = "Not yet supported for kiro \u2014 see `setup capabilities --help`";
1176
+ getOutputPath() {
1177
+ throw buildNotYetSupportedError(this.name);
1178
+ }
1179
+ renderCapabilityFile() {
1180
+ return Promise.reject(buildNotYetSupportedError(this.name));
1181
+ }
1182
+ };
1183
+ var ClaudeCapabilityGenerator = class extends CapabilityGenerator {
1184
+ name = "claude";
1185
+ description = "Not yet supported for claude \u2014 see `setup capabilities --help`";
1186
+ getOutputPath() {
1187
+ throw buildNotYetSupportedError(this.name);
1188
+ }
1189
+ renderCapabilityFile() {
1190
+ return Promise.reject(buildNotYetSupportedError(this.name));
1191
+ }
1192
+ };
1193
+ var GeminiCapabilityGenerator = class extends CapabilityGenerator {
1194
+ name = "gemini";
1195
+ description = "Not yet supported for gemini \u2014 see `setup capabilities --help`";
1196
+ getOutputPath() {
1197
+ throw buildNotYetSupportedError(this.name);
1198
+ }
1199
+ renderCapabilityFile() {
1200
+ return Promise.reject(buildNotYetSupportedError(this.name));
1201
+ }
1202
+ };
1203
+ var VSCodeCapabilityGenerator = class extends CapabilityGenerator {
1204
+ name = "vscode";
1205
+ description = "Not yet supported for vscode \u2014 see `setup capabilities --help`";
1206
+ getOutputPath() {
1207
+ throw buildNotYetSupportedError(this.name);
1208
+ }
1209
+ renderCapabilityFile() {
1210
+ return Promise.reject(buildNotYetSupportedError(this.name));
1211
+ }
1212
+ };
1213
+ var GithubCopilotCapabilityGenerator = class extends CapabilityGenerator {
1214
+ name = "github-copilot";
1215
+ description = "Not yet supported for github-copilot \u2014 see `setup capabilities --help`";
1216
+ getOutputPath() {
1217
+ throw buildNotYetSupportedError(this.name);
1218
+ }
1219
+ renderCapabilityFile() {
1220
+ return Promise.reject(buildNotYetSupportedError(this.name));
1221
+ }
1222
+ };
1223
+ var CapabilityGeneratorRegistry = class {
1224
+ static generators = /* @__PURE__ */ new Map();
1225
+ /**
1226
+ * Register a generator with its metadata.
1227
+ */
1228
+ static register(metadata) {
1229
+ this.generators.set(metadata.name.toLowerCase(), metadata);
1230
+ }
1231
+ /**
1232
+ * Create a generator instance by name.
1233
+ *
1234
+ * - Throws `Unknown capability target: ...` when the name is not
1235
+ * registered at all.
1236
+ * - Throws `Capability generation for <target> is not yet supported` when
1237
+ * the name is registered but `supported: false`.
1238
+ * - Otherwise returns a fresh `CapabilityGenerator` instance.
1239
+ */
1240
+ static createGenerator(name) {
1241
+ const metadata = this.generators.get(name.toLowerCase());
1242
+ if (!metadata) {
1243
+ const supported = this.getSupportedNames();
1244
+ throw new Error(
1245
+ `Unknown capability target: ${name}. Supported: ${supported.join(", ")}`
1246
+ );
1247
+ }
1248
+ if (!metadata.supported) {
1249
+ throw new Error(
1250
+ `Capability generation for ${metadata.name} is not yet supported \u2014 see \`setup capabilities --help\``
1251
+ );
1252
+ }
1253
+ return new metadata.generatorClass();
1254
+ }
1255
+ /**
1256
+ * Get all registered generators (including unsupported stubs).
1257
+ */
1258
+ static getAllGenerators() {
1259
+ return Array.from(this.generators.values());
1260
+ }
1261
+ /**
1262
+ * Get the names of fully-supported generators (excludes stubs).
1263
+ */
1264
+ static getSupportedNames() {
1265
+ return this.getAllGenerators().filter((g) => g.supported).map((g) => g.name);
1266
+ }
1267
+ /**
1268
+ * Get formatted help text for all registered generators, with a status
1269
+ * indicator (✅ supported / ⏳ not yet supported) and a padded name column
1270
+ * so the descriptions line up as the list grows.
1271
+ */
1272
+ static getHelpText() {
1273
+ const generators = this.getAllGenerators();
1274
+ if (generators.length === 0) {
1275
+ return "";
1276
+ }
1277
+ const maxNameLength = Math.max(...generators.map((g) => g.name.length));
1278
+ return generators.map((g) => {
1279
+ const icon = g.supported ? "\u2705" : "\u23F3";
1280
+ const paddedName = g.name.padEnd(maxNameLength + 2, " ");
1281
+ return `${icon} ${paddedName}${g.description}`;
1282
+ }).join("\n");
1283
+ }
1284
+ /**
1285
+ * Check if a generator is registered by name.
1286
+ */
1287
+ static exists(name) {
1288
+ return this.generators.has(name.toLowerCase());
1289
+ }
1290
+ };
1291
+ CapabilityGeneratorRegistry.register({
1292
+ name: "opencode",
1293
+ description: "Generate .opencode/agents/<capability>.md (mode: subagent, model pinned)",
1294
+ generatorClass: OpencodeCapabilityGenerator,
1295
+ supported: true
1296
+ });
1297
+ CapabilityGeneratorRegistry.register({
1298
+ name: "kiro",
1299
+ description: "Not yet supported for kiro \u2014 see `setup capabilities --help`",
1300
+ generatorClass: KiroCapabilityGenerator,
1301
+ supported: false
1302
+ });
1303
+ CapabilityGeneratorRegistry.register({
1304
+ name: "claude",
1305
+ description: "Not yet supported for claude \u2014 see `setup capabilities --help`",
1306
+ generatorClass: ClaudeCapabilityGenerator,
1307
+ supported: false
1308
+ });
1309
+ CapabilityGeneratorRegistry.register({
1310
+ name: "gemini",
1311
+ description: "Not yet supported for gemini \u2014 see `setup capabilities --help`",
1312
+ generatorClass: GeminiCapabilityGenerator,
1313
+ supported: false
1314
+ });
1315
+ CapabilityGeneratorRegistry.register({
1316
+ name: "vscode",
1317
+ description: "Not yet supported for vscode \u2014 see `setup capabilities --help`",
1318
+ generatorClass: VSCodeCapabilityGenerator,
1319
+ supported: false
1320
+ });
1321
+ CapabilityGeneratorRegistry.register({
1322
+ name: "github-copilot",
1323
+ description: "Not yet supported for github-copilot \u2014 see `setup capabilities --help`",
1324
+ generatorClass: GithubCopilotCapabilityGenerator,
1325
+ supported: false
1326
+ });
1327
+ function generateCapabilities(target, opts) {
1328
+ return CapabilityGeneratorRegistry.createGenerator(target).generate(opts);
1329
+ }
1330
+
1331
+ // src/cli.ts
1332
+ var __filename4 = fileURLToPath4(import.meta.url);
1333
+ var __dirname4 = dirname4(__filename4);
1334
+ var isLocal = existsSync4(join6(__dirname4, "../../core/dist/index.js"));
998
1335
  var generateSystemPrompt2;
999
1336
  var StateMachineLoader2;
1000
1337
  if (isLocal) {
1001
- const coreModule = await import("./dist-TDV3DJ2J.js");
1338
+ const coreModule = await import("./dist-ZTAPC4IK.js");
1002
1339
  generateSystemPrompt2 = coreModule.generateSystemPrompt;
1003
1340
  StateMachineLoader2 = coreModule.StateMachineLoader;
1004
1341
  } else {
1005
- const coreModule = await import("./dist-TDV3DJ2J.js");
1342
+ const coreModule = await import("./dist-ZTAPC4IK.js");
1006
1343
  generateSystemPrompt2 = coreModule.generateSystemPrompt;
1007
1344
  StateMachineLoader2 = coreModule.StateMachineLoader;
1008
1345
  }
@@ -1020,7 +1357,7 @@ function parseFlag(args, flag) {
1020
1357
  }
1021
1358
  async function parseCliArgs() {
1022
1359
  const args = process.argv.slice(2);
1023
- if (args.includes("--help") || args.includes("-h")) {
1360
+ if (args[0] === "--help" || args[0] === "-h") {
1024
1361
  showHelp();
1025
1362
  return { shouldExit: true };
1026
1363
  }
@@ -1030,6 +1367,9 @@ async function parseCliArgs() {
1030
1367
  if (subcommand === "list") {
1031
1368
  handleSetupList();
1032
1369
  return { shouldExit: true };
1370
+ } else if (subcommand === "capabilities") {
1371
+ await handleSetupCapabilities(args.slice(2));
1372
+ return { shouldExit: true };
1033
1373
  } else if (subcommand) {
1034
1374
  const mode = parseFlag(args, "--mode") ?? "config";
1035
1375
  if (mode !== "skill" && mode !== "config") {
@@ -1042,6 +1382,9 @@ async function parseCliArgs() {
1042
1382
  console.error("\u274C Error: setup requires a target");
1043
1383
  console.error("Usage: setup <target> [--mode config|skill]");
1044
1384
  console.error(" setup list");
1385
+ console.error(
1386
+ " setup capabilities <target> [--model-thinking M] [--model-coding M] [--model-research M] [--force]"
1387
+ );
1045
1388
  process.exit(1);
1046
1389
  }
1047
1390
  }
@@ -1201,8 +1544,8 @@ function handleWorkflowCopy(sourceWorkflow, customName) {
1201
1544
  process.exit(1);
1202
1545
  }
1203
1546
  const possibleSourcePaths = [
1204
- join5(
1205
- __dirname3,
1547
+ join6(
1548
+ __dirname4,
1206
1549
  "..",
1207
1550
  "..",
1208
1551
  "..",
@@ -1210,8 +1553,8 @@ function handleWorkflowCopy(sourceWorkflow, customName) {
1210
1553
  "workflows",
1211
1554
  `${sourceWorkflow}.yaml`
1212
1555
  ),
1213
- join5(
1214
- __dirname3,
1556
+ join6(
1557
+ __dirname4,
1215
1558
  "..",
1216
1559
  "..",
1217
1560
  "core",
@@ -1219,28 +1562,28 @@ function handleWorkflowCopy(sourceWorkflow, customName) {
1219
1562
  "workflows",
1220
1563
  `${sourceWorkflow}.yaml`
1221
1564
  ),
1222
- join5(process.cwd(), "resources", "workflows", `${sourceWorkflow}.yaml`)
1565
+ join6(process.cwd(), "resources", "workflows", `${sourceWorkflow}.yaml`)
1223
1566
  ];
1224
- const foundPath = possibleSourcePaths.find((p) => existsSync3(p));
1567
+ const foundPath = possibleSourcePaths.find((p) => existsSync4(p));
1225
1568
  if (!foundPath) {
1226
1569
  console.error(`\u274C Could not find source workflow: ${sourceWorkflow}`);
1227
1570
  process.exit(1);
1228
1571
  }
1229
1572
  const sourceContent = readFileSync(foundPath, "utf8");
1230
- const vibeDir = join5(process.cwd(), ".vibe");
1231
- const workflowsDir = join5(vibeDir, "workflows");
1232
- if (!existsSync3(vibeDir)) {
1573
+ const vibeDir = join6(process.cwd(), ".vibe");
1574
+ const workflowsDir = join6(vibeDir, "workflows");
1575
+ if (!existsSync4(vibeDir)) {
1233
1576
  mkdirSync(vibeDir, { recursive: true });
1234
1577
  }
1235
- if (!existsSync3(workflowsDir)) {
1578
+ if (!existsSync4(workflowsDir)) {
1236
1579
  mkdirSync(workflowsDir, { recursive: true });
1237
1580
  }
1238
1581
  const customContent = sourceContent.replace(
1239
1582
  new RegExp(`name: '${sourceWorkflow}'`, "g"),
1240
1583
  `name: '${customName}'`
1241
1584
  );
1242
- const workflowPath = join5(workflowsDir, `${customName}.yaml`);
1243
- if (existsSync3(workflowPath)) {
1585
+ const workflowPath = join6(workflowsDir, `${customName}.yaml`);
1586
+ if (existsSync4(workflowPath)) {
1244
1587
  console.error(
1245
1588
  `\u274C Workflow '${customName}' already exists at ${workflowPath}`
1246
1589
  );
@@ -1291,6 +1634,97 @@ async function handleSetup(target, mode) {
1291
1634
  process.exit(1);
1292
1635
  }
1293
1636
  }
1637
+ function printSetupCapabilitiesHelp() {
1638
+ console.log(`
1639
+ setup capabilities <target> [flags]
1640
+
1641
+ Wire up capability-routed subagents for a target IDE/CLI and merge the
1642
+ matching \`capability_models\` entries into \`.vibe/config.yaml\`.
1643
+
1644
+ FLAGS:
1645
+ --model-thinking <model> Set the model for the thinking agent
1646
+ --model-coding <model> Set the model for the coding agent
1647
+ --model-research <model> Set the model for the research agent
1648
+ --force Overwrite existing per-target agent files
1649
+ --help, -h Show this help message
1650
+
1651
+ TARGETS:
1652
+ ${CapabilityGeneratorRegistry.getHelpText().split("\n").map((line) => ` ${line}`).join("\n")}
1653
+
1654
+ USAGE:
1655
+ setup capabilities opencode --model-thinking anthropic/claude-opus-4-7 --model-coding anthropic/claude-sonnet-4-5 --model-research anthropic/claude-haiku-4-5
1656
+
1657
+ Only 'opencode' is currently implemented. Other targets listed above will
1658
+ throw a "not yet supported" error and exit non-zero.
1659
+ `);
1660
+ }
1661
+ async function handleSetupCapabilities(args) {
1662
+ if (args[0] === "--help" || args[0] === "-h") {
1663
+ printSetupCapabilitiesHelp();
1664
+ return;
1665
+ }
1666
+ if (args.length === 0 || args[0].startsWith("--")) {
1667
+ console.error("\u274C Error: setup capabilities requires a <target>");
1668
+ console.error(
1669
+ "Usage: setup capabilities <target> [--model-thinking M] [--model-coding M] [--model-research M] [--force]"
1670
+ );
1671
+ console.error(
1672
+ `Supported targets: ${CapabilityGeneratorRegistry.getSupportedNames().join(", ")}`
1673
+ );
1674
+ console.error("Run `setup capabilities --help` for the full target list.");
1675
+ process.exit(1);
1676
+ }
1677
+ const target = args[0];
1678
+ const flagArgs = args.slice(1);
1679
+ const thinking = parseFlag(flagArgs, "--model-thinking");
1680
+ const coding = parseFlag(flagArgs, "--model-coding");
1681
+ const research = parseFlag(flagArgs, "--model-research");
1682
+ const force = flagArgs.includes("--force");
1683
+ const models = {};
1684
+ if (thinking !== void 0) models.thinking = thinking;
1685
+ if (coding !== void 0) models.coding = coding;
1686
+ if (research !== void 0) models.research = research;
1687
+ if (Object.keys(models).length === 0) {
1688
+ console.error(
1689
+ "\u274C Error: setup capabilities requires at least one --model-* flag"
1690
+ );
1691
+ console.error(
1692
+ "Usage: setup capabilities <target> [--model-thinking M] [--model-coding M] [--model-research M] [--force]"
1693
+ );
1694
+ process.exit(1);
1695
+ }
1696
+ for (const [capability, value] of Object.entries(models)) {
1697
+ if (value.trim() === "") {
1698
+ console.error(
1699
+ `\u274C Error: --model-${capability} must be a non-empty string`
1700
+ );
1701
+ process.exit(1);
1702
+ }
1703
+ }
1704
+ try {
1705
+ const result = await generateCapabilities(target, {
1706
+ projectPath: process.cwd(),
1707
+ models,
1708
+ force
1709
+ });
1710
+ for (const file of result.generatedFiles) {
1711
+ console.log(`\u2705 Generated: ${file}`);
1712
+ }
1713
+ for (const file of result.skippedFiles) {
1714
+ console.log(
1715
+ `\u23ED\uFE0F Skipped: ${file} (already exists; re-run with --force to overwrite)`
1716
+ );
1717
+ }
1718
+ if (result.configUpdated) {
1719
+ console.log(`\u2705 Config updated: ${result.configPath}`);
1720
+ } else {
1721
+ console.log(`\u2139\uFE0F Config unchanged: ${result.configPath}`);
1722
+ }
1723
+ } catch (error) {
1724
+ console.error(`\u274C Failed: ${error.message}`);
1725
+ process.exit(1);
1726
+ }
1727
+ }
1294
1728
  function handleSetupList() {
1295
1729
  const skillTargets = SkillGeneratorRegistry.getGeneratorNames();
1296
1730
  const configTargets = GeneratorRegistry.getGeneratorNames();
@@ -1316,12 +1750,12 @@ function handleSetupList() {
1316
1750
  function handleCrowdList() {
1317
1751
  try {
1318
1752
  const possibleAgentsPaths = [
1319
- join5(__dirname3, "..", "..", "..", "resources", "agents"),
1320
- join5(__dirname3, "..", "..", "core", "resources", "agents")
1753
+ join6(__dirname4, "..", "..", "..", "resources", "agents"),
1754
+ join6(__dirname4, "..", "..", "core", "resources", "agents")
1321
1755
  ];
1322
1756
  let agentsDir = null;
1323
1757
  for (const path of possibleAgentsPaths) {
1324
- if (existsSync3(path)) {
1758
+ if (existsSync4(path)) {
1325
1759
  agentsDir = path;
1326
1760
  break;
1327
1761
  }
@@ -1339,7 +1773,7 @@ function handleCrowdList() {
1339
1773
  }
1340
1774
  console.log("\u{1F4CB} Available crowd agent configurations:\n");
1341
1775
  for (const file of files) {
1342
- const agentPath = join5(agentsDir, file);
1776
+ const agentPath = join6(agentsDir, file);
1343
1777
  const content = readFileSync(agentPath, "utf8");
1344
1778
  const nameMatch = content.match(/^name:\s*(.+)$/m);
1345
1779
  const displayNameMatch = content.match(/^displayName:\s*(.+)$/m);
@@ -1358,12 +1792,12 @@ function handleCrowdList() {
1358
1792
  function handleCrowdCopy(outputDir) {
1359
1793
  try {
1360
1794
  const possibleAgentsPaths = [
1361
- join5(__dirname3, "..", "..", "..", "resources", "agents"),
1362
- join5(__dirname3, "..", "..", "core", "resources", "agents")
1795
+ join6(__dirname4, "..", "..", "..", "resources", "agents"),
1796
+ join6(__dirname4, "..", "..", "core", "resources", "agents")
1363
1797
  ];
1364
1798
  let sourceAgentsDir = null;
1365
1799
  for (const path of possibleAgentsPaths) {
1366
- if (existsSync3(path)) {
1800
+ if (existsSync4(path)) {
1367
1801
  sourceAgentsDir = path;
1368
1802
  break;
1369
1803
  }
@@ -1372,8 +1806,8 @@ function handleCrowdCopy(outputDir) {
1372
1806
  console.error("\u274C Could not find source agents directory");
1373
1807
  process.exit(1);
1374
1808
  }
1375
- const targetDir = outputDir || join5(process.cwd(), ".crowd", "agents");
1376
- if (!existsSync3(targetDir)) {
1809
+ const targetDir = outputDir || join6(process.cwd(), ".crowd", "agents");
1810
+ if (!existsSync4(targetDir)) {
1377
1811
  mkdirSync(targetDir, { recursive: true });
1378
1812
  }
1379
1813
  const files = readdirSync(sourceAgentsDir).filter(
@@ -1390,9 +1824,9 @@ function handleCrowdCopy(outputDir) {
1390
1824
  let copiedCount = 0;
1391
1825
  let skippedCount = 0;
1392
1826
  for (const file of files) {
1393
- const sourcePath = join5(sourceAgentsDir, file);
1394
- const targetPath = join5(targetDir, file);
1395
- if (existsSync3(targetPath)) {
1827
+ const sourcePath = join6(sourceAgentsDir, file);
1828
+ const targetPath = join6(targetDir, file);
1829
+ if (existsSync4(targetPath)) {
1396
1830
  console.log(`\u23ED\uFE0F ${file} (already exists, skipping)`);
1397
1831
  skippedCount++;
1398
1832
  } else {
@@ -1430,6 +1864,7 @@ SETUP COMMANDS:
1430
1864
  setup <target> --mode config Generate full agent configuration
1431
1865
  setup <target> --mode skill Generate skill files only
1432
1866
  setup list List available targets
1867
+ setup capabilities <target> Wire up capability-routed agents (see --help)
1433
1868
 
1434
1869
  WORKFLOW COMMANDS:
1435
1870
  workflow list List available workflows