@codemcp/workflows 6.20.2 → 6.22.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.
- package/package.json +2 -2
- package/packages/cli/dist/{chunk-4N42FFJE.js → chunk-QMPDZD7D.js} +117 -2674
- package/packages/cli/dist/{cli-MFHC7UWY.js → cli-CY4PLNWR.js} +475 -34
- package/packages/cli/dist/{dist-ISN3FRV4.js → dist-6BKGI5U7.js} +91 -8
- package/packages/cli/dist/{dist-TDV3DJ2J.js → dist-S4HQ3JQN.js} +3 -1
- package/packages/cli/dist/index.js +2 -2
- package/packages/cli/package.json +5 -2
- package/packages/cli/resources/templates/opencode-agents/coding.md.tmpl +13 -0
- package/packages/cli/resources/templates/opencode-agents/research.md.tmpl +13 -0
- package/packages/cli/resources/templates/opencode-agents/thinking.md.tmpl +13 -0
- package/packages/cli/resources/workflows/bugfix.yaml +6 -0
- package/packages/cli/resources/workflows/epcc.yaml +3 -0
- package/packages/cli/resources/workflows/greenfield.yaml +3 -0
- package/packages/cli/resources/workflows/pr-review.yaml +2 -0
- package/packages/cli/resources/workflows/qrspi.yaml +5 -0
- package/packages/cli/resources/workflows/tdd.yaml +3 -0
- package/packages/cli/resources/workflows/waterfall.yaml +3 -0
- package/packages/core/dist/capability-hint.d.ts +28 -0
- package/packages/core/dist/capability-hint.js +52 -0
- package/packages/core/dist/capability-hint.js.map +1 -0
- package/packages/core/dist/config-manager.d.ts +19 -0
- package/packages/core/dist/config-manager.js +26 -0
- package/packages/core/dist/config-manager.js.map +1 -1
- package/packages/core/dist/index.d.ts +1 -0
- package/packages/core/dist/index.js +1 -0
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/instruction-generator.js +7 -1
- package/packages/core/dist/instruction-generator.js.map +1 -1
- package/packages/core/dist/interfaces/instruction-generator.interface.d.ts +14 -0
- package/packages/core/dist/state-machine-types.d.ts +7 -0
- package/packages/core/dist/system-prompt-generator.js +26 -4
- package/packages/core/dist/system-prompt-generator.js.map +1 -1
- package/packages/core/package.json +1 -1
- package/packages/core/resources/templates/opencode-agents/coding.md.tmpl +13 -0
- package/packages/core/resources/templates/opencode-agents/research.md.tmpl +13 -0
- package/packages/core/resources/templates/opencode-agents/thinking.md.tmpl +13 -0
- package/packages/core/resources/workflows/bugfix.yaml +6 -0
- package/packages/core/resources/workflows/epcc.yaml +3 -0
- package/packages/core/resources/workflows/greenfield.yaml +3 -0
- package/packages/core/resources/workflows/pr-review.yaml +2 -0
- package/packages/core/resources/workflows/qrspi.yaml +5 -0
- package/packages/core/resources/workflows/tdd.yaml +3 -0
- package/packages/core/resources/workflows/waterfall.yaml +3 -0
- package/packages/docs/.vitepress/dist/404.html +1 -1
- package/packages/docs/.vitepress/dist/assets/user_capability-routing.md.DbNKvMiS.js +15 -0
- package/packages/docs/.vitepress/dist/assets/user_capability-routing.md.DbNKvMiS.lean.js +1 -0
- package/packages/docs/.vitepress/dist/dev/ARCHITECTURE.html +2 -2
- package/packages/docs/.vitepress/dist/dev/DEVELOPMENT.html +2 -2
- package/packages/docs/.vitepress/dist/dev/LOGGING.html +2 -2
- package/packages/docs/.vitepress/dist/dev/PUBLISHING.html +2 -2
- package/packages/docs/.vitepress/dist/hashmap.json +1 -1
- package/packages/docs/.vitepress/dist/index.html +2 -2
- package/packages/docs/.vitepress/dist/user/advanced-engineering.html +3 -3
- package/packages/docs/.vitepress/dist/user/agent-setup.html +3 -3
- package/packages/docs/.vitepress/dist/user/beads-integration.html +2 -2
- package/packages/docs/.vitepress/dist/user/capability-routing.html +40 -0
- package/packages/docs/.vitepress/dist/user/crowd-mcp-integration.html +2 -2
- package/packages/docs/.vitepress/dist/user/custom-workflows.html +2 -2
- package/packages/docs/.vitepress/dist/user/git-commit-feature.html +2 -2
- package/packages/docs/.vitepress/dist/user/how-it-works.html +2 -2
- package/packages/docs/.vitepress/dist/user/long-term-memory.html +2 -2
- package/packages/docs/.vitepress/dist/user/packaged-workflows.html +2 -2
- package/packages/docs/.vitepress/dist/user/tutorial.html +2 -2
- package/packages/docs/.vitepress/dist/user/workflow-selection.html +2 -2
- package/packages/docs/.vitepress/dist/workflows/adr.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/big-bang-conversion.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/boundary-testing.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/bugfix.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/bugfix.yaml +6 -0
- package/packages/docs/.vitepress/dist/workflows/business-analysis.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/c4-analysis.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/epcc.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/epcc.yaml +3 -0
- package/packages/docs/.vitepress/dist/workflows/game-beginner.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/greenfield.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/greenfield.yaml +3 -0
- package/packages/docs/.vitepress/dist/workflows/minor.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/posts.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/pr-review.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/pr-review.yaml +2 -0
- package/packages/docs/.vitepress/dist/workflows/qrspi.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/qrspi.yaml +5 -0
- package/packages/docs/.vitepress/dist/workflows/sdd-bugfix-crowd.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/sdd-bugfix.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/sdd-feature-crowd.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/sdd-feature.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/sdd-greenfield-crowd.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/sdd-greenfield.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/skilled-bugfix.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/skilled-epcc.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/skilled-greenfield.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/slides.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/tdd.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/tdd.yaml +3 -0
- package/packages/docs/.vitepress/dist/workflows/waterfall.html +1 -1
- package/packages/docs/.vitepress/dist/workflows/waterfall.yaml +3 -0
- package/packages/docs/.vitepress/dist/workflows.html +1 -1
- package/packages/docs/package.json +1 -1
- package/packages/mcp-server/dist/index.js +93 -8
- package/packages/mcp-server/package.json +1 -1
- package/packages/mcp-server/resources/templates/opencode-agents/coding.md.tmpl +13 -0
- package/packages/mcp-server/resources/templates/opencode-agents/research.md.tmpl +13 -0
- package/packages/mcp-server/resources/templates/opencode-agents/thinking.md.tmpl +13 -0
- package/packages/mcp-server/resources/workflows/bugfix.yaml +6 -0
- package/packages/mcp-server/resources/workflows/epcc.yaml +3 -0
- package/packages/mcp-server/resources/workflows/greenfield.yaml +3 -0
- package/packages/mcp-server/resources/workflows/pr-review.yaml +2 -0
- package/packages/mcp-server/resources/workflows/qrspi.yaml +5 -0
- package/packages/mcp-server/resources/workflows/tdd.yaml +3 -0
- package/packages/mcp-server/resources/workflows/waterfall.yaml +3 -0
- package/packages/opencode-plugin/dist/index.js +93 -8
- package/packages/opencode-plugin/package.json +1 -1
- package/packages/opencode-plugin/resources/templates/opencode-agents/coding.md.tmpl +13 -0
- package/packages/opencode-plugin/resources/templates/opencode-agents/research.md.tmpl +13 -0
- package/packages/opencode-plugin/resources/templates/opencode-agents/thinking.md.tmpl +13 -0
- package/packages/opencode-plugin/resources/workflows/bugfix.yaml +6 -0
- package/packages/opencode-plugin/resources/workflows/epcc.yaml +3 -0
- package/packages/opencode-plugin/resources/workflows/greenfield.yaml +3 -0
- package/packages/opencode-plugin/resources/workflows/pr-review.yaml +2 -0
- package/packages/opencode-plugin/resources/workflows/qrspi.yaml +5 -0
- package/packages/opencode-plugin/resources/workflows/tdd.yaml +3 -0
- package/packages/opencode-plugin/resources/workflows/waterfall.yaml +3 -0
- package/packages/opencode-tui-plugin/package.json +1 -1
- package/packages/visualizer/package.json +1 -1
- package/resources/state-machine-schema.json +4 -0
- package/resources/templates/opencode-agents/coding.md.tmpl +13 -0
- package/resources/templates/opencode-agents/research.md.tmpl +13 -0
- package/resources/templates/opencode-agents/thinking.md.tmpl +13 -0
- package/resources/workflows/bugfix.yaml +6 -0
- package/resources/workflows/epcc.yaml +3 -0
- package/resources/workflows/greenfield.yaml +3 -0
- package/resources/workflows/pr-review.yaml +2 -0
- package/resources/workflows/qrspi.yaml +5 -0
- package/resources/workflows/tdd.yaml +3 -0
- 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-
|
|
6
|
+
} from "./chunk-QMPDZD7D.js";
|
|
6
7
|
import "./chunk-R5U7XKVJ.js";
|
|
7
8
|
|
|
8
9
|
// src/cli.ts
|
|
9
|
-
import { fileURLToPath as
|
|
10
|
-
import { dirname as
|
|
10
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
11
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
11
12
|
import {
|
|
12
|
-
existsSync as
|
|
13
|
+
existsSync as existsSync4,
|
|
13
14
|
mkdirSync,
|
|
14
15
|
writeFileSync,
|
|
15
16
|
readFileSync,
|
|
@@ -219,11 +220,13 @@ var KiroConfigGenerator = class extends ConfigGenerator {
|
|
|
219
220
|
"knowledge",
|
|
220
221
|
"thinking",
|
|
221
222
|
"use_aws",
|
|
223
|
+
"subagent",
|
|
222
224
|
"@workflows"
|
|
223
225
|
],
|
|
224
226
|
allowedTools: [
|
|
225
227
|
"fs_read",
|
|
226
228
|
"fs_write",
|
|
229
|
+
"subagent",
|
|
227
230
|
"@workflows/whats_next",
|
|
228
231
|
"@workflows/conduct_review",
|
|
229
232
|
"@workflows/list_workflows",
|
|
@@ -245,7 +248,11 @@ var KiroConfigGenerator = class extends ConfigGenerator {
|
|
|
245
248
|
]
|
|
246
249
|
}
|
|
247
250
|
},
|
|
248
|
-
resources: [
|
|
251
|
+
resources: [
|
|
252
|
+
"file://README.md",
|
|
253
|
+
"file://.kiro/rules/**/*.md",
|
|
254
|
+
"skill://.kiro/skills/**/SKILL.md"
|
|
255
|
+
],
|
|
249
256
|
hooks: {}
|
|
250
257
|
};
|
|
251
258
|
const kiroDir = join2(outputDir, ".kiro", "agents");
|
|
@@ -991,18 +998,354 @@ async function generateSkill(platform, outputDir = ".") {
|
|
|
991
998
|
console.log(`\u2705 Skill generated successfully for ${platform}`);
|
|
992
999
|
}
|
|
993
1000
|
|
|
994
|
-
// src/
|
|
1001
|
+
// src/capability-generator.ts
|
|
1002
|
+
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
1003
|
+
import { existsSync as existsSync3 } from "fs";
|
|
1004
|
+
import { join as join5, dirname as dirname3 } from "path";
|
|
1005
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
1006
|
+
import yaml from "js-yaml";
|
|
995
1007
|
var __filename3 = fileURLToPath3(import.meta.url);
|
|
996
1008
|
var __dirname3 = dirname3(__filename3);
|
|
997
|
-
var
|
|
1009
|
+
var SUPPORTED_CAPABILITIES = [
|
|
1010
|
+
"thinking",
|
|
1011
|
+
"coding",
|
|
1012
|
+
"research"
|
|
1013
|
+
];
|
|
1014
|
+
var CapabilityGenerator = class {
|
|
1015
|
+
/**
|
|
1016
|
+
* Concrete orchestration: for each provided capability, resolve the output
|
|
1017
|
+
* path, render the file, then write (or skip if it exists and `!force`).
|
|
1018
|
+
* Finally, merge the matching `capability_models` entries into
|
|
1019
|
+
* `.vibe/config.yaml` (target-agnostic; lives in the base).
|
|
1020
|
+
*/
|
|
1021
|
+
async generate(opts) {
|
|
1022
|
+
const { projectPath, models, force = false } = opts;
|
|
1023
|
+
const generatedFiles = [];
|
|
1024
|
+
const skippedFiles = [];
|
|
1025
|
+
for (const capability of SUPPORTED_CAPABILITIES) {
|
|
1026
|
+
const model = models[capability];
|
|
1027
|
+
if (!model) {
|
|
1028
|
+
continue;
|
|
1029
|
+
}
|
|
1030
|
+
const targetPath = this.getOutputPath(capability, projectPath);
|
|
1031
|
+
const content = await this.renderCapabilityFile(capability, model);
|
|
1032
|
+
if (existsSync3(targetPath) && !force) {
|
|
1033
|
+
skippedFiles.push(targetPath);
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1036
|
+
await mkdir3(dirname3(targetPath), { recursive: true });
|
|
1037
|
+
await writeFile3(targetPath, content, "utf-8");
|
|
1038
|
+
generatedFiles.push(targetPath);
|
|
1039
|
+
}
|
|
1040
|
+
const configPath = join5(projectPath, ".vibe", "config.yaml");
|
|
1041
|
+
const configUpdated = await mergeCapabilityModels(configPath, models);
|
|
1042
|
+
return { generatedFiles, skippedFiles, configUpdated, configPath };
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
async function mergeCapabilityModels(configPath, models) {
|
|
1046
|
+
const newEntries = {};
|
|
1047
|
+
for (const capability of SUPPORTED_CAPABILITIES) {
|
|
1048
|
+
const model = models[capability];
|
|
1049
|
+
if (model) {
|
|
1050
|
+
newEntries[capability] = { model, agent: capability };
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
if (Object.keys(newEntries).length === 0) {
|
|
1054
|
+
return false;
|
|
1055
|
+
}
|
|
1056
|
+
let existingConfig = {};
|
|
1057
|
+
let configExisted = false;
|
|
1058
|
+
if (existsSync3(configPath)) {
|
|
1059
|
+
configExisted = true;
|
|
1060
|
+
const projectRoot = dirname3(dirname3(configPath));
|
|
1061
|
+
const loaded = ConfigManager.loadProjectConfig(projectRoot);
|
|
1062
|
+
if (loaded !== null) {
|
|
1063
|
+
existingConfig = loaded;
|
|
1064
|
+
} else {
|
|
1065
|
+
const existingRaw = await readFile3(configPath, "utf-8");
|
|
1066
|
+
const parsed = yaml.load(existingRaw);
|
|
1067
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
1068
|
+
existingConfig = parsed;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
const mergedConfig = {
|
|
1073
|
+
...existingConfig,
|
|
1074
|
+
capability_models: {
|
|
1075
|
+
...existingConfig.capability_models,
|
|
1076
|
+
...newEntries
|
|
1077
|
+
}
|
|
1078
|
+
};
|
|
1079
|
+
const serialized = yaml.dump(mergedConfig, { noRefs: true, sortKeys: false });
|
|
1080
|
+
if (configExisted) {
|
|
1081
|
+
const existingSerialized = yaml.dump(existingConfig, {
|
|
1082
|
+
noRefs: true,
|
|
1083
|
+
sortKeys: false
|
|
1084
|
+
});
|
|
1085
|
+
if (existingSerialized === serialized) {
|
|
1086
|
+
return false;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
await mkdir3(dirname3(configPath), { recursive: true });
|
|
1090
|
+
await writeFile3(configPath, serialized, "utf-8");
|
|
1091
|
+
return true;
|
|
1092
|
+
}
|
|
1093
|
+
function resolveOpencodeTemplatePath(capability) {
|
|
1094
|
+
const filename = `${capability}.md.tmpl`;
|
|
1095
|
+
const possiblePaths = [
|
|
1096
|
+
// From src/ in dev (vitest): <cli>/resources/templates/opencode-agents/<file>
|
|
1097
|
+
join5(
|
|
1098
|
+
__dirname3,
|
|
1099
|
+
"..",
|
|
1100
|
+
"resources",
|
|
1101
|
+
"templates",
|
|
1102
|
+
"opencode-agents",
|
|
1103
|
+
filename
|
|
1104
|
+
),
|
|
1105
|
+
// From dist/ at runtime: <cli>/resources/templates/opencode-agents/<file>
|
|
1106
|
+
join5(
|
|
1107
|
+
__dirname3,
|
|
1108
|
+
"..",
|
|
1109
|
+
"..",
|
|
1110
|
+
"resources",
|
|
1111
|
+
"templates",
|
|
1112
|
+
"opencode-agents",
|
|
1113
|
+
filename
|
|
1114
|
+
),
|
|
1115
|
+
// From dist/cli/ at runtime (alt bundled layout)
|
|
1116
|
+
join5(
|
|
1117
|
+
__dirname3,
|
|
1118
|
+
"..",
|
|
1119
|
+
"..",
|
|
1120
|
+
"..",
|
|
1121
|
+
"resources",
|
|
1122
|
+
"templates",
|
|
1123
|
+
"opencode-agents",
|
|
1124
|
+
filename
|
|
1125
|
+
),
|
|
1126
|
+
// Root canonical source of truth
|
|
1127
|
+
join5(
|
|
1128
|
+
__dirname3,
|
|
1129
|
+
"..",
|
|
1130
|
+
"..",
|
|
1131
|
+
"..",
|
|
1132
|
+
"..",
|
|
1133
|
+
"resources",
|
|
1134
|
+
"templates",
|
|
1135
|
+
"opencode-agents",
|
|
1136
|
+
filename
|
|
1137
|
+
),
|
|
1138
|
+
// From core package resources
|
|
1139
|
+
join5(
|
|
1140
|
+
__dirname3,
|
|
1141
|
+
"..",
|
|
1142
|
+
"..",
|
|
1143
|
+
"core",
|
|
1144
|
+
"resources",
|
|
1145
|
+
"templates",
|
|
1146
|
+
"opencode-agents",
|
|
1147
|
+
filename
|
|
1148
|
+
)
|
|
1149
|
+
];
|
|
1150
|
+
for (const candidate of possiblePaths) {
|
|
1151
|
+
if (existsSync3(candidate)) {
|
|
1152
|
+
return candidate;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
throw new Error(
|
|
1156
|
+
`Capability template not found: ${filename}. Searched: ${possiblePaths.join(", ")}`
|
|
1157
|
+
);
|
|
1158
|
+
}
|
|
1159
|
+
function renderOpencodeTemplate(content, capability, model) {
|
|
1160
|
+
return content.replace(/\$\{capability\}/g, capability).replace(/\$\{model\}/g, model);
|
|
1161
|
+
}
|
|
1162
|
+
var OpencodeCapabilityGenerator = class extends CapabilityGenerator {
|
|
1163
|
+
name = "opencode";
|
|
1164
|
+
description = "Generate .opencode/agents/<capability>.md (mode: subagent, model pinned)";
|
|
1165
|
+
getOutputPath(capability, projectPath) {
|
|
1166
|
+
return join5(projectPath, ".opencode", "agents", `${capability}.md`);
|
|
1167
|
+
}
|
|
1168
|
+
async renderCapabilityFile(capability, model) {
|
|
1169
|
+
const templatePath = resolveOpencodeTemplatePath(capability);
|
|
1170
|
+
const templateContent = await readFile3(templatePath, "utf-8");
|
|
1171
|
+
return renderOpencodeTemplate(templateContent, capability, model);
|
|
1172
|
+
}
|
|
1173
|
+
};
|
|
1174
|
+
function buildNotYetSupportedError(target) {
|
|
1175
|
+
return new Error(
|
|
1176
|
+
`Capability generation for ${target} is not yet supported \u2014 see \`setup capabilities --help\``
|
|
1177
|
+
);
|
|
1178
|
+
}
|
|
1179
|
+
var KiroCapabilityGenerator = class extends CapabilityGenerator {
|
|
1180
|
+
name = "kiro";
|
|
1181
|
+
description = "Not yet supported for kiro \u2014 see `setup capabilities --help`";
|
|
1182
|
+
getOutputPath() {
|
|
1183
|
+
throw buildNotYetSupportedError(this.name);
|
|
1184
|
+
}
|
|
1185
|
+
renderCapabilityFile() {
|
|
1186
|
+
return Promise.reject(buildNotYetSupportedError(this.name));
|
|
1187
|
+
}
|
|
1188
|
+
};
|
|
1189
|
+
var ClaudeCapabilityGenerator = class extends CapabilityGenerator {
|
|
1190
|
+
name = "claude";
|
|
1191
|
+
description = "Not yet supported for claude \u2014 see `setup capabilities --help`";
|
|
1192
|
+
getOutputPath() {
|
|
1193
|
+
throw buildNotYetSupportedError(this.name);
|
|
1194
|
+
}
|
|
1195
|
+
renderCapabilityFile() {
|
|
1196
|
+
return Promise.reject(buildNotYetSupportedError(this.name));
|
|
1197
|
+
}
|
|
1198
|
+
};
|
|
1199
|
+
var GeminiCapabilityGenerator = class extends CapabilityGenerator {
|
|
1200
|
+
name = "gemini";
|
|
1201
|
+
description = "Not yet supported for gemini \u2014 see `setup capabilities --help`";
|
|
1202
|
+
getOutputPath() {
|
|
1203
|
+
throw buildNotYetSupportedError(this.name);
|
|
1204
|
+
}
|
|
1205
|
+
renderCapabilityFile() {
|
|
1206
|
+
return Promise.reject(buildNotYetSupportedError(this.name));
|
|
1207
|
+
}
|
|
1208
|
+
};
|
|
1209
|
+
var VSCodeCapabilityGenerator = class extends CapabilityGenerator {
|
|
1210
|
+
name = "vscode";
|
|
1211
|
+
description = "Not yet supported for vscode \u2014 see `setup capabilities --help`";
|
|
1212
|
+
getOutputPath() {
|
|
1213
|
+
throw buildNotYetSupportedError(this.name);
|
|
1214
|
+
}
|
|
1215
|
+
renderCapabilityFile() {
|
|
1216
|
+
return Promise.reject(buildNotYetSupportedError(this.name));
|
|
1217
|
+
}
|
|
1218
|
+
};
|
|
1219
|
+
var GithubCopilotCapabilityGenerator = class extends CapabilityGenerator {
|
|
1220
|
+
name = "github-copilot";
|
|
1221
|
+
description = "Not yet supported for github-copilot \u2014 see `setup capabilities --help`";
|
|
1222
|
+
getOutputPath() {
|
|
1223
|
+
throw buildNotYetSupportedError(this.name);
|
|
1224
|
+
}
|
|
1225
|
+
renderCapabilityFile() {
|
|
1226
|
+
return Promise.reject(buildNotYetSupportedError(this.name));
|
|
1227
|
+
}
|
|
1228
|
+
};
|
|
1229
|
+
var CapabilityGeneratorRegistry = class {
|
|
1230
|
+
static generators = /* @__PURE__ */ new Map();
|
|
1231
|
+
/**
|
|
1232
|
+
* Register a generator with its metadata.
|
|
1233
|
+
*/
|
|
1234
|
+
static register(metadata) {
|
|
1235
|
+
this.generators.set(metadata.name.toLowerCase(), metadata);
|
|
1236
|
+
}
|
|
1237
|
+
/**
|
|
1238
|
+
* Create a generator instance by name.
|
|
1239
|
+
*
|
|
1240
|
+
* - Throws `Unknown capability target: ...` when the name is not
|
|
1241
|
+
* registered at all.
|
|
1242
|
+
* - Throws `Capability generation for <target> is not yet supported` when
|
|
1243
|
+
* the name is registered but `supported: false`.
|
|
1244
|
+
* - Otherwise returns a fresh `CapabilityGenerator` instance.
|
|
1245
|
+
*/
|
|
1246
|
+
static createGenerator(name) {
|
|
1247
|
+
const metadata = this.generators.get(name.toLowerCase());
|
|
1248
|
+
if (!metadata) {
|
|
1249
|
+
const supported = this.getSupportedNames();
|
|
1250
|
+
throw new Error(
|
|
1251
|
+
`Unknown capability target: ${name}. Supported: ${supported.join(", ")}`
|
|
1252
|
+
);
|
|
1253
|
+
}
|
|
1254
|
+
if (!metadata.supported) {
|
|
1255
|
+
throw new Error(
|
|
1256
|
+
`Capability generation for ${metadata.name} is not yet supported \u2014 see \`setup capabilities --help\``
|
|
1257
|
+
);
|
|
1258
|
+
}
|
|
1259
|
+
return new metadata.generatorClass();
|
|
1260
|
+
}
|
|
1261
|
+
/**
|
|
1262
|
+
* Get all registered generators (including unsupported stubs).
|
|
1263
|
+
*/
|
|
1264
|
+
static getAllGenerators() {
|
|
1265
|
+
return Array.from(this.generators.values());
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* Get the names of fully-supported generators (excludes stubs).
|
|
1269
|
+
*/
|
|
1270
|
+
static getSupportedNames() {
|
|
1271
|
+
return this.getAllGenerators().filter((g) => g.supported).map((g) => g.name);
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* Get formatted help text for all registered generators, with a status
|
|
1275
|
+
* indicator (✅ supported / ⏳ not yet supported) and a padded name column
|
|
1276
|
+
* so the descriptions line up as the list grows.
|
|
1277
|
+
*/
|
|
1278
|
+
static getHelpText() {
|
|
1279
|
+
const generators = this.getAllGenerators();
|
|
1280
|
+
if (generators.length === 0) {
|
|
1281
|
+
return "";
|
|
1282
|
+
}
|
|
1283
|
+
const maxNameLength = Math.max(...generators.map((g) => g.name.length));
|
|
1284
|
+
return generators.map((g) => {
|
|
1285
|
+
const icon = g.supported ? "\u2705" : "\u23F3";
|
|
1286
|
+
const paddedName = g.name.padEnd(maxNameLength + 2, " ");
|
|
1287
|
+
return `${icon} ${paddedName}${g.description}`;
|
|
1288
|
+
}).join("\n");
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Check if a generator is registered by name.
|
|
1292
|
+
*/
|
|
1293
|
+
static exists(name) {
|
|
1294
|
+
return this.generators.has(name.toLowerCase());
|
|
1295
|
+
}
|
|
1296
|
+
};
|
|
1297
|
+
CapabilityGeneratorRegistry.register({
|
|
1298
|
+
name: "opencode",
|
|
1299
|
+
description: "Generate .opencode/agents/<capability>.md (mode: subagent, model pinned)",
|
|
1300
|
+
generatorClass: OpencodeCapabilityGenerator,
|
|
1301
|
+
supported: true
|
|
1302
|
+
});
|
|
1303
|
+
CapabilityGeneratorRegistry.register({
|
|
1304
|
+
name: "kiro",
|
|
1305
|
+
description: "Not yet supported for kiro \u2014 see `setup capabilities --help`",
|
|
1306
|
+
generatorClass: KiroCapabilityGenerator,
|
|
1307
|
+
supported: false
|
|
1308
|
+
});
|
|
1309
|
+
CapabilityGeneratorRegistry.register({
|
|
1310
|
+
name: "claude",
|
|
1311
|
+
description: "Not yet supported for claude \u2014 see `setup capabilities --help`",
|
|
1312
|
+
generatorClass: ClaudeCapabilityGenerator,
|
|
1313
|
+
supported: false
|
|
1314
|
+
});
|
|
1315
|
+
CapabilityGeneratorRegistry.register({
|
|
1316
|
+
name: "gemini",
|
|
1317
|
+
description: "Not yet supported for gemini \u2014 see `setup capabilities --help`",
|
|
1318
|
+
generatorClass: GeminiCapabilityGenerator,
|
|
1319
|
+
supported: false
|
|
1320
|
+
});
|
|
1321
|
+
CapabilityGeneratorRegistry.register({
|
|
1322
|
+
name: "vscode",
|
|
1323
|
+
description: "Not yet supported for vscode \u2014 see `setup capabilities --help`",
|
|
1324
|
+
generatorClass: VSCodeCapabilityGenerator,
|
|
1325
|
+
supported: false
|
|
1326
|
+
});
|
|
1327
|
+
CapabilityGeneratorRegistry.register({
|
|
1328
|
+
name: "github-copilot",
|
|
1329
|
+
description: "Not yet supported for github-copilot \u2014 see `setup capabilities --help`",
|
|
1330
|
+
generatorClass: GithubCopilotCapabilityGenerator,
|
|
1331
|
+
supported: false
|
|
1332
|
+
});
|
|
1333
|
+
function generateCapabilities(target, opts) {
|
|
1334
|
+
return CapabilityGeneratorRegistry.createGenerator(target).generate(opts);
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
// src/cli.ts
|
|
1338
|
+
var __filename4 = fileURLToPath4(import.meta.url);
|
|
1339
|
+
var __dirname4 = dirname4(__filename4);
|
|
1340
|
+
var isLocal = existsSync4(join6(__dirname4, "../../core/dist/index.js"));
|
|
998
1341
|
var generateSystemPrompt2;
|
|
999
1342
|
var StateMachineLoader2;
|
|
1000
1343
|
if (isLocal) {
|
|
1001
|
-
const coreModule = await import("./dist-
|
|
1344
|
+
const coreModule = await import("./dist-S4HQ3JQN.js");
|
|
1002
1345
|
generateSystemPrompt2 = coreModule.generateSystemPrompt;
|
|
1003
1346
|
StateMachineLoader2 = coreModule.StateMachineLoader;
|
|
1004
1347
|
} else {
|
|
1005
|
-
const coreModule = await import("./dist-
|
|
1348
|
+
const coreModule = await import("./dist-S4HQ3JQN.js");
|
|
1006
1349
|
generateSystemPrompt2 = coreModule.generateSystemPrompt;
|
|
1007
1350
|
StateMachineLoader2 = coreModule.StateMachineLoader;
|
|
1008
1351
|
}
|
|
@@ -1020,7 +1363,7 @@ function parseFlag(args, flag) {
|
|
|
1020
1363
|
}
|
|
1021
1364
|
async function parseCliArgs() {
|
|
1022
1365
|
const args = process.argv.slice(2);
|
|
1023
|
-
if (args
|
|
1366
|
+
if (args[0] === "--help" || args[0] === "-h") {
|
|
1024
1367
|
showHelp();
|
|
1025
1368
|
return { shouldExit: true };
|
|
1026
1369
|
}
|
|
@@ -1030,6 +1373,9 @@ async function parseCliArgs() {
|
|
|
1030
1373
|
if (subcommand === "list") {
|
|
1031
1374
|
handleSetupList();
|
|
1032
1375
|
return { shouldExit: true };
|
|
1376
|
+
} else if (subcommand === "capabilities") {
|
|
1377
|
+
await handleSetupCapabilities(args.slice(2));
|
|
1378
|
+
return { shouldExit: true };
|
|
1033
1379
|
} else if (subcommand) {
|
|
1034
1380
|
const mode = parseFlag(args, "--mode") ?? "config";
|
|
1035
1381
|
if (mode !== "skill" && mode !== "config") {
|
|
@@ -1042,6 +1388,9 @@ async function parseCliArgs() {
|
|
|
1042
1388
|
console.error("\u274C Error: setup requires a target");
|
|
1043
1389
|
console.error("Usage: setup <target> [--mode config|skill]");
|
|
1044
1390
|
console.error(" setup list");
|
|
1391
|
+
console.error(
|
|
1392
|
+
" setup capabilities <target> [--model-thinking M] [--model-coding M] [--model-research M] [--force]"
|
|
1393
|
+
);
|
|
1045
1394
|
process.exit(1);
|
|
1046
1395
|
}
|
|
1047
1396
|
}
|
|
@@ -1201,8 +1550,8 @@ function handleWorkflowCopy(sourceWorkflow, customName) {
|
|
|
1201
1550
|
process.exit(1);
|
|
1202
1551
|
}
|
|
1203
1552
|
const possibleSourcePaths = [
|
|
1204
|
-
|
|
1205
|
-
|
|
1553
|
+
join6(
|
|
1554
|
+
__dirname4,
|
|
1206
1555
|
"..",
|
|
1207
1556
|
"..",
|
|
1208
1557
|
"..",
|
|
@@ -1210,8 +1559,8 @@ function handleWorkflowCopy(sourceWorkflow, customName) {
|
|
|
1210
1559
|
"workflows",
|
|
1211
1560
|
`${sourceWorkflow}.yaml`
|
|
1212
1561
|
),
|
|
1213
|
-
|
|
1214
|
-
|
|
1562
|
+
join6(
|
|
1563
|
+
__dirname4,
|
|
1215
1564
|
"..",
|
|
1216
1565
|
"..",
|
|
1217
1566
|
"core",
|
|
@@ -1219,28 +1568,28 @@ function handleWorkflowCopy(sourceWorkflow, customName) {
|
|
|
1219
1568
|
"workflows",
|
|
1220
1569
|
`${sourceWorkflow}.yaml`
|
|
1221
1570
|
),
|
|
1222
|
-
|
|
1571
|
+
join6(process.cwd(), "resources", "workflows", `${sourceWorkflow}.yaml`)
|
|
1223
1572
|
];
|
|
1224
|
-
const foundPath = possibleSourcePaths.find((p) =>
|
|
1573
|
+
const foundPath = possibleSourcePaths.find((p) => existsSync4(p));
|
|
1225
1574
|
if (!foundPath) {
|
|
1226
1575
|
console.error(`\u274C Could not find source workflow: ${sourceWorkflow}`);
|
|
1227
1576
|
process.exit(1);
|
|
1228
1577
|
}
|
|
1229
1578
|
const sourceContent = readFileSync(foundPath, "utf8");
|
|
1230
|
-
const vibeDir =
|
|
1231
|
-
const workflowsDir =
|
|
1232
|
-
if (!
|
|
1579
|
+
const vibeDir = join6(process.cwd(), ".vibe");
|
|
1580
|
+
const workflowsDir = join6(vibeDir, "workflows");
|
|
1581
|
+
if (!existsSync4(vibeDir)) {
|
|
1233
1582
|
mkdirSync(vibeDir, { recursive: true });
|
|
1234
1583
|
}
|
|
1235
|
-
if (!
|
|
1584
|
+
if (!existsSync4(workflowsDir)) {
|
|
1236
1585
|
mkdirSync(workflowsDir, { recursive: true });
|
|
1237
1586
|
}
|
|
1238
1587
|
const customContent = sourceContent.replace(
|
|
1239
1588
|
new RegExp(`name: '${sourceWorkflow}'`, "g"),
|
|
1240
1589
|
`name: '${customName}'`
|
|
1241
1590
|
);
|
|
1242
|
-
const workflowPath =
|
|
1243
|
-
if (
|
|
1591
|
+
const workflowPath = join6(workflowsDir, `${customName}.yaml`);
|
|
1592
|
+
if (existsSync4(workflowPath)) {
|
|
1244
1593
|
console.error(
|
|
1245
1594
|
`\u274C Workflow '${customName}' already exists at ${workflowPath}`
|
|
1246
1595
|
);
|
|
@@ -1291,6 +1640,97 @@ async function handleSetup(target, mode) {
|
|
|
1291
1640
|
process.exit(1);
|
|
1292
1641
|
}
|
|
1293
1642
|
}
|
|
1643
|
+
function printSetupCapabilitiesHelp() {
|
|
1644
|
+
console.log(`
|
|
1645
|
+
setup capabilities <target> [flags]
|
|
1646
|
+
|
|
1647
|
+
Wire up capability-routed subagents for a target IDE/CLI and merge the
|
|
1648
|
+
matching \`capability_models\` entries into \`.vibe/config.yaml\`.
|
|
1649
|
+
|
|
1650
|
+
FLAGS:
|
|
1651
|
+
--model-thinking <model> Set the model for the thinking agent
|
|
1652
|
+
--model-coding <model> Set the model for the coding agent
|
|
1653
|
+
--model-research <model> Set the model for the research agent
|
|
1654
|
+
--force Overwrite existing per-target agent files
|
|
1655
|
+
--help, -h Show this help message
|
|
1656
|
+
|
|
1657
|
+
TARGETS:
|
|
1658
|
+
${CapabilityGeneratorRegistry.getHelpText().split("\n").map((line) => ` ${line}`).join("\n")}
|
|
1659
|
+
|
|
1660
|
+
USAGE:
|
|
1661
|
+
setup capabilities opencode --model-thinking anthropic/claude-opus-4-7 --model-coding anthropic/claude-sonnet-4-5 --model-research anthropic/claude-haiku-4-5
|
|
1662
|
+
|
|
1663
|
+
Only 'opencode' is currently implemented. Other targets listed above will
|
|
1664
|
+
throw a "not yet supported" error and exit non-zero.
|
|
1665
|
+
`);
|
|
1666
|
+
}
|
|
1667
|
+
async function handleSetupCapabilities(args) {
|
|
1668
|
+
if (args[0] === "--help" || args[0] === "-h") {
|
|
1669
|
+
printSetupCapabilitiesHelp();
|
|
1670
|
+
return;
|
|
1671
|
+
}
|
|
1672
|
+
if (args.length === 0 || args[0].startsWith("--")) {
|
|
1673
|
+
console.error("\u274C Error: setup capabilities requires a <target>");
|
|
1674
|
+
console.error(
|
|
1675
|
+
"Usage: setup capabilities <target> [--model-thinking M] [--model-coding M] [--model-research M] [--force]"
|
|
1676
|
+
);
|
|
1677
|
+
console.error(
|
|
1678
|
+
`Supported targets: ${CapabilityGeneratorRegistry.getSupportedNames().join(", ")}`
|
|
1679
|
+
);
|
|
1680
|
+
console.error("Run `setup capabilities --help` for the full target list.");
|
|
1681
|
+
process.exit(1);
|
|
1682
|
+
}
|
|
1683
|
+
const target = args[0];
|
|
1684
|
+
const flagArgs = args.slice(1);
|
|
1685
|
+
const thinking = parseFlag(flagArgs, "--model-thinking");
|
|
1686
|
+
const coding = parseFlag(flagArgs, "--model-coding");
|
|
1687
|
+
const research = parseFlag(flagArgs, "--model-research");
|
|
1688
|
+
const force = flagArgs.includes("--force");
|
|
1689
|
+
const models = {};
|
|
1690
|
+
if (thinking !== void 0) models.thinking = thinking;
|
|
1691
|
+
if (coding !== void 0) models.coding = coding;
|
|
1692
|
+
if (research !== void 0) models.research = research;
|
|
1693
|
+
if (Object.keys(models).length === 0) {
|
|
1694
|
+
console.error(
|
|
1695
|
+
"\u274C Error: setup capabilities requires at least one --model-* flag"
|
|
1696
|
+
);
|
|
1697
|
+
console.error(
|
|
1698
|
+
"Usage: setup capabilities <target> [--model-thinking M] [--model-coding M] [--model-research M] [--force]"
|
|
1699
|
+
);
|
|
1700
|
+
process.exit(1);
|
|
1701
|
+
}
|
|
1702
|
+
for (const [capability, value] of Object.entries(models)) {
|
|
1703
|
+
if (value.trim() === "") {
|
|
1704
|
+
console.error(
|
|
1705
|
+
`\u274C Error: --model-${capability} must be a non-empty string`
|
|
1706
|
+
);
|
|
1707
|
+
process.exit(1);
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
try {
|
|
1711
|
+
const result = await generateCapabilities(target, {
|
|
1712
|
+
projectPath: process.cwd(),
|
|
1713
|
+
models,
|
|
1714
|
+
force
|
|
1715
|
+
});
|
|
1716
|
+
for (const file of result.generatedFiles) {
|
|
1717
|
+
console.log(`\u2705 Generated: ${file}`);
|
|
1718
|
+
}
|
|
1719
|
+
for (const file of result.skippedFiles) {
|
|
1720
|
+
console.log(
|
|
1721
|
+
`\u23ED\uFE0F Skipped: ${file} (already exists; re-run with --force to overwrite)`
|
|
1722
|
+
);
|
|
1723
|
+
}
|
|
1724
|
+
if (result.configUpdated) {
|
|
1725
|
+
console.log(`\u2705 Config updated: ${result.configPath}`);
|
|
1726
|
+
} else {
|
|
1727
|
+
console.log(`\u2139\uFE0F Config unchanged: ${result.configPath}`);
|
|
1728
|
+
}
|
|
1729
|
+
} catch (error) {
|
|
1730
|
+
console.error(`\u274C Failed: ${error.message}`);
|
|
1731
|
+
process.exit(1);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1294
1734
|
function handleSetupList() {
|
|
1295
1735
|
const skillTargets = SkillGeneratorRegistry.getGeneratorNames();
|
|
1296
1736
|
const configTargets = GeneratorRegistry.getGeneratorNames();
|
|
@@ -1316,12 +1756,12 @@ function handleSetupList() {
|
|
|
1316
1756
|
function handleCrowdList() {
|
|
1317
1757
|
try {
|
|
1318
1758
|
const possibleAgentsPaths = [
|
|
1319
|
-
|
|
1320
|
-
|
|
1759
|
+
join6(__dirname4, "..", "..", "..", "resources", "agents"),
|
|
1760
|
+
join6(__dirname4, "..", "..", "core", "resources", "agents")
|
|
1321
1761
|
];
|
|
1322
1762
|
let agentsDir = null;
|
|
1323
1763
|
for (const path of possibleAgentsPaths) {
|
|
1324
|
-
if (
|
|
1764
|
+
if (existsSync4(path)) {
|
|
1325
1765
|
agentsDir = path;
|
|
1326
1766
|
break;
|
|
1327
1767
|
}
|
|
@@ -1339,7 +1779,7 @@ function handleCrowdList() {
|
|
|
1339
1779
|
}
|
|
1340
1780
|
console.log("\u{1F4CB} Available crowd agent configurations:\n");
|
|
1341
1781
|
for (const file of files) {
|
|
1342
|
-
const agentPath =
|
|
1782
|
+
const agentPath = join6(agentsDir, file);
|
|
1343
1783
|
const content = readFileSync(agentPath, "utf8");
|
|
1344
1784
|
const nameMatch = content.match(/^name:\s*(.+)$/m);
|
|
1345
1785
|
const displayNameMatch = content.match(/^displayName:\s*(.+)$/m);
|
|
@@ -1358,12 +1798,12 @@ function handleCrowdList() {
|
|
|
1358
1798
|
function handleCrowdCopy(outputDir) {
|
|
1359
1799
|
try {
|
|
1360
1800
|
const possibleAgentsPaths = [
|
|
1361
|
-
|
|
1362
|
-
|
|
1801
|
+
join6(__dirname4, "..", "..", "..", "resources", "agents"),
|
|
1802
|
+
join6(__dirname4, "..", "..", "core", "resources", "agents")
|
|
1363
1803
|
];
|
|
1364
1804
|
let sourceAgentsDir = null;
|
|
1365
1805
|
for (const path of possibleAgentsPaths) {
|
|
1366
|
-
if (
|
|
1806
|
+
if (existsSync4(path)) {
|
|
1367
1807
|
sourceAgentsDir = path;
|
|
1368
1808
|
break;
|
|
1369
1809
|
}
|
|
@@ -1372,8 +1812,8 @@ function handleCrowdCopy(outputDir) {
|
|
|
1372
1812
|
console.error("\u274C Could not find source agents directory");
|
|
1373
1813
|
process.exit(1);
|
|
1374
1814
|
}
|
|
1375
|
-
const targetDir = outputDir ||
|
|
1376
|
-
if (!
|
|
1815
|
+
const targetDir = outputDir || join6(process.cwd(), ".crowd", "agents");
|
|
1816
|
+
if (!existsSync4(targetDir)) {
|
|
1377
1817
|
mkdirSync(targetDir, { recursive: true });
|
|
1378
1818
|
}
|
|
1379
1819
|
const files = readdirSync(sourceAgentsDir).filter(
|
|
@@ -1390,9 +1830,9 @@ function handleCrowdCopy(outputDir) {
|
|
|
1390
1830
|
let copiedCount = 0;
|
|
1391
1831
|
let skippedCount = 0;
|
|
1392
1832
|
for (const file of files) {
|
|
1393
|
-
const sourcePath =
|
|
1394
|
-
const targetPath =
|
|
1395
|
-
if (
|
|
1833
|
+
const sourcePath = join6(sourceAgentsDir, file);
|
|
1834
|
+
const targetPath = join6(targetDir, file);
|
|
1835
|
+
if (existsSync4(targetPath)) {
|
|
1396
1836
|
console.log(`\u23ED\uFE0F ${file} (already exists, skipping)`);
|
|
1397
1837
|
skippedCount++;
|
|
1398
1838
|
} else {
|
|
@@ -1430,6 +1870,7 @@ SETUP COMMANDS:
|
|
|
1430
1870
|
setup <target> --mode config Generate full agent configuration
|
|
1431
1871
|
setup <target> --mode skill Generate skill files only
|
|
1432
1872
|
setup list List available targets
|
|
1873
|
+
setup capabilities <target> Wire up capability-routed agents (see --help)
|
|
1433
1874
|
|
|
1434
1875
|
WORKFLOW COMMANDS:
|
|
1435
1876
|
workflow list List available workflows
|