cc-codeconductor 1.6.0 → 1.6.1
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 +5 -5
- package/dist/core/verification/rdd-receipt.d.ts +19 -0
- package/dist/core/verification/verification-runner.d.ts +16 -0
- package/dist/index.js +343 -245
- package/dist/library.js +36 -9
- package/package.json +2 -1
- package/presets/agy/skills/cc-feature/SKILL.md +17 -16
- package/presets/agy/skills/cc-fix/SKILL.md +28 -34
- package/presets/agy/workflows/cc-council.md +2 -0
- package/presets/claude/commands/cc/council.md +2 -83
- package/presets/codex/skills/cc-council/SKILL.md +2 -93
- package/presets/cursor/commands/cc/council.md +2 -83
- package/presets/gemini/commands/cc/council.toml +2 -83
- package/presets/opencode/commands/cc-council.md +2 -83
package/dist/index.js
CHANGED
|
@@ -72,7 +72,7 @@ var package_default;
|
|
|
72
72
|
var init_package = __esm(() => {
|
|
73
73
|
package_default = {
|
|
74
74
|
name: "cc-codeconductor",
|
|
75
|
-
version: "1.6.
|
|
75
|
+
version: "1.6.1",
|
|
76
76
|
description: "A multi-agent orchestration framework for AI-assisted software engineering workflows.",
|
|
77
77
|
keywords: [
|
|
78
78
|
"ai",
|
|
@@ -126,6 +126,7 @@ var init_package = __esm(() => {
|
|
|
126
126
|
"test:fast": "bun run scripts/test-fast.ts",
|
|
127
127
|
typecheck: "tsc --noEmit",
|
|
128
128
|
lint: "bun run scripts/lint.ts",
|
|
129
|
+
"check:council-redirect": "bun run scripts/check-council-redirect.ts",
|
|
129
130
|
"check:coverage": "bun run scripts/check-coverage.ts",
|
|
130
131
|
"check:prompt-changelog": "bun run scripts/check-prompt-changelog.ts",
|
|
131
132
|
"check:drift": "bun run scripts/check-drift.ts",
|
|
@@ -13733,6 +13734,12 @@ function profileFor(agentId) {
|
|
|
13733
13734
|
function checklistFor(agentId) {
|
|
13734
13735
|
return profileFor(agentId).checklist;
|
|
13735
13736
|
}
|
|
13737
|
+
function responsibilitiesFor(agentId) {
|
|
13738
|
+
return profileFor(agentId).responsibilities;
|
|
13739
|
+
}
|
|
13740
|
+
function vetoNoteFor(agentId) {
|
|
13741
|
+
return profileFor(agentId).vetoNote;
|
|
13742
|
+
}
|
|
13736
13743
|
function generateAgentContent(agent) {
|
|
13737
13744
|
const profile = profileFor(agent.id);
|
|
13738
13745
|
const vetoSection = profile.vetoNote ? `
|
|
@@ -14256,13 +14263,16 @@ ${agentTables}
|
|
|
14256
14263
|
}
|
|
14257
14264
|
function generateCodexAgent(agent) {
|
|
14258
14265
|
const focusAreas = agent.focus.join(", ");
|
|
14266
|
+
const responsibilities = responsibilitiesFor(agent.id).join("; ");
|
|
14259
14267
|
const checklist = checklistFor(agent.id).join("; ");
|
|
14268
|
+
const veto = vetoNoteFor(agent.id);
|
|
14269
|
+
const vetoSentence = veto ? ` ${veto}` : "";
|
|
14260
14270
|
return `model = "gpt-6.1-sol"
|
|
14261
14271
|
model_reasoning_effort = "medium"
|
|
14262
14272
|
name = "${agent.role}"
|
|
14263
14273
|
description = "${agent.role} council agent. Focus: ${focusAreas}. Context: ${agent.context}. Model hint: ${agent.modelHint}."
|
|
14264
14274
|
nickname_candidates = ["${agent.role}", "Council ${agent.role}"]
|
|
14265
|
-
developer_instructions = "You are the ${agent.role} council agent. Your focus areas are: ${focusAreas}. Context: ${agent.context}. Apply ${agent.modelHint} reasoning to your analysis. Review checklist: ${checklist}
|
|
14275
|
+
developer_instructions = "You are the ${agent.role} council agent. Your focus areas are: ${focusAreas}. Context: ${agent.context}. Apply ${agent.modelHint} reasoning to your analysis. Responsibilities: ${responsibilities}. Review checklist: ${checklist}.${vetoSentence} Categorize findings as CRITICAL (blocks the verdict), WARNING, or SUGGESTION."
|
|
14266
14276
|
`;
|
|
14267
14277
|
}
|
|
14268
14278
|
function generateCodexSkill(spec) {
|
|
@@ -15408,10 +15418,90 @@ var init_config_writer = __esm(() => {
|
|
|
15408
15418
|
init_codeconductor_config();
|
|
15409
15419
|
});
|
|
15410
15420
|
|
|
15421
|
+
// src/core/ccep/council-fallback.generated.ts
|
|
15422
|
+
var COUNCIL_FALLBACK_PROFILE;
|
|
15423
|
+
var init_council_fallback_generated = __esm(() => {
|
|
15424
|
+
COUNCIL_FALLBACK_PROFILE = {
|
|
15425
|
+
id: "council",
|
|
15426
|
+
version: 1,
|
|
15427
|
+
command: "council",
|
|
15428
|
+
phases: [
|
|
15429
|
+
{
|
|
15430
|
+
id: "wayfinding",
|
|
15431
|
+
agent: "repo-explorer",
|
|
15432
|
+
outputSchema: "agent-output"
|
|
15433
|
+
},
|
|
15434
|
+
{
|
|
15435
|
+
id: "deliberation",
|
|
15436
|
+
agents: [
|
|
15437
|
+
"task-coach",
|
|
15438
|
+
"architect",
|
|
15439
|
+
"devil"
|
|
15440
|
+
],
|
|
15441
|
+
skill: "council",
|
|
15442
|
+
outputSchema: "planner-output",
|
|
15443
|
+
stopGate: "confirmation"
|
|
15444
|
+
},
|
|
15445
|
+
{
|
|
15446
|
+
id: "tdd",
|
|
15447
|
+
agent: "tester",
|
|
15448
|
+
requires: "red-state"
|
|
15449
|
+
},
|
|
15450
|
+
{
|
|
15451
|
+
id: "implement",
|
|
15452
|
+
agent: "implementer"
|
|
15453
|
+
},
|
|
15454
|
+
{
|
|
15455
|
+
id: "council-review",
|
|
15456
|
+
agents: [
|
|
15457
|
+
"architect",
|
|
15458
|
+
"product",
|
|
15459
|
+
"delivery",
|
|
15460
|
+
"data-ops",
|
|
15461
|
+
"security-reviewer",
|
|
15462
|
+
"devil"
|
|
15463
|
+
],
|
|
15464
|
+
skill: "council",
|
|
15465
|
+
outputSchema: "council-verdict"
|
|
15466
|
+
}
|
|
15467
|
+
],
|
|
15468
|
+
routing: {
|
|
15469
|
+
default: [
|
|
15470
|
+
"wayfinding",
|
|
15471
|
+
"deliberation",
|
|
15472
|
+
"tdd",
|
|
15473
|
+
"implement",
|
|
15474
|
+
"council-review"
|
|
15475
|
+
]
|
|
15476
|
+
},
|
|
15477
|
+
confirmationGate: {
|
|
15478
|
+
stopOnHighRisk: true,
|
|
15479
|
+
stopOnQuestions: true
|
|
15480
|
+
}
|
|
15481
|
+
};
|
|
15482
|
+
});
|
|
15483
|
+
|
|
15411
15484
|
// src/core/ccep/profiles.ts
|
|
15412
|
-
|
|
15485
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
15486
|
+
import { dirname as dirname5, join as join7 } from "node:path";
|
|
15487
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
15488
|
+
function loadCouncilMirror() {
|
|
15489
|
+
try {
|
|
15490
|
+
const raw = readFileSync2(join7(dirname5(fileURLToPath2(import.meta.url)), "workflows", "council.yml"), "utf-8");
|
|
15491
|
+
return validateWorkflowProfile($parse(raw));
|
|
15492
|
+
} catch (error) {
|
|
15493
|
+
if (error?.code !== "ENOENT")
|
|
15494
|
+
throw error;
|
|
15495
|
+
return COUNCIL_FALLBACK_PROFILE;
|
|
15496
|
+
}
|
|
15497
|
+
}
|
|
15498
|
+
var baseGate, councilMirror, WORKFLOW_PROFILES;
|
|
15413
15499
|
var init_profiles = __esm(() => {
|
|
15500
|
+
init_dist();
|
|
15501
|
+
init_schemas();
|
|
15502
|
+
init_council_fallback_generated();
|
|
15414
15503
|
baseGate = { stopOnHighRisk: true, stopOnQuestions: true };
|
|
15504
|
+
councilMirror = loadCouncilMirror();
|
|
15415
15505
|
WORKFLOW_PROFILES = {
|
|
15416
15506
|
feature: {
|
|
15417
15507
|
id: "feature",
|
|
@@ -15645,31 +15735,7 @@ var init_profiles = __esm(() => {
|
|
|
15645
15735
|
routing: { default: ["analyze", "create", "evaluate"] },
|
|
15646
15736
|
confirmationGate: { stopOnHighRisk: false, stopOnQuestions: false }
|
|
15647
15737
|
},
|
|
15648
|
-
council:
|
|
15649
|
-
id: "council",
|
|
15650
|
-
version: 1,
|
|
15651
|
-
command: "council",
|
|
15652
|
-
phases: [
|
|
15653
|
-
{ id: "wayfinding", agent: "repo-explorer", outputSchema: "agent-output" },
|
|
15654
|
-
{
|
|
15655
|
-
id: "deliberation",
|
|
15656
|
-
agents: ["task-coach", "architect", "devil"],
|
|
15657
|
-
skill: "council",
|
|
15658
|
-
outputSchema: "planner-output",
|
|
15659
|
-
stopGate: "confirmation"
|
|
15660
|
-
},
|
|
15661
|
-
{ id: "tdd", agent: "tester", requires: "red-state" },
|
|
15662
|
-
{ id: "implement", agent: "implementer" },
|
|
15663
|
-
{
|
|
15664
|
-
id: "council-review",
|
|
15665
|
-
agents: ["architect", "product", "delivery", "data-ops", "security-reviewer", "devil"],
|
|
15666
|
-
skill: "council",
|
|
15667
|
-
outputSchema: "council-verdict"
|
|
15668
|
-
}
|
|
15669
|
-
],
|
|
15670
|
-
routing: { default: ["wayfinding", "deliberation", "tdd", "implement", "council-review"] },
|
|
15671
|
-
confirmationGate: baseGate
|
|
15672
|
-
},
|
|
15738
|
+
council: councilMirror,
|
|
15673
15739
|
iterative: {
|
|
15674
15740
|
id: "iterative",
|
|
15675
15741
|
version: 1,
|
|
@@ -15797,17 +15863,17 @@ var init_profiles = __esm(() => {
|
|
|
15797
15863
|
});
|
|
15798
15864
|
|
|
15799
15865
|
// src/core/ccep/profile-yaml.ts
|
|
15800
|
-
import { existsSync as existsSync2, readFileSync as
|
|
15801
|
-
import { dirname as
|
|
15802
|
-
import { fileURLToPath as
|
|
15866
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
|
|
15867
|
+
import { dirname as dirname6, join as join8 } from "node:path";
|
|
15868
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
15803
15869
|
function workflowYamlPath(command, projectRoot) {
|
|
15804
15870
|
if (projectRoot) {
|
|
15805
|
-
const projectPath =
|
|
15871
|
+
const projectPath = join8(projectRoot, ".codeconductor", "workflows", `${command}.yml`);
|
|
15806
15872
|
if (existsSync2(projectPath)) {
|
|
15807
15873
|
return projectPath;
|
|
15808
15874
|
}
|
|
15809
15875
|
}
|
|
15810
|
-
const bundledPath =
|
|
15876
|
+
const bundledPath = join8(BUNDLED_WORKFLOWS_DIR, `${command}.yml`);
|
|
15811
15877
|
if (existsSync2(bundledPath)) {
|
|
15812
15878
|
return bundledPath;
|
|
15813
15879
|
}
|
|
@@ -15822,7 +15888,7 @@ function loadWorkflowProfileFromYaml(command, projectRoot) {
|
|
|
15822
15888
|
if (!path) {
|
|
15823
15889
|
return null;
|
|
15824
15890
|
}
|
|
15825
|
-
const content =
|
|
15891
|
+
const content = readFileSync3(path, "utf-8");
|
|
15826
15892
|
return parseWorkflowYaml(content);
|
|
15827
15893
|
}
|
|
15828
15894
|
function loadWorkflowProfileFallback(command) {
|
|
@@ -15837,12 +15903,12 @@ var init_profile_yaml = __esm(() => {
|
|
|
15837
15903
|
init_dist();
|
|
15838
15904
|
init_schemas();
|
|
15839
15905
|
init_profiles();
|
|
15840
|
-
BUNDLED_WORKFLOWS_DIR =
|
|
15906
|
+
BUNDLED_WORKFLOWS_DIR = join8(dirname6(fileURLToPath3(import.meta.url)), "workflows");
|
|
15841
15907
|
});
|
|
15842
15908
|
|
|
15843
15909
|
// src/core/ccep/workflow-init.ts
|
|
15844
15910
|
import { access as access3, copyFile, mkdir as mkdir4, readdir as readdir2 } from "node:fs/promises";
|
|
15845
|
-
import { join as
|
|
15911
|
+
import { join as join9, resolve as resolve9 } from "node:path";
|
|
15846
15912
|
async function fileExists4(path) {
|
|
15847
15913
|
try {
|
|
15848
15914
|
await access3(path);
|
|
@@ -15862,11 +15928,11 @@ async function initWorkflowArtifacts(baseDir, force) {
|
|
|
15862
15928
|
for (const file of files) {
|
|
15863
15929
|
if (!file.endsWith(".yml"))
|
|
15864
15930
|
continue;
|
|
15865
|
-
const destPath =
|
|
15931
|
+
const destPath = join9(destDir, file);
|
|
15866
15932
|
if (!force && await fileExists4(destPath)) {
|
|
15867
15933
|
continue;
|
|
15868
15934
|
}
|
|
15869
|
-
await copyFile(
|
|
15935
|
+
await copyFile(join9(BUNDLED_WORKFLOWS_DIR, file), destPath);
|
|
15870
15936
|
created.push(`.codeconductor/workflows/${file}`);
|
|
15871
15937
|
}
|
|
15872
15938
|
return created;
|
|
@@ -15924,12 +15990,12 @@ async function detectDjango(rootDir) {
|
|
|
15924
15990
|
}
|
|
15925
15991
|
async function detectFastApi(rootDir) {
|
|
15926
15992
|
const { fileExists: fileExists5 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
|
|
15927
|
-
const { join:
|
|
15993
|
+
const { join: join10 } = await import("node:path");
|
|
15928
15994
|
const { readFile: readFile9 } = await import("node:fs/promises");
|
|
15929
15995
|
const signals = [];
|
|
15930
15996
|
if (await fileExists5(rootDir, "requirements.txt")) {
|
|
15931
15997
|
try {
|
|
15932
|
-
const content = await readFile9(
|
|
15998
|
+
const content = await readFile9(join10(rootDir, "requirements.txt"), "utf-8");
|
|
15933
15999
|
if (content.includes("fastapi")) {
|
|
15934
16000
|
signals.push("fastapi-requirements");
|
|
15935
16001
|
}
|
|
@@ -15937,7 +16003,7 @@ async function detectFastApi(rootDir) {
|
|
|
15937
16003
|
}
|
|
15938
16004
|
if (await fileExists5(rootDir, "pyproject.toml")) {
|
|
15939
16005
|
try {
|
|
15940
|
-
const content = await readFile9(
|
|
16006
|
+
const content = await readFile9(join10(rootDir, "pyproject.toml"), "utf-8");
|
|
15941
16007
|
if (content.includes("fastapi")) {
|
|
15942
16008
|
signals.push("fastapi-pyproject");
|
|
15943
16009
|
}
|
|
@@ -15946,7 +16012,7 @@ async function detectFastApi(rootDir) {
|
|
|
15946
16012
|
for (const filename of ["main.py", "app.py", "app/main.py", "app/app.py"]) {
|
|
15947
16013
|
if (await fileExists5(rootDir, filename)) {
|
|
15948
16014
|
try {
|
|
15949
|
-
const content = await readFile9(
|
|
16015
|
+
const content = await readFile9(join10(rootDir, filename), "utf-8");
|
|
15950
16016
|
if (content.includes("FastAPI") && content.includes("fastapi")) {
|
|
15951
16017
|
signals.push(`${filename}-fastapi`);
|
|
15952
16018
|
}
|
|
@@ -16008,7 +16074,7 @@ async function detectAstro(rootDir) {
|
|
|
16008
16074
|
}
|
|
16009
16075
|
async function detectNext(rootDir) {
|
|
16010
16076
|
const { fileExists: fileExists5 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
|
|
16011
|
-
const { join:
|
|
16077
|
+
const { join: join10 } = await import("node:path");
|
|
16012
16078
|
const { readFile: readFile9 } = await import("node:fs/promises");
|
|
16013
16079
|
const signals = [];
|
|
16014
16080
|
if (await fileExists5(rootDir, "next.config.js") || await fileExists5(rootDir, "next.config.mjs") || await fileExists5(rootDir, "next.config.ts")) {
|
|
@@ -16016,7 +16082,7 @@ async function detectNext(rootDir) {
|
|
|
16016
16082
|
}
|
|
16017
16083
|
if (await fileExists5(rootDir, "package.json")) {
|
|
16018
16084
|
try {
|
|
16019
|
-
const content = await readFile9(
|
|
16085
|
+
const content = await readFile9(join10(rootDir, "package.json"), "utf-8");
|
|
16020
16086
|
const pkg = JSON.parse(content);
|
|
16021
16087
|
if (pkg.dependencies?.next || pkg.devDependencies?.next) {
|
|
16022
16088
|
signals.push("package.json-next");
|
|
@@ -16027,7 +16093,7 @@ async function detectNext(rootDir) {
|
|
|
16027
16093
|
}
|
|
16028
16094
|
async function detectGenericFrontend(rootDir) {
|
|
16029
16095
|
const { fileExists: fileExists5 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
|
|
16030
|
-
const { join:
|
|
16096
|
+
const { join: join10 } = await import("node:path");
|
|
16031
16097
|
const { readFile: readFile9 } = await import("node:fs/promises");
|
|
16032
16098
|
const signals = [];
|
|
16033
16099
|
if (await fileExists5(rootDir, "index.html")) {
|
|
@@ -16041,7 +16107,7 @@ async function detectGenericFrontend(rootDir) {
|
|
|
16041
16107
|
}
|
|
16042
16108
|
if (await fileExists5(rootDir, "package.json")) {
|
|
16043
16109
|
try {
|
|
16044
|
-
const content = await readFile9(
|
|
16110
|
+
const content = await readFile9(join10(rootDir, "package.json"), "utf-8");
|
|
16045
16111
|
const pkg = JSON.parse(content);
|
|
16046
16112
|
const frontendDeps = ["react", "vue", "svelte", "solid-js", "angular", "@angular/core"];
|
|
16047
16113
|
const hasFrontendDep = frontendDeps.some((dep) => pkg.dependencies?.[dep] || pkg.devDependencies?.[dep]);
|
|
@@ -16056,7 +16122,7 @@ async function detectGenericFrontend(rootDir) {
|
|
|
16056
16122
|
// src/core/detection/detectors/monorepo.ts
|
|
16057
16123
|
async function detectMonorepo(rootDir) {
|
|
16058
16124
|
const { fileExists: fileExists5 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
|
|
16059
|
-
const { join:
|
|
16125
|
+
const { join: join10 } = await import("node:path");
|
|
16060
16126
|
const { readFile: readFile9 } = await import("node:fs/promises");
|
|
16061
16127
|
const signals = [];
|
|
16062
16128
|
if (await fileExists5(rootDir, "pnpm-workspace.yaml")) {
|
|
@@ -16070,7 +16136,7 @@ async function detectMonorepo(rootDir) {
|
|
|
16070
16136
|
}
|
|
16071
16137
|
if (await fileExists5(rootDir, "package.json")) {
|
|
16072
16138
|
try {
|
|
16073
|
-
const content = await readFile9(
|
|
16139
|
+
const content = await readFile9(join10(rootDir, "package.json"), "utf-8");
|
|
16074
16140
|
const pkg = JSON.parse(content);
|
|
16075
16141
|
if (pkg.workspaces) {
|
|
16076
16142
|
signals.push("package.json-workspaces");
|
|
@@ -16079,7 +16145,7 @@ async function detectMonorepo(rootDir) {
|
|
|
16079
16145
|
}
|
|
16080
16146
|
if (await fileExists5(rootDir, "Cargo.toml")) {
|
|
16081
16147
|
try {
|
|
16082
|
-
const content = await readFile9(
|
|
16148
|
+
const content = await readFile9(join10(rootDir, "Cargo.toml"), "utf-8");
|
|
16083
16149
|
if (content.includes("[workspace]")) {
|
|
16084
16150
|
signals.push("Cargo.toml-workspace");
|
|
16085
16151
|
}
|
|
@@ -17125,7 +17191,7 @@ __export(exports_install_command, {
|
|
|
17125
17191
|
});
|
|
17126
17192
|
import { readFile as readFile12 } from "node:fs/promises";
|
|
17127
17193
|
import { homedir as homedir7 } from "node:os";
|
|
17128
|
-
import { basename as basename5, dirname as
|
|
17194
|
+
import { basename as basename5, dirname as dirname7, resolve as resolve12, sep as sep3 } from "node:path";
|
|
17129
17195
|
async function installCommand(options) {
|
|
17130
17196
|
const { target, dryRun, force, global: isGlobal, output, projectRoot } = options;
|
|
17131
17197
|
const baseDir = isGlobal ? homedir7() : projectRoot;
|
|
@@ -17271,7 +17337,7 @@ async function verifyRenderedFiles(manifest, baseDir, results) {
|
|
|
17271
17337
|
if (!parsed.ok) {
|
|
17272
17338
|
warnings.push(`${r.dest}: ${parsed.error.kind} — ${parsed.error.message}`);
|
|
17273
17339
|
} else {
|
|
17274
|
-
const dir = basename5(
|
|
17340
|
+
const dir = basename5(dirname7(r.dest));
|
|
17275
17341
|
const ident = skillIdentifier(parsed.frontmatter);
|
|
17276
17342
|
if (ident !== dir) {
|
|
17277
17343
|
warnings.push(`${r.dest}: identifier "${ident}" does not match its directory "${dir}"`);
|
|
@@ -18515,7 +18581,7 @@ var init_binary_downloader = __esm(() => {
|
|
|
18515
18581
|
import { execFile as execFile2 } from "node:child_process";
|
|
18516
18582
|
import { access as access6, mkdir as mkdir6, mkdtemp, rename as rename2, rm, writeFile as writeFile5 } from "node:fs/promises";
|
|
18517
18583
|
import { homedir as homedir8, tmpdir } from "node:os";
|
|
18518
|
-
import { join as
|
|
18584
|
+
import { join as join10 } from "node:path";
|
|
18519
18585
|
import { promisify as promisify2 } from "node:util";
|
|
18520
18586
|
async function assertTarArchiveSafe(archivePath, destRoot) {
|
|
18521
18587
|
const { stdout } = await execFileAsync2("tar", ["-tzf", archivePath], {
|
|
@@ -18536,7 +18602,7 @@ async function extractHardenedTar(archivePath, destRoot) {
|
|
|
18536
18602
|
class LspInstaller {
|
|
18537
18603
|
lspBinDir;
|
|
18538
18604
|
constructor() {
|
|
18539
|
-
this.lspBinDir =
|
|
18605
|
+
this.lspBinDir = join10(homedir8(), ".codeconductor", "lsp", "bin");
|
|
18540
18606
|
}
|
|
18541
18607
|
async checkInstalled(def) {
|
|
18542
18608
|
try {
|
|
@@ -18664,7 +18730,7 @@ class LspInstaller {
|
|
|
18664
18730
|
}
|
|
18665
18731
|
assertBinaryArtifact(binary);
|
|
18666
18732
|
await mkdir6(this.lspBinDir, { recursive: true });
|
|
18667
|
-
const destPath =
|
|
18733
|
+
const destPath = join10(this.lspBinDir, def.binaryName);
|
|
18668
18734
|
try {
|
|
18669
18735
|
await access6(destPath);
|
|
18670
18736
|
return;
|
|
@@ -18676,16 +18742,16 @@ class LspInstaller {
|
|
|
18676
18742
|
throw new Error(`Failed to download ${def.serverName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
18677
18743
|
}
|
|
18678
18744
|
assertSha256Hex(bytes, binary.sha256);
|
|
18679
|
-
const workDir = await mkdtemp(
|
|
18745
|
+
const workDir = await mkdtemp(join10(tmpdir(), "cc-lsp-"));
|
|
18680
18746
|
try {
|
|
18681
18747
|
const archiveName = binary.url.endsWith(".zip") ? "server.zip" : "server.tar.gz";
|
|
18682
|
-
const archivePath =
|
|
18748
|
+
const archivePath = join10(workDir, archiveName);
|
|
18683
18749
|
await writeFile5(archivePath, bytes);
|
|
18684
18750
|
if (archiveName.endsWith(".zip")) {
|
|
18685
18751
|
throw new Error(`Zip binary installs are not supported yet for ${def.serverName}; use a .tar.gz artifact`);
|
|
18686
18752
|
}
|
|
18687
18753
|
await extractHardenedTar(archivePath, workDir);
|
|
18688
|
-
const candidate =
|
|
18754
|
+
const candidate = join10(workDir, def.binaryName);
|
|
18689
18755
|
try {
|
|
18690
18756
|
await access6(candidate);
|
|
18691
18757
|
await rename2(candidate, destPath);
|
|
@@ -18964,7 +19030,7 @@ var init_install_lsp_command = __esm(() => {
|
|
|
18964
19030
|
|
|
18965
19031
|
// src/core/install/update-transaction.ts
|
|
18966
19032
|
import { mkdir as mkdir7, readFile as readFile13, rm as rm2, unlink, writeFile as writeFile6 } from "node:fs/promises";
|
|
18967
|
-
import { dirname as
|
|
19033
|
+
import { dirname as dirname8, isAbsolute as isAbsolute4, join as join11, relative as relative5, resolve as resolve16, sep as sep5 } from "node:path";
|
|
18968
19034
|
function assertInsideBase(basePath, destination) {
|
|
18969
19035
|
const base = resolve16(basePath);
|
|
18970
19036
|
const absolute = resolve16(base, destination);
|
|
@@ -18996,8 +19062,8 @@ class UpdateTransaction {
|
|
|
18996
19062
|
try {
|
|
18997
19063
|
const content = await readFile13(destination);
|
|
18998
19064
|
snapshots.push({ path: destination, existed: true, content });
|
|
18999
|
-
const backupPath =
|
|
19000
|
-
await mkdir7(
|
|
19065
|
+
const backupPath = join11(backupDir, relative5(resolve16(basePath), resolve16(destination)));
|
|
19066
|
+
await mkdir7(dirname8(backupPath), { recursive: true });
|
|
19001
19067
|
await writeFile6(backupPath, content);
|
|
19002
19068
|
} catch (error) {
|
|
19003
19069
|
if (error.code === "ENOENT") {
|
|
@@ -19017,7 +19083,7 @@ class UpdateTransaction {
|
|
|
19017
19083
|
throw new Error(`Rollback destination is no longer contained: ${snapshot.path}`);
|
|
19018
19084
|
}
|
|
19019
19085
|
if (snapshot.existed) {
|
|
19020
|
-
await mkdir7(
|
|
19086
|
+
await mkdir7(dirname8(gated), { recursive: true });
|
|
19021
19087
|
await writeFile6(gated, snapshot.content);
|
|
19022
19088
|
} else {
|
|
19023
19089
|
await unlink(gated).catch((error) => {
|
|
@@ -19042,7 +19108,7 @@ __export(exports_update_command, {
|
|
|
19042
19108
|
updateCommand: () => updateCommand
|
|
19043
19109
|
});
|
|
19044
19110
|
import { homedir as homedir10 } from "node:os";
|
|
19045
|
-
import { join as
|
|
19111
|
+
import { join as join12, resolve as resolve17 } from "node:path";
|
|
19046
19112
|
import { readFile as readFile14, stat as stat3 } from "node:fs/promises";
|
|
19047
19113
|
async function updateCommand(options) {
|
|
19048
19114
|
const { dryRun, force, global: isGlobal, output, projectRoot, check = false } = options;
|
|
@@ -19152,7 +19218,7 @@ async function updateCommand(options) {
|
|
|
19152
19218
|
const bundledCouncil = resolve17(SRC_PRESETS_DIR, "council", "council.yml");
|
|
19153
19219
|
try {
|
|
19154
19220
|
const content = await readFile14(bundledCouncil, "utf-8");
|
|
19155
|
-
const written = await writeContainedFile(basePath,
|
|
19221
|
+
const written = await writeContainedFile(basePath, join12(".codeconductor", "presets", "council.yml"), content, { force: true });
|
|
19156
19222
|
updated.push(written);
|
|
19157
19223
|
} catch (e) {
|
|
19158
19224
|
throw new Error(`Failed to update council.yml: ${e}`);
|
|
@@ -19161,7 +19227,7 @@ async function updateCommand(options) {
|
|
|
19161
19227
|
if (updateResults.policy) {
|
|
19162
19228
|
try {
|
|
19163
19229
|
const content = await readFile14(POLICY_PATH, "utf-8");
|
|
19164
|
-
const written = await writeContainedFile(basePath,
|
|
19230
|
+
const written = await writeContainedFile(basePath, join12(".codeconductor", "presets", "policy.yml"), content, { force: true });
|
|
19165
19231
|
updated.push(written);
|
|
19166
19232
|
} catch (e) {
|
|
19167
19233
|
throw new Error(`Failed to update policy.yml: ${e}`);
|
|
@@ -19240,13 +19306,13 @@ async function updateCommand(options) {
|
|
|
19240
19306
|
for (const s of updateResults.skills) {
|
|
19241
19307
|
newSkillsLock[s.id] = s.latestVersion;
|
|
19242
19308
|
}
|
|
19243
|
-
let lockRel =
|
|
19309
|
+
let lockRel = join12(".codeconductor", "skills-lock.json");
|
|
19244
19310
|
try {
|
|
19245
19311
|
const statAgents = await stat3(resolve17(basePath, ".agents"));
|
|
19246
19312
|
if (statAgents.isDirectory()) {
|
|
19247
19313
|
const statCodeConductor = await stat3(resolve17(basePath, ".codeconductor")).catch(() => null);
|
|
19248
19314
|
if (!statCodeConductor) {
|
|
19249
|
-
lockRel =
|
|
19315
|
+
lockRel = join12(".agents", "skills-lock.json");
|
|
19250
19316
|
}
|
|
19251
19317
|
}
|
|
19252
19318
|
} catch {}
|
|
@@ -19319,7 +19385,7 @@ __export(exports_migrate_command, {
|
|
|
19319
19385
|
});
|
|
19320
19386
|
import { readFile as readFile15, readdir as readdir3, rm as rm3, writeFile as writeFile7 } from "node:fs/promises";
|
|
19321
19387
|
import { homedir as homedir11 } from "node:os";
|
|
19322
|
-
import { join as
|
|
19388
|
+
import { join as join13, resolve as resolve18 } from "node:path";
|
|
19323
19389
|
function migratePermissionRules(settings) {
|
|
19324
19390
|
const permissions = settings.permissions;
|
|
19325
19391
|
if (typeof permissions !== "object" || permissions === null) {
|
|
@@ -19366,7 +19432,7 @@ function resolveSettingsPath(options) {
|
|
|
19366
19432
|
if (options.file)
|
|
19367
19433
|
return resolve18(options.projectRoot, options.file);
|
|
19368
19434
|
const base = options.global ? homedir11() : options.projectRoot;
|
|
19369
|
-
return
|
|
19435
|
+
return join13(base, ".claude", "settings.json");
|
|
19370
19436
|
}
|
|
19371
19437
|
async function findOrphanedPromptVersions(basePath, isGlobal) {
|
|
19372
19438
|
const found = [];
|
|
@@ -19376,7 +19442,7 @@ async function findOrphanedPromptVersions(basePath, isGlobal) {
|
|
|
19376
19442
|
if (!installed)
|
|
19377
19443
|
continue;
|
|
19378
19444
|
const installPath = getTargetInstallationPath(target, basePath, isGlobal);
|
|
19379
|
-
const promptsDir =
|
|
19445
|
+
const promptsDir = join13(installPath, "prompts");
|
|
19380
19446
|
if (seenDirs.has(promptsDir))
|
|
19381
19447
|
continue;
|
|
19382
19448
|
seenDirs.add(promptsDir);
|
|
@@ -19391,7 +19457,7 @@ async function findOrphanedPromptVersions(basePath, isGlobal) {
|
|
|
19391
19457
|
continue;
|
|
19392
19458
|
if (entry.name === CURRENT_PRESET_VERSION)
|
|
19393
19459
|
continue;
|
|
19394
|
-
found.push({ target, path:
|
|
19460
|
+
found.push({ target, path: join13(promptsDir, entry.name), version: entry.name });
|
|
19395
19461
|
}
|
|
19396
19462
|
}
|
|
19397
19463
|
return found;
|
|
@@ -19673,7 +19739,7 @@ __export(exports_help_command, {
|
|
|
19673
19739
|
helpCommand: () => helpCommand
|
|
19674
19740
|
});
|
|
19675
19741
|
import { readdir as readdir4 } from "node:fs/promises";
|
|
19676
|
-
import { join as
|
|
19742
|
+
import { join as join14 } from "node:path";
|
|
19677
19743
|
async function scanPresetDir(projectRoot, target) {
|
|
19678
19744
|
const inventory = {
|
|
19679
19745
|
target,
|
|
@@ -19682,12 +19748,12 @@ async function scanPresetDir(projectRoot, target) {
|
|
|
19682
19748
|
agents: [],
|
|
19683
19749
|
workflows: []
|
|
19684
19750
|
};
|
|
19685
|
-
const presetDir =
|
|
19751
|
+
const presetDir = join14(projectRoot, "presets", target);
|
|
19686
19752
|
try {
|
|
19687
19753
|
const entries = await readdir4(presetDir, { withFileTypes: true });
|
|
19688
19754
|
for (const entry of entries) {
|
|
19689
19755
|
if (entry.isDirectory()) {
|
|
19690
|
-
const subDir =
|
|
19756
|
+
const subDir = join14(presetDir, entry.name);
|
|
19691
19757
|
const subEntries = await readdir4(subDir, { withFileTypes: true });
|
|
19692
19758
|
for (const sub of subEntries) {
|
|
19693
19759
|
if (sub.isFile()) {
|
|
@@ -19814,13 +19880,13 @@ __export(exports_debt_harvest_command, {
|
|
|
19814
19880
|
debtHarvestCommand: () => debtHarvestCommand
|
|
19815
19881
|
});
|
|
19816
19882
|
import { readdir as readdir5, readFile as readFile16, writeFile as writeFile8, mkdir as mkdir8 } from "node:fs/promises";
|
|
19817
|
-
import { join as
|
|
19883
|
+
import { join as join15, relative as relative6, extname } from "node:path";
|
|
19818
19884
|
async function walkDir(dir, extensions) {
|
|
19819
19885
|
const results = [];
|
|
19820
19886
|
try {
|
|
19821
19887
|
const entries = await readdir5(dir, { withFileTypes: true });
|
|
19822
19888
|
for (const entry of entries) {
|
|
19823
|
-
const fullPath =
|
|
19889
|
+
const fullPath = join15(dir, entry.name);
|
|
19824
19890
|
if (entry.isDirectory()) {
|
|
19825
19891
|
if (entry.name.startsWith(".") || entry.name === "node_modules")
|
|
19826
19892
|
continue;
|
|
@@ -19887,7 +19953,7 @@ function renderLedger(entries) {
|
|
|
19887
19953
|
async function debtHarvestCommand(options) {
|
|
19888
19954
|
const { projectRoot, dir = "src", output } = options;
|
|
19889
19955
|
try {
|
|
19890
|
-
const targetDir =
|
|
19956
|
+
const targetDir = join15(projectRoot, dir);
|
|
19891
19957
|
const files = await walkDir(targetDir, SOURCE_EXTENSIONS);
|
|
19892
19958
|
const allEntries = [];
|
|
19893
19959
|
for (const file of files) {
|
|
@@ -19895,9 +19961,9 @@ async function debtHarvestCommand(options) {
|
|
|
19895
19961
|
const entries = extractDefers(content, relative6(projectRoot, file));
|
|
19896
19962
|
allEntries.push(...entries);
|
|
19897
19963
|
}
|
|
19898
|
-
const ledgerDir =
|
|
19964
|
+
const ledgerDir = join15(projectRoot, ".codeconductor");
|
|
19899
19965
|
await mkdir8(ledgerDir, { recursive: true });
|
|
19900
|
-
const ledgerPath =
|
|
19966
|
+
const ledgerPath = join15(ledgerDir, "debt-ledger.md");
|
|
19901
19967
|
const ledgerContent = renderLedger(allEntries);
|
|
19902
19968
|
await writeFile8(ledgerPath, ledgerContent, "utf-8");
|
|
19903
19969
|
if (output === "json") {
|
|
@@ -20332,27 +20398,27 @@ var init_goal_planner = __esm(() => {
|
|
|
20332
20398
|
});
|
|
20333
20399
|
|
|
20334
20400
|
// src/core/product-graph/paths.ts
|
|
20335
|
-
import { join as
|
|
20401
|
+
import { join as join16 } from "node:path";
|
|
20336
20402
|
function productGraphPath(projectRoot) {
|
|
20337
|
-
return
|
|
20403
|
+
return join16(projectRoot, PRODUCT_DIR, PRODUCT_GRAPH_FILE);
|
|
20338
20404
|
}
|
|
20339
20405
|
function productMetaPath(projectRoot) {
|
|
20340
|
-
return
|
|
20406
|
+
return join16(projectRoot, PRODUCT_DIR, PRODUCT_META_FILE);
|
|
20341
20407
|
}
|
|
20342
20408
|
function eventsPath(projectRoot) {
|
|
20343
|
-
return
|
|
20409
|
+
return join16(projectRoot, PRODUCT_DIR, EVENTS_FILE);
|
|
20344
20410
|
}
|
|
20345
20411
|
function operationalStatePath(projectRoot) {
|
|
20346
|
-
return
|
|
20412
|
+
return join16(projectRoot, PRODUCT_DIR, OPERATIONAL_STATE_FILE);
|
|
20347
20413
|
}
|
|
20348
20414
|
function strategicPath(projectRoot) {
|
|
20349
|
-
return
|
|
20415
|
+
return join16(projectRoot, PRODUCT_DIR, STRATEGIC_FILE);
|
|
20350
20416
|
}
|
|
20351
20417
|
function productReportPath(projectRoot) {
|
|
20352
|
-
return
|
|
20418
|
+
return join16(projectRoot, PRODUCT_DIR, PRODUCT_REPORT_FILE);
|
|
20353
20419
|
}
|
|
20354
20420
|
function evidenceDir(projectRoot) {
|
|
20355
|
-
return
|
|
20421
|
+
return join16(projectRoot, PRODUCT_DIR, EVIDENCE_DIR);
|
|
20356
20422
|
}
|
|
20357
20423
|
var PRODUCT_DIR = ".codeconductor", PRODUCT_GRAPH_FILE = "product-graph.json", PRODUCT_META_FILE = "product-meta.json", EVENTS_FILE = "events.jsonl", OPERATIONAL_STATE_FILE = "operational-state.json", STRATEGIC_FILE = "strategic.json", PRODUCT_REPORT_FILE = "product-report.md", EVIDENCE_DIR = "evidence";
|
|
20358
20424
|
var init_paths = () => {};
|
|
@@ -20370,7 +20436,7 @@ __export(exports_graph_store, {
|
|
|
20370
20436
|
upsertNode: () => upsertNode
|
|
20371
20437
|
});
|
|
20372
20438
|
import { mkdir as mkdir9, readFile as readFile17, writeFile as writeFile9 } from "node:fs/promises";
|
|
20373
|
-
import { dirname as
|
|
20439
|
+
import { dirname as dirname9 } from "node:path";
|
|
20374
20440
|
async function loadGraph(projectRoot) {
|
|
20375
20441
|
try {
|
|
20376
20442
|
const raw = await readFile17(productGraphPath(projectRoot), "utf-8");
|
|
@@ -20386,7 +20452,7 @@ async function saveGraph(projectRoot, graph) {
|
|
|
20386
20452
|
try {
|
|
20387
20453
|
const validated = ProductGraphSchema.parse(graph);
|
|
20388
20454
|
const path = productGraphPath(projectRoot);
|
|
20389
|
-
await mkdir9(
|
|
20455
|
+
await mkdir9(dirname9(path), { recursive: true });
|
|
20390
20456
|
await writeFile9(path, JSON.stringify(validated, null, 2), "utf-8");
|
|
20391
20457
|
return ok(undefined);
|
|
20392
20458
|
} catch (e) {
|
|
@@ -20996,7 +21062,7 @@ function slugify(text) {
|
|
|
20996
21062
|
|
|
20997
21063
|
// src/core/knowledge/source-parsers.ts
|
|
20998
21064
|
import { readFile as readFile20 } from "node:fs/promises";
|
|
20999
|
-
import { basename as basename6, join as
|
|
21065
|
+
import { basename as basename6, join as join17, relative as relative7, sep as sep6 } from "node:path";
|
|
21000
21066
|
async function parseAdrFile(filePath) {
|
|
21001
21067
|
try {
|
|
21002
21068
|
const content = await readFile20(filePath, "utf-8");
|
|
@@ -21048,7 +21114,7 @@ function adrToEntities(adr, source) {
|
|
|
21048
21114
|
}
|
|
21049
21115
|
async function parseReadmeEntities(projectRoot, productName) {
|
|
21050
21116
|
try {
|
|
21051
|
-
const content = await readFile20(
|
|
21117
|
+
const content = await readFile20(join17(projectRoot, "README.md"), "utf-8");
|
|
21052
21118
|
const firstPara = content.split(`
|
|
21053
21119
|
|
|
21054
21120
|
`).find((p) => p.trim() && !p.startsWith("#") && !p.startsWith(">")) ?? "";
|
|
@@ -21069,7 +21135,7 @@ async function parseReadmeEntities(projectRoot, productName) {
|
|
|
21069
21135
|
}
|
|
21070
21136
|
async function parseGraphifyEntities(projectRoot) {
|
|
21071
21137
|
try {
|
|
21072
|
-
const raw = await readFile20(
|
|
21138
|
+
const raw = await readFile20(join17(projectRoot, "graphify-out", "graph.json"), "utf-8");
|
|
21073
21139
|
const graph = JSON.parse(raw);
|
|
21074
21140
|
const entities = [];
|
|
21075
21141
|
for (const node2 of graph.nodes ?? []) {
|
|
@@ -21093,14 +21159,14 @@ async function parseGraphifyEntities(projectRoot) {
|
|
|
21093
21159
|
async function scanSrcComponents(projectRoot) {
|
|
21094
21160
|
const { readdir: readdir6 } = await import("node:fs/promises");
|
|
21095
21161
|
const entities = [];
|
|
21096
|
-
const srcDir =
|
|
21162
|
+
const srcDir = join17(projectRoot, "src");
|
|
21097
21163
|
async function walk(dir, prefix) {
|
|
21098
21164
|
try {
|
|
21099
21165
|
const entries = await readdir6(dir, { withFileTypes: true });
|
|
21100
21166
|
for (const entry of entries) {
|
|
21101
21167
|
if (entry.name.startsWith("."))
|
|
21102
21168
|
continue;
|
|
21103
|
-
const full =
|
|
21169
|
+
const full = join17(dir, entry.name);
|
|
21104
21170
|
if (entry.isDirectory()) {
|
|
21105
21171
|
if (entry.name === "node_modules")
|
|
21106
21172
|
continue;
|
|
@@ -21173,7 +21239,7 @@ var init_episodic_store = __esm(() => {
|
|
|
21173
21239
|
// src/core/knowledge/ingest-pipeline.ts
|
|
21174
21240
|
import { createHash as createHash3 } from "node:crypto";
|
|
21175
21241
|
import { readFile as readFile22 } from "node:fs/promises";
|
|
21176
|
-
import { join as
|
|
21242
|
+
import { join as join18, relative as relative8, sep as sep7 } from "node:path";
|
|
21177
21243
|
import { mkdir as mkdir12, writeFile as writeFile11 } from "node:fs/promises";
|
|
21178
21244
|
async function mapLimit(items, limit, fn) {
|
|
21179
21245
|
if (items.length === 0)
|
|
@@ -21209,7 +21275,7 @@ async function collectDeferRisks(projectRoot) {
|
|
|
21209
21275
|
for (const entry of entries) {
|
|
21210
21276
|
if (entry.name.startsWith(".") || entry.name === "node_modules")
|
|
21211
21277
|
continue;
|
|
21212
|
-
const full =
|
|
21278
|
+
const full = join18(dir, entry.name);
|
|
21213
21279
|
if (entry.isDirectory()) {
|
|
21214
21280
|
await walk(full);
|
|
21215
21281
|
} else if (entry.name.endsWith(".ts")) {
|
|
@@ -21218,7 +21284,7 @@ async function collectDeferRisks(projectRoot) {
|
|
|
21218
21284
|
}
|
|
21219
21285
|
} catch {}
|
|
21220
21286
|
}
|
|
21221
|
-
await walk(
|
|
21287
|
+
await walk(join18(projectRoot, "src"));
|
|
21222
21288
|
const perFile = await mapLimit(files, WALK_READ_CONCURRENCY, async (full) => {
|
|
21223
21289
|
const entities = [];
|
|
21224
21290
|
const content = await readFile22(full, "utf-8");
|
|
@@ -21281,12 +21347,12 @@ async function parseBacklogEntities(projectRoot) {
|
|
|
21281
21347
|
}
|
|
21282
21348
|
async function parseAdrEntities(projectRoot) {
|
|
21283
21349
|
const { readdir: readdir6 } = await import("node:fs/promises");
|
|
21284
|
-
const adrDir =
|
|
21350
|
+
const adrDir = join18(projectRoot, "docs", "adr");
|
|
21285
21351
|
const entities = [];
|
|
21286
21352
|
try {
|
|
21287
21353
|
const files = (await readdir6(adrDir)).filter((file) => file.endsWith(".md"));
|
|
21288
21354
|
const parsed = await Promise.all(files.map(async (file) => {
|
|
21289
|
-
const adr = await parseAdrFile(
|
|
21355
|
+
const adr = await parseAdrFile(join18(adrDir, file));
|
|
21290
21356
|
return adr ? adrToEntities(adr, `docs/adr/${file}`) : [];
|
|
21291
21357
|
}));
|
|
21292
21358
|
entities.push(...parsed.flat());
|
|
@@ -21378,7 +21444,7 @@ async function runIngest(projectRoot, productName) {
|
|
|
21378
21444
|
await saveGraph2(projectRoot, graph);
|
|
21379
21445
|
const sourceHashes = {};
|
|
21380
21446
|
for (const src of ["README.md", "BACKLOG.md", "ROADMAP.md"]) {
|
|
21381
|
-
const h = await hashFile(
|
|
21447
|
+
const h = await hashFile(join18(projectRoot, src));
|
|
21382
21448
|
if (h)
|
|
21383
21449
|
sourceHashes[src] = h;
|
|
21384
21450
|
}
|
|
@@ -21388,7 +21454,7 @@ async function runIngest(projectRoot, productName) {
|
|
|
21388
21454
|
lastIngestAt: new Date().toISOString(),
|
|
21389
21455
|
sourceHashes
|
|
21390
21456
|
};
|
|
21391
|
-
await mkdir12(
|
|
21457
|
+
await mkdir12(join18(projectRoot, ".codeconductor"), { recursive: true });
|
|
21392
21458
|
await writeFile11(productMetaPath(projectRoot), JSON.stringify(ProductMetaSchema.parse(meta), null, 2), "utf-8");
|
|
21393
21459
|
await appendEvent(projectRoot, {
|
|
21394
21460
|
type: "ingest.completed",
|
|
@@ -21813,10 +21879,10 @@ var init_outcome_store = __esm(() => {
|
|
|
21813
21879
|
|
|
21814
21880
|
// src/core/feedback/feedback-ingestor.ts
|
|
21815
21881
|
import { readFile as readFile27 } from "node:fs/promises";
|
|
21816
|
-
import { join as
|
|
21882
|
+
import { join as join19 } from "node:path";
|
|
21817
21883
|
async function parseChangelogLearnings(projectRoot) {
|
|
21818
21884
|
try {
|
|
21819
|
-
const content = await readFile27(
|
|
21885
|
+
const content = await readFile27(join19(projectRoot, "CHANGELOG.md"), "utf-8");
|
|
21820
21886
|
const unreleased = content.match(/## \[Unreleased\]([\s\S]*?)(?=## \[|\n## )/i);
|
|
21821
21887
|
if (!unreleased)
|
|
21822
21888
|
return [];
|
|
@@ -22417,11 +22483,12 @@ __export(exports_rdd_receipt, {
|
|
|
22417
22483
|
captureReceipt: () => captureReceipt,
|
|
22418
22484
|
collectReceiptPaths: () => collectReceiptPaths,
|
|
22419
22485
|
isRddReceipt: () => isRddReceipt,
|
|
22420
|
-
verifyReceipt: () => verifyReceipt
|
|
22486
|
+
verifyReceipt: () => verifyReceipt,
|
|
22487
|
+
verifyReceiptLock: () => verifyReceiptLock
|
|
22421
22488
|
});
|
|
22422
|
-
import { createHash as createHash4 } from "node:crypto";
|
|
22423
|
-
import { readdir as readdir7, readFile as readFile28 } from "node:fs/promises";
|
|
22424
|
-
import { join as
|
|
22489
|
+
import { createHash as createHash4, randomBytes } from "node:crypto";
|
|
22490
|
+
import { mkdir as mkdir17, readdir as readdir7, readFile as readFile28, writeFile as writeFile17 } from "node:fs/promises";
|
|
22491
|
+
import { join as join20, relative as relative9, resolve as resolve26, sep as sep8 } from "node:path";
|
|
22425
22492
|
function sha2562(content) {
|
|
22426
22493
|
return createHash4("sha256").update(content).digest("hex");
|
|
22427
22494
|
}
|
|
@@ -22453,6 +22520,23 @@ function manifestHash(paths) {
|
|
|
22453
22520
|
return sha2562(paths.map((entry) => `${entry.path}\x00${entry.hash}`).join(`
|
|
22454
22521
|
`));
|
|
22455
22522
|
}
|
|
22523
|
+
function receiptRegistryDir(projectRoot) {
|
|
22524
|
+
return join20(resolve26(projectRoot), ".codeconductor", "rdd-receipts");
|
|
22525
|
+
}
|
|
22526
|
+
function isWellFormedNonce(nonce) {
|
|
22527
|
+
return typeof nonce === "string" && /^[0-9a-f]{32}$/.test(nonce);
|
|
22528
|
+
}
|
|
22529
|
+
async function isRegisteredReceipt(projectRoot, receipt) {
|
|
22530
|
+
if (!isWellFormedNonce(receipt.nonce))
|
|
22531
|
+
return false;
|
|
22532
|
+
try {
|
|
22533
|
+
const raw = await readFile28(join20(receiptRegistryDir(projectRoot), `${receipt.nonce}.json`), "utf-8");
|
|
22534
|
+
const entry = JSON.parse(raw);
|
|
22535
|
+
return entry.manifestHash === receipt.manifestHash;
|
|
22536
|
+
} catch {
|
|
22537
|
+
return false;
|
|
22538
|
+
}
|
|
22539
|
+
}
|
|
22456
22540
|
function isRddReceipt(value) {
|
|
22457
22541
|
if (!value || typeof value !== "object")
|
|
22458
22542
|
return false;
|
|
@@ -22466,17 +22550,26 @@ async function captureReceipt(projectRoot, input) {
|
|
|
22466
22550
|
throw new Error("RDD receipts require at least one protected path");
|
|
22467
22551
|
}
|
|
22468
22552
|
const paths = await fingerprint(projectRoot, input.paths);
|
|
22469
|
-
|
|
22553
|
+
const hashed = manifestHash(paths);
|
|
22554
|
+
const nonce = randomBytes(16).toString("hex");
|
|
22555
|
+
const capturedAt = new Date().toISOString();
|
|
22556
|
+
const receipt = {
|
|
22470
22557
|
version: 1,
|
|
22471
22558
|
taskId: input.taskId,
|
|
22472
22559
|
phase: input.phase,
|
|
22473
22560
|
paths,
|
|
22474
22561
|
coverage: input.coverage ?? "paths",
|
|
22475
|
-
manifestHash:
|
|
22562
|
+
manifestHash: hashed,
|
|
22476
22563
|
command: input.command,
|
|
22477
22564
|
outcome: input.outcome,
|
|
22478
|
-
capturedAt
|
|
22565
|
+
capturedAt,
|
|
22566
|
+
nonce
|
|
22479
22567
|
};
|
|
22568
|
+
const directory = receiptRegistryDir(projectRoot);
|
|
22569
|
+
await mkdir17(directory, { recursive: true });
|
|
22570
|
+
const entry = { manifestHash: hashed, taskId: input.taskId, capturedAt };
|
|
22571
|
+
await writeFile17(join20(directory, `${nonce}.json`), JSON.stringify(entry, null, 2), "utf-8");
|
|
22572
|
+
return receipt;
|
|
22480
22573
|
}
|
|
22481
22574
|
async function collectReceiptPaths(projectRoot) {
|
|
22482
22575
|
const root = resolve26(projectRoot);
|
|
@@ -22486,17 +22579,18 @@ async function collectReceiptPaths(projectRoot) {
|
|
|
22486
22579
|
for (const entry of entries) {
|
|
22487
22580
|
if (entry.isDirectory()) {
|
|
22488
22581
|
if (!EXCLUDED_DIRECTORIES.has(entry.name))
|
|
22489
|
-
await visit2(
|
|
22582
|
+
await visit2(join20(current, entry.name));
|
|
22490
22583
|
continue;
|
|
22491
22584
|
}
|
|
22492
22585
|
if (entry.isFile())
|
|
22493
|
-
paths.push(relative9(root,
|
|
22586
|
+
paths.push(relative9(root, join20(current, entry.name)).split(sep8).join("/"));
|
|
22494
22587
|
}
|
|
22495
22588
|
}
|
|
22496
22589
|
await visit2(root);
|
|
22497
22590
|
return paths.sort();
|
|
22498
22591
|
}
|
|
22499
22592
|
async function verifyReceipt(projectRoot, receipt) {
|
|
22593
|
+
const registered = await isRegisteredReceipt(projectRoot, receipt);
|
|
22500
22594
|
const expected = new Map(receipt.paths.map((entry) => [entry.path, entry.hash]));
|
|
22501
22595
|
const changedPaths = [];
|
|
22502
22596
|
const current = [];
|
|
@@ -22522,12 +22616,24 @@ async function verifyReceipt(projectRoot, receipt) {
|
|
|
22522
22616
|
changedPaths.sort();
|
|
22523
22617
|
const actualHash = manifestHash(current.sort((left, right) => left.path.localeCompare(right.path)));
|
|
22524
22618
|
return {
|
|
22525
|
-
valid: changedPaths.length === 0 && actualHash === receipt.manifestHash,
|
|
22619
|
+
valid: registered && changedPaths.length === 0 && actualHash === receipt.manifestHash,
|
|
22526
22620
|
expectedHash: receipt.manifestHash,
|
|
22527
22621
|
actualHash,
|
|
22528
22622
|
changedPaths
|
|
22529
22623
|
};
|
|
22530
22624
|
}
|
|
22625
|
+
async function verifyReceiptLock(projectRoot, lockPath) {
|
|
22626
|
+
let parsed;
|
|
22627
|
+
try {
|
|
22628
|
+
parsed = JSON.parse(await readFile28(resolve26(projectRoot, lockPath), "utf-8"));
|
|
22629
|
+
} catch {
|
|
22630
|
+
return { valid: false, changedPaths: [] };
|
|
22631
|
+
}
|
|
22632
|
+
if (!isRddReceipt(parsed))
|
|
22633
|
+
return { valid: false, changedPaths: [] };
|
|
22634
|
+
const verification = await verifyReceipt(projectRoot, parsed);
|
|
22635
|
+
return { valid: verification.valid, changedPaths: verification.changedPaths };
|
|
22636
|
+
}
|
|
22531
22637
|
var EXCLUDED_DIRECTORIES;
|
|
22532
22638
|
var init_rdd_receipt = __esm(() => {
|
|
22533
22639
|
EXCLUDED_DIRECTORIES = new Set([
|
|
@@ -22543,8 +22649,8 @@ var init_rdd_receipt = __esm(() => {
|
|
|
22543
22649
|
// src/core/verification/verification-runner.ts
|
|
22544
22650
|
import { existsSync as existsSync3 } from "node:fs";
|
|
22545
22651
|
import { readFile as readFile29 } from "node:fs/promises";
|
|
22546
|
-
import { dirname as
|
|
22547
|
-
import { mkdir as
|
|
22652
|
+
import { dirname as dirname10, join as join21, resolve as resolve27 } from "node:path";
|
|
22653
|
+
import { mkdir as mkdir18, readdir as readdir8, writeFile as writeFile18 } from "node:fs/promises";
|
|
22548
22654
|
function isPassingEvidence(ev) {
|
|
22549
22655
|
switch (ev.type) {
|
|
22550
22656
|
case "verification":
|
|
@@ -22571,7 +22677,7 @@ async function isCurrentPassingEvidence(projectRoot, ev) {
|
|
|
22571
22677
|
}
|
|
22572
22678
|
function evidenceFilePath(evDir, id) {
|
|
22573
22679
|
const path = resolve27(evDir, `${id.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
|
|
22574
|
-
if (
|
|
22680
|
+
if (dirname10(path) !== resolve27(evDir)) {
|
|
22575
22681
|
return err(new Error(`Refusing to write evidence for "${id}" outside ${evDir}`));
|
|
22576
22682
|
}
|
|
22577
22683
|
return ok(path);
|
|
@@ -22582,8 +22688,8 @@ async function persistEvidence(projectRoot, evidence) {
|
|
|
22582
22688
|
if (!evidencePath.success)
|
|
22583
22689
|
return evidencePath;
|
|
22584
22690
|
try {
|
|
22585
|
-
await
|
|
22586
|
-
await
|
|
22691
|
+
await mkdir18(evDir, { recursive: true });
|
|
22692
|
+
await writeFile18(evidencePath.data, JSON.stringify(evidence, null, 2), "utf-8");
|
|
22587
22693
|
} catch (e) {
|
|
22588
22694
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
22589
22695
|
}
|
|
@@ -22605,7 +22711,7 @@ async function collectTaskEvidence(projectRoot, taskId) {
|
|
|
22605
22711
|
if (!file.endsWith(".json"))
|
|
22606
22712
|
continue;
|
|
22607
22713
|
try {
|
|
22608
|
-
const raw = await readFile29(
|
|
22714
|
+
const raw = await readFile29(join21(evDir, file), "utf-8");
|
|
22609
22715
|
const ev = EvidenceSchema.parse(JSON.parse(raw));
|
|
22610
22716
|
if (ev.relatedTask === taskId)
|
|
22611
22717
|
records.push(ev);
|
|
@@ -23984,13 +24090,13 @@ __export(exports_rdd_command, {
|
|
|
23984
24090
|
});
|
|
23985
24091
|
import { execFile as execFile4 } from "node:child_process";
|
|
23986
24092
|
import { existsSync as existsSync4 } from "node:fs";
|
|
23987
|
-
import { mkdir as
|
|
23988
|
-
import { dirname as
|
|
24093
|
+
import { mkdir as mkdir19, readFile as readFile30, readdir as readdir9, rename as rename3, writeFile as writeFile19, chmod } from "node:fs/promises";
|
|
24094
|
+
import { dirname as dirname11, resolve as resolve28 } from "node:path";
|
|
23989
24095
|
import { promisify as promisify4 } from "node:util";
|
|
23990
24096
|
function receiptPath(projectRoot, id) {
|
|
23991
24097
|
const directory = resolve28(evidenceDir(projectRoot));
|
|
23992
24098
|
const path = resolve28(directory, `${id.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
|
|
23993
|
-
if (
|
|
24099
|
+
if (dirname11(path) !== directory)
|
|
23994
24100
|
throw new Error(`Invalid RDD receipt id: ${id}`);
|
|
23995
24101
|
return path;
|
|
23996
24102
|
}
|
|
@@ -24038,7 +24144,7 @@ async function installHooks(projectRoot) {
|
|
|
24038
24144
|
encoding: "utf8"
|
|
24039
24145
|
});
|
|
24040
24146
|
const hooksDir = resolve28(projectRoot, stdout.trim());
|
|
24041
|
-
await
|
|
24147
|
+
await mkdir19(hooksDir, { recursive: true });
|
|
24042
24148
|
const installed = [];
|
|
24043
24149
|
const skipped = [];
|
|
24044
24150
|
for (const hook of ["pre-commit", "pre-push"]) {
|
|
@@ -24065,7 +24171,7 @@ if [ -x "$HOOK_DIR/${hook}.rdd-original" ]; then
|
|
|
24065
24171
|
fi
|
|
24066
24172
|
cc-codeconductor rdd git-check
|
|
24067
24173
|
`;
|
|
24068
|
-
await
|
|
24174
|
+
await writeFile19(path, script, "utf8");
|
|
24069
24175
|
await chmod(path, 493);
|
|
24070
24176
|
installed.push(hook);
|
|
24071
24177
|
}
|
|
@@ -24097,8 +24203,8 @@ async function rddCommand(options) {
|
|
|
24097
24203
|
data: { rddReceipt: receipt }
|
|
24098
24204
|
};
|
|
24099
24205
|
const directory = evidenceDir(options.projectRoot);
|
|
24100
|
-
await
|
|
24101
|
-
await
|
|
24206
|
+
await mkdir19(directory, { recursive: true });
|
|
24207
|
+
await writeFile19(receiptPath(options.projectRoot, id), JSON.stringify(evidence, null, 2), "utf-8");
|
|
24102
24208
|
return { code: 0, data: { success: true, receiptId: id, receipt } };
|
|
24103
24209
|
}
|
|
24104
24210
|
if (options.subcommand === "verify") {
|
|
@@ -24324,15 +24430,7 @@ var init_output_validator = __esm(() => {
|
|
|
24324
24430
|
|
|
24325
24431
|
// src/core/ccep/prompt-compiler.ts
|
|
24326
24432
|
function buildSystemLayer() {
|
|
24327
|
-
return
|
|
24328
|
-
"You are a CodeConductor agent operating under CCEP-1.",
|
|
24329
|
-
"Rules:",
|
|
24330
|
-
"- Do not invent context.",
|
|
24331
|
-
"- If critical data is missing, return questions in structured output.",
|
|
24332
|
-
"- Produce valid JSON only — no free-form prose as the final answer.",
|
|
24333
|
-
"- Match the output schema exactly."
|
|
24334
|
-
].join(`
|
|
24335
|
-
`);
|
|
24433
|
+
return "You are a CodeConductor agent (CCEP-1): never invent context; missing critical data goes to structured output as questions; the final answer is valid JSON only, matching the output schema exactly.";
|
|
24336
24434
|
}
|
|
24337
24435
|
function buildAgentLayer(role, phase, outputSchema) {
|
|
24338
24436
|
const label = ROLE_LABELS[role] ?? role;
|
|
@@ -24342,11 +24440,11 @@ function buildAgentLayer(role, phase, outputSchema) {
|
|
|
24342
24440
|
Convert product intent into a structured plan without writing code.`;
|
|
24343
24441
|
} else if (role === "implementer") {
|
|
24344
24442
|
instruction = `You are the ${label}.
|
|
24345
|
-
|
|
24443
|
+
Work only on phase ${phase}.
|
|
24346
24444
|
Write the minimal diff.`;
|
|
24347
24445
|
} else {
|
|
24348
24446
|
instruction = `You are the ${label}.
|
|
24349
|
-
|
|
24447
|
+
Work only on phase ${phase}.`;
|
|
24350
24448
|
}
|
|
24351
24449
|
return `${instruction}
|
|
24352
24450
|
Return ${outputSchema} JSON only.`;
|
|
@@ -24511,13 +24609,13 @@ var init_prompt_compiler = __esm(() => {
|
|
|
24511
24609
|
});
|
|
24512
24610
|
|
|
24513
24611
|
// src/core/ccep/command-parser.ts
|
|
24514
|
-
import { existsSync as existsSync5, readFileSync as
|
|
24515
|
-
import { basename as basename7, join as
|
|
24612
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
|
|
24613
|
+
import { basename as basename7, join as join22 } from "node:path";
|
|
24516
24614
|
function readProjectId(projectRoot) {
|
|
24517
|
-
const packageJsonPath =
|
|
24615
|
+
const packageJsonPath = join22(projectRoot, "package.json");
|
|
24518
24616
|
if (existsSync5(packageJsonPath)) {
|
|
24519
24617
|
try {
|
|
24520
|
-
const pkg = JSON.parse(
|
|
24618
|
+
const pkg = JSON.parse(readFileSync4(packageJsonPath, "utf-8"));
|
|
24521
24619
|
if (pkg.name) {
|
|
24522
24620
|
return pkg.name;
|
|
24523
24621
|
}
|
|
@@ -24544,10 +24642,10 @@ function parseCommand(command, userRequest, projectRoot) {
|
|
|
24544
24642
|
maxVariance: "low"
|
|
24545
24643
|
}
|
|
24546
24644
|
};
|
|
24547
|
-
const packageJsonPath =
|
|
24645
|
+
const packageJsonPath = join22(projectRoot, "package.json");
|
|
24548
24646
|
if (existsSync5(packageJsonPath)) {
|
|
24549
24647
|
try {
|
|
24550
|
-
const pkg = JSON.parse(
|
|
24648
|
+
const pkg = JSON.parse(readFileSync4(packageJsonPath, "utf-8"));
|
|
24551
24649
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
24552
24650
|
const stack = ["typescript"];
|
|
24553
24651
|
if (deps?.next)
|
|
@@ -24618,9 +24716,9 @@ var init_workflow_profile_loader = __esm(() => {
|
|
|
24618
24716
|
|
|
24619
24717
|
// src/core/evaluation/harness-catalog.ts
|
|
24620
24718
|
import { createHash as createHash5 } from "node:crypto";
|
|
24621
|
-
import { existsSync as existsSync6, readFileSync as
|
|
24622
|
-
import { copyFile as copyFile2, mkdir as
|
|
24623
|
-
import { dirname as
|
|
24719
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "node:fs";
|
|
24720
|
+
import { copyFile as copyFile2, mkdir as mkdir20, readFile as readFile31, readdir as readdir10, rm as rm4, writeFile as writeFile20 } from "node:fs/promises";
|
|
24721
|
+
import { dirname as dirname12, join as join23, resolve as resolve29 } from "node:path";
|
|
24624
24722
|
function catalogIds(catalog = DEFAULT_HARNESS_CATALOG) {
|
|
24625
24723
|
return catalog.components.map((c) => c.id);
|
|
24626
24724
|
}
|
|
@@ -24697,7 +24795,7 @@ function isProductGraphDisabled(projectRoot) {
|
|
|
24697
24795
|
const path = activeOverlayPath(projectRoot);
|
|
24698
24796
|
if (!existsSync6(path))
|
|
24699
24797
|
return false;
|
|
24700
|
-
const overlay = HarnessOverlaySchema.parse($parse(
|
|
24798
|
+
const overlay = HarnessOverlaySchema.parse($parse(readFileSync5(path, "utf-8")));
|
|
24701
24799
|
return overlay.disableProductGraph === true || overlay.disabledComponents.includes("product_graph");
|
|
24702
24800
|
} catch {
|
|
24703
24801
|
return false;
|
|
@@ -24743,22 +24841,22 @@ async function restoreOverlayBackup(projectRoot) {
|
|
|
24743
24841
|
const backupRoot = resolve29(projectRoot, EVAL_DIR2, OVERLAY_BACKUP_DIR);
|
|
24744
24842
|
if (!existsSync6(backupRoot))
|
|
24745
24843
|
return;
|
|
24746
|
-
const configBackup =
|
|
24844
|
+
const configBackup = join23(backupRoot, "config.yml");
|
|
24747
24845
|
const configDest = resolve29(projectRoot, ".codeconductor", "config.yml");
|
|
24748
24846
|
if (existsSync6(configBackup)) {
|
|
24749
|
-
await
|
|
24847
|
+
await mkdir20(dirname12(configDest), { recursive: true });
|
|
24750
24848
|
await copyFile2(configBackup, configDest);
|
|
24751
24849
|
}
|
|
24752
|
-
const workflowsBackup =
|
|
24850
|
+
const workflowsBackup = join23(backupRoot, "workflows");
|
|
24753
24851
|
const workflowsDest = resolve29(projectRoot, ".codeconductor", "workflows");
|
|
24754
24852
|
if (existsSync6(workflowsBackup)) {
|
|
24755
|
-
await
|
|
24853
|
+
await mkdir20(workflowsDest, { recursive: true });
|
|
24756
24854
|
const files = await readdir10(workflowsBackup);
|
|
24757
24855
|
for (const file of files) {
|
|
24758
|
-
await copyFile2(
|
|
24856
|
+
await copyFile2(join23(workflowsBackup, file), join23(workflowsDest, file));
|
|
24759
24857
|
}
|
|
24760
24858
|
}
|
|
24761
|
-
const overlayBackup =
|
|
24859
|
+
const overlayBackup = join23(backupRoot, ACTIVE_OVERLAY_FILE);
|
|
24762
24860
|
const overlayDest = activeOverlayPath(projectRoot);
|
|
24763
24861
|
if (existsSync6(overlayBackup)) {
|
|
24764
24862
|
await copyFile2(overlayBackup, overlayDest);
|
|
@@ -24770,25 +24868,25 @@ async function snapshotForBackup(projectRoot) {
|
|
|
24770
24868
|
const backupRoot = resolve29(projectRoot, EVAL_DIR2, OVERLAY_BACKUP_DIR);
|
|
24771
24869
|
if (existsSync6(backupRoot))
|
|
24772
24870
|
return;
|
|
24773
|
-
await
|
|
24871
|
+
await mkdir20(backupRoot, { recursive: true });
|
|
24774
24872
|
const configPath = resolve29(projectRoot, ".codeconductor", "config.yml");
|
|
24775
24873
|
if (existsSync6(configPath)) {
|
|
24776
|
-
await copyFile2(configPath,
|
|
24874
|
+
await copyFile2(configPath, join23(backupRoot, "config.yml"));
|
|
24777
24875
|
}
|
|
24778
24876
|
const workflowsDir = resolve29(projectRoot, ".codeconductor", "workflows");
|
|
24779
24877
|
if (existsSync6(workflowsDir)) {
|
|
24780
|
-
const dest =
|
|
24781
|
-
await
|
|
24878
|
+
const dest = join23(backupRoot, "workflows");
|
|
24879
|
+
await mkdir20(dest, { recursive: true });
|
|
24782
24880
|
const files = await readdir10(workflowsDir);
|
|
24783
24881
|
for (const file of files) {
|
|
24784
24882
|
if (file.endsWith(".yml")) {
|
|
24785
|
-
await copyFile2(
|
|
24883
|
+
await copyFile2(join23(workflowsDir, file), join23(dest, file));
|
|
24786
24884
|
}
|
|
24787
24885
|
}
|
|
24788
24886
|
}
|
|
24789
24887
|
const overlay = activeOverlayPath(projectRoot);
|
|
24790
24888
|
if (existsSync6(overlay)) {
|
|
24791
|
-
await copyFile2(overlay,
|
|
24889
|
+
await copyFile2(overlay, join23(backupRoot, ACTIVE_OVERLAY_FILE));
|
|
24792
24890
|
}
|
|
24793
24891
|
}
|
|
24794
24892
|
async function applyHarnessOverlay(projectRoot, disabled, options = {}) {
|
|
@@ -24798,12 +24896,12 @@ async function applyHarnessOverlay(projectRoot, disabled, options = {}) {
|
|
|
24798
24896
|
await snapshotForBackup(projectRoot);
|
|
24799
24897
|
}
|
|
24800
24898
|
const workflowsDir = resolve29(projectRoot, ".codeconductor", "workflows");
|
|
24801
|
-
await
|
|
24802
|
-
await
|
|
24899
|
+
await mkdir20(workflowsDir, { recursive: true });
|
|
24900
|
+
await mkdir20(resolve29(projectRoot, EVAL_DIR2), { recursive: true });
|
|
24803
24901
|
for (const command of WORKFLOW_OVERLAY_COMMANDS) {
|
|
24804
24902
|
const base = loadWorkflowProfile(command);
|
|
24805
24903
|
const next = applyCatalogToProfile(base, disabled);
|
|
24806
|
-
await
|
|
24904
|
+
await writeFile20(join23(workflowsDir, `${command}.yml`), $stringify(next), "utf-8");
|
|
24807
24905
|
}
|
|
24808
24906
|
const needsConfig = disabled.includes("compile_loop") || disabled.includes("council");
|
|
24809
24907
|
if (needsConfig) {
|
|
@@ -24831,7 +24929,7 @@ async function applyHarnessOverlay(projectRoot, disabled, options = {}) {
|
|
|
24831
24929
|
contractVersion: options.contractVersion,
|
|
24832
24930
|
ccepProfile: options.ccepProfile ?? "feature"
|
|
24833
24931
|
});
|
|
24834
|
-
await
|
|
24932
|
+
await writeFile20(activeOverlayPath(projectRoot), $stringify(overlay), "utf-8");
|
|
24835
24933
|
return ok(overlay);
|
|
24836
24934
|
} catch (e) {
|
|
24837
24935
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -24943,7 +25041,7 @@ var init_harness_catalog = __esm(() => {
|
|
|
24943
25041
|
|
|
24944
25042
|
// src/core/openspec/openspec-state.ts
|
|
24945
25043
|
import { createHash as createHash6 } from "node:crypto";
|
|
24946
|
-
import { mkdir as
|
|
25044
|
+
import { mkdir as mkdir21, readFile as readFile32, rename as rename4, writeFile as writeFile21 } from "node:fs/promises";
|
|
24947
25045
|
import { resolve as resolve30 } from "node:path";
|
|
24948
25046
|
function canTransition(from, to) {
|
|
24949
25047
|
return ALLOWED_TRANSITIONS[from]?.includes(to) ?? false;
|
|
@@ -24965,7 +25063,7 @@ function applyBacklogTransition(content, itemId, from, to, progress) {
|
|
|
24965
25063
|
}
|
|
24966
25064
|
async function writeFileAtomic(path, content) {
|
|
24967
25065
|
const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
24968
|
-
await
|
|
25066
|
+
await writeFile21(tmp, content, "utf-8");
|
|
24969
25067
|
await rename4(tmp, path);
|
|
24970
25068
|
}
|
|
24971
25069
|
async function loadOpenspecState(projectRoot) {
|
|
@@ -24989,7 +25087,7 @@ async function loadOpenspecState(projectRoot) {
|
|
|
24989
25087
|
async function writeOpenspecState(projectRoot, state) {
|
|
24990
25088
|
try {
|
|
24991
25089
|
const dir = resolve30(projectRoot, ".codeconductor");
|
|
24992
|
-
await
|
|
25090
|
+
await mkdir21(dir, { recursive: true });
|
|
24993
25091
|
const validated = OpenspecStateSchema.parse(state);
|
|
24994
25092
|
await writeFileAtomic(resolve30(dir, "openspec-state.json"), JSON.stringify(validated, null, 2));
|
|
24995
25093
|
return ok(undefined);
|
|
@@ -25097,7 +25195,7 @@ var init_openspec_state = __esm(() => {
|
|
|
25097
25195
|
// src/core/ccep/context-resolver.ts
|
|
25098
25196
|
import { existsSync as existsSync7 } from "node:fs";
|
|
25099
25197
|
import { readFile as readFile33 } from "node:fs/promises";
|
|
25100
|
-
import { join as
|
|
25198
|
+
import { join as join24 } from "node:path";
|
|
25101
25199
|
async function loadProductKnowledge(projectRoot) {
|
|
25102
25200
|
if (isProductGraphDisabled(projectRoot)) {
|
|
25103
25201
|
return {};
|
|
@@ -25123,7 +25221,7 @@ async function loadProductKnowledge(projectRoot) {
|
|
|
25123
25221
|
}
|
|
25124
25222
|
async function resolveAstSource(projectRoot) {
|
|
25125
25223
|
if (isProductGraphDisabled(projectRoot)) {
|
|
25126
|
-
const graphifyPath2 =
|
|
25224
|
+
const graphifyPath2 = join24(projectRoot, "graphify-out", "graph.json");
|
|
25127
25225
|
if (existsSync7(graphifyPath2)) {
|
|
25128
25226
|
return { source: "graphify", confidence: "medium" };
|
|
25129
25227
|
}
|
|
@@ -25133,7 +25231,7 @@ async function resolveAstSource(projectRoot) {
|
|
|
25133
25231
|
if (existsSync7(graphPath)) {
|
|
25134
25232
|
return { source: "product-graph", confidence: "high" };
|
|
25135
25233
|
}
|
|
25136
|
-
const graphifyPath =
|
|
25234
|
+
const graphifyPath = join24(projectRoot, "graphify-out", "graph.json");
|
|
25137
25235
|
if (existsSync7(graphifyPath)) {
|
|
25138
25236
|
return { source: "graphify", confidence: "medium" };
|
|
25139
25237
|
}
|
|
@@ -26781,7 +26879,7 @@ var init_backlog_planner = __esm(() => {
|
|
|
26781
26879
|
});
|
|
26782
26880
|
|
|
26783
26881
|
// src/core/openspec/openspec-generator.ts
|
|
26784
|
-
import { access as access7, mkdir as
|
|
26882
|
+
import { access as access7, mkdir as mkdir22, rename as rename5, writeFile as writeFile22 } from "node:fs/promises";
|
|
26785
26883
|
import { basename as basename8, resolve as resolve32 } from "node:path";
|
|
26786
26884
|
function pad3(n) {
|
|
26787
26885
|
return String(n).padStart(3, "0");
|
|
@@ -26869,8 +26967,8 @@ ${blocks.join(`
|
|
|
26869
26967
|
`;
|
|
26870
26968
|
}
|
|
26871
26969
|
async function writeTasksMarkdown(projectRoot, changePath, cards, options = {}) {
|
|
26872
|
-
await
|
|
26873
|
-
await
|
|
26970
|
+
await mkdir22(resolve32(projectRoot, changePath), { recursive: true });
|
|
26971
|
+
await writeFile22(resolve32(projectRoot, changePath, "tasks.md"), tasksContent(cards, options), "utf-8");
|
|
26874
26972
|
}
|
|
26875
26973
|
function tasksContent(cards, options = {}) {
|
|
26876
26974
|
const criteria = options.acceptanceCriteria ?? [];
|
|
@@ -26916,18 +27014,18 @@ function tasksContent(cards, options = {}) {
|
|
|
26916
27014
|
async function generateOpenspecChange(projectRoot, item, taskCards, options = {}) {
|
|
26917
27015
|
const slug = buildChangeSlug(item);
|
|
26918
27016
|
const changeDir = resolve32(projectRoot, "openspec", "changes", slug);
|
|
26919
|
-
await
|
|
27017
|
+
await mkdir22(resolve32(changeDir, "specs"), { recursive: true });
|
|
26920
27018
|
const taskOpts = {
|
|
26921
27019
|
tddRequired: options.tddRequired,
|
|
26922
27020
|
acceptanceCriteria: options.acceptanceCriteria ?? item.acceptanceCriteria
|
|
26923
27021
|
};
|
|
26924
|
-
await
|
|
26925
|
-
await
|
|
26926
|
-
await
|
|
27022
|
+
await writeFile22(resolve32(changeDir, "proposal.md"), proposalContent(item), "utf-8");
|
|
27023
|
+
await writeFile22(resolve32(changeDir, "design.md"), designContent(item), "utf-8");
|
|
27024
|
+
await writeFile22(resolve32(changeDir, "tasks.md"), tasksContent(taskCards, taskOpts), "utf-8");
|
|
26927
27025
|
const capability = capabilitySlug(item.title);
|
|
26928
|
-
await
|
|
26929
|
-
await
|
|
26930
|
-
await
|
|
27026
|
+
await mkdir22(resolve32(changeDir, "specs", capability), { recursive: true });
|
|
27027
|
+
await writeFile22(resolve32(changeDir, "specs", capability, "spec.md"), specDelta(item), "utf-8");
|
|
27028
|
+
await writeFile22(resolve32(changeDir, "change.yaml"), `version: 1
|
|
26931
27029
|
backlogId: ${item.id}
|
|
26932
27030
|
profile: standard
|
|
26933
27031
|
capabilities:
|
|
@@ -26939,7 +27037,7 @@ async function archiveChangeFolder(projectRoot, changePath) {
|
|
|
26939
27037
|
const src = resolve32(projectRoot, changePath);
|
|
26940
27038
|
const slug = basename8(changePath);
|
|
26941
27039
|
const destDir = resolve32(projectRoot, "openspec", "changes", "archive");
|
|
26942
|
-
await
|
|
27040
|
+
await mkdir22(destDir, { recursive: true });
|
|
26943
27041
|
const dest = resolve32(destDir, slug);
|
|
26944
27042
|
try {
|
|
26945
27043
|
await access7(dest);
|
|
@@ -26958,11 +27056,11 @@ async function ensureOpenspecConfig(projectRoot) {
|
|
|
26958
27056
|
const { access: access8 } = await import("node:fs/promises");
|
|
26959
27057
|
await access8(configPath);
|
|
26960
27058
|
} catch {
|
|
26961
|
-
await
|
|
27059
|
+
await mkdir22(resolve32(projectRoot, "openspec"), { recursive: true });
|
|
26962
27060
|
const stub = `# OpenSpec project config (CodeConductor native compatible)
|
|
26963
27061
|
schema: spec-driven
|
|
26964
27062
|
`;
|
|
26965
|
-
await
|
|
27063
|
+
await writeFile22(configPath, stub, "utf-8");
|
|
26966
27064
|
}
|
|
26967
27065
|
}
|
|
26968
27066
|
var init_openspec_generator = __esm(() => {
|
|
@@ -26972,7 +27070,7 @@ var init_openspec_generator = __esm(() => {
|
|
|
26972
27070
|
|
|
26973
27071
|
// src/core/openspec/spec-files.ts
|
|
26974
27072
|
import { readFile as readFile35, readdir as readdir11 } from "node:fs/promises";
|
|
26975
|
-
import { join as
|
|
27073
|
+
import { join as join25 } from "node:path";
|
|
26976
27074
|
async function walkMarkdownFiles(dir) {
|
|
26977
27075
|
let entries;
|
|
26978
27076
|
try {
|
|
@@ -26982,7 +27080,7 @@ async function walkMarkdownFiles(dir) {
|
|
|
26982
27080
|
}
|
|
26983
27081
|
const files = [];
|
|
26984
27082
|
for (const entry of entries) {
|
|
26985
|
-
const path =
|
|
27083
|
+
const path = join25(dir, entry.name);
|
|
26986
27084
|
if (entry.isDirectory()) {
|
|
26987
27085
|
files.push(...await walkMarkdownFiles(path));
|
|
26988
27086
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -27015,7 +27113,7 @@ var init_spec_files = __esm(() => {
|
|
|
27015
27113
|
|
|
27016
27114
|
// src/core/openspec/spec-quality.ts
|
|
27017
27115
|
import { readFile as readFile36 } from "node:fs/promises";
|
|
27018
|
-
import { join as
|
|
27116
|
+
import { join as join26, relative as relative10, resolve as resolve33 } from "node:path";
|
|
27019
27117
|
function uniqueIds(matches) {
|
|
27020
27118
|
return [...new Set(matches ?? [])];
|
|
27021
27119
|
}
|
|
@@ -27145,9 +27243,9 @@ async function assessChangeFolder(projectRoot, changePath) {
|
|
|
27145
27243
|
successCriteria: []
|
|
27146
27244
|
};
|
|
27147
27245
|
}
|
|
27148
|
-
const specDir =
|
|
27246
|
+
const specDir = join26(changeRoot, "specs");
|
|
27149
27247
|
const specFiles = await walkMarkdownFiles(specDir);
|
|
27150
|
-
const extra = ["proposal.md", "design.md"].map((name) =>
|
|
27248
|
+
const extra = ["proposal.md", "design.md"].map((name) => join26(changeRoot, name));
|
|
27151
27249
|
const reports = [];
|
|
27152
27250
|
for (const file of specFiles) {
|
|
27153
27251
|
const content = await readFile36(file, "utf-8");
|
|
@@ -27213,7 +27311,7 @@ var init_spec_quality = __esm(() => {
|
|
|
27213
27311
|
|
|
27214
27312
|
// src/core/openspec/spec-analyzer.ts
|
|
27215
27313
|
import { readFile as readFile37 } from "node:fs/promises";
|
|
27216
|
-
import { join as
|
|
27314
|
+
import { join as join27, resolve as resolve34 } from "node:path";
|
|
27217
27315
|
function unique(ids) {
|
|
27218
27316
|
return [...new Set(ids)];
|
|
27219
27317
|
}
|
|
@@ -27315,16 +27413,16 @@ function analyzeSpecArtifacts(input) {
|
|
|
27315
27413
|
}
|
|
27316
27414
|
async function analyzeChangeFolder(projectRoot, changePath, options) {
|
|
27317
27415
|
const changeRoot = resolve34(projectRoot, changePath);
|
|
27318
|
-
const specMarkdown = await readDeltaSpecs(
|
|
27416
|
+
const specMarkdown = await readDeltaSpecs(join27(changeRoot, "specs"));
|
|
27319
27417
|
let tasksMarkdown = "";
|
|
27320
27418
|
try {
|
|
27321
|
-
tasksMarkdown = await readFile37(
|
|
27419
|
+
tasksMarkdown = await readFile37(join27(changeRoot, "tasks.md"), "utf-8");
|
|
27322
27420
|
} catch {
|
|
27323
27421
|
tasksMarkdown = "";
|
|
27324
27422
|
}
|
|
27325
27423
|
let designMarkdown;
|
|
27326
27424
|
try {
|
|
27327
|
-
designMarkdown = await readFile37(
|
|
27425
|
+
designMarkdown = await readFile37(join27(changeRoot, "design.md"), "utf-8");
|
|
27328
27426
|
} catch {
|
|
27329
27427
|
designMarkdown = undefined;
|
|
27330
27428
|
}
|
|
@@ -27344,8 +27442,8 @@ var init_spec_analyzer = __esm(() => {
|
|
|
27344
27442
|
});
|
|
27345
27443
|
|
|
27346
27444
|
// src/core/openspec/spec-sync.ts
|
|
27347
|
-
import { mkdir as
|
|
27348
|
-
import { join as
|
|
27445
|
+
import { mkdir as mkdir23, readFile as readFile38 } from "node:fs/promises";
|
|
27446
|
+
import { join as join28, relative as relative11, resolve as resolve35 } from "node:path";
|
|
27349
27447
|
function deltaRequirements(markdown) {
|
|
27350
27448
|
const sections = [...markdown.matchAll(SECTION_HEADING)];
|
|
27351
27449
|
return sections.flatMap((section, index) => {
|
|
@@ -27407,7 +27505,7 @@ ${delta.markdown}`;
|
|
|
27407
27505
|
async function syncChangeSpecs(projectRoot, changePath) {
|
|
27408
27506
|
const root = resolve35(projectRoot);
|
|
27409
27507
|
const changeRoot = resolve35(root, changePath);
|
|
27410
|
-
const changeSpecs =
|
|
27508
|
+
const changeSpecs = join28(changeRoot, "specs");
|
|
27411
27509
|
if (changeRoot !== root && !changeRoot.startsWith(`${root}/`)) {
|
|
27412
27510
|
return { success: false, syncedPaths: [], errors: ["Change path escapes project root"] };
|
|
27413
27511
|
}
|
|
@@ -27427,7 +27525,7 @@ async function syncChangeSpecs(projectRoot, changePath) {
|
|
|
27427
27525
|
};
|
|
27428
27526
|
}
|
|
27429
27527
|
const relativeSpec = relative11(changeSpecs, file);
|
|
27430
|
-
const target =
|
|
27528
|
+
const target = join28(root, "openspec", "specs", relativeSpec);
|
|
27431
27529
|
let existing = `# ${relativeSpec.replace(/\\/g, "/")}
|
|
27432
27530
|
`;
|
|
27433
27531
|
try {
|
|
@@ -27439,7 +27537,7 @@ async function syncChangeSpecs(projectRoot, changePath) {
|
|
|
27439
27537
|
writes.push({ path: target, content: merged.content });
|
|
27440
27538
|
}
|
|
27441
27539
|
for (const write of writes) {
|
|
27442
|
-
await
|
|
27540
|
+
await mkdir23(resolve35(write.path, ".."), { recursive: true });
|
|
27443
27541
|
await writeFileAtomic(write.path, write.content);
|
|
27444
27542
|
}
|
|
27445
27543
|
return {
|
|
@@ -27457,7 +27555,7 @@ var init_spec_sync = __esm(() => {
|
|
|
27457
27555
|
|
|
27458
27556
|
// src/core/openspec/artifact-progress.ts
|
|
27459
27557
|
import { access as access8, readdir as readdir12, readFile as readFile39 } from "node:fs/promises";
|
|
27460
|
-
import { join as
|
|
27558
|
+
import { join as join29, resolve as resolve36 } from "node:path";
|
|
27461
27559
|
function countCheckboxes(markdown) {
|
|
27462
27560
|
let total = 0;
|
|
27463
27561
|
let complete = 0;
|
|
@@ -27488,7 +27586,7 @@ async function hasMarkdown(dir) {
|
|
|
27488
27586
|
return false;
|
|
27489
27587
|
}
|
|
27490
27588
|
for (const entry of entries) {
|
|
27491
|
-
const full =
|
|
27589
|
+
const full = join29(dir, entry.name);
|
|
27492
27590
|
if (entry.isFile() && entry.name.endsWith(".md"))
|
|
27493
27591
|
return true;
|
|
27494
27592
|
if (entry.isDirectory() && await hasMarkdown(full))
|
|
@@ -27503,15 +27601,15 @@ async function readArtifactProgress(projectRoot, changePath) {
|
|
|
27503
27601
|
return ABSENT;
|
|
27504
27602
|
}
|
|
27505
27603
|
const [proposal, design, tasks, specs] = await Promise.all([
|
|
27506
|
-
exists(
|
|
27507
|
-
exists(
|
|
27508
|
-
exists(
|
|
27509
|
-
hasMarkdown(
|
|
27604
|
+
exists(join29(changeRoot, "proposal.md")),
|
|
27605
|
+
exists(join29(changeRoot, "design.md")),
|
|
27606
|
+
exists(join29(changeRoot, "tasks.md")),
|
|
27607
|
+
hasMarkdown(join29(changeRoot, "specs"))
|
|
27510
27608
|
]);
|
|
27511
27609
|
let checkboxes = { total: 0, complete: 0, remaining: 0 };
|
|
27512
27610
|
if (tasks) {
|
|
27513
27611
|
try {
|
|
27514
|
-
checkboxes = countCheckboxes(await readFile39(
|
|
27612
|
+
checkboxes = countCheckboxes(await readFile39(join29(changeRoot, "tasks.md"), "utf-8"));
|
|
27515
27613
|
} catch {
|
|
27516
27614
|
checkboxes = { total: 0, complete: 0, remaining: 0 };
|
|
27517
27615
|
}
|
|
@@ -28473,7 +28571,7 @@ var init_handoff_envelope = __esm(() => {
|
|
|
28473
28571
|
|
|
28474
28572
|
// src/core/delivery/delivery-ledger.ts
|
|
28475
28573
|
import { createHash as createHash7 } from "node:crypto";
|
|
28476
|
-
import { mkdir as
|
|
28574
|
+
import { mkdir as mkdir24, readFile as readFile41, writeFile as writeFile23 } from "node:fs/promises";
|
|
28477
28575
|
import { resolve as resolve38, sep as sep9 } from "node:path";
|
|
28478
28576
|
function ledgerPath(projectRoot, id) {
|
|
28479
28577
|
if (!/^[a-z0-9][a-z0-9-]{0,63}$/.test(id))
|
|
@@ -28538,9 +28636,9 @@ async function createDeliveryLedger(projectRoot, input) {
|
|
|
28538
28636
|
createdAt: now,
|
|
28539
28637
|
updatedAt: now
|
|
28540
28638
|
});
|
|
28541
|
-
await
|
|
28639
|
+
await mkdir24(resolve38(projectRoot, DELIVERY_DIR), { recursive: true });
|
|
28542
28640
|
try {
|
|
28543
|
-
await
|
|
28641
|
+
await writeFile23(path, render(ledger), { encoding: "utf-8", flag: "wx" });
|
|
28544
28642
|
return { created: true, ledger };
|
|
28545
28643
|
} catch (error) {
|
|
28546
28644
|
if (error instanceof Error && error.message.includes("EEXIST")) {
|
|
@@ -28871,9 +28969,9 @@ __export(exports_hook_command, {
|
|
|
28871
28969
|
readStdinText: () => readStdinText
|
|
28872
28970
|
});
|
|
28873
28971
|
import { spawnSync } from "node:child_process";
|
|
28874
|
-
import { existsSync as existsSync8, readFileSync as
|
|
28972
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6 } from "node:fs";
|
|
28875
28973
|
import { createRequire as createRequire2 } from "node:module";
|
|
28876
|
-
import { dirname as
|
|
28974
|
+
import { dirname as dirname13, resolve as resolve39 } from "node:path";
|
|
28877
28975
|
function parseHookFormat(raw) {
|
|
28878
28976
|
return raw === "agy" || raw === "claude" || raw === "muse" ? raw : undefined;
|
|
28879
28977
|
}
|
|
@@ -28972,10 +29070,10 @@ function formatWrittenFile(filePath, projectRoot) {
|
|
|
28972
29070
|
function runNodeTool(name, args) {
|
|
28973
29071
|
try {
|
|
28974
29072
|
const manifestPath = require2.resolve(`${name}/package.json`);
|
|
28975
|
-
const manifest = JSON.parse(
|
|
29073
|
+
const manifest = JSON.parse(readFileSync6(manifestPath, "utf8"));
|
|
28976
29074
|
const bin = typeof manifest.bin === "string" ? manifest.bin : manifest.bin?.[name];
|
|
28977
29075
|
if (typeof bin === "string")
|
|
28978
|
-
spawnSync(process.execPath, [resolve39(
|
|
29076
|
+
spawnSync(process.execPath, [resolve39(dirname13(manifestPath), bin), ...args], opts);
|
|
28979
29077
|
} catch {}
|
|
28980
29078
|
}
|
|
28981
29079
|
if (prettier.test(filePath)) {
|
|
@@ -29514,13 +29612,13 @@ var init_scorecard_signals = __esm(() => {
|
|
|
29514
29612
|
|
|
29515
29613
|
// src/core/evaluation/harness-experiment.ts
|
|
29516
29614
|
import { existsSync as existsSync9 } from "node:fs";
|
|
29517
|
-
import { cp, mkdir as
|
|
29518
|
-
import { dirname as
|
|
29615
|
+
import { cp, mkdir as mkdir25, readFile as readFile42, readdir as readdir13, writeFile as writeFile24 } from "node:fs/promises";
|
|
29616
|
+
import { dirname as dirname14, join as join30, resolve as resolve40 } from "node:path";
|
|
29519
29617
|
function experimentDir(projectRoot, experimentId) {
|
|
29520
29618
|
return resolve40(projectRoot, EVAL_DIR2, EXPERIMENTS_DIR, experimentId);
|
|
29521
29619
|
}
|
|
29522
29620
|
function experimentYamlPath(projectRoot, experimentId) {
|
|
29523
|
-
return
|
|
29621
|
+
return join30(experimentDir(projectRoot, experimentId), "experiment.yml");
|
|
29524
29622
|
}
|
|
29525
29623
|
async function loadHarnessSuite(projectRoot, suiteId, suitePath) {
|
|
29526
29624
|
const candidates = suitePath ? [suitePath] : [
|
|
@@ -29630,8 +29728,8 @@ function generateExperimentId(suiteId, now = new Date) {
|
|
|
29630
29728
|
return `abl-${date}-${suiteId}-${rand}`;
|
|
29631
29729
|
}
|
|
29632
29730
|
async function copyFixture(suitePath, fixtureDir, dest) {
|
|
29633
|
-
const source = fixtureDir ? resolve40(
|
|
29634
|
-
await
|
|
29731
|
+
const source = fixtureDir ? resolve40(dirname14(suitePath), fixtureDir) : join30(dirname14(suitePath), "fixture");
|
|
29732
|
+
await mkdir25(dest, { recursive: true });
|
|
29635
29733
|
if (existsSync9(source)) {
|
|
29636
29734
|
await cp(source, dest, { recursive: true });
|
|
29637
29735
|
}
|
|
@@ -29653,12 +29751,12 @@ async function startHarnessExperiment(projectRoot, options) {
|
|
|
29653
29751
|
suitePath: suite.data.path
|
|
29654
29752
|
};
|
|
29655
29753
|
const root = experimentDir(projectRoot, experimentId);
|
|
29656
|
-
await
|
|
29657
|
-
await
|
|
29658
|
-
await
|
|
29754
|
+
await mkdir25(root, { recursive: true });
|
|
29755
|
+
await writeFile24(experimentYamlPath(projectRoot, experimentId), $stringify(experiment), "utf-8");
|
|
29756
|
+
await writeFile24(join30(root, "EXPERIMENT.md"), formatExperimentMarkdown(experiment), "utf-8");
|
|
29659
29757
|
for (const task of suite.data.tasks) {
|
|
29660
29758
|
for (const variantId of variants) {
|
|
29661
|
-
const runRoot =
|
|
29759
|
+
const runRoot = join30(root, "runs", task.id, variantDirName(variantId));
|
|
29662
29760
|
await copyFixture(suite.data.path, suite.data.fixtureDir, runRoot);
|
|
29663
29761
|
await writeConfig(runRoot, structuredClone(DEFAULT_CONFIG), true);
|
|
29664
29762
|
const disabled = variantId === "baseline" ? [] : options.components.filter((id) => variantIdFor(id) === variantId);
|
|
@@ -29670,7 +29768,7 @@ async function startHarnessExperiment(projectRoot, options) {
|
|
|
29670
29768
|
});
|
|
29671
29769
|
if (!overlay.success)
|
|
29672
29770
|
return overlay;
|
|
29673
|
-
await
|
|
29771
|
+
await writeFile24(join30(runRoot, "TASK.md"), formatTaskCard(task, experimentId, variantId), "utf-8");
|
|
29674
29772
|
}
|
|
29675
29773
|
}
|
|
29676
29774
|
return ok(experiment);
|
|
@@ -29901,7 +29999,7 @@ var init_execution_profile = __esm(() => {
|
|
|
29901
29999
|
|
|
29902
30000
|
// src/core/evaluation/prompt-diff.ts
|
|
29903
30001
|
import { readFile as readFile44, readdir as readdir14 } from "node:fs/promises";
|
|
29904
|
-
import { join as
|
|
30002
|
+
import { join as join31, resolve as resolve43 } from "node:path";
|
|
29905
30003
|
function normalizeVersion(v) {
|
|
29906
30004
|
return v.startsWith("v") ? v : `v${v}`;
|
|
29907
30005
|
}
|
|
@@ -29951,29 +30049,29 @@ async function diffPromptVersions(fromVersion, toVersion, options = {}) {
|
|
|
29951
30049
|
const toV = normalizeVersion(toVersion);
|
|
29952
30050
|
const searchRoots = [
|
|
29953
30051
|
resolve43(options.projectRoot ?? PACKAGE_ROOT, ".agents", "prompts"),
|
|
29954
|
-
|
|
29955
|
-
|
|
30052
|
+
join31(ROOT_PRESETS_DIR, target, "prompts"),
|
|
30053
|
+
join31(ROOT_PRESETS_DIR, "opencode", "prompts")
|
|
29956
30054
|
];
|
|
29957
30055
|
let fromDir = "";
|
|
29958
30056
|
let toDir = "";
|
|
29959
30057
|
for (const root of searchRoots) {
|
|
29960
|
-
const f =
|
|
29961
|
-
const t =
|
|
30058
|
+
const f = join31(root, fromV);
|
|
30059
|
+
const t = join31(root, toV);
|
|
29962
30060
|
try {
|
|
29963
|
-
await readFile44(
|
|
30061
|
+
await readFile44(join31(f, "orchestrator.md"), "utf-8");
|
|
29964
30062
|
fromDir = f;
|
|
29965
30063
|
toDir = t;
|
|
29966
30064
|
break;
|
|
29967
30065
|
} catch {}
|
|
29968
30066
|
}
|
|
29969
30067
|
if (!fromDir) {
|
|
29970
|
-
fromDir =
|
|
29971
|
-
toDir =
|
|
30068
|
+
fromDir = join31(ROOT_PRESETS_DIR, "opencode", "prompts", fromV);
|
|
30069
|
+
toDir = join31(ROOT_PRESETS_DIR, "opencode", "prompts", toV);
|
|
29972
30070
|
} else {
|
|
29973
30071
|
try {
|
|
29974
|
-
await readFile44(
|
|
30072
|
+
await readFile44(join31(toDir, "orchestrator.md"), "utf-8");
|
|
29975
30073
|
} catch {
|
|
29976
|
-
toDir =
|
|
30074
|
+
toDir = join31(ROOT_PRESETS_DIR, "opencode", "prompts", toV);
|
|
29977
30075
|
}
|
|
29978
30076
|
}
|
|
29979
30077
|
const fromFiles = await listPromptFiles(fromDir);
|
|
@@ -29991,12 +30089,12 @@ async function diffPromptVersions(fromVersion, toVersion, options = {}) {
|
|
|
29991
30089
|
let oldText = "";
|
|
29992
30090
|
let newText = "";
|
|
29993
30091
|
try {
|
|
29994
|
-
oldText = await readFile44(
|
|
30092
|
+
oldText = await readFile44(join31(fromDir, name), "utf-8");
|
|
29995
30093
|
} catch {
|
|
29996
30094
|
oldText = "";
|
|
29997
30095
|
}
|
|
29998
30096
|
try {
|
|
29999
|
-
newText = await readFile44(
|
|
30097
|
+
newText = await readFile44(join31(toDir, name), "utf-8");
|
|
30000
30098
|
} catch {
|
|
30001
30099
|
newText = "";
|
|
30002
30100
|
}
|
|
@@ -30036,8 +30134,8 @@ var init_prompt_diff = __esm(() => {
|
|
|
30036
30134
|
|
|
30037
30135
|
// src/core/evaluation/regression-checklist.ts
|
|
30038
30136
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
30039
|
-
import { mkdir as
|
|
30040
|
-
import { dirname as
|
|
30137
|
+
import { mkdir as mkdir26, readFile as readFile45, writeFile as writeFile25 } from "node:fs/promises";
|
|
30138
|
+
import { dirname as dirname15, resolve as resolve44 } from "node:path";
|
|
30041
30139
|
async function loadRegressionChecklist() {
|
|
30042
30140
|
try {
|
|
30043
30141
|
const path = resolve44(ROOT_PRESETS_DIR, "templates", "regression-checklist.yml");
|
|
@@ -30097,8 +30195,8 @@ async function runRegressionChecklist(projectRoot, options = {}) {
|
|
|
30097
30195
|
timestamp: new Date().toISOString()
|
|
30098
30196
|
};
|
|
30099
30197
|
const outPath = resolve44(projectRoot, ".codeconductor/evaluation/regression-last.json");
|
|
30100
|
-
await
|
|
30101
|
-
await
|
|
30198
|
+
await mkdir26(dirname15(outPath), { recursive: true });
|
|
30199
|
+
await writeFile25(outPath, JSON.stringify(report, null, 2), "utf-8");
|
|
30102
30200
|
return ok(report);
|
|
30103
30201
|
} catch (e) {
|
|
30104
30202
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -30140,7 +30238,7 @@ var init_model_comparison = __esm(() => {
|
|
|
30140
30238
|
});
|
|
30141
30239
|
|
|
30142
30240
|
// src/core/evaluation/cost-quality-matrix.ts
|
|
30143
|
-
import { writeFile as
|
|
30241
|
+
import { writeFile as writeFile26 } from "node:fs/promises";
|
|
30144
30242
|
import { resolve as resolve45 } from "node:path";
|
|
30145
30243
|
async function buildCostQualityMatrix(projectRoot, outcomes) {
|
|
30146
30244
|
const agg = aggregateOutcomes(outcomes);
|
|
@@ -30161,7 +30259,7 @@ async function buildCostQualityMatrix(projectRoot, outcomes) {
|
|
|
30161
30259
|
rows
|
|
30162
30260
|
};
|
|
30163
30261
|
const dir = await ensureEvaluationDir(projectRoot);
|
|
30164
|
-
await
|
|
30262
|
+
await writeFile26(resolve45(dir, "matrix.yml"), $stringify(matrix), "utf-8");
|
|
30165
30263
|
return matrix;
|
|
30166
30264
|
}
|
|
30167
30265
|
function formatMatrixMarkdown(matrix) {
|
|
@@ -30185,7 +30283,7 @@ var init_cost_quality_matrix = __esm(() => {
|
|
|
30185
30283
|
});
|
|
30186
30284
|
|
|
30187
30285
|
// src/core/evaluation/ablation-report.ts
|
|
30188
|
-
import { mkdir as
|
|
30286
|
+
import { mkdir as mkdir27, writeFile as writeFile27 } from "node:fs/promises";
|
|
30189
30287
|
import { resolve as resolve46 } from "node:path";
|
|
30190
30288
|
function isPass(o) {
|
|
30191
30289
|
return o.verdict === "PASS" || o.status === "pass";
|
|
@@ -30355,9 +30453,9 @@ function formatAblationMarkdown(report) {
|
|
|
30355
30453
|
}
|
|
30356
30454
|
async function persistAblationReport(projectRoot, markdown) {
|
|
30357
30455
|
const dir = resolve46(projectRoot, EVAL_DIR2);
|
|
30358
|
-
await
|
|
30456
|
+
await mkdir27(dir, { recursive: true });
|
|
30359
30457
|
const path = resolve46(dir, "ablation-last.md");
|
|
30360
|
-
await
|
|
30458
|
+
await writeFile27(path, markdown, "utf-8");
|
|
30361
30459
|
return path;
|
|
30362
30460
|
}
|
|
30363
30461
|
var SCORE_THRESHOLD = 0.1, PASS_RATE_THRESHOLD = 0.05;
|
|
@@ -30664,9 +30762,9 @@ async function handleCompareModels(projectRoot, options) {
|
|
|
30664
30762
|
try {
|
|
30665
30763
|
await readFile46(templatePath);
|
|
30666
30764
|
} catch {}
|
|
30667
|
-
const { writeFile:
|
|
30668
|
-
await
|
|
30669
|
-
await
|
|
30765
|
+
const { writeFile: writeFile28, mkdir: mkdir28 } = await import("node:fs/promises");
|
|
30766
|
+
await mkdir28(resolve47(projectRoot, ".codeconductor/evaluation"), { recursive: true });
|
|
30767
|
+
await writeFile28(templatePath, markdown, "utf-8");
|
|
30670
30768
|
return {
|
|
30671
30769
|
code: 0,
|
|
30672
30770
|
data: {
|
|
@@ -32135,7 +32233,7 @@ var exports_seo_audit_command = {};
|
|
|
32135
32233
|
__export(exports_seo_audit_command, {
|
|
32136
32234
|
seoAuditCommand: () => seoAuditCommand
|
|
32137
32235
|
});
|
|
32138
|
-
import { join as
|
|
32236
|
+
import { join as join32 } from "node:path";
|
|
32139
32237
|
async function seoAuditCommand(options) {
|
|
32140
32238
|
const { url, sitemap, format, failOn, delay: delay2, output, followRedirects, force } = options;
|
|
32141
32239
|
if (!url && !sitemap) {
|
|
@@ -32148,7 +32246,7 @@ async function seoAuditCommand(options) {
|
|
|
32148
32246
|
}
|
|
32149
32247
|
};
|
|
32150
32248
|
}
|
|
32151
|
-
const defaultMarkdownPath = output === undefined && format === "markdown" ?
|
|
32249
|
+
const defaultMarkdownPath = output === undefined && format === "markdown" ? join32("seo-reports", `audit-report-${new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19)}.md`) : undefined;
|
|
32152
32250
|
const outputPathToWrite = output ?? defaultMarkdownPath;
|
|
32153
32251
|
if (outputPathToWrite !== undefined) {
|
|
32154
32252
|
const preflightError = await preflightContainedOutput(options.projectRoot, outputPathToWrite, { force });
|