cc-codeconductor 0.2.1 → 0.2.4
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/README.md +29 -29
- package/dist/index.js +249 -17
- package/package.json +2 -1
- package/presets/claude/commands/cc/api-contract.md +58 -0
- package/presets/claude/commands/cc/db-migration.md +58 -0
- package/presets/codex/AGENTS.md +6 -0
- package/presets/codex/README.md +2 -0
- package/presets/opencode/commands/cc-api-contract.md +70 -0
- package/presets/opencode/commands/cc-db-migration.md +69 -0
- package/presets/opencode/opencode.jsonc +9 -9
- package/presets/opencode/prompts/v0.2.0/architect.md +2 -2
- package/presets/opencode/prompts/v0.2.0/docs.md +2 -2
- package/presets/opencode/prompts/v0.2.0/implementer.md +4 -4
- package/presets/opencode/prompts/v0.2.0/orchestrator.md +2 -2
- package/presets/opencode/prompts/v0.2.0/repo-explorer.md +2 -2
- package/presets/opencode/prompts/v0.2.0/reviewer.md +2 -2
- package/presets/opencode/prompts/v0.2.0/task-coach.md +2 -2
- package/presets/opencode/prompts/v0.2.0/tester.md +2 -2
- package/src/presets/manifests/claude.yml +1 -1
- package/src/presets/manifests/codex.yml +2 -2
- package/src/presets/models/claude.yml +9 -9
- package/src/presets/models/codex.yml +9 -9
- package/src/presets/models/opencode.yml +9 -9
package/README.md
CHANGED
|
@@ -130,10 +130,10 @@ bun run src/cli/main.ts --help
|
|
|
130
130
|
#### `init` — initialize CodeConductor in a project
|
|
131
131
|
|
|
132
132
|
```bash
|
|
133
|
-
codeconductor init # detect stack, write .codeconductor/config.yml
|
|
134
|
-
codeconductor init --force # overwrite existing config
|
|
135
|
-
codeconductor init --global # write to ~/.codeconductor/
|
|
136
|
-
codeconductor init --dry-run # preview without writing
|
|
133
|
+
cc-codeconductor init # detect stack, write .codeconductor/config.yml
|
|
134
|
+
cc-codeconductor init --force # overwrite existing config
|
|
135
|
+
cc-codeconductor init --global # write to ~/.codeconductor/
|
|
136
|
+
cc-codeconductor init --dry-run # preview without writing
|
|
137
137
|
```
|
|
138
138
|
|
|
139
139
|
On first run, `init` copies `council.yml` and `policy.yml` into
|
|
@@ -143,8 +143,8 @@ files. `install` reads from there first.
|
|
|
143
143
|
#### `detect` — detect project stack
|
|
144
144
|
|
|
145
145
|
```bash
|
|
146
|
-
codeconductor detect
|
|
147
|
-
codeconductor detect --output json
|
|
146
|
+
cc-codeconductor detect
|
|
147
|
+
cc-codeconductor detect --output json
|
|
148
148
|
```
|
|
149
149
|
|
|
150
150
|
Output:
|
|
@@ -159,17 +159,17 @@ Detected:
|
|
|
159
159
|
#### `install` — install council preset
|
|
160
160
|
|
|
161
161
|
```bash
|
|
162
|
-
codeconductor install council --target opencode # project-level
|
|
163
|
-
codeconductor install council --target claude
|
|
164
|
-
codeconductor install council --target codex
|
|
165
|
-
codeconductor install council --target all # all three targets
|
|
162
|
+
cc-codeconductor install council --target opencode # project-level
|
|
163
|
+
cc-codeconductor install council --target claude
|
|
164
|
+
cc-codeconductor install council --target codex
|
|
165
|
+
cc-codeconductor install council --target all # all three targets
|
|
166
166
|
|
|
167
|
-
codeconductor install council --target claude --global # write to ~/.claude/
|
|
168
|
-
codeconductor install council --target opencode --global
|
|
169
|
-
codeconductor install council --target all --global
|
|
167
|
+
cc-codeconductor install council --target claude --global # write to ~/.claude/
|
|
168
|
+
cc-codeconductor install council --target opencode --global
|
|
169
|
+
cc-codeconductor install council --target all --global
|
|
170
170
|
|
|
171
|
-
codeconductor install council --target opencode --dry-run # preview
|
|
172
|
-
codeconductor install council --target opencode --force # overwrite
|
|
171
|
+
cc-codeconductor install council --target opencode --dry-run # preview
|
|
172
|
+
cc-codeconductor install council --target opencode --force # overwrite
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
Files generated per target:
|
|
@@ -185,7 +185,7 @@ With `--global`, the same files are written under `~/` instead of `./`.
|
|
|
185
185
|
#### `doctor` — validate configuration
|
|
186
186
|
|
|
187
187
|
```bash
|
|
188
|
-
codeconductor doctor
|
|
188
|
+
cc-codeconductor doctor
|
|
189
189
|
```
|
|
190
190
|
|
|
191
191
|
Checks config exists and is valid, reports runner directory status.
|
|
@@ -193,9 +193,9 @@ Checks config exists and is valid, reports runner directory status.
|
|
|
193
193
|
#### `update` — re-apply preset
|
|
194
194
|
|
|
195
195
|
```bash
|
|
196
|
-
codeconductor update
|
|
197
|
-
codeconductor update --force
|
|
198
|
-
codeconductor update --dry-run
|
|
196
|
+
cc-codeconductor update
|
|
197
|
+
cc-codeconductor update --force
|
|
198
|
+
cc-codeconductor update --dry-run
|
|
199
199
|
```
|
|
200
200
|
|
|
201
201
|
Re-generates preset files for the `defaults.target` in your config.
|
|
@@ -238,9 +238,9 @@ src/presets/models/
|
|
|
238
238
|
|
|
239
239
|
Agent template files contain placeholders that are replaced during `install`:
|
|
240
240
|
|
|
241
|
-
| Placeholder
|
|
242
|
-
|
|
|
243
|
-
| `{{MODEL_CLAUDE}}`
|
|
241
|
+
| Placeholder | Description |
|
|
242
|
+
| -------------------- | ------------------------------- |
|
|
243
|
+
| `{{MODEL_CLAUDE}}` | Model for the Claude provider |
|
|
244
244
|
| `{{MODEL_OPENCODE}}` | Model for the OpenCode provider |
|
|
245
245
|
| `{{MODEL_CODEX}}` | Model for the Codex provider |
|
|
246
246
|
|
|
@@ -296,13 +296,13 @@ codeconductor/
|
|
|
296
296
|
|
|
297
297
|
## Roadmap
|
|
298
298
|
|
|
299
|
-
| Version | Focus
|
|
300
|
-
| ---------- |
|
|
301
|
-
| **v0.2.0** | **CLI: init, detect, install, doctor, update — shipped** ✅
|
|
302
|
-
| v0.3.0 | Next.js, FastAPI, generic presets, monorepo support
|
|
303
|
-
| v0.4.0 | Provider compatibility matrix and target sync workflows
|
|
304
|
-
| v0.5.0 | Scorecard CLI, task outcome tracking, prompt regression
|
|
305
|
-
| v1.0.0 | Stable contracts, stable routing, documented evaluation
|
|
299
|
+
| Version | Focus |
|
|
300
|
+
| ---------- | ----------------------------------------------------------- |
|
|
301
|
+
| **v0.2.0** | **CLI: init, detect, install, doctor, update — shipped** ✅ |
|
|
302
|
+
| v0.3.0 | Next.js, FastAPI, generic presets, monorepo support |
|
|
303
|
+
| v0.4.0 | Provider compatibility matrix and target sync workflows |
|
|
304
|
+
| v0.5.0 | Scorecard CLI, task outcome tracking, prompt regression |
|
|
305
|
+
| v1.0.0 | Stable contracts, stable routing, documented evaluation |
|
|
306
306
|
|
|
307
307
|
See [ROADMAP.md](ROADMAP.md) for details.
|
|
308
308
|
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
import { createRequire } from "node:module";
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -7214,15 +7215,35 @@ async function detectProject(rootDir) {
|
|
|
7214
7215
|
signals.push(...astroSignals);
|
|
7215
7216
|
frameworks.push("astro");
|
|
7216
7217
|
}
|
|
7218
|
+
const uniqueSignals = [...new Set(signals)];
|
|
7217
7219
|
return {
|
|
7218
7220
|
rootDir,
|
|
7219
7221
|
languages: [...new Set(languages)],
|
|
7220
7222
|
runtimes: [...new Set(runtimes)],
|
|
7221
7223
|
packageManagers: [...new Set(packageManagers)],
|
|
7222
7224
|
frameworks: [...new Set(frameworks)],
|
|
7223
|
-
signals:
|
|
7225
|
+
signals: uniqueSignals,
|
|
7226
|
+
confidence: calculateConfidence({
|
|
7227
|
+
signals: uniqueSignals,
|
|
7228
|
+
runtimes: [...new Set(runtimes)],
|
|
7229
|
+
frameworks: [...new Set(frameworks)]
|
|
7230
|
+
})
|
|
7224
7231
|
};
|
|
7225
7232
|
}
|
|
7233
|
+
function calculateConfidence(profile) {
|
|
7234
|
+
if (profile.signals.length === 0) {
|
|
7235
|
+
return "low";
|
|
7236
|
+
}
|
|
7237
|
+
const hasFramework = profile.frameworks.length > 0;
|
|
7238
|
+
const hasRuntime = profile.runtimes.length > 0;
|
|
7239
|
+
if (hasFramework && profile.signals.length >= 2 || hasRuntime && profile.signals.length >= 3) {
|
|
7240
|
+
return "high";
|
|
7241
|
+
}
|
|
7242
|
+
if (hasFramework || profile.signals.length >= 2 || hasRuntime) {
|
|
7243
|
+
return "medium";
|
|
7244
|
+
}
|
|
7245
|
+
return "low";
|
|
7246
|
+
}
|
|
7226
7247
|
async function detectNode(rootDir) {
|
|
7227
7248
|
const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
|
|
7228
7249
|
const signals = [];
|
|
@@ -7285,6 +7306,57 @@ var SRC_PRESETS_DIR = resolve2(PACKAGE_ROOT, "src", "presets");
|
|
|
7285
7306
|
var ROOT_PRESETS_DIR = resolve2(PACKAGE_ROOT, "presets");
|
|
7286
7307
|
var POLICY_PATH = resolve2(PACKAGE_ROOT, "policy.yml");
|
|
7287
7308
|
|
|
7309
|
+
// src/core/presets/preset-resolver.ts
|
|
7310
|
+
var CURRENT_PRESET_VERSION = "v0.2.0";
|
|
7311
|
+
function resolvePreset(target, profile) {
|
|
7312
|
+
const stack = resolveStack(profile);
|
|
7313
|
+
const architecture = profile.signals.length > 0 ? "single-project" : "unknown";
|
|
7314
|
+
const warnings = [];
|
|
7315
|
+
if (profile.confidence === "low") {
|
|
7316
|
+
warnings.push("Detection confidence is low; review the selected preset before applying it.");
|
|
7317
|
+
}
|
|
7318
|
+
if (stack === "unknown") {
|
|
7319
|
+
warnings.push("No supported stack was detected; using the generic CodeConductor workflow preset.");
|
|
7320
|
+
} else {
|
|
7321
|
+
warnings.push(`${stack} projects currently receive the generic ${target} workflow plus matching skills; stack-specific asset pruning is not implemented yet.`);
|
|
7322
|
+
}
|
|
7323
|
+
if (architecture === "unknown") {
|
|
7324
|
+
warnings.push("Project architecture could not be inferred from available signals.");
|
|
7325
|
+
}
|
|
7326
|
+
return {
|
|
7327
|
+
target,
|
|
7328
|
+
stack,
|
|
7329
|
+
architecture,
|
|
7330
|
+
confidence: profile.confidence,
|
|
7331
|
+
presetVersion: CURRENT_PRESET_VERSION,
|
|
7332
|
+
assets: resolveAssets(target),
|
|
7333
|
+
warnings
|
|
7334
|
+
};
|
|
7335
|
+
}
|
|
7336
|
+
function resolveStack(profile) {
|
|
7337
|
+
if (profile.frameworks.includes("spring"))
|
|
7338
|
+
return "spring";
|
|
7339
|
+
if (profile.frameworks.includes("django"))
|
|
7340
|
+
return "django";
|
|
7341
|
+
if (profile.frameworks.includes("astro"))
|
|
7342
|
+
return "astro";
|
|
7343
|
+
if (profile.runtimes.includes("bun"))
|
|
7344
|
+
return "bun";
|
|
7345
|
+
if (profile.runtimes.includes("node"))
|
|
7346
|
+
return "node";
|
|
7347
|
+
return "unknown";
|
|
7348
|
+
}
|
|
7349
|
+
function resolveAssets(target) {
|
|
7350
|
+
switch (target) {
|
|
7351
|
+
case "opencode":
|
|
7352
|
+
return ["opencode.jsonc", "agents", "commands", "prompts/v0.2.0", "skills"];
|
|
7353
|
+
case "claude":
|
|
7354
|
+
return ["CLAUDE.md", "settings.json", "commands", "skills", "agents", "prompts/v0.2.0"];
|
|
7355
|
+
case "codex":
|
|
7356
|
+
return ["AGENTS.md", "skills", "prompts/v0.2.0"];
|
|
7357
|
+
}
|
|
7358
|
+
}
|
|
7359
|
+
|
|
7288
7360
|
// src/commands/init.command.ts
|
|
7289
7361
|
async function initCommand(options) {
|
|
7290
7362
|
const { projectRoot, dryRun, force, global: isGlobal, output } = options;
|
|
@@ -7323,6 +7395,7 @@ async function initCommand(options) {
|
|
|
7323
7395
|
overwrite: force
|
|
7324
7396
|
}
|
|
7325
7397
|
};
|
|
7398
|
+
const presetResolution = profile ? resolvePreset("opencode", profile) : null;
|
|
7326
7399
|
const wouldCreate = [".codeconductor/config.yml"];
|
|
7327
7400
|
const presetsToCopy = await resolvePresetsToCopy();
|
|
7328
7401
|
for (const p of presetsToCopy) {
|
|
@@ -7340,8 +7413,11 @@ async function initCommand(options) {
|
|
|
7340
7413
|
detected: {
|
|
7341
7414
|
languages: profile.languages,
|
|
7342
7415
|
runtimes: profile.runtimes,
|
|
7343
|
-
frameworks: profile.frameworks
|
|
7344
|
-
|
|
7416
|
+
frameworks: profile.frameworks,
|
|
7417
|
+
signals: profile.signals,
|
|
7418
|
+
confidence: profile.confidence
|
|
7419
|
+
},
|
|
7420
|
+
presetResolution
|
|
7345
7421
|
} : { global: true }
|
|
7346
7422
|
}
|
|
7347
7423
|
};
|
|
@@ -7368,8 +7444,11 @@ async function initCommand(options) {
|
|
|
7368
7444
|
detected: {
|
|
7369
7445
|
languages: profile.languages,
|
|
7370
7446
|
runtimes: profile.runtimes,
|
|
7371
|
-
frameworks: profile.frameworks
|
|
7372
|
-
|
|
7447
|
+
frameworks: profile.frameworks,
|
|
7448
|
+
signals: profile.signals,
|
|
7449
|
+
confidence: profile.confidence
|
|
7450
|
+
},
|
|
7451
|
+
presetResolution
|
|
7373
7452
|
} : { global: true }
|
|
7374
7453
|
}
|
|
7375
7454
|
};
|
|
@@ -7453,7 +7532,8 @@ async function detectCommand(options) {
|
|
|
7453
7532
|
runtimes: profile.runtimes,
|
|
7454
7533
|
packageManagers: profile.packageManagers,
|
|
7455
7534
|
frameworks: profile.frameworks,
|
|
7456
|
-
signals: profile.signals
|
|
7535
|
+
signals: profile.signals,
|
|
7536
|
+
confidence: profile.confidence
|
|
7457
7537
|
},
|
|
7458
7538
|
recommendedPresets: getRecommendedPresets(profile)
|
|
7459
7539
|
}
|
|
@@ -11485,7 +11565,8 @@ var ProjectProfileSchema = exports_external.object({
|
|
|
11485
11565
|
runtimes: exports_external.array(exports_external.string()),
|
|
11486
11566
|
packageManagers: exports_external.array(exports_external.string()),
|
|
11487
11567
|
frameworks: exports_external.array(exports_external.string()),
|
|
11488
|
-
signals: exports_external.array(exports_external.string())
|
|
11568
|
+
signals: exports_external.array(exports_external.string()),
|
|
11569
|
+
confidence: exports_external.enum(["low", "medium", "high"])
|
|
11489
11570
|
});
|
|
11490
11571
|
var CodeConductorConfigSchema = exports_external.object({
|
|
11491
11572
|
version: exports_external.string(),
|
|
@@ -11509,7 +11590,7 @@ var CodeConductorConfigSchema = exports_external.object({
|
|
|
11509
11590
|
})
|
|
11510
11591
|
});
|
|
11511
11592
|
var RunnerTargetSchema = exports_external.enum(["opencode", "claude", "codex", "all"]);
|
|
11512
|
-
var InstallStrategySchema = exports_external.enum(["overwrite", "append", "merge-json", "skip"]);
|
|
11593
|
+
var InstallStrategySchema = exports_external.enum(["overwrite", "append", "merge-json", "merge-managed", "skip"]);
|
|
11513
11594
|
var ManifestEntrySchema = exports_external.object({
|
|
11514
11595
|
src: exports_external.string(),
|
|
11515
11596
|
dest: exports_external.string(),
|
|
@@ -11588,6 +11669,43 @@ async function loadModelConfig(target) {
|
|
|
11588
11669
|
// src/core/presets/file-copier.ts
|
|
11589
11670
|
import { readFile as readFile4, writeFile as writeFile3, mkdir as mkdir3, readdir, stat } from "node:fs/promises";
|
|
11590
11671
|
import { resolve as resolve5, join as join2, relative, dirname as dirname2 } from "node:path";
|
|
11672
|
+
|
|
11673
|
+
// src/core/filesystem/safe-merger.ts
|
|
11674
|
+
var MANAGED_BEGIN_MARKER = "<!-- CODECONDUCTOR:BEGIN managed -->";
|
|
11675
|
+
var MANAGED_END_MARKER = "<!-- CODECONDUCTOR:END managed -->";
|
|
11676
|
+
function mergeManagedBlock(existing, incoming) {
|
|
11677
|
+
validateMarkers(incoming, "incoming content");
|
|
11678
|
+
if (!existing) {
|
|
11679
|
+
return { content: incoming, action: "written" };
|
|
11680
|
+
}
|
|
11681
|
+
validateMarkers(existing, "existing content");
|
|
11682
|
+
const existingBlock = getManagedBlockRange(existing);
|
|
11683
|
+
const incomingBlock = getManagedBlockRange(incoming);
|
|
11684
|
+
return {
|
|
11685
|
+
content: existing.slice(0, existingBlock.start) + incoming.slice(incomingBlock.start, incomingBlock.end) + existing.slice(existingBlock.end),
|
|
11686
|
+
action: "merged"
|
|
11687
|
+
};
|
|
11688
|
+
}
|
|
11689
|
+
function validateMarkers(content, label) {
|
|
11690
|
+
const beginCount = countOccurrences(content, MANAGED_BEGIN_MARKER);
|
|
11691
|
+
const endCount = countOccurrences(content, MANAGED_END_MARKER);
|
|
11692
|
+
if (beginCount !== 1 || endCount !== 1) {
|
|
11693
|
+
throw new Error(`${label} must contain exactly one managed begin marker and one managed end marker`);
|
|
11694
|
+
}
|
|
11695
|
+
if (content.indexOf(MANAGED_BEGIN_MARKER) > content.indexOf(MANAGED_END_MARKER)) {
|
|
11696
|
+
throw new Error(`${label} has managed markers in the wrong order`);
|
|
11697
|
+
}
|
|
11698
|
+
}
|
|
11699
|
+
function getManagedBlockRange(content) {
|
|
11700
|
+
const start = content.indexOf(MANAGED_BEGIN_MARKER);
|
|
11701
|
+
const end = content.indexOf(MANAGED_END_MARKER) + MANAGED_END_MARKER.length;
|
|
11702
|
+
return { start, end };
|
|
11703
|
+
}
|
|
11704
|
+
function countOccurrences(content, needle) {
|
|
11705
|
+
return content.split(needle).length - 1;
|
|
11706
|
+
}
|
|
11707
|
+
|
|
11708
|
+
// src/core/presets/file-copier.ts
|
|
11591
11709
|
async function listFilesRecursive(dir, base = dir) {
|
|
11592
11710
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
11593
11711
|
const files = [];
|
|
@@ -11673,7 +11791,8 @@ async function applySingleFile(srcPath, destPath, strategy, force, dryRun, isTem
|
|
|
11673
11791
|
} catch (e) {
|
|
11674
11792
|
return { src: srcPath, dest: destPath, action: "error", error: `Cannot read source: ${e}` };
|
|
11675
11793
|
}
|
|
11676
|
-
|
|
11794
|
+
const incomingContent = isTemplate && modelConfig ? renderTemplate(content, modelConfig, srcPath) : content;
|
|
11795
|
+
let finalContent = incomingContent;
|
|
11677
11796
|
let action = "written";
|
|
11678
11797
|
if (strategy === "append" && !force) {
|
|
11679
11798
|
let existing = "";
|
|
@@ -11685,7 +11804,7 @@ async function applySingleFile(srcPath, destPath, strategy, force, dryRun, isTem
|
|
|
11685
11804
|
|
|
11686
11805
|
---
|
|
11687
11806
|
|
|
11688
|
-
` +
|
|
11807
|
+
` + incomingContent;
|
|
11689
11808
|
}
|
|
11690
11809
|
action = "appended";
|
|
11691
11810
|
} else if (strategy === "merge-json" && !force) {
|
|
@@ -11694,15 +11813,24 @@ async function applySingleFile(srcPath, destPath, strategy, force, dryRun, isTem
|
|
|
11694
11813
|
existing = JSON.parse(await readFile4(destPath, "utf-8"));
|
|
11695
11814
|
} catch {}
|
|
11696
11815
|
try {
|
|
11697
|
-
const incoming = JSON.parse(
|
|
11816
|
+
const incoming = JSON.parse(incomingContent);
|
|
11698
11817
|
finalContent = JSON.stringify(mergeDeep(existing, incoming), null, 2);
|
|
11699
11818
|
} catch (e) {
|
|
11700
11819
|
return { src: srcPath, dest: destPath, action: "error", error: `JSON merge failed: ${e}` };
|
|
11701
11820
|
}
|
|
11702
11821
|
action = "merged";
|
|
11703
|
-
}
|
|
11704
|
-
|
|
11705
|
-
|
|
11822
|
+
} else if (strategy === "merge-managed") {
|
|
11823
|
+
let existing = null;
|
|
11824
|
+
try {
|
|
11825
|
+
existing = await readFile4(destPath, "utf-8");
|
|
11826
|
+
} catch {}
|
|
11827
|
+
try {
|
|
11828
|
+
const merged = mergeManagedBlock(existing, incomingContent);
|
|
11829
|
+
finalContent = merged.content;
|
|
11830
|
+
action = merged.action;
|
|
11831
|
+
} catch (e) {
|
|
11832
|
+
return { src: srcPath, dest: destPath, action: "error", error: `Managed merge failed: ${e}` };
|
|
11833
|
+
}
|
|
11706
11834
|
}
|
|
11707
11835
|
if (dryRun) {
|
|
11708
11836
|
return { src: srcPath, dest: destPath, action, dryRun: true };
|
|
@@ -12185,6 +12313,8 @@ async function installPresetCommand(options) {
|
|
|
12185
12313
|
try {
|
|
12186
12314
|
const runnerTarget = parseRunnerTarget(target);
|
|
12187
12315
|
const targets = getIndividualTargets(runnerTarget);
|
|
12316
|
+
const profile = await detectProject(projectRoot);
|
|
12317
|
+
const presetResolution = targets.map((t) => resolvePreset(t, profile));
|
|
12188
12318
|
const allFileResults = [];
|
|
12189
12319
|
for (const t of targets) {
|
|
12190
12320
|
const manifest = await loadManifest(t);
|
|
@@ -12204,6 +12334,7 @@ async function installPresetCommand(options) {
|
|
|
12204
12334
|
targets,
|
|
12205
12335
|
global: isGlobal,
|
|
12206
12336
|
dryRun,
|
|
12337
|
+
presetResolution,
|
|
12207
12338
|
fileResults: allFileResults
|
|
12208
12339
|
}
|
|
12209
12340
|
};
|
|
@@ -12256,6 +12387,32 @@ async function configExists(projectRoot) {
|
|
|
12256
12387
|
}
|
|
12257
12388
|
}
|
|
12258
12389
|
|
|
12390
|
+
// src/core/security/target-compatibility.ts
|
|
12391
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
12392
|
+
async function loadTargetSecurityCompatibility() {
|
|
12393
|
+
const policy = $parse(await readFile6(POLICY_PATH, "utf-8"));
|
|
12394
|
+
const targets = ["opencode", "claude", "codex"];
|
|
12395
|
+
return targets.map((target) => {
|
|
12396
|
+
const policyTarget = policy.targets?.[target];
|
|
12397
|
+
if (!policyTarget) {
|
|
12398
|
+
return {
|
|
12399
|
+
target,
|
|
12400
|
+
status: "fail",
|
|
12401
|
+
unsupportedRules: [],
|
|
12402
|
+
warnings: [`No security compatibility policy found for ${target}.`]
|
|
12403
|
+
};
|
|
12404
|
+
}
|
|
12405
|
+
const unsupportedRules = policyTarget.unsupportedRules ?? [];
|
|
12406
|
+
const warnings = policyTarget.warnings ?? [];
|
|
12407
|
+
return {
|
|
12408
|
+
target,
|
|
12409
|
+
status: unsupportedRules.length > 0 || warnings.length > 0 ? "warn" : "pass",
|
|
12410
|
+
unsupportedRules,
|
|
12411
|
+
warnings
|
|
12412
|
+
};
|
|
12413
|
+
});
|
|
12414
|
+
}
|
|
12415
|
+
|
|
12259
12416
|
// src/commands/doctor.command.ts
|
|
12260
12417
|
async function doctorCommand(options) {
|
|
12261
12418
|
const { projectRoot, output } = options;
|
|
@@ -12331,6 +12488,14 @@ async function doctorCommand(options) {
|
|
|
12331
12488
|
message: `Council preset enabled (v${config.presets.council.version})`
|
|
12332
12489
|
});
|
|
12333
12490
|
}
|
|
12491
|
+
const securityCompatibility = await loadTargetSecurityCompatibility();
|
|
12492
|
+
for (const compatibility of securityCompatibility) {
|
|
12493
|
+
checks.push({
|
|
12494
|
+
name: `security-${compatibility.target}`,
|
|
12495
|
+
status: compatibility.status,
|
|
12496
|
+
message: compatibility.status === "pass" ? `${compatibility.target} can represent the canonical policy model` : `${compatibility.target} cannot enforce: ${compatibility.unsupportedRules.join(", ") || "see warnings"}`
|
|
12497
|
+
});
|
|
12498
|
+
}
|
|
12334
12499
|
const failedCount = checks.filter((c) => c.status === "fail").length;
|
|
12335
12500
|
if (failedCount > 0) {
|
|
12336
12501
|
return {
|
|
@@ -12347,7 +12512,8 @@ async function doctorCommand(options) {
|
|
|
12347
12512
|
data: {
|
|
12348
12513
|
success: true,
|
|
12349
12514
|
command: "doctor",
|
|
12350
|
-
checks
|
|
12515
|
+
checks,
|
|
12516
|
+
securityCompatibility
|
|
12351
12517
|
}
|
|
12352
12518
|
};
|
|
12353
12519
|
} catch (error) {
|
|
@@ -12486,11 +12652,65 @@ async function updateCommand(options) {
|
|
|
12486
12652
|
};
|
|
12487
12653
|
}
|
|
12488
12654
|
}
|
|
12655
|
+
// package.json
|
|
12656
|
+
var package_default = {
|
|
12657
|
+
name: "cc-codeconductor",
|
|
12658
|
+
version: "0.2.3",
|
|
12659
|
+
description: "A multi-agent orchestration framework for AI-assisted software engineering workflows.",
|
|
12660
|
+
keywords: [
|
|
12661
|
+
"ai",
|
|
12662
|
+
"agents",
|
|
12663
|
+
"orchestration",
|
|
12664
|
+
"workflow",
|
|
12665
|
+
"opencode",
|
|
12666
|
+
"claude",
|
|
12667
|
+
"codex"
|
|
12668
|
+
],
|
|
12669
|
+
license: "MIT",
|
|
12670
|
+
files: [
|
|
12671
|
+
"dist/index.js",
|
|
12672
|
+
"policy.yml",
|
|
12673
|
+
"presets/",
|
|
12674
|
+
"src/presets/"
|
|
12675
|
+
],
|
|
12676
|
+
repository: {
|
|
12677
|
+
type: "git",
|
|
12678
|
+
url: "https://github.com/lgzarturo/codeconductor"
|
|
12679
|
+
},
|
|
12680
|
+
engines: {
|
|
12681
|
+
node: ">=20.11"
|
|
12682
|
+
},
|
|
12683
|
+
type: "module",
|
|
12684
|
+
bin: {
|
|
12685
|
+
codeconductor: "./dist/index.js"
|
|
12686
|
+
},
|
|
12687
|
+
scripts: {
|
|
12688
|
+
dev: "bun run src/cli/main.ts",
|
|
12689
|
+
build: "bun build src/cli/main.ts --target=node --outfile=dist/index.js",
|
|
12690
|
+
test: "bun test",
|
|
12691
|
+
typecheck: "tsc --noEmit",
|
|
12692
|
+
"check:prompt-changelog": "bun run scripts/check-prompt-changelog.ts",
|
|
12693
|
+
"release:patch": "bash release.sh patch",
|
|
12694
|
+
"release:minor": "bash release.sh minor",
|
|
12695
|
+
"release:major": "bash release.sh major",
|
|
12696
|
+
"release:notes": "git-cliff --config .cliff.toml --output CHANGELOG.md",
|
|
12697
|
+
release: "bash release.sh"
|
|
12698
|
+
},
|
|
12699
|
+
dependencies: {
|
|
12700
|
+
zod: "^3.23.8",
|
|
12701
|
+
yaml: "^2.4.5"
|
|
12702
|
+
},
|
|
12703
|
+
devDependencies: {
|
|
12704
|
+
"@types/bun": "^1.1.8",
|
|
12705
|
+
typescript: "^5.5.3"
|
|
12706
|
+
}
|
|
12707
|
+
};
|
|
12489
12708
|
|
|
12490
12709
|
// src/cli/router.ts
|
|
12491
12710
|
function parseArgs(args) {
|
|
12492
12711
|
const flags = {
|
|
12493
12712
|
help: false,
|
|
12713
|
+
version: false,
|
|
12494
12714
|
dryRun: false,
|
|
12495
12715
|
force: false,
|
|
12496
12716
|
output: "human"
|
|
@@ -12500,6 +12720,8 @@ function parseArgs(args) {
|
|
|
12500
12720
|
for (const arg of args) {
|
|
12501
12721
|
if (arg === "--help" || arg === "-h") {
|
|
12502
12722
|
flags.help = true;
|
|
12723
|
+
} else if (arg === "--version" || arg === "-v") {
|
|
12724
|
+
flags.version = true;
|
|
12503
12725
|
} else if (arg === "--dry-run") {
|
|
12504
12726
|
flags.dryRun = true;
|
|
12505
12727
|
} else if (arg === "--force") {
|
|
@@ -12542,8 +12764,11 @@ function parseArgs(args) {
|
|
|
12542
12764
|
}
|
|
12543
12765
|
return { command, subcommand, options, flags };
|
|
12544
12766
|
}
|
|
12767
|
+
function getVersion() {
|
|
12768
|
+
return `${package_default.name} v${package_default.version}`;
|
|
12769
|
+
}
|
|
12545
12770
|
function getHelp() {
|
|
12546
|
-
return `CodeConductor CLI
|
|
12771
|
+
return `CodeConductor CLI v${package_default.version}
|
|
12547
12772
|
|
|
12548
12773
|
Usage: codeconductor <command> [options]
|
|
12549
12774
|
|
|
@@ -12557,6 +12782,7 @@ Commands:
|
|
|
12557
12782
|
|
|
12558
12783
|
Options:
|
|
12559
12784
|
--help, -h Show this help message
|
|
12785
|
+
--version, -v Show package version
|
|
12560
12786
|
--dry-run Show what would happen without writing files
|
|
12561
12787
|
--force Allow overwriting existing files
|
|
12562
12788
|
--global Install to home directory (~/.claude, ~/.opencode, etc.)
|
|
@@ -12653,6 +12879,10 @@ async function routeCommand(args, projectRoot) {
|
|
|
12653
12879
|
// src/cli/main.ts
|
|
12654
12880
|
async function runCli(args) {
|
|
12655
12881
|
const parsed = parseArgs(args.slice(2));
|
|
12882
|
+
if (parsed.flags.version) {
|
|
12883
|
+
console.log(getVersion());
|
|
12884
|
+
process.exit(0);
|
|
12885
|
+
}
|
|
12656
12886
|
if (parsed.flags.help || !parsed.command || parsed.command === "help") {
|
|
12657
12887
|
console.log(getHelp());
|
|
12658
12888
|
process.exit(0);
|
|
@@ -12713,8 +12943,10 @@ ${count} files processed${errCount > 0 ? `, ${errCount} errors` : ""}${note}`);
|
|
|
12713
12943
|
console.log("Detected:");
|
|
12714
12944
|
const detected = data.detected;
|
|
12715
12945
|
Object.entries(detected).forEach(([key, value]) => {
|
|
12716
|
-
if (value.length > 0) {
|
|
12946
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
12717
12947
|
console.log(` - ${key}: ${value.join(", ")}`);
|
|
12948
|
+
} else if (typeof value === "string" && value.length > 0) {
|
|
12949
|
+
console.log(` - ${key}: ${value}`);
|
|
12718
12950
|
}
|
|
12719
12951
|
});
|
|
12720
12952
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-codeconductor",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "A multi-agent orchestration framework for AI-assisted software engineering workflows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"build": "bun build src/cli/main.ts --target=node --outfile=dist/index.js",
|
|
35
35
|
"test": "bun test",
|
|
36
36
|
"typecheck": "tsc --noEmit",
|
|
37
|
+
"check:prompt-changelog": "bun run scripts/check-prompt-changelog.ts",
|
|
37
38
|
"release:patch": "bash release.sh patch",
|
|
38
39
|
"release:minor": "bash release.sh minor",
|
|
39
40
|
"release:major": "bash release.sh major",
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: >-
|
|
3
|
+
[cc: alias] Run the API contract workflow for public interface changes,
|
|
4
|
+
compatibility constraints, contract tests, documentation, and review.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# API Contract Workflow
|
|
8
|
+
|
|
9
|
+
API contract request: $ARGUMENTS
|
|
10
|
+
|
|
11
|
+
## Step 1 — Task Card validation (Task Coach role)
|
|
12
|
+
|
|
13
|
+
Adopt the **Task Coach** role as defined in `CLAUDE.md`.
|
|
14
|
+
|
|
15
|
+
The Task Card must classify the task as high risk by default and include the
|
|
16
|
+
affected public interface, request/response examples, compatibility notes,
|
|
17
|
+
versioning impact, consumer impact, contract tests, and docs acceptance
|
|
18
|
+
criteria.
|
|
19
|
+
|
|
20
|
+
**STOP here. Show the completed Task Card and wait for human confirmation.**
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Step 2 — Technical Plan (Architect role)
|
|
25
|
+
|
|
26
|
+
Adopt the **Architect** role as defined in `CLAUDE.md`.
|
|
27
|
+
|
|
28
|
+
Define the API contract, validation strategy, compatibility behavior, docs or
|
|
29
|
+
OpenAPI changes, and reviewer blocking conditions.
|
|
30
|
+
|
|
31
|
+
**STOP here. Show the Technical Plan and wait for explicit human approval.**
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Step 3 — Implementation (Implementer role)
|
|
36
|
+
|
|
37
|
+
Adopt the **Implementer** role as defined in `CLAUDE.md`.
|
|
38
|
+
|
|
39
|
+
Apply the minimal diff, preserve compatible behavior unless explicitly approved
|
|
40
|
+
as breaking, and update only the planned files.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Step 4 — Contract Tests (Tester role)
|
|
45
|
+
|
|
46
|
+
Adopt the **Tester** role as defined in `CLAUDE.md`.
|
|
47
|
+
|
|
48
|
+
Add or update tests for request shape, response shape, status/error behavior,
|
|
49
|
+
and backward compatibility.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Step 5 — Review (Reviewer role)
|
|
54
|
+
|
|
55
|
+
Adopt the **Reviewer** role as defined in `CLAUDE.md`.
|
|
56
|
+
|
|
57
|
+
Block on missing contract tests, undocumented breaking changes, or docs/OpenAPI
|
|
58
|
+
drift.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: >-
|
|
3
|
+
[cc: alias] Run the database migration workflow for schema/data changes,
|
|
4
|
+
operational sequencing, tests, and review.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Database Migration Workflow
|
|
8
|
+
|
|
9
|
+
Migration request: $ARGUMENTS
|
|
10
|
+
|
|
11
|
+
## Step 1 — Task Card validation (Task Coach role)
|
|
12
|
+
|
|
13
|
+
Adopt the **Task Coach** role as defined in `CLAUDE.md`.
|
|
14
|
+
|
|
15
|
+
The Task Card must classify the task as high risk and include affected schema,
|
|
16
|
+
model, and migration files; data backfill needs; deployment ordering;
|
|
17
|
+
rollback/forward-fix strategy; lock risk; data risk; and verification commands.
|
|
18
|
+
|
|
19
|
+
**STOP here. Show the completed Task Card and wait for human confirmation.**
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Step 2 — Migration Plan (Architect role)
|
|
24
|
+
|
|
25
|
+
Adopt the **Architect** role as defined in `CLAUDE.md`.
|
|
26
|
+
|
|
27
|
+
Define the schema/data plan, operational sequencing, compatibility strategy,
|
|
28
|
+
rollback/forward-fix notes, and test approach.
|
|
29
|
+
|
|
30
|
+
**STOP here. Show the Technical Plan and wait for explicit human approval.**
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Step 3 — Implementation (Implementer role)
|
|
35
|
+
|
|
36
|
+
Adopt the **Implementer** role as defined in `CLAUDE.md`.
|
|
37
|
+
|
|
38
|
+
Keep model and migration changes together, avoid unrelated refactors, and
|
|
39
|
+
preserve the deployment order specified by architect.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Step 4 — Migration Tests (Tester role)
|
|
44
|
+
|
|
45
|
+
Adopt the **Tester** role as defined in `CLAUDE.md`.
|
|
46
|
+
|
|
47
|
+
Cover migration-sensitive behavior where the stack supports it, including
|
|
48
|
+
existing-data edge cases and rollback/forward-fix notes when automated rollback
|
|
49
|
+
tests are not practical.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Step 5 — Review (Reviewer role)
|
|
54
|
+
|
|
55
|
+
Adopt the **Reviewer** role as defined in `CLAUDE.md`.
|
|
56
|
+
|
|
57
|
+
Block on missing migration tests, missing data-risk notes, undocumented
|
|
58
|
+
deployment sequencing, or model/migration drift.
|
package/presets/codex/AGENTS.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<!-- CODECONDUCTOR:BEGIN managed -->
|
|
2
|
+
|
|
1
3
|
# CodeConductor — Codex Preset
|
|
2
4
|
|
|
3
5
|
This file configures CodeConductor for **OpenAI Codex CLI**. Place it at your
|
|
@@ -37,6 +39,8 @@ language patterns to activate each workflow:
|
|
|
37
39
|
| Full feature | "Run the feature workflow for: [description]" |
|
|
38
40
|
| Bug fix | "Run the fix workflow for: [description]" |
|
|
39
41
|
| Refactor | "Run the refactor workflow for: [scope]" |
|
|
42
|
+
| API contract | "Run the API contract workflow for: [change]" |
|
|
43
|
+
| DB migration | "Run the database migration workflow for: [scope]" |
|
|
40
44
|
| Code review | "Run a structured review of: [target]" |
|
|
41
45
|
| Test plan | "Create a test plan for: [scope]" |
|
|
42
46
|
| Task intake | "Help me define a Task Card for: [vague request]" |
|
|
@@ -881,3 +885,5 @@ Contract version:** v0.1.0 **Date:** [YYYY-MM-DD] **Evaluator:** [human name or
|
|
|
881
885
|
- If the task type differs from the previous one, execute "/clear" before
|
|
882
886
|
starting.
|
|
883
887
|
- Delegate verbose operations to sub-agents.
|
|
888
|
+
|
|
889
|
+
<!-- CODECONDUCTOR:END managed -->
|
package/presets/codex/README.md
CHANGED
|
@@ -70,6 +70,8 @@ language trigger phrases:
|
|
|
70
70
|
| Full feature | `Run the feature workflow for: [description]` |
|
|
71
71
|
| Bug fix | `Run the fix workflow for: [description]` |
|
|
72
72
|
| Refactor | `Run the refactor workflow for: [scope]` |
|
|
73
|
+
| API contract | `Run the API contract workflow for: [change]` |
|
|
74
|
+
| DB migration | `Run the database migration workflow for: [scope]` |
|
|
73
75
|
| Code review | `Run a structured review of: [target]` |
|
|
74
76
|
| Test plan | `Create a test plan for: [scope]` |
|
|
75
77
|
| Task intake | `Help me define a Task Card for: [vague request]` |
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
description:
|
|
3
|
+
Run the API contract workflow for request/response shape changes,
|
|
4
|
+
compatibility constraints, contract tests, documentation, and review.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# API Contract Workflow
|
|
8
|
+
|
|
9
|
+
API contract request: $ARGUMENTS
|
|
10
|
+
|
|
11
|
+
## Step 1 — Task Card validation (task-coach)
|
|
12
|
+
|
|
13
|
+
Invoke `task-coach` with the request above.
|
|
14
|
+
|
|
15
|
+
The Task Card must classify the task as `feature` or `refactor` with `high`
|
|
16
|
+
risk unless the human provides a narrower validated risk. It must include:
|
|
17
|
+
|
|
18
|
+
- affected endpoint, command, or public interface
|
|
19
|
+
- request and response examples
|
|
20
|
+
- backward compatibility and versioning impact
|
|
21
|
+
- consumers that must remain compatible
|
|
22
|
+
- contract tests and documentation acceptance criteria
|
|
23
|
+
|
|
24
|
+
**STOP here. Show the Task Card and wait for human confirmation.**
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Step 2 — Technical Plan (architect)
|
|
29
|
+
|
|
30
|
+
Invoke `architect` with the approved Task Card.
|
|
31
|
+
|
|
32
|
+
architect must define the API contract, compatibility strategy, validation
|
|
33
|
+
rules, docs/OpenAPI impact, and migration path for consumers.
|
|
34
|
+
|
|
35
|
+
**STOP here. Show the Technical Plan and wait for explicit human approval.**
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Step 3 — Implementation (implementer)
|
|
40
|
+
|
|
41
|
+
Invoke `implementer` with the approved plan.
|
|
42
|
+
|
|
43
|
+
implementer must apply the minimal diff, preserve compatible behavior unless a
|
|
44
|
+
breaking change was explicitly approved, and update only the files named in the
|
|
45
|
+
plan.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Step 4 — Contract tests (tester)
|
|
50
|
+
|
|
51
|
+
Invoke `tester`.
|
|
52
|
+
|
|
53
|
+
tester must add or update contract tests covering request shape, response shape,
|
|
54
|
+
status/error behavior, and backward compatibility constraints.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Step 5 — Review (reviewer)
|
|
59
|
+
|
|
60
|
+
Invoke `reviewer`.
|
|
61
|
+
|
|
62
|
+
reviewer must block on missing contract tests, undocumented breaking changes,
|
|
63
|
+
or docs/OpenAPI drift.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Completion
|
|
68
|
+
|
|
69
|
+
Report the final Task Card, Technical Plan, implementation summary, test report,
|
|
70
|
+
review report, docs updated, compatibility impact, and residual risks.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
description:
|
|
3
|
+
Run the database migration workflow for schema/data changes, operational
|
|
4
|
+
sequencing, tests, and review.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Database Migration Workflow
|
|
8
|
+
|
|
9
|
+
Migration request: $ARGUMENTS
|
|
10
|
+
|
|
11
|
+
## Step 1 — Task Card validation (task-coach)
|
|
12
|
+
|
|
13
|
+
Invoke `task-coach` with the request above.
|
|
14
|
+
|
|
15
|
+
The Task Card must classify the task as `high` risk and include:
|
|
16
|
+
|
|
17
|
+
- tables, collections, models, or migration files in scope
|
|
18
|
+
- data backfill or data cleanup requirements
|
|
19
|
+
- deployment ordering and compatibility window
|
|
20
|
+
- rollback or forward-fix strategy
|
|
21
|
+
- lock risk, data risk, and verification commands
|
|
22
|
+
|
|
23
|
+
**STOP here. Show the Task Card and wait for human confirmation.**
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Step 2 — Migration Plan (architect)
|
|
28
|
+
|
|
29
|
+
Invoke `architect` with the approved Task Card.
|
|
30
|
+
|
|
31
|
+
architect must define the schema/data plan, operational sequencing,
|
|
32
|
+
compatibility strategy, rollback/forward-fix notes, and test approach.
|
|
33
|
+
|
|
34
|
+
**STOP here. Show the Technical Plan and wait for explicit human approval.**
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Step 3 — Implementation (implementer)
|
|
39
|
+
|
|
40
|
+
Invoke `implementer` with the approved plan.
|
|
41
|
+
|
|
42
|
+
implementer must keep model and migration changes together, avoid unrelated
|
|
43
|
+
refactors, and preserve the deployment order specified by architect.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Step 4 — Migration tests (tester)
|
|
48
|
+
|
|
49
|
+
Invoke `tester`.
|
|
50
|
+
|
|
51
|
+
tester must cover migration-sensitive behavior where the stack supports it,
|
|
52
|
+
including happy path, existing-data edge cases, and rollback/forward-fix notes
|
|
53
|
+
when automated rollback tests are not practical.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Step 5 — Review (reviewer)
|
|
58
|
+
|
|
59
|
+
Invoke `reviewer`.
|
|
60
|
+
|
|
61
|
+
reviewer must block on missing migration tests, missing data-risk notes,
|
|
62
|
+
undocumented deployment sequencing, or model/migration drift.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Completion
|
|
67
|
+
|
|
68
|
+
Report migration files changed, model files changed, tests run, lock risk, data
|
|
69
|
+
risk, operational sequencing, rollback/forward-fix notes, and residual risk.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// CodeConductor policies are declarative until the policy compiler exists.
|
|
3
3
|
// Enforcement depends on OpenCode permission support.
|
|
4
4
|
"$schema": "https://opencode.ai/config.json",
|
|
5
|
-
"model": "
|
|
5
|
+
"model": "opencode-go/qwen3.7-max",
|
|
6
6
|
"permission": {
|
|
7
7
|
"*": "ask",
|
|
8
8
|
"read": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"~/.kube/**": "deny",
|
|
16
16
|
"~/.gnupg/**": "deny",
|
|
17
17
|
"~/.npmrc": "deny",
|
|
18
|
-
"~/.pypirc": "deny"
|
|
18
|
+
"~/.pypirc": "deny"
|
|
19
19
|
},
|
|
20
20
|
"edit": {
|
|
21
21
|
"*": "ask",
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
".opencode/**": "deny",
|
|
25
25
|
".claude/**": "deny",
|
|
26
26
|
"*.env": "deny",
|
|
27
|
-
"*.env.*": "deny"
|
|
27
|
+
"*.env.*": "deny"
|
|
28
28
|
},
|
|
29
29
|
"glob": "allow",
|
|
30
30
|
"grep": "allow",
|
|
31
31
|
"external_directory": {
|
|
32
|
-
"*": "deny"
|
|
32
|
+
"*": "deny"
|
|
33
33
|
},
|
|
34
34
|
"bash": {
|
|
35
35
|
"*": "ask",
|
|
@@ -75,15 +75,15 @@
|
|
|
75
75
|
"git push --force*": "deny",
|
|
76
76
|
"git push -f*": "deny",
|
|
77
77
|
"git rebase *": "deny",
|
|
78
|
-
"git reset --hard *": "deny"
|
|
78
|
+
"git reset --hard *": "deny"
|
|
79
79
|
},
|
|
80
80
|
"webfetch": "ask",
|
|
81
81
|
"websearch": "ask",
|
|
82
82
|
"task": {
|
|
83
|
-
"*": "ask"
|
|
83
|
+
"*": "ask"
|
|
84
84
|
},
|
|
85
85
|
"skill": {
|
|
86
|
-
"*": "ask"
|
|
87
|
-
}
|
|
88
|
-
}
|
|
86
|
+
"*": "ask"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
89
|
}
|
|
@@ -9,8 +9,8 @@ description:
|
|
|
9
9
|
| Provider | Model | Use Case |
|
|
10
10
|
|----------|-------|----------|
|
|
11
11
|
| Claude | claude-opus-4-7 | Complex architecture, design |
|
|
12
|
-
| OpenCode Go | deepseek-v4-pro | Best — reasoning, technical design |
|
|
13
|
-
| OpenCode Go | mimo-v2.5-pro | Alternative |
|
|
12
|
+
| OpenCode Go | opencode-go/deepseek-v4-pro | Best — reasoning, technical design |
|
|
13
|
+
| OpenCode Go | opencode-go/mimo-v2.5-pro | Alternative |
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# Agent Contract — architect v0.1.0
|
|
@@ -8,8 +8,8 @@ description:
|
|
|
8
8
|
| Provider | Model | Use Case |
|
|
9
9
|
|----------|-------|----------|
|
|
10
10
|
| Claude | claude-haiku-4-5-20251001 | Fast — documentation |
|
|
11
|
-
| OpenCode Go | qwen-3.6-plus | Best — efficient docs |
|
|
12
|
-
| OpenCode Go | kimi-k2.6 | Alternative |
|
|
11
|
+
| OpenCode Go | opencode-go/qwen-3.6-plus | Best — efficient docs |
|
|
12
|
+
| OpenCode Go | opencode-go/kimi-k2.6 | Alternative |
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
# Agent Contract — docs v0.1.0
|
|
@@ -8,8 +8,8 @@ description:
|
|
|
8
8
|
| Provider | Model | Use Case |
|
|
9
9
|
|----------|-------|----------|
|
|
10
10
|
| Claude | claude-sonnet-4-6 | Default — code implementation |
|
|
11
|
-
| OpenCode Go | mimo-v2.5-pro | Best — reasoning for code |
|
|
12
|
-
| OpenCode Go | minimax-m2.7 | Alternative |
|
|
11
|
+
| OpenCode Go | opencode-go/mimo-v2.5-pro | Best — reasoning for code |
|
|
12
|
+
| OpenCode Go | opencode-go/minimax-m2.7 | Alternative |
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
# Agent Contract — implementer v0.1.0
|
|
@@ -41,8 +41,8 @@ If either is missing, escalate to the orchestrator. Do not begin without both.
|
|
|
41
41
|
Complete this checklist before opening any file for editing:
|
|
42
42
|
|
|
43
43
|
0. Create a Git Worktree for this session before opening any file for editing:
|
|
44
|
-
`git worktree add ../<branch>-session <branch>`
|
|
45
|
-
|
|
44
|
+
`git worktree add ../<branch>-session <branch>` All changes happen inside
|
|
45
|
+
this worktree. Never modify the main working tree directly.
|
|
46
46
|
1. Read the Technical Plan completely.
|
|
47
47
|
2. Read every file listed under "Affected Files and Modules."
|
|
48
48
|
3. Understand the existing patterns in those files: naming, error handling,
|
|
@@ -9,8 +9,8 @@ description:
|
|
|
9
9
|
| Provider | Model | Use Case |
|
|
10
10
|
|----------|-------|----------|
|
|
11
11
|
| Claude | claude-sonnet-4-6 | Default — coordination, routing |
|
|
12
|
-
| OpenCode Go | deepseek-v4-pro | Complex routing, delegation |
|
|
13
|
-
| OpenCode Go | minimax-m2.7 | Alternative |
|
|
12
|
+
| OpenCode Go | opencode-go/deepseek-v4-pro | Complex routing, delegation |
|
|
13
|
+
| OpenCode Go | opencode-go/minimax-m2.7 | Alternative |
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# Agent Contract — orchestrator v0.1.0
|
|
@@ -9,8 +9,8 @@ description:
|
|
|
9
9
|
| Provider | Model | Use Case |
|
|
10
10
|
|----------|-------|----------|
|
|
11
11
|
| Claude | claude-haiku-4-5-20251001 | Fast — exploration |
|
|
12
|
-
| OpenCode Go | qwen-3.6-plus | Best — quick mapping |
|
|
13
|
-
| OpenCode Go | kimi-k2.6 | Alternative |
|
|
12
|
+
| OpenCode Go | opencode-go/qwen-3.6-plus | Best — quick mapping |
|
|
13
|
+
| OpenCode Go | opencode-go/kimi-k2.6 | Alternative |
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
You are the Repo Explorer — the codebase mapping agent in the CodeConductor
|
|
@@ -9,8 +9,8 @@ description:
|
|
|
9
9
|
| Provider | Model | Use Case |
|
|
10
10
|
|----------|-------|----------|
|
|
11
11
|
| Claude | claude-sonnet-4-6 | Default — code review |
|
|
12
|
-
| OpenCode Go | qwen-3.6-plus | Best — efficient reviews |
|
|
13
|
-
| OpenCode Go | minimax-m2.7 | Detailed reviews |
|
|
12
|
+
| OpenCode Go | opencode-go/qwen-3.6-plus | Best — efficient reviews |
|
|
13
|
+
| OpenCode Go | opencode-go/minimax-m2.7 | Detailed reviews |
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# Agent Contract — reviewer v0.1.0
|
|
@@ -9,8 +9,8 @@ description:
|
|
|
9
9
|
| Provider | Model | Use Case |
|
|
10
10
|
|----------|-------|----------|
|
|
11
11
|
| Claude | claude-haiku-4-5-20251001 | Fast — intake, Q&A |
|
|
12
|
-
| OpenCode Go | qwen-3.6-plus | Best — efficient Q&A |
|
|
13
|
-
| OpenCode Go | kimi-k2.6 | Alternative |
|
|
12
|
+
| OpenCode Go | opencode-go/qwen-3.6-plus | Best — efficient Q&A |
|
|
13
|
+
| OpenCode Go | opencode-go/kimi-k2.6 | Alternative |
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# Agent Contract — task-coach v0.1.0
|
|
@@ -9,8 +9,8 @@ description:
|
|
|
9
9
|
| Provider | Model | Use Case |
|
|
10
10
|
|----------|-------|----------|
|
|
11
11
|
| Claude | claude-sonnet-4-6 | Default — test generation |
|
|
12
|
-
| OpenCode Go | minimax-m2.7 | Best — balanced reasoning |
|
|
13
|
-
| OpenCode Go | deepseek-v4-pro | Complex test scenarios |
|
|
12
|
+
| OpenCode Go | opencode-go/minimax-m2.7 | Best — balanced reasoning |
|
|
13
|
+
| OpenCode Go | opencode-go/deepseek-v4-pro | Complex test scenarios |
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# Agent Contract — tester v0.1.0
|
|
@@ -2,11 +2,11 @@ target: codex
|
|
|
2
2
|
entries:
|
|
3
3
|
- src: codex/AGENTS.md
|
|
4
4
|
dest: .codex/AGENTS.md
|
|
5
|
-
strategy:
|
|
5
|
+
strategy: merge-managed
|
|
6
6
|
template: true
|
|
7
7
|
- src: codex/skills
|
|
8
8
|
dest: .codex/skills
|
|
9
9
|
strategy: overwrite
|
|
10
10
|
- src: opencode/prompts/v0.2.0
|
|
11
11
|
dest: .codex/prompts/v0.2.0
|
|
12
|
-
strategy: overwrite
|
|
12
|
+
strategy: overwrite
|
|
@@ -5,33 +5,33 @@ target: claude
|
|
|
5
5
|
agents:
|
|
6
6
|
architect:
|
|
7
7
|
claude: claude-opus-4-7
|
|
8
|
-
opencode: deepseek-v4-pro
|
|
8
|
+
opencode: opencode-go/deepseek-v4-pro
|
|
9
9
|
codex: gpt-5.5
|
|
10
10
|
implementer:
|
|
11
11
|
claude: claude-sonnet-4-6
|
|
12
|
-
opencode: mimo-v2.5-pro
|
|
12
|
+
opencode: opencode-go/mimo-v2.5-pro
|
|
13
13
|
codex: gpt-5.3-codex
|
|
14
14
|
tester:
|
|
15
15
|
claude: claude-sonnet-4-6
|
|
16
|
-
opencode: minimax-m2.7
|
|
16
|
+
opencode: opencode-go/minimax-m2.7
|
|
17
17
|
codex: gpt-5.3-codex
|
|
18
18
|
orchestrator:
|
|
19
19
|
claude: claude-sonnet-4-6
|
|
20
|
-
opencode: deepseek-v4-pro
|
|
20
|
+
opencode: opencode-go/deepseek-v4-pro
|
|
21
21
|
codex: gpt-5.2
|
|
22
22
|
reviewer:
|
|
23
23
|
claude: claude-sonnet-4-6
|
|
24
|
-
opencode: qwen-3.6-plus
|
|
24
|
+
opencode: opencode-go/qwen-3.6-plus
|
|
25
25
|
codex: gpt-5.4
|
|
26
26
|
docs:
|
|
27
27
|
claude: claude-haiku-4-5-20251001
|
|
28
|
-
opencode: qwen-3.6-plus
|
|
28
|
+
opencode: opencode-go/qwen-3.6-plus
|
|
29
29
|
codex: gpt-5.4-mini
|
|
30
30
|
task-coach:
|
|
31
31
|
claude: claude-haiku-4-5-20251001
|
|
32
|
-
opencode:
|
|
32
|
+
opencode: opencode-go/kimi-k2.6
|
|
33
33
|
codex: gpt-5.4-mini
|
|
34
34
|
repo-explorer:
|
|
35
35
|
claude: claude-haiku-4-5-20251001
|
|
36
|
-
opencode:
|
|
37
|
-
codex: gpt-5.4-mini
|
|
36
|
+
opencode: opencode-go/qwen3.5-plus
|
|
37
|
+
codex: gpt-5.4-mini
|
|
@@ -6,33 +6,33 @@ target: codex
|
|
|
6
6
|
agents:
|
|
7
7
|
architect:
|
|
8
8
|
claude: claude-opus-4-7
|
|
9
|
-
opencode: deepseek-v4-pro
|
|
9
|
+
opencode: opencode-go/deepseek-v4-pro
|
|
10
10
|
codex: gpt-5.5
|
|
11
11
|
implementer:
|
|
12
12
|
claude: claude-sonnet-4-6
|
|
13
|
-
opencode: mimo-v2.5-pro
|
|
13
|
+
opencode: opencode-go/mimo-v2.5-pro
|
|
14
14
|
codex: gpt-5.3-codex
|
|
15
15
|
tester:
|
|
16
16
|
claude: claude-sonnet-4-6
|
|
17
|
-
opencode: minimax-m2.7
|
|
17
|
+
opencode: opencode-go/minimax-m2.7
|
|
18
18
|
codex: gpt-5.3-codex
|
|
19
19
|
orchestrator:
|
|
20
20
|
claude: claude-sonnet-4-6
|
|
21
|
-
opencode: deepseek-v4-pro
|
|
21
|
+
opencode: opencode-go/deepseek-v4-pro
|
|
22
22
|
codex: gpt-5.2
|
|
23
23
|
reviewer:
|
|
24
24
|
claude: claude-sonnet-4-6
|
|
25
|
-
opencode: qwen-3.6-plus
|
|
25
|
+
opencode: opencode-go/qwen-3.6-plus
|
|
26
26
|
codex: gpt-5.4
|
|
27
27
|
docs:
|
|
28
28
|
claude: claude-haiku-4-5-20251001
|
|
29
|
-
opencode: qwen-3.6-plus
|
|
29
|
+
opencode: opencode-go/qwen-3.6-plus
|
|
30
30
|
codex: gpt-5.4-mini
|
|
31
31
|
task-coach:
|
|
32
32
|
claude: claude-haiku-4-5-20251001
|
|
33
|
-
opencode:
|
|
33
|
+
opencode: opencode-go/kimi-k2.6
|
|
34
34
|
codex: gpt-5.4-mini
|
|
35
35
|
repo-explorer:
|
|
36
36
|
claude: claude-haiku-4-5-20251001
|
|
37
|
-
opencode:
|
|
38
|
-
codex: gpt-5.4-mini
|
|
37
|
+
opencode: opencode-go/qwen3.5-plus
|
|
38
|
+
codex: gpt-5.4-mini
|
|
@@ -5,33 +5,33 @@ target: opencode
|
|
|
5
5
|
agents:
|
|
6
6
|
architect:
|
|
7
7
|
claude: claude-opus-4-7
|
|
8
|
-
opencode: deepseek-v4-pro
|
|
8
|
+
opencode: opencode-go/deepseek-v4-pro
|
|
9
9
|
codex: gpt-5.5
|
|
10
10
|
implementer:
|
|
11
11
|
claude: claude-sonnet-4-6
|
|
12
|
-
opencode: mimo-v2.5-pro
|
|
12
|
+
opencode: opencode-go/mimo-v2.5-pro
|
|
13
13
|
codex: gpt-5.3-codex
|
|
14
14
|
tester:
|
|
15
15
|
claude: claude-sonnet-4-6
|
|
16
|
-
opencode: minimax-m2.7
|
|
16
|
+
opencode: opencode-go/minimax-m2.7
|
|
17
17
|
codex: gpt-5.3-codex
|
|
18
18
|
orchestrator:
|
|
19
19
|
claude: claude-sonnet-4-6
|
|
20
|
-
opencode: deepseek-v4-pro
|
|
20
|
+
opencode: opencode-go/deepseek-v4-pro
|
|
21
21
|
codex: gpt-5.2
|
|
22
22
|
reviewer:
|
|
23
23
|
claude: claude-sonnet-4-6
|
|
24
|
-
opencode: qwen-3.6-plus
|
|
24
|
+
opencode: opencode-go/qwen-3.6-plus
|
|
25
25
|
codex: gpt-5.4
|
|
26
26
|
docs:
|
|
27
27
|
claude: claude-haiku-4-5-20251001
|
|
28
|
-
opencode: qwen-3.6-plus
|
|
28
|
+
opencode: opencode-go/qwen-3.6-plus
|
|
29
29
|
codex: gpt-5.4-mini
|
|
30
30
|
task-coach:
|
|
31
31
|
claude: claude-haiku-4-5-20251001
|
|
32
|
-
opencode:
|
|
32
|
+
opencode: opencode-go/kimi-k2.6
|
|
33
33
|
codex: gpt-5.4-mini
|
|
34
34
|
repo-explorer:
|
|
35
35
|
claude: claude-haiku-4-5-20251001
|
|
36
|
-
opencode:
|
|
37
|
-
codex: gpt-5.4-mini
|
|
36
|
+
opencode: opencode-go/qwen3.5-plus
|
|
37
|
+
codex: gpt-5.4-mini
|