substrate-ai 0.1.24 → 0.1.25
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/dist/cli/index.js
CHANGED
|
@@ -389,7 +389,7 @@ function listTemplates() {
|
|
|
389
389
|
|
|
390
390
|
//#endregion
|
|
391
391
|
//#region src/cli/commands/init.ts
|
|
392
|
-
const logger$
|
|
392
|
+
const logger$35 = createLogger("init");
|
|
393
393
|
/**
|
|
394
394
|
* Detect whether the CLI was invoked via `npx substrate`.
|
|
395
395
|
* When true, prefix suggested commands with `npx `.
|
|
@@ -573,7 +573,7 @@ async function runInit(options = {}) {
|
|
|
573
573
|
discoveryReport = await registry.discoverAndRegister();
|
|
574
574
|
} catch (err) {
|
|
575
575
|
const message = err instanceof Error ? err.message : String(err);
|
|
576
|
-
logger$
|
|
576
|
+
logger$35.error({ err }, "Adapter discovery failed");
|
|
577
577
|
process.stderr.write(` Error: adapter discovery failed — ${message}\n`);
|
|
578
578
|
return INIT_EXIT_ERROR;
|
|
579
579
|
}
|
|
@@ -611,7 +611,7 @@ async function runInit(options = {}) {
|
|
|
611
611
|
await writeFile(routingPolicyPath, routingHeader + yaml.dump(routingPolicy), "utf-8");
|
|
612
612
|
} catch (err) {
|
|
613
613
|
const message = err instanceof Error ? err.message : String(err);
|
|
614
|
-
logger$
|
|
614
|
+
logger$35.error({ err }, "Failed to write config files");
|
|
615
615
|
process.stderr.write(` Error: failed to write configuration — ${message}\n`);
|
|
616
616
|
return INIT_EXIT_ERROR;
|
|
617
617
|
}
|
|
@@ -686,7 +686,7 @@ function formatUnsupportedVersionError(formatType, version, supported) {
|
|
|
686
686
|
|
|
687
687
|
//#endregion
|
|
688
688
|
//#region src/modules/config/config-system-impl.ts
|
|
689
|
-
const logger$
|
|
689
|
+
const logger$34 = createLogger("config");
|
|
690
690
|
function deepMerge(base, override) {
|
|
691
691
|
const result = { ...base };
|
|
692
692
|
for (const [key, val] of Object.entries(override)) if (val !== null && val !== void 0 && typeof val === "object" && !Array.isArray(val) && typeof result[key] === "object" && result[key] !== null && !Array.isArray(result[key])) result[key] = deepMerge(result[key], val);
|
|
@@ -731,7 +731,7 @@ function readEnvOverrides() {
|
|
|
731
731
|
}
|
|
732
732
|
const parsed = PartialSubstrateConfigSchema.safeParse(overrides);
|
|
733
733
|
if (!parsed.success) {
|
|
734
|
-
logger$
|
|
734
|
+
logger$34.warn({ errors: parsed.error.issues }, "Invalid environment variable overrides ignored");
|
|
735
735
|
return {};
|
|
736
736
|
}
|
|
737
737
|
return parsed.data;
|
|
@@ -795,7 +795,7 @@ var ConfigSystemImpl = class {
|
|
|
795
795
|
throw new ConfigError(`Configuration validation failed:\n${issues}`, { issues: result.error.issues });
|
|
796
796
|
}
|
|
797
797
|
this._config = result.data;
|
|
798
|
-
logger$
|
|
798
|
+
logger$34.debug("Configuration loaded successfully");
|
|
799
799
|
}
|
|
800
800
|
getConfig() {
|
|
801
801
|
if (this._config === null) throw new ConfigError("Configuration has not been loaded. Call load() before getConfig().", {});
|
|
@@ -858,7 +858,7 @@ var ConfigSystemImpl = class {
|
|
|
858
858
|
if (version !== void 0 && typeof version === "string" && !isVersionSupported(version, SUPPORTED_CONFIG_FORMAT_VERSIONS)) if (defaultConfigMigrator.canMigrate(version, CURRENT_CONFIG_FORMAT_VERSION)) {
|
|
859
859
|
const migrationOutput = defaultConfigMigrator.migrate(rawObj, version, CURRENT_CONFIG_FORMAT_VERSION, filePath);
|
|
860
860
|
if (migrationOutput.result.success) {
|
|
861
|
-
logger$
|
|
861
|
+
logger$34.info({
|
|
862
862
|
from: version,
|
|
863
863
|
to: CURRENT_CONFIG_FORMAT_VERSION,
|
|
864
864
|
backup: migrationOutput.result.backupPath
|
|
@@ -901,7 +901,7 @@ function createConfigSystem(options = {}) {
|
|
|
901
901
|
|
|
902
902
|
//#endregion
|
|
903
903
|
//#region src/cli/commands/config.ts
|
|
904
|
-
const logger$
|
|
904
|
+
const logger$33 = createLogger("config-cmd");
|
|
905
905
|
const CONFIG_EXIT_SUCCESS = 0;
|
|
906
906
|
const CONFIG_EXIT_ERROR = 1;
|
|
907
907
|
const CONFIG_EXIT_INVALID = 2;
|
|
@@ -927,7 +927,7 @@ async function runConfigShow(opts = {}) {
|
|
|
927
927
|
return CONFIG_EXIT_INVALID;
|
|
928
928
|
}
|
|
929
929
|
const message = err instanceof Error ? err.message : String(err);
|
|
930
|
-
logger$
|
|
930
|
+
logger$33.error({ err }, "Failed to load configuration");
|
|
931
931
|
process.stderr.write(` Error loading configuration: ${message}\n`);
|
|
932
932
|
return CONFIG_EXIT_ERROR;
|
|
933
933
|
}
|
|
@@ -1001,7 +1001,7 @@ async function runConfigExport(opts = {}) {
|
|
|
1001
1001
|
return CONFIG_EXIT_INVALID;
|
|
1002
1002
|
}
|
|
1003
1003
|
const message = err instanceof Error ? err.message : String(err);
|
|
1004
|
-
logger$
|
|
1004
|
+
logger$33.error({ err }, "Failed to load configuration");
|
|
1005
1005
|
process.stderr.write(`Error loading configuration: ${message}\n`);
|
|
1006
1006
|
return CONFIG_EXIT_ERROR;
|
|
1007
1007
|
}
|
|
@@ -1155,7 +1155,7 @@ function registerConfigCommand(program, _version) {
|
|
|
1155
1155
|
|
|
1156
1156
|
//#endregion
|
|
1157
1157
|
//#region src/cli/commands/merge.ts
|
|
1158
|
-
const logger$
|
|
1158
|
+
const logger$32 = createLogger("merge-cmd");
|
|
1159
1159
|
const MERGE_EXIT_SUCCESS = 0;
|
|
1160
1160
|
const MERGE_EXIT_CONFLICT = 1;
|
|
1161
1161
|
const MERGE_EXIT_ERROR = 2;
|
|
@@ -1193,7 +1193,7 @@ async function mergeTask(taskId, targetBranch, projectRoot) {
|
|
|
1193
1193
|
projectRoot
|
|
1194
1194
|
});
|
|
1195
1195
|
try {
|
|
1196
|
-
logger$
|
|
1196
|
+
logger$32.info({
|
|
1197
1197
|
taskId,
|
|
1198
1198
|
targetBranch
|
|
1199
1199
|
}, "Running conflict detection...");
|
|
@@ -1215,7 +1215,7 @@ async function mergeTask(taskId, targetBranch, projectRoot) {
|
|
|
1215
1215
|
} catch (err) {
|
|
1216
1216
|
const message = err instanceof Error ? err.message : String(err);
|
|
1217
1217
|
console.error(`Error merging task "${taskId}": ${message}`);
|
|
1218
|
-
logger$
|
|
1218
|
+
logger$32.error({
|
|
1219
1219
|
taskId,
|
|
1220
1220
|
err
|
|
1221
1221
|
}, "merge --task failed");
|
|
@@ -1269,7 +1269,7 @@ async function mergeAll(targetBranch, projectRoot, taskIds) {
|
|
|
1269
1269
|
error: message
|
|
1270
1270
|
});
|
|
1271
1271
|
console.log(` Error for task "${taskId}": ${message}`);
|
|
1272
|
-
logger$
|
|
1272
|
+
logger$32.error({
|
|
1273
1273
|
taskId,
|
|
1274
1274
|
err
|
|
1275
1275
|
}, "merge --all: task failed");
|
|
@@ -1322,7 +1322,7 @@ function registerMergeCommand(program, projectRoot = process.cwd()) {
|
|
|
1322
1322
|
|
|
1323
1323
|
//#endregion
|
|
1324
1324
|
//#region src/cli/commands/worktrees.ts
|
|
1325
|
-
const logger$
|
|
1325
|
+
const logger$31 = createLogger("worktrees-cmd");
|
|
1326
1326
|
const WORKTREES_EXIT_SUCCESS = 0;
|
|
1327
1327
|
const WORKTREES_EXIT_ERROR = 1;
|
|
1328
1328
|
/** Valid task statuses for filtering */
|
|
@@ -1449,7 +1449,7 @@ async function listWorktreesAction(options) {
|
|
|
1449
1449
|
try {
|
|
1450
1450
|
worktreeInfos = await manager.listWorktrees();
|
|
1451
1451
|
} catch (err) {
|
|
1452
|
-
logger$
|
|
1452
|
+
logger$31.error({ err }, "Failed to list worktrees");
|
|
1453
1453
|
const message = err instanceof Error ? err.message : String(err);
|
|
1454
1454
|
process.stderr.write(`Error listing worktrees: ${message}\n`);
|
|
1455
1455
|
return WORKTREES_EXIT_ERROR;
|
|
@@ -1476,7 +1476,7 @@ async function listWorktreesAction(options) {
|
|
|
1476
1476
|
} catch (err) {
|
|
1477
1477
|
const message = err instanceof Error ? err.message : String(err);
|
|
1478
1478
|
process.stderr.write(`Error: ${message}\n`);
|
|
1479
|
-
logger$
|
|
1479
|
+
logger$31.error({ err }, "listWorktreesAction failed");
|
|
1480
1480
|
return WORKTREES_EXIT_ERROR;
|
|
1481
1481
|
}
|
|
1482
1482
|
}
|
|
@@ -1738,7 +1738,7 @@ function getPlanningCostTotal(db, sessionId) {
|
|
|
1738
1738
|
|
|
1739
1739
|
//#endregion
|
|
1740
1740
|
//#region src/cli/commands/cost.ts
|
|
1741
|
-
const logger$
|
|
1741
|
+
const logger$30 = createLogger("cost-cmd");
|
|
1742
1742
|
const COST_EXIT_SUCCESS = 0;
|
|
1743
1743
|
const COST_EXIT_ERROR = 1;
|
|
1744
1744
|
/**
|
|
@@ -1984,7 +1984,7 @@ async function runCostAction(options) {
|
|
|
1984
1984
|
} catch (err) {
|
|
1985
1985
|
const message = err instanceof Error ? err.message : String(err);
|
|
1986
1986
|
process.stderr.write(`Error: ${message}\n`);
|
|
1987
|
-
logger$
|
|
1987
|
+
logger$30.error({ err }, "runCostAction failed");
|
|
1988
1988
|
return COST_EXIT_ERROR;
|
|
1989
1989
|
} finally {
|
|
1990
1990
|
if (wrapper !== null) try {
|
|
@@ -2046,7 +2046,7 @@ function emitStatusSnapshot(snapshot) {
|
|
|
2046
2046
|
|
|
2047
2047
|
//#endregion
|
|
2048
2048
|
//#region src/recovery/crash-recovery.ts
|
|
2049
|
-
const logger$
|
|
2049
|
+
const logger$29 = createLogger("crash-recovery");
|
|
2050
2050
|
var CrashRecoveryManager = class {
|
|
2051
2051
|
db;
|
|
2052
2052
|
gitWorktreeManager;
|
|
@@ -2099,7 +2099,7 @@ var CrashRecoveryManager = class {
|
|
|
2099
2099
|
});
|
|
2100
2100
|
}
|
|
2101
2101
|
if (this.gitWorktreeManager !== void 0) this.cleanupOrphanedWorktrees().catch((err) => {
|
|
2102
|
-
logger$
|
|
2102
|
+
logger$29.warn({ err }, "Worktree cleanup failed during recovery (non-fatal)");
|
|
2103
2103
|
});
|
|
2104
2104
|
let newlyReady = 0;
|
|
2105
2105
|
if (sessionId !== void 0) {
|
|
@@ -2109,7 +2109,7 @@ var CrashRecoveryManager = class {
|
|
|
2109
2109
|
const row = db.prepare("SELECT COUNT(*) as count FROM ready_tasks").get();
|
|
2110
2110
|
newlyReady = row.count;
|
|
2111
2111
|
}
|
|
2112
|
-
logger$
|
|
2112
|
+
logger$29.info({
|
|
2113
2113
|
event: "recovery:complete",
|
|
2114
2114
|
recovered,
|
|
2115
2115
|
failed,
|
|
@@ -2131,10 +2131,10 @@ var CrashRecoveryManager = class {
|
|
|
2131
2131
|
if (this.gitWorktreeManager === void 0) return 0;
|
|
2132
2132
|
try {
|
|
2133
2133
|
const count = await this.gitWorktreeManager.cleanupAllWorktrees();
|
|
2134
|
-
logger$
|
|
2134
|
+
logger$29.info({ count }, "Cleaned up orphaned worktrees");
|
|
2135
2135
|
return count;
|
|
2136
2136
|
} catch (err) {
|
|
2137
|
-
logger$
|
|
2137
|
+
logger$29.warn({ err }, "Failed to clean up orphaned worktrees — continuing");
|
|
2138
2138
|
return 0;
|
|
2139
2139
|
}
|
|
2140
2140
|
}
|
|
@@ -2217,7 +2217,7 @@ function setupGracefulShutdown(options) {
|
|
|
2217
2217
|
|
|
2218
2218
|
//#endregion
|
|
2219
2219
|
//#region src/cli/commands/start.ts
|
|
2220
|
-
const logger$
|
|
2220
|
+
const logger$28 = createLogger("start-cmd");
|
|
2221
2221
|
const START_EXIT_SUCCESS = 0;
|
|
2222
2222
|
const START_EXIT_ERROR = 1;
|
|
2223
2223
|
const START_EXIT_USAGE_ERROR = 2;
|
|
@@ -2326,7 +2326,7 @@ async function runStartAction(options) {
|
|
|
2326
2326
|
let configWatcher$1 = null;
|
|
2327
2327
|
const configFilePath = join(projectRoot, "substrate.config.yaml");
|
|
2328
2328
|
if (noWatchConfig) {
|
|
2329
|
-
logger$
|
|
2329
|
+
logger$28.info("Config hot-reload disabled (--no-watch-config).");
|
|
2330
2330
|
process.stdout.write("Config hot-reload disabled (--no-watch-config).\n");
|
|
2331
2331
|
} else {
|
|
2332
2332
|
let currentHotConfig = config;
|
|
@@ -2341,7 +2341,7 @@ async function runStartAction(options) {
|
|
|
2341
2341
|
const changedKeys = computeChangedKeys(previousConfig, newConfig);
|
|
2342
2342
|
currentHotConfig = newConfig;
|
|
2343
2343
|
const n = changedKeys.length;
|
|
2344
|
-
logger$
|
|
2344
|
+
logger$28.info({
|
|
2345
2345
|
changedKeys,
|
|
2346
2346
|
configPath: configFilePath
|
|
2347
2347
|
}, `Config reloaded: ${n} setting(s) changed`);
|
|
@@ -2353,7 +2353,7 @@ async function runStartAction(options) {
|
|
|
2353
2353
|
});
|
|
2354
2354
|
},
|
|
2355
2355
|
onError: (err) => {
|
|
2356
|
-
logger$
|
|
2356
|
+
logger$28.error({
|
|
2357
2357
|
err,
|
|
2358
2358
|
configPath: configFilePath
|
|
2359
2359
|
}, `Config reload failed: ${err.message}. Continuing with previous config.`);
|
|
@@ -2366,7 +2366,7 @@ async function runStartAction(options) {
|
|
|
2366
2366
|
let cleanupShutdown = null;
|
|
2367
2367
|
if (resolvedGraphFile === null) if (interruptedSession !== void 0) {
|
|
2368
2368
|
process.stdout.write(`Resuming interrupted session ${interruptedSession.id}\n`);
|
|
2369
|
-
logger$
|
|
2369
|
+
logger$28.info({ sessionId: interruptedSession.id }, "session:resumed");
|
|
2370
2370
|
const recovery = new CrashRecoveryManager({
|
|
2371
2371
|
db: databaseService.db,
|
|
2372
2372
|
gitWorktreeManager
|
|
@@ -2490,7 +2490,7 @@ async function runStartAction(options) {
|
|
|
2490
2490
|
} catch (err) {
|
|
2491
2491
|
const message = err instanceof Error ? err.message : String(err);
|
|
2492
2492
|
process.stderr.write(`Error: ${message}\n`);
|
|
2493
|
-
logger$
|
|
2493
|
+
logger$28.error({ err }, "runStartAction failed");
|
|
2494
2494
|
return START_EXIT_ERROR;
|
|
2495
2495
|
} finally {
|
|
2496
2496
|
try {
|
|
@@ -2648,7 +2648,7 @@ function renderTaskGraph(snapshot, tasks) {
|
|
|
2648
2648
|
|
|
2649
2649
|
//#endregion
|
|
2650
2650
|
//#region src/cli/commands/status.ts
|
|
2651
|
-
const logger$
|
|
2651
|
+
const logger$27 = createLogger("status-cmd");
|
|
2652
2652
|
const STATUS_EXIT_SUCCESS = 0;
|
|
2653
2653
|
const STATUS_EXIT_ERROR = 1;
|
|
2654
2654
|
const STATUS_EXIT_NOT_FOUND = 2;
|
|
@@ -2801,7 +2801,7 @@ async function runStatusAction(options) {
|
|
|
2801
2801
|
} catch (err) {
|
|
2802
2802
|
const message = err instanceof Error ? err.message : String(err);
|
|
2803
2803
|
process.stderr.write(`Error: ${message}\n`);
|
|
2804
|
-
logger$
|
|
2804
|
+
logger$27.error({ err }, "runStatusAction failed");
|
|
2805
2805
|
return STATUS_EXIT_ERROR;
|
|
2806
2806
|
} finally {
|
|
2807
2807
|
if (wrapper !== null) try {
|
|
@@ -2834,7 +2834,7 @@ function registerStatusCommand(program, _version = "0.0.0", projectRoot = proces
|
|
|
2834
2834
|
|
|
2835
2835
|
//#endregion
|
|
2836
2836
|
//#region src/cli/commands/pause.ts
|
|
2837
|
-
const logger$
|
|
2837
|
+
const logger$26 = createLogger("pause-cmd");
|
|
2838
2838
|
const PAUSE_EXIT_SUCCESS = 0;
|
|
2839
2839
|
const PAUSE_EXIT_ERROR = 1;
|
|
2840
2840
|
const PAUSE_EXIT_USAGE_ERROR = 2;
|
|
@@ -2903,7 +2903,7 @@ async function runPauseAction(options) {
|
|
|
2903
2903
|
} catch (err) {
|
|
2904
2904
|
const message = err instanceof Error ? err.message : String(err);
|
|
2905
2905
|
process.stderr.write(`Error: ${message}\n`);
|
|
2906
|
-
logger$
|
|
2906
|
+
logger$26.error({ err }, "runPauseAction failed");
|
|
2907
2907
|
return PAUSE_EXIT_ERROR;
|
|
2908
2908
|
} finally {
|
|
2909
2909
|
if (wrapper !== null) try {
|
|
@@ -2933,7 +2933,7 @@ function registerPauseCommand(program, version = "0.0.0", projectRoot = process.
|
|
|
2933
2933
|
|
|
2934
2934
|
//#endregion
|
|
2935
2935
|
//#region src/cli/commands/resume.ts
|
|
2936
|
-
const logger$
|
|
2936
|
+
const logger$25 = createLogger("resume-cmd");
|
|
2937
2937
|
const RESUME_EXIT_SUCCESS = 0;
|
|
2938
2938
|
const RESUME_EXIT_ERROR = 1;
|
|
2939
2939
|
const RESUME_EXIT_USAGE_ERROR = 2;
|
|
@@ -3018,7 +3018,7 @@ async function runResumeAction(options) {
|
|
|
3018
3018
|
} catch (err) {
|
|
3019
3019
|
const message = err instanceof Error ? err.message : String(err);
|
|
3020
3020
|
process.stderr.write(`Error: ${message}\n`);
|
|
3021
|
-
logger$
|
|
3021
|
+
logger$25.error({ err }, "runResumeAction failed");
|
|
3022
3022
|
return RESUME_EXIT_ERROR;
|
|
3023
3023
|
} finally {
|
|
3024
3024
|
if (wrapper !== null) try {
|
|
@@ -3051,7 +3051,7 @@ function registerResumeCommand(program, version = "0.0.0", projectRoot = process
|
|
|
3051
3051
|
|
|
3052
3052
|
//#endregion
|
|
3053
3053
|
//#region src/cli/commands/cancel.ts
|
|
3054
|
-
const logger$
|
|
3054
|
+
const logger$24 = createLogger("cancel-cmd");
|
|
3055
3055
|
const CANCEL_EXIT_SUCCESS = 0;
|
|
3056
3056
|
const CANCEL_EXIT_ERROR = 1;
|
|
3057
3057
|
const CANCEL_EXIT_USAGE_ERROR = 2;
|
|
@@ -3148,7 +3148,7 @@ async function runCancelAction(options) {
|
|
|
3148
3148
|
} catch (err) {
|
|
3149
3149
|
const message = err instanceof Error ? err.message : String(err);
|
|
3150
3150
|
process.stderr.write(`Error: ${message}\n`);
|
|
3151
|
-
logger$
|
|
3151
|
+
logger$24.error({ err }, "runCancelAction failed");
|
|
3152
3152
|
return CANCEL_EXIT_ERROR;
|
|
3153
3153
|
} finally {
|
|
3154
3154
|
if (wrapper !== null) try {
|
|
@@ -3263,7 +3263,7 @@ function renderFailedTasksJson(tasks) {
|
|
|
3263
3263
|
|
|
3264
3264
|
//#endregion
|
|
3265
3265
|
//#region src/cli/commands/retry.ts
|
|
3266
|
-
const logger$
|
|
3266
|
+
const logger$23 = createLogger("retry-cmd");
|
|
3267
3267
|
const RETRY_EXIT_SUCCESS = 0;
|
|
3268
3268
|
const RETRY_EXIT_PARTIAL_FAILURE = 1;
|
|
3269
3269
|
const RETRY_EXIT_USAGE_ERROR = 2;
|
|
@@ -3368,7 +3368,7 @@ async function runRetryAction(options) {
|
|
|
3368
3368
|
} catch (err) {
|
|
3369
3369
|
const message = err instanceof Error ? err.message : String(err);
|
|
3370
3370
|
process.stderr.write(`Error: ${message}\n`);
|
|
3371
|
-
logger$
|
|
3371
|
+
logger$23.error({ err }, "runRetryAction failed");
|
|
3372
3372
|
return RETRY_EXIT_USAGE_ERROR;
|
|
3373
3373
|
} finally {
|
|
3374
3374
|
if (wrapper !== null) try {
|
|
@@ -3497,11 +3497,11 @@ async function runFollowMode(opts) {
|
|
|
3497
3497
|
});
|
|
3498
3498
|
});
|
|
3499
3499
|
const sigintHandler = () => {
|
|
3500
|
-
logger$
|
|
3500
|
+
logger$23.info("SIGINT received — initiating graceful shutdown");
|
|
3501
3501
|
taskGraphEngine.cancelAll();
|
|
3502
3502
|
};
|
|
3503
3503
|
const sigtermHandler = () => {
|
|
3504
|
-
logger$
|
|
3504
|
+
logger$23.info("SIGTERM received — initiating graceful shutdown");
|
|
3505
3505
|
taskGraphEngine.cancelAll();
|
|
3506
3506
|
};
|
|
3507
3507
|
process.once("SIGINT", sigintHandler);
|
|
@@ -3514,7 +3514,7 @@ async function runFollowMode(opts) {
|
|
|
3514
3514
|
} catch (err) {
|
|
3515
3515
|
const message = err instanceof Error ? err.message : String(err);
|
|
3516
3516
|
process.stderr.write(`Error: ${message}\n`);
|
|
3517
|
-
logger$
|
|
3517
|
+
logger$23.error({ err }, "runFollowMode failed");
|
|
3518
3518
|
return RETRY_EXIT_USAGE_ERROR;
|
|
3519
3519
|
} finally {
|
|
3520
3520
|
try {
|
|
@@ -3974,7 +3974,7 @@ function buildMultiAgentInstructionsSection(agentCount) {
|
|
|
3974
3974
|
|
|
3975
3975
|
//#endregion
|
|
3976
3976
|
//#region src/modules/plan-generator/plan-generator.ts
|
|
3977
|
-
const logger$
|
|
3977
|
+
const logger$22 = createLogger("plan-generator");
|
|
3978
3978
|
/**
|
|
3979
3979
|
* Wrapper around execFile that immediately closes stdin on the child process.
|
|
3980
3980
|
* Some CLI tools (e.g. Claude Code) wait for stdin to close before processing
|
|
@@ -4151,7 +4151,7 @@ var PlanGenerator = class {
|
|
|
4151
4151
|
else {
|
|
4152
4152
|
const slugified = dep.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 64);
|
|
4153
4153
|
if (taskKeys.has(slugified)) resolvedDeps.push(slugified);
|
|
4154
|
-
else logger$
|
|
4154
|
+
else logger$22.warn({
|
|
4155
4155
|
taskKey,
|
|
4156
4156
|
dep
|
|
4157
4157
|
}, `depends_on reference '${dep}' not found in task keys; removing`);
|
|
@@ -4898,7 +4898,7 @@ function getLatestPlanVersion(db, planId) {
|
|
|
4898
4898
|
|
|
4899
4899
|
//#endregion
|
|
4900
4900
|
//#region src/modules/plan-generator/plan-refiner.ts
|
|
4901
|
-
const logger$
|
|
4901
|
+
const logger$21 = createLogger("plan-refiner");
|
|
4902
4902
|
var PlanRefiner = class {
|
|
4903
4903
|
db;
|
|
4904
4904
|
planGenerator;
|
|
@@ -4941,7 +4941,7 @@ var PlanRefiner = class {
|
|
|
4941
4941
|
newFeedback: feedback,
|
|
4942
4942
|
availableAgents: this.availableAgents
|
|
4943
4943
|
});
|
|
4944
|
-
logger$
|
|
4944
|
+
logger$21.info({
|
|
4945
4945
|
planId,
|
|
4946
4946
|
currentVersion,
|
|
4947
4947
|
feedbackRounds: feedbackHistory.length
|
|
@@ -4988,7 +4988,7 @@ var PlanRefiner = class {
|
|
|
4988
4988
|
newVersion,
|
|
4989
4989
|
taskCount
|
|
4990
4990
|
});
|
|
4991
|
-
logger$
|
|
4991
|
+
logger$21.info({
|
|
4992
4992
|
planId,
|
|
4993
4993
|
newVersion,
|
|
4994
4994
|
taskCount
|
|
@@ -5070,7 +5070,7 @@ function normalizeForDiff(value) {
|
|
|
5070
5070
|
|
|
5071
5071
|
//#endregion
|
|
5072
5072
|
//#region src/cli/commands/plan-refine.ts
|
|
5073
|
-
const logger$
|
|
5073
|
+
const logger$20 = createLogger("plan-refine-cmd");
|
|
5074
5074
|
const REFINE_EXIT_SUCCESS = 0;
|
|
5075
5075
|
const REFINE_EXIT_ERROR = 1;
|
|
5076
5076
|
const REFINE_EXIT_USAGE_ERROR = 2;
|
|
@@ -5112,7 +5112,7 @@ async function runPlanRefineAction(options) {
|
|
|
5112
5112
|
let result;
|
|
5113
5113
|
try {
|
|
5114
5114
|
result = await refiner.refine(planId, feedback, (event, payload) => {
|
|
5115
|
-
logger$
|
|
5115
|
+
logger$20.info({
|
|
5116
5116
|
event,
|
|
5117
5117
|
payload
|
|
5118
5118
|
}, "Plan refinement event");
|
|
@@ -5155,7 +5155,7 @@ async function runPlanRefineAction(options) {
|
|
|
5155
5155
|
} catch (err) {
|
|
5156
5156
|
const message = err instanceof Error ? err.message : String(err);
|
|
5157
5157
|
process.stderr.write(`Error: ${message}\n`);
|
|
5158
|
-
logger$
|
|
5158
|
+
logger$20.error({ err }, "runPlanRefineAction failed");
|
|
5159
5159
|
return REFINE_EXIT_ERROR;
|
|
5160
5160
|
} finally {
|
|
5161
5161
|
dbWrapper.close();
|
|
@@ -5180,7 +5180,7 @@ function registerPlanRefineCommand(planCmd, _version = "0.0.0", projectRoot = pr
|
|
|
5180
5180
|
|
|
5181
5181
|
//#endregion
|
|
5182
5182
|
//#region src/cli/commands/plan-diff.ts
|
|
5183
|
-
const logger$
|
|
5183
|
+
const logger$19 = createLogger("plan-diff-cmd");
|
|
5184
5184
|
const DIFF_EXIT_SUCCESS = 0;
|
|
5185
5185
|
const DIFF_EXIT_ERROR = 1;
|
|
5186
5186
|
const DIFF_EXIT_NOT_FOUND = 2;
|
|
@@ -5223,7 +5223,7 @@ async function runPlanDiffAction(options) {
|
|
|
5223
5223
|
} catch (err) {
|
|
5224
5224
|
const message = err instanceof Error ? err.message : String(err);
|
|
5225
5225
|
process.stderr.write(`Error: ${message}\n`);
|
|
5226
|
-
logger$
|
|
5226
|
+
logger$19.error({ err }, "runPlanDiffAction failed");
|
|
5227
5227
|
return DIFF_EXIT_ERROR;
|
|
5228
5228
|
} finally {
|
|
5229
5229
|
dbWrapper.close();
|
|
@@ -5271,7 +5271,7 @@ function registerPlanDiffCommand(planCmd, _version = "0.0.0", projectRoot = proc
|
|
|
5271
5271
|
|
|
5272
5272
|
//#endregion
|
|
5273
5273
|
//#region src/cli/commands/plan-rollback.ts
|
|
5274
|
-
const logger$
|
|
5274
|
+
const logger$18 = createLogger("plan-rollback-cmd");
|
|
5275
5275
|
const ROLLBACK_EXIT_SUCCESS = 0;
|
|
5276
5276
|
const ROLLBACK_EXIT_ERROR = 1;
|
|
5277
5277
|
const ROLLBACK_EXIT_USAGE_ERROR = 2;
|
|
@@ -5319,7 +5319,7 @@ async function runPlanRollbackAction(options, onEvent) {
|
|
|
5319
5319
|
toVersion,
|
|
5320
5320
|
newVersion
|
|
5321
5321
|
});
|
|
5322
|
-
logger$
|
|
5322
|
+
logger$18.info({
|
|
5323
5323
|
planId,
|
|
5324
5324
|
fromVersion,
|
|
5325
5325
|
toVersion,
|
|
@@ -5360,7 +5360,7 @@ async function runPlanRollbackAction(options, onEvent) {
|
|
|
5360
5360
|
} catch (err) {
|
|
5361
5361
|
const message = err instanceof Error ? err.message : String(err);
|
|
5362
5362
|
process.stderr.write(`Error: ${message}\n`);
|
|
5363
|
-
logger$
|
|
5363
|
+
logger$18.error({ err }, "runPlanRollbackAction failed");
|
|
5364
5364
|
return ROLLBACK_EXIT_ERROR;
|
|
5365
5365
|
} finally {
|
|
5366
5366
|
dbWrapper.close();
|
|
@@ -5554,7 +5554,7 @@ function validatePlan(raw, adapterRegistry, options) {
|
|
|
5554
5554
|
|
|
5555
5555
|
//#endregion
|
|
5556
5556
|
//#region src/cli/commands/plan.ts
|
|
5557
|
-
const logger$
|
|
5557
|
+
const logger$17 = createLogger("plan-cmd");
|
|
5558
5558
|
const PLAN_EXIT_SUCCESS = 0;
|
|
5559
5559
|
const PLAN_EXIT_ERROR = 1;
|
|
5560
5560
|
const PLAN_EXIT_USAGE_ERROR = 2;
|
|
@@ -5698,7 +5698,7 @@ async function runPlanReviewAction(options) {
|
|
|
5698
5698
|
}
|
|
5699
5699
|
const message = err instanceof Error ? err.message : String(err);
|
|
5700
5700
|
process.stderr.write(`Error: ${message}\n`);
|
|
5701
|
-
logger$
|
|
5701
|
+
logger$17.error({ err }, "runPlanReviewAction failed");
|
|
5702
5702
|
return PLAN_EXIT_ERROR;
|
|
5703
5703
|
}
|
|
5704
5704
|
if (dryRun) {
|
|
@@ -5724,7 +5724,7 @@ async function runPlanReviewAction(options) {
|
|
|
5724
5724
|
if (ext.endsWith(".yaml") || ext.endsWith(".yml")) taskGraph = load(planYaml);
|
|
5725
5725
|
else taskGraph = JSON.parse(planYaml);
|
|
5726
5726
|
} catch {
|
|
5727
|
-
logger$
|
|
5727
|
+
logger$17.warn("Could not read generated plan file for DB storage");
|
|
5728
5728
|
}
|
|
5729
5729
|
if (outputFormat === "json") {
|
|
5730
5730
|
const envelope = {
|
|
@@ -7181,7 +7181,7 @@ function truncateToTokens(text, maxTokens) {
|
|
|
7181
7181
|
|
|
7182
7182
|
//#endregion
|
|
7183
7183
|
//#region src/modules/context-compiler/context-compiler-impl.ts
|
|
7184
|
-
const logger$
|
|
7184
|
+
const logger$16 = createLogger("context-compiler");
|
|
7185
7185
|
/**
|
|
7186
7186
|
* Fraction of the original token budget that must remain (after required +
|
|
7187
7187
|
* important sections) before an optional section is included.
|
|
@@ -7273,7 +7273,7 @@ var ContextCompilerImpl = class {
|
|
|
7273
7273
|
includedParts.push(truncated);
|
|
7274
7274
|
remainingBudget -= truncatedTokens;
|
|
7275
7275
|
anyTruncated = true;
|
|
7276
|
-
logger$
|
|
7276
|
+
logger$16.warn({
|
|
7277
7277
|
section: section.name,
|
|
7278
7278
|
originalTokens: tokens,
|
|
7279
7279
|
budgetTokens: truncatedTokens
|
|
@@ -7287,7 +7287,7 @@ var ContextCompilerImpl = class {
|
|
|
7287
7287
|
});
|
|
7288
7288
|
} else {
|
|
7289
7289
|
anyTruncated = true;
|
|
7290
|
-
logger$
|
|
7290
|
+
logger$16.warn({
|
|
7291
7291
|
section: section.name,
|
|
7292
7292
|
tokens
|
|
7293
7293
|
}, "Context compiler: omitted \"important\" section — no budget remaining");
|
|
@@ -7314,7 +7314,7 @@ var ContextCompilerImpl = class {
|
|
|
7314
7314
|
} else {
|
|
7315
7315
|
if (tokens > 0) {
|
|
7316
7316
|
anyTruncated = true;
|
|
7317
|
-
logger$
|
|
7317
|
+
logger$16.warn({
|
|
7318
7318
|
section: section.name,
|
|
7319
7319
|
tokens,
|
|
7320
7320
|
budgetFractionRemaining: budgetFractionRemaining.toFixed(2)
|
|
@@ -7582,7 +7582,7 @@ function parseYamlResult(yamlText, schema) {
|
|
|
7582
7582
|
|
|
7583
7583
|
//#endregion
|
|
7584
7584
|
//#region src/modules/agent-dispatch/dispatcher-impl.ts
|
|
7585
|
-
const logger$
|
|
7585
|
+
const logger$15 = createLogger("agent-dispatch");
|
|
7586
7586
|
const SHUTDOWN_GRACE_MS = 1e4;
|
|
7587
7587
|
const SHUTDOWN_MAX_WAIT_MS = 3e4;
|
|
7588
7588
|
const CHARS_PER_TOKEN = 4;
|
|
@@ -7651,7 +7651,7 @@ var DispatcherImpl = class {
|
|
|
7651
7651
|
resolve: typedResolve,
|
|
7652
7652
|
reject
|
|
7653
7653
|
});
|
|
7654
|
-
logger$
|
|
7654
|
+
logger$15.debug({
|
|
7655
7655
|
id,
|
|
7656
7656
|
queueLength: this._queue.length
|
|
7657
7657
|
}, "Dispatch queued");
|
|
@@ -7681,7 +7681,7 @@ var DispatcherImpl = class {
|
|
|
7681
7681
|
}
|
|
7682
7682
|
async shutdown() {
|
|
7683
7683
|
this._shuttingDown = true;
|
|
7684
|
-
logger$
|
|
7684
|
+
logger$15.info({
|
|
7685
7685
|
running: this._running.size,
|
|
7686
7686
|
queued: this._queue.length
|
|
7687
7687
|
}, "Dispatcher shutting down");
|
|
@@ -7714,13 +7714,13 @@ var DispatcherImpl = class {
|
|
|
7714
7714
|
}
|
|
7715
7715
|
}, 50);
|
|
7716
7716
|
});
|
|
7717
|
-
logger$
|
|
7717
|
+
logger$15.info("Dispatcher shutdown complete");
|
|
7718
7718
|
}
|
|
7719
7719
|
async _startDispatch(id, request, resolve$2) {
|
|
7720
7720
|
const { prompt, agent, taskType, timeout, outputSchema, workingDirectory, model, maxTurns } = request;
|
|
7721
7721
|
const adapter = this._adapterRegistry.get(agent);
|
|
7722
7722
|
if (adapter === void 0) {
|
|
7723
|
-
logger$
|
|
7723
|
+
logger$15.warn({
|
|
7724
7724
|
id,
|
|
7725
7725
|
agent
|
|
7726
7726
|
}, "No adapter found for agent");
|
|
@@ -7764,7 +7764,7 @@ var DispatcherImpl = class {
|
|
|
7764
7764
|
});
|
|
7765
7765
|
const startedAt = Date.now();
|
|
7766
7766
|
proc.on("error", (err) => {
|
|
7767
|
-
logger$
|
|
7767
|
+
logger$15.error({
|
|
7768
7768
|
id,
|
|
7769
7769
|
binary: cmd.binary,
|
|
7770
7770
|
error: err.message
|
|
@@ -7772,7 +7772,7 @@ var DispatcherImpl = class {
|
|
|
7772
7772
|
});
|
|
7773
7773
|
if (proc.stdin !== null) {
|
|
7774
7774
|
proc.stdin.on("error", (err) => {
|
|
7775
|
-
if (err.code !== "EPIPE") logger$
|
|
7775
|
+
if (err.code !== "EPIPE") logger$15.warn({
|
|
7776
7776
|
id,
|
|
7777
7777
|
error: err.message
|
|
7778
7778
|
}, "stdin write error");
|
|
@@ -7814,7 +7814,7 @@ var DispatcherImpl = class {
|
|
|
7814
7814
|
agent,
|
|
7815
7815
|
taskType
|
|
7816
7816
|
});
|
|
7817
|
-
logger$
|
|
7817
|
+
logger$15.debug({
|
|
7818
7818
|
id,
|
|
7819
7819
|
agent,
|
|
7820
7820
|
taskType,
|
|
@@ -7831,7 +7831,7 @@ var DispatcherImpl = class {
|
|
|
7831
7831
|
dispatchId: id,
|
|
7832
7832
|
timeoutMs
|
|
7833
7833
|
});
|
|
7834
|
-
logger$
|
|
7834
|
+
logger$15.warn({
|
|
7835
7835
|
id,
|
|
7836
7836
|
agent,
|
|
7837
7837
|
taskType,
|
|
@@ -7885,7 +7885,7 @@ var DispatcherImpl = class {
|
|
|
7885
7885
|
exitCode: code,
|
|
7886
7886
|
output: stdout
|
|
7887
7887
|
});
|
|
7888
|
-
logger$
|
|
7888
|
+
logger$15.debug({
|
|
7889
7889
|
id,
|
|
7890
7890
|
agent,
|
|
7891
7891
|
taskType,
|
|
@@ -7911,7 +7911,7 @@ var DispatcherImpl = class {
|
|
|
7911
7911
|
error: stderr || `Process exited with code ${String(code)}`,
|
|
7912
7912
|
exitCode: code
|
|
7913
7913
|
});
|
|
7914
|
-
logger$
|
|
7914
|
+
logger$15.debug({
|
|
7915
7915
|
id,
|
|
7916
7916
|
agent,
|
|
7917
7917
|
taskType,
|
|
@@ -7963,7 +7963,7 @@ var DispatcherImpl = class {
|
|
|
7963
7963
|
const next = this._queue.shift();
|
|
7964
7964
|
if (next === void 0) return;
|
|
7965
7965
|
next.handle.status = "running";
|
|
7966
|
-
logger$
|
|
7966
|
+
logger$15.debug({
|
|
7967
7967
|
id: next.id,
|
|
7968
7968
|
queueLength: this._queue.length
|
|
7969
7969
|
}, "Dequeued dispatch");
|
|
@@ -8435,7 +8435,7 @@ function aggregateTokenUsageForRun(db, runId) {
|
|
|
8435
8435
|
|
|
8436
8436
|
//#endregion
|
|
8437
8437
|
//#region src/modules/compiled-workflows/prompt-assembler.ts
|
|
8438
|
-
const logger$
|
|
8438
|
+
const logger$14 = createLogger("compiled-workflows:prompt-assembler");
|
|
8439
8439
|
/**
|
|
8440
8440
|
* Assemble a final prompt from a template and sections map.
|
|
8441
8441
|
*
|
|
@@ -8460,7 +8460,7 @@ function assemblePrompt(template, sections, tokenCeiling = 2200) {
|
|
|
8460
8460
|
tokenCount,
|
|
8461
8461
|
truncated: false
|
|
8462
8462
|
};
|
|
8463
|
-
logger$
|
|
8463
|
+
logger$14.warn({
|
|
8464
8464
|
tokenCount,
|
|
8465
8465
|
ceiling: tokenCeiling
|
|
8466
8466
|
}, "Prompt exceeds token ceiling — truncating optional sections");
|
|
@@ -8476,10 +8476,10 @@ function assemblePrompt(template, sections, tokenCeiling = 2200) {
|
|
|
8476
8476
|
const targetSectionTokens = Math.max(0, currentSectionTokens - overBy);
|
|
8477
8477
|
if (targetSectionTokens === 0) {
|
|
8478
8478
|
contentMap[section.name] = "";
|
|
8479
|
-
logger$
|
|
8479
|
+
logger$14.warn({ sectionName: section.name }, "Section eliminated to fit token budget");
|
|
8480
8480
|
} else {
|
|
8481
8481
|
contentMap[section.name] = truncateToTokens(section.content, targetSectionTokens);
|
|
8482
|
-
logger$
|
|
8482
|
+
logger$14.warn({
|
|
8483
8483
|
sectionName: section.name,
|
|
8484
8484
|
targetSectionTokens
|
|
8485
8485
|
}, "Section truncated to fit token budget");
|
|
@@ -8490,7 +8490,7 @@ function assemblePrompt(template, sections, tokenCeiling = 2200) {
|
|
|
8490
8490
|
}
|
|
8491
8491
|
if (tokenCount <= tokenCeiling) break;
|
|
8492
8492
|
}
|
|
8493
|
-
if (tokenCount > tokenCeiling) logger$
|
|
8493
|
+
if (tokenCount > tokenCeiling) logger$14.warn({
|
|
8494
8494
|
tokenCount,
|
|
8495
8495
|
ceiling: tokenCeiling
|
|
8496
8496
|
}, "Required sections alone exceed token ceiling — returning over-budget prompt");
|
|
@@ -8631,7 +8631,7 @@ const CodeReviewResultSchema = z.object({
|
|
|
8631
8631
|
|
|
8632
8632
|
//#endregion
|
|
8633
8633
|
//#region src/modules/compiled-workflows/create-story.ts
|
|
8634
|
-
const logger$
|
|
8634
|
+
const logger$13 = createLogger("compiled-workflows:create-story");
|
|
8635
8635
|
/**
|
|
8636
8636
|
* Hard ceiling for the assembled create-story prompt.
|
|
8637
8637
|
*/
|
|
@@ -8655,7 +8655,7 @@ const TOKEN_CEILING$2 = 3e3;
|
|
|
8655
8655
|
*/
|
|
8656
8656
|
async function runCreateStory(deps, params) {
|
|
8657
8657
|
const { epicId, storyKey, pipelineRunId } = params;
|
|
8658
|
-
logger$
|
|
8658
|
+
logger$13.debug({
|
|
8659
8659
|
epicId,
|
|
8660
8660
|
storyKey,
|
|
8661
8661
|
pipelineRunId
|
|
@@ -8665,7 +8665,7 @@ async function runCreateStory(deps, params) {
|
|
|
8665
8665
|
template = await deps.pack.getPrompt("create-story");
|
|
8666
8666
|
} catch (err) {
|
|
8667
8667
|
const error = err instanceof Error ? err.message : String(err);
|
|
8668
|
-
logger$
|
|
8668
|
+
logger$13.error({ error }, "Failed to retrieve create-story prompt template");
|
|
8669
8669
|
return {
|
|
8670
8670
|
result: "failed",
|
|
8671
8671
|
error: `Failed to retrieve prompt template: ${error}`,
|
|
@@ -8707,7 +8707,7 @@ async function runCreateStory(deps, params) {
|
|
|
8707
8707
|
priority: "important"
|
|
8708
8708
|
}
|
|
8709
8709
|
], TOKEN_CEILING$2);
|
|
8710
|
-
logger$
|
|
8710
|
+
logger$13.debug({
|
|
8711
8711
|
tokenCount,
|
|
8712
8712
|
truncated,
|
|
8713
8713
|
tokenCeiling: TOKEN_CEILING$2
|
|
@@ -8724,7 +8724,7 @@ async function runCreateStory(deps, params) {
|
|
|
8724
8724
|
dispatchResult = await handle.result;
|
|
8725
8725
|
} catch (err) {
|
|
8726
8726
|
const error = err instanceof Error ? err.message : String(err);
|
|
8727
|
-
logger$
|
|
8727
|
+
logger$13.error({
|
|
8728
8728
|
epicId,
|
|
8729
8729
|
storyKey,
|
|
8730
8730
|
error
|
|
@@ -8745,7 +8745,7 @@ async function runCreateStory(deps, params) {
|
|
|
8745
8745
|
if (dispatchResult.status === "failed") {
|
|
8746
8746
|
const errorMsg = dispatchResult.parseError ?? `Dispatch failed with exit code ${dispatchResult.exitCode}`;
|
|
8747
8747
|
const stderrDetail = dispatchResult.output ? ` Output: ${dispatchResult.output}` : "";
|
|
8748
|
-
logger$
|
|
8748
|
+
logger$13.warn({
|
|
8749
8749
|
epicId,
|
|
8750
8750
|
storyKey,
|
|
8751
8751
|
exitCode: dispatchResult.exitCode
|
|
@@ -8757,7 +8757,7 @@ async function runCreateStory(deps, params) {
|
|
|
8757
8757
|
};
|
|
8758
8758
|
}
|
|
8759
8759
|
if (dispatchResult.status === "timeout") {
|
|
8760
|
-
logger$
|
|
8760
|
+
logger$13.warn({
|
|
8761
8761
|
epicId,
|
|
8762
8762
|
storyKey
|
|
8763
8763
|
}, "Create-story dispatch timed out");
|
|
@@ -8770,7 +8770,7 @@ async function runCreateStory(deps, params) {
|
|
|
8770
8770
|
if (dispatchResult.parsed === null) {
|
|
8771
8771
|
const details = dispatchResult.parseError ?? "No YAML block found in output";
|
|
8772
8772
|
const rawSnippet = dispatchResult.output ? dispatchResult.output.slice(0, 1e3) : "(empty)";
|
|
8773
|
-
logger$
|
|
8773
|
+
logger$13.warn({
|
|
8774
8774
|
epicId,
|
|
8775
8775
|
storyKey,
|
|
8776
8776
|
details,
|
|
@@ -8786,7 +8786,7 @@ async function runCreateStory(deps, params) {
|
|
|
8786
8786
|
const parseResult = CreateStoryResultSchema.safeParse(dispatchResult.parsed);
|
|
8787
8787
|
if (!parseResult.success) {
|
|
8788
8788
|
const details = parseResult.error.message;
|
|
8789
|
-
logger$
|
|
8789
|
+
logger$13.warn({
|
|
8790
8790
|
epicId,
|
|
8791
8791
|
storyKey,
|
|
8792
8792
|
details
|
|
@@ -8799,7 +8799,7 @@ async function runCreateStory(deps, params) {
|
|
|
8799
8799
|
};
|
|
8800
8800
|
}
|
|
8801
8801
|
const parsed = parseResult.data;
|
|
8802
|
-
logger$
|
|
8802
|
+
logger$13.info({
|
|
8803
8803
|
epicId,
|
|
8804
8804
|
storyKey,
|
|
8805
8805
|
storyFile: parsed.story_file,
|
|
@@ -8821,7 +8821,7 @@ function getImplementationDecisions(deps) {
|
|
|
8821
8821
|
try {
|
|
8822
8822
|
return getDecisionsByPhase(deps.db, "implementation");
|
|
8823
8823
|
} catch (err) {
|
|
8824
|
-
logger$
|
|
8824
|
+
logger$13.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve implementation decisions");
|
|
8825
8825
|
return [];
|
|
8826
8826
|
}
|
|
8827
8827
|
}
|
|
@@ -8837,13 +8837,13 @@ function getEpicShard(decisions, epicId, projectRoot) {
|
|
|
8837
8837
|
if (projectRoot) {
|
|
8838
8838
|
const fallback = readEpicShardFromFile(projectRoot, epicId);
|
|
8839
8839
|
if (fallback) {
|
|
8840
|
-
logger$
|
|
8840
|
+
logger$13.info({ epicId }, "Using file-based fallback for epic shard (decisions table empty)");
|
|
8841
8841
|
return fallback;
|
|
8842
8842
|
}
|
|
8843
8843
|
}
|
|
8844
8844
|
return "";
|
|
8845
8845
|
} catch (err) {
|
|
8846
|
-
logger$
|
|
8846
|
+
logger$13.warn({
|
|
8847
8847
|
epicId,
|
|
8848
8848
|
error: err instanceof Error ? err.message : String(err)
|
|
8849
8849
|
}, "Failed to retrieve epic shard");
|
|
@@ -8860,7 +8860,7 @@ function getPrevDevNotes(decisions, epicId) {
|
|
|
8860
8860
|
if (devNotes.length === 0) return "";
|
|
8861
8861
|
return devNotes[devNotes.length - 1].value;
|
|
8862
8862
|
} catch (err) {
|
|
8863
|
-
logger$
|
|
8863
|
+
logger$13.warn({
|
|
8864
8864
|
epicId,
|
|
8865
8865
|
error: err instanceof Error ? err.message : String(err)
|
|
8866
8866
|
}, "Failed to retrieve prev dev notes");
|
|
@@ -8880,13 +8880,13 @@ function getArchConstraints$1(deps) {
|
|
|
8880
8880
|
if (deps.projectRoot) {
|
|
8881
8881
|
const fallback = readArchConstraintsFromFile(deps.projectRoot);
|
|
8882
8882
|
if (fallback) {
|
|
8883
|
-
logger$
|
|
8883
|
+
logger$13.info("Using file-based fallback for architecture constraints (decisions table empty)");
|
|
8884
8884
|
return fallback;
|
|
8885
8885
|
}
|
|
8886
8886
|
}
|
|
8887
8887
|
return "";
|
|
8888
8888
|
} catch (err) {
|
|
8889
|
-
logger$
|
|
8889
|
+
logger$13.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve architecture constraints");
|
|
8890
8890
|
return "";
|
|
8891
8891
|
}
|
|
8892
8892
|
}
|
|
@@ -8906,7 +8906,7 @@ function readEpicShardFromFile(projectRoot, epicId) {
|
|
|
8906
8906
|
const match = pattern.exec(content);
|
|
8907
8907
|
return match ? match[0].trim() : "";
|
|
8908
8908
|
} catch (err) {
|
|
8909
|
-
logger$
|
|
8909
|
+
logger$13.warn({
|
|
8910
8910
|
epicId,
|
|
8911
8911
|
error: err instanceof Error ? err.message : String(err)
|
|
8912
8912
|
}, "File-based epic shard fallback failed");
|
|
@@ -8929,7 +8929,7 @@ function readArchConstraintsFromFile(projectRoot) {
|
|
|
8929
8929
|
const content = readFileSync$1(archPath, "utf-8");
|
|
8930
8930
|
return content.slice(0, 1500);
|
|
8931
8931
|
} catch (err) {
|
|
8932
|
-
logger$
|
|
8932
|
+
logger$13.warn({ error: err instanceof Error ? err.message : String(err) }, "File-based architecture fallback failed");
|
|
8933
8933
|
return "";
|
|
8934
8934
|
}
|
|
8935
8935
|
}
|
|
@@ -8942,14 +8942,14 @@ async function getStoryTemplate(deps) {
|
|
|
8942
8942
|
try {
|
|
8943
8943
|
return await deps.pack.getTemplate("story");
|
|
8944
8944
|
} catch (err) {
|
|
8945
|
-
logger$
|
|
8945
|
+
logger$13.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve story template from pack");
|
|
8946
8946
|
return "";
|
|
8947
8947
|
}
|
|
8948
8948
|
}
|
|
8949
8949
|
|
|
8950
8950
|
//#endregion
|
|
8951
8951
|
//#region src/modules/compiled-workflows/git-helpers.ts
|
|
8952
|
-
const logger$
|
|
8952
|
+
const logger$12 = createLogger("compiled-workflows:git-helpers");
|
|
8953
8953
|
/**
|
|
8954
8954
|
* Capture the full git diff for HEAD (working tree vs current commit).
|
|
8955
8955
|
*
|
|
@@ -9073,7 +9073,7 @@ async function runGitCommand(args, cwd, logLabel) {
|
|
|
9073
9073
|
stderr += chunk.toString("utf-8");
|
|
9074
9074
|
});
|
|
9075
9075
|
proc.on("error", (err) => {
|
|
9076
|
-
logger$
|
|
9076
|
+
logger$12.warn({
|
|
9077
9077
|
label: logLabel,
|
|
9078
9078
|
cwd,
|
|
9079
9079
|
error: err.message
|
|
@@ -9082,7 +9082,7 @@ async function runGitCommand(args, cwd, logLabel) {
|
|
|
9082
9082
|
});
|
|
9083
9083
|
proc.on("close", (code) => {
|
|
9084
9084
|
if (code !== 0) {
|
|
9085
|
-
logger$
|
|
9085
|
+
logger$12.warn({
|
|
9086
9086
|
label: logLabel,
|
|
9087
9087
|
cwd,
|
|
9088
9088
|
code,
|
|
@@ -9098,7 +9098,7 @@ async function runGitCommand(args, cwd, logLabel) {
|
|
|
9098
9098
|
|
|
9099
9099
|
//#endregion
|
|
9100
9100
|
//#region src/modules/compiled-workflows/dev-story.ts
|
|
9101
|
-
const logger$
|
|
9101
|
+
const logger$11 = createLogger("compiled-workflows:dev-story");
|
|
9102
9102
|
/** Hard token ceiling for the assembled dev-story prompt */
|
|
9103
9103
|
const TOKEN_CEILING$1 = 24e3;
|
|
9104
9104
|
/** Default timeout for dev-story dispatches in milliseconds (30 min) */
|
|
@@ -9120,7 +9120,7 @@ const DEFAULT_VITEST_PATTERNS = `## Test Patterns (defaults)
|
|
|
9120
9120
|
*/
|
|
9121
9121
|
async function runDevStory(deps, params) {
|
|
9122
9122
|
const { storyKey, storyFilePath, taskScope, priorFiles } = params;
|
|
9123
|
-
logger$
|
|
9123
|
+
logger$11.info({
|
|
9124
9124
|
storyKey,
|
|
9125
9125
|
storyFilePath
|
|
9126
9126
|
}, "Starting compiled dev-story workflow");
|
|
@@ -9162,10 +9162,10 @@ async function runDevStory(deps, params) {
|
|
|
9162
9162
|
let template;
|
|
9163
9163
|
try {
|
|
9164
9164
|
template = await deps.pack.getPrompt("dev-story");
|
|
9165
|
-
logger$
|
|
9165
|
+
logger$11.debug({ storyKey }, "Retrieved dev-story prompt template from pack");
|
|
9166
9166
|
} catch (err) {
|
|
9167
9167
|
const error = err instanceof Error ? err.message : String(err);
|
|
9168
|
-
logger$
|
|
9168
|
+
logger$11.error({
|
|
9169
9169
|
storyKey,
|
|
9170
9170
|
error
|
|
9171
9171
|
}, "Failed to retrieve dev-story prompt template");
|
|
@@ -9176,14 +9176,14 @@ async function runDevStory(deps, params) {
|
|
|
9176
9176
|
storyContent = await readFile$2(storyFilePath, "utf-8");
|
|
9177
9177
|
} catch (err) {
|
|
9178
9178
|
if (err.code === "ENOENT") {
|
|
9179
|
-
logger$
|
|
9179
|
+
logger$11.error({
|
|
9180
9180
|
storyKey,
|
|
9181
9181
|
storyFilePath
|
|
9182
9182
|
}, "Story file not found");
|
|
9183
9183
|
return makeFailureResult("story_file_not_found");
|
|
9184
9184
|
}
|
|
9185
9185
|
const error = err instanceof Error ? err.message : String(err);
|
|
9186
|
-
logger$
|
|
9186
|
+
logger$11.error({
|
|
9187
9187
|
storyKey,
|
|
9188
9188
|
storyFilePath,
|
|
9189
9189
|
error
|
|
@@ -9191,7 +9191,7 @@ async function runDevStory(deps, params) {
|
|
|
9191
9191
|
return makeFailureResult(`story_file_read_error: ${error}`);
|
|
9192
9192
|
}
|
|
9193
9193
|
if (storyContent.trim().length === 0) {
|
|
9194
|
-
logger$
|
|
9194
|
+
logger$11.error({
|
|
9195
9195
|
storyKey,
|
|
9196
9196
|
storyFilePath
|
|
9197
9197
|
}, "Story file is empty");
|
|
@@ -9203,17 +9203,17 @@ async function runDevStory(deps, params) {
|
|
|
9203
9203
|
const testPatternDecisions = solutioningDecisions.filter((d) => d.category === "test-patterns");
|
|
9204
9204
|
if (testPatternDecisions.length > 0) {
|
|
9205
9205
|
testPatternsContent = "## Test Patterns\n" + testPatternDecisions.map((d) => `- ${d.key}: ${d.value}`).join("\n");
|
|
9206
|
-
logger$
|
|
9206
|
+
logger$11.debug({
|
|
9207
9207
|
storyKey,
|
|
9208
9208
|
count: testPatternDecisions.length
|
|
9209
9209
|
}, "Loaded test patterns from decision store");
|
|
9210
9210
|
} else {
|
|
9211
9211
|
testPatternsContent = DEFAULT_VITEST_PATTERNS;
|
|
9212
|
-
logger$
|
|
9212
|
+
logger$11.debug({ storyKey }, "No test-pattern decisions found — using default Vitest patterns");
|
|
9213
9213
|
}
|
|
9214
9214
|
} catch (err) {
|
|
9215
9215
|
const error = err instanceof Error ? err.message : String(err);
|
|
9216
|
-
logger$
|
|
9216
|
+
logger$11.warn({
|
|
9217
9217
|
storyKey,
|
|
9218
9218
|
error
|
|
9219
9219
|
}, "Failed to load test patterns — using defaults");
|
|
@@ -9256,7 +9256,7 @@ async function runDevStory(deps, params) {
|
|
|
9256
9256
|
}
|
|
9257
9257
|
];
|
|
9258
9258
|
const { prompt, tokenCount, truncated } = assemblePrompt(template, sections, TOKEN_CEILING$1);
|
|
9259
|
-
logger$
|
|
9259
|
+
logger$11.info({
|
|
9260
9260
|
storyKey,
|
|
9261
9261
|
tokenCount,
|
|
9262
9262
|
ceiling: TOKEN_CEILING$1,
|
|
@@ -9275,7 +9275,7 @@ async function runDevStory(deps, params) {
|
|
|
9275
9275
|
dispatchResult = await handle.result;
|
|
9276
9276
|
} catch (err) {
|
|
9277
9277
|
const error = err instanceof Error ? err.message : String(err);
|
|
9278
|
-
logger$
|
|
9278
|
+
logger$11.error({
|
|
9279
9279
|
storyKey,
|
|
9280
9280
|
error
|
|
9281
9281
|
}, "Dispatch threw an unexpected error");
|
|
@@ -9286,11 +9286,11 @@ async function runDevStory(deps, params) {
|
|
|
9286
9286
|
output: dispatchResult.tokenEstimate.output
|
|
9287
9287
|
};
|
|
9288
9288
|
if (dispatchResult.status === "timeout") {
|
|
9289
|
-
logger$
|
|
9289
|
+
logger$11.error({
|
|
9290
9290
|
storyKey,
|
|
9291
9291
|
durationMs: dispatchResult.durationMs
|
|
9292
9292
|
}, "Dev-story dispatch timed out");
|
|
9293
|
-
if (dispatchResult.output.length > 0) logger$
|
|
9293
|
+
if (dispatchResult.output.length > 0) logger$11.info({
|
|
9294
9294
|
storyKey,
|
|
9295
9295
|
partialOutput: dispatchResult.output.slice(0, 500)
|
|
9296
9296
|
}, "Partial output before timeout");
|
|
@@ -9300,12 +9300,12 @@ async function runDevStory(deps, params) {
|
|
|
9300
9300
|
};
|
|
9301
9301
|
}
|
|
9302
9302
|
if (dispatchResult.status === "failed" || dispatchResult.exitCode !== 0) {
|
|
9303
|
-
logger$
|
|
9303
|
+
logger$11.error({
|
|
9304
9304
|
storyKey,
|
|
9305
9305
|
exitCode: dispatchResult.exitCode,
|
|
9306
9306
|
status: dispatchResult.status
|
|
9307
9307
|
}, "Dev-story dispatch failed");
|
|
9308
|
-
if (dispatchResult.output.length > 0) logger$
|
|
9308
|
+
if (dispatchResult.output.length > 0) logger$11.info({
|
|
9309
9309
|
storyKey,
|
|
9310
9310
|
partialOutput: dispatchResult.output.slice(0, 500)
|
|
9311
9311
|
}, "Partial output from failed dispatch");
|
|
@@ -9317,7 +9317,7 @@ async function runDevStory(deps, params) {
|
|
|
9317
9317
|
if (dispatchResult.parseError !== null || dispatchResult.parsed === null) {
|
|
9318
9318
|
const details = dispatchResult.parseError ?? "parsed result was null";
|
|
9319
9319
|
const rawSnippet = dispatchResult.output ? dispatchResult.output.slice(0, 1e3) : "(empty)";
|
|
9320
|
-
logger$
|
|
9320
|
+
logger$11.error({
|
|
9321
9321
|
storyKey,
|
|
9322
9322
|
parseError: details,
|
|
9323
9323
|
rawOutputSnippet: rawSnippet
|
|
@@ -9325,12 +9325,12 @@ async function runDevStory(deps, params) {
|
|
|
9325
9325
|
let filesModified = [];
|
|
9326
9326
|
try {
|
|
9327
9327
|
filesModified = await getGitChangedFiles(deps.projectRoot ?? process.cwd());
|
|
9328
|
-
if (filesModified.length > 0) logger$
|
|
9328
|
+
if (filesModified.length > 0) logger$11.info({
|
|
9329
9329
|
storyKey,
|
|
9330
9330
|
fileCount: filesModified.length
|
|
9331
9331
|
}, "Recovered files_modified from git status (YAML fallback)");
|
|
9332
9332
|
} catch (err) {
|
|
9333
|
-
logger$
|
|
9333
|
+
logger$11.warn({
|
|
9334
9334
|
storyKey,
|
|
9335
9335
|
error: err instanceof Error ? err.message : String(err)
|
|
9336
9336
|
}, "Failed to recover files_modified from git");
|
|
@@ -9347,7 +9347,7 @@ async function runDevStory(deps, params) {
|
|
|
9347
9347
|
};
|
|
9348
9348
|
}
|
|
9349
9349
|
const parsed = dispatchResult.parsed;
|
|
9350
|
-
logger$
|
|
9350
|
+
logger$11.info({
|
|
9351
9351
|
storyKey,
|
|
9352
9352
|
result: parsed.result,
|
|
9353
9353
|
acMet: parsed.ac_met.length
|
|
@@ -9486,7 +9486,7 @@ function extractFilesInScope(storyContent) {
|
|
|
9486
9486
|
|
|
9487
9487
|
//#endregion
|
|
9488
9488
|
//#region src/modules/compiled-workflows/code-review.ts
|
|
9489
|
-
const logger$
|
|
9489
|
+
const logger$10 = createLogger("compiled-workflows:code-review");
|
|
9490
9490
|
/**
|
|
9491
9491
|
* Hard token ceiling for the assembled code-review prompt (50,000 tokens).
|
|
9492
9492
|
* Quality reviews require seeing actual code diffs, not just file names.
|
|
@@ -9526,7 +9526,7 @@ function defaultFailResult(error, tokenUsage) {
|
|
|
9526
9526
|
async function runCodeReview(deps, params) {
|
|
9527
9527
|
const { storyKey, storyFilePath, workingDirectory, pipelineRunId, filesModified, previousIssues } = params;
|
|
9528
9528
|
const cwd = workingDirectory ?? process.cwd();
|
|
9529
|
-
logger$
|
|
9529
|
+
logger$10.debug({
|
|
9530
9530
|
storyKey,
|
|
9531
9531
|
storyFilePath,
|
|
9532
9532
|
cwd,
|
|
@@ -9537,7 +9537,7 @@ async function runCodeReview(deps, params) {
|
|
|
9537
9537
|
template = await deps.pack.getPrompt("code-review");
|
|
9538
9538
|
} catch (err) {
|
|
9539
9539
|
const error = err instanceof Error ? err.message : String(err);
|
|
9540
|
-
logger$
|
|
9540
|
+
logger$10.error({ error }, "Failed to retrieve code-review prompt template");
|
|
9541
9541
|
return defaultFailResult(`Failed to retrieve prompt template: ${error}`, {
|
|
9542
9542
|
input: 0,
|
|
9543
9543
|
output: 0
|
|
@@ -9548,7 +9548,7 @@ async function runCodeReview(deps, params) {
|
|
|
9548
9548
|
storyContent = await readFile$2(storyFilePath, "utf-8");
|
|
9549
9549
|
} catch (err) {
|
|
9550
9550
|
const error = err instanceof Error ? err.message : String(err);
|
|
9551
|
-
logger$
|
|
9551
|
+
logger$10.error({
|
|
9552
9552
|
storyFilePath,
|
|
9553
9553
|
error
|
|
9554
9554
|
}, "Failed to read story file");
|
|
@@ -9568,12 +9568,12 @@ async function runCodeReview(deps, params) {
|
|
|
9568
9568
|
const scopedTotal = nonDiffTokens + countTokens(scopedDiff);
|
|
9569
9569
|
if (scopedTotal <= TOKEN_CEILING) {
|
|
9570
9570
|
gitDiffContent = scopedDiff;
|
|
9571
|
-
logger$
|
|
9571
|
+
logger$10.debug({
|
|
9572
9572
|
fileCount: filesModified.length,
|
|
9573
9573
|
tokenCount: scopedTotal
|
|
9574
9574
|
}, "Using scoped file diff");
|
|
9575
9575
|
} else {
|
|
9576
|
-
logger$
|
|
9576
|
+
logger$10.warn({
|
|
9577
9577
|
estimatedTotal: scopedTotal,
|
|
9578
9578
|
ceiling: TOKEN_CEILING,
|
|
9579
9579
|
fileCount: filesModified.length
|
|
@@ -9587,7 +9587,7 @@ async function runCodeReview(deps, params) {
|
|
|
9587
9587
|
const fullTotal = nonDiffTokens + countTokens(fullDiff);
|
|
9588
9588
|
if (fullTotal <= TOKEN_CEILING) gitDiffContent = fullDiff;
|
|
9589
9589
|
else {
|
|
9590
|
-
logger$
|
|
9590
|
+
logger$10.warn({
|
|
9591
9591
|
estimatedTotal: fullTotal,
|
|
9592
9592
|
ceiling: TOKEN_CEILING
|
|
9593
9593
|
}, "Full git diff would exceed token ceiling — using stat-only summary");
|
|
@@ -9625,11 +9625,11 @@ async function runCodeReview(deps, params) {
|
|
|
9625
9625
|
}
|
|
9626
9626
|
];
|
|
9627
9627
|
const assembleResult = assemblePrompt(template, sections, TOKEN_CEILING);
|
|
9628
|
-
if (assembleResult.truncated) logger$
|
|
9628
|
+
if (assembleResult.truncated) logger$10.warn({
|
|
9629
9629
|
storyKey,
|
|
9630
9630
|
tokenCount: assembleResult.tokenCount
|
|
9631
9631
|
}, "Code-review prompt truncated to fit token ceiling");
|
|
9632
|
-
logger$
|
|
9632
|
+
logger$10.debug({
|
|
9633
9633
|
storyKey,
|
|
9634
9634
|
tokenCount: assembleResult.tokenCount,
|
|
9635
9635
|
truncated: assembleResult.truncated
|
|
@@ -9647,7 +9647,7 @@ async function runCodeReview(deps, params) {
|
|
|
9647
9647
|
dispatchResult = await handle.result;
|
|
9648
9648
|
} catch (err) {
|
|
9649
9649
|
const error = err instanceof Error ? err.message : String(err);
|
|
9650
|
-
logger$
|
|
9650
|
+
logger$10.error({
|
|
9651
9651
|
storyKey,
|
|
9652
9652
|
error
|
|
9653
9653
|
}, "Code-review dispatch threw unexpected error");
|
|
@@ -9663,7 +9663,7 @@ async function runCodeReview(deps, params) {
|
|
|
9663
9663
|
const rawOutput = dispatchResult.output ?? void 0;
|
|
9664
9664
|
if (dispatchResult.status === "failed") {
|
|
9665
9665
|
const errorMsg = `Dispatch status: failed. Exit code: ${dispatchResult.exitCode}. ${dispatchResult.parseError ?? ""} ${dispatchResult.output ? `Stderr: ${dispatchResult.output}` : ""}`.trim();
|
|
9666
|
-
logger$
|
|
9666
|
+
logger$10.warn({
|
|
9667
9667
|
storyKey,
|
|
9668
9668
|
exitCode: dispatchResult.exitCode
|
|
9669
9669
|
}, "Code-review dispatch failed");
|
|
@@ -9673,7 +9673,7 @@ async function runCodeReview(deps, params) {
|
|
|
9673
9673
|
};
|
|
9674
9674
|
}
|
|
9675
9675
|
if (dispatchResult.status === "timeout") {
|
|
9676
|
-
logger$
|
|
9676
|
+
logger$10.warn({ storyKey }, "Code-review dispatch timed out");
|
|
9677
9677
|
return {
|
|
9678
9678
|
...defaultFailResult("Dispatch status: timeout. The agent did not complete within the allowed time.", tokenUsage),
|
|
9679
9679
|
rawOutput
|
|
@@ -9681,7 +9681,7 @@ async function runCodeReview(deps, params) {
|
|
|
9681
9681
|
}
|
|
9682
9682
|
if (dispatchResult.parsed === null) {
|
|
9683
9683
|
const details = dispatchResult.parseError ?? "No YAML block found in output";
|
|
9684
|
-
logger$
|
|
9684
|
+
logger$10.warn({
|
|
9685
9685
|
storyKey,
|
|
9686
9686
|
details
|
|
9687
9687
|
}, "Code-review output schema validation failed");
|
|
@@ -9698,7 +9698,7 @@ async function runCodeReview(deps, params) {
|
|
|
9698
9698
|
const parseResult = CodeReviewResultSchema.safeParse(dispatchResult.parsed);
|
|
9699
9699
|
if (!parseResult.success) {
|
|
9700
9700
|
const details = parseResult.error.message;
|
|
9701
|
-
logger$
|
|
9701
|
+
logger$10.warn({
|
|
9702
9702
|
storyKey,
|
|
9703
9703
|
details
|
|
9704
9704
|
}, "Code-review output failed schema validation");
|
|
@@ -9713,13 +9713,13 @@ async function runCodeReview(deps, params) {
|
|
|
9713
9713
|
};
|
|
9714
9714
|
}
|
|
9715
9715
|
const parsed = parseResult.data;
|
|
9716
|
-
if (parsed.agentVerdict !== parsed.verdict) logger$
|
|
9716
|
+
if (parsed.agentVerdict !== parsed.verdict) logger$10.info({
|
|
9717
9717
|
storyKey,
|
|
9718
9718
|
agentVerdict: parsed.agentVerdict,
|
|
9719
9719
|
pipelineVerdict: parsed.verdict,
|
|
9720
9720
|
issues: parsed.issues
|
|
9721
9721
|
}, "Pipeline overrode agent verdict based on issue severities");
|
|
9722
|
-
logger$
|
|
9722
|
+
logger$10.info({
|
|
9723
9723
|
storyKey,
|
|
9724
9724
|
verdict: parsed.verdict,
|
|
9725
9725
|
issues: parsed.issues
|
|
@@ -9744,7 +9744,7 @@ function getArchConstraints(deps) {
|
|
|
9744
9744
|
if (constraints.length === 0) return "";
|
|
9745
9745
|
return constraints.map((d) => `${d.key}: ${d.value}`).join("\n");
|
|
9746
9746
|
} catch (err) {
|
|
9747
|
-
logger$
|
|
9747
|
+
logger$10.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve architecture constraints");
|
|
9748
9748
|
return "";
|
|
9749
9749
|
}
|
|
9750
9750
|
}
|
|
@@ -10076,7 +10076,7 @@ function detectConflictGroups(storyKeys, config) {
|
|
|
10076
10076
|
|
|
10077
10077
|
//#endregion
|
|
10078
10078
|
//#region src/modules/implementation-orchestrator/seed-methodology-context.ts
|
|
10079
|
-
const logger$
|
|
10079
|
+
const logger$9 = createLogger("implementation-orchestrator:seed");
|
|
10080
10080
|
/** Max chars for the architecture summary seeded into decisions */
|
|
10081
10081
|
const MAX_ARCH_CHARS = 6e3;
|
|
10082
10082
|
/** Max chars per epic shard */
|
|
@@ -10110,12 +10110,12 @@ function seedMethodologyContext(db, projectRoot) {
|
|
|
10110
10110
|
const testCount = seedTestPatterns(db, projectRoot);
|
|
10111
10111
|
if (testCount === -1) result.skippedCategories.push("test-patterns");
|
|
10112
10112
|
else result.decisionsCreated += testCount;
|
|
10113
|
-
logger$
|
|
10113
|
+
logger$9.info({
|
|
10114
10114
|
decisionsCreated: result.decisionsCreated,
|
|
10115
10115
|
skippedCategories: result.skippedCategories
|
|
10116
10116
|
}, "Methodology context seeding complete");
|
|
10117
10117
|
} catch (err) {
|
|
10118
|
-
logger$
|
|
10118
|
+
logger$9.warn({ error: err instanceof Error ? err.message : String(err) }, "Methodology context seeding failed (non-fatal)");
|
|
10119
10119
|
}
|
|
10120
10120
|
return result;
|
|
10121
10121
|
}
|
|
@@ -10159,7 +10159,7 @@ function seedArchitecture(db, projectRoot) {
|
|
|
10159
10159
|
});
|
|
10160
10160
|
count = 1;
|
|
10161
10161
|
}
|
|
10162
|
-
logger$
|
|
10162
|
+
logger$9.debug({ count }, "Seeded architecture decisions");
|
|
10163
10163
|
return count;
|
|
10164
10164
|
}
|
|
10165
10165
|
/**
|
|
@@ -10187,7 +10187,7 @@ function seedEpicShards(db, projectRoot) {
|
|
|
10187
10187
|
});
|
|
10188
10188
|
count++;
|
|
10189
10189
|
}
|
|
10190
|
-
logger$
|
|
10190
|
+
logger$9.debug({ count }, "Seeded epic shard decisions");
|
|
10191
10191
|
return count;
|
|
10192
10192
|
}
|
|
10193
10193
|
/**
|
|
@@ -10208,7 +10208,7 @@ function seedTestPatterns(db, projectRoot) {
|
|
|
10208
10208
|
value: patterns.slice(0, MAX_TEST_PATTERNS_CHARS),
|
|
10209
10209
|
rationale: "Detected from project configuration at orchestrator startup"
|
|
10210
10210
|
});
|
|
10211
|
-
logger$
|
|
10211
|
+
logger$9.debug("Seeded test patterns decision");
|
|
10212
10212
|
return 1;
|
|
10213
10213
|
}
|
|
10214
10214
|
/**
|
|
@@ -10400,7 +10400,7 @@ function createPauseGate() {
|
|
|
10400
10400
|
*/
|
|
10401
10401
|
function createImplementationOrchestrator(deps) {
|
|
10402
10402
|
const { db, pack, contextCompiler, dispatcher, eventBus, config, projectRoot } = deps;
|
|
10403
|
-
const logger$
|
|
10403
|
+
const logger$36 = createLogger("implementation-orchestrator");
|
|
10404
10404
|
let _state = "IDLE";
|
|
10405
10405
|
let _startedAt;
|
|
10406
10406
|
let _completedAt;
|
|
@@ -10456,7 +10456,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10456
10456
|
dispatches: _storyDispatches.get(storyKey) ?? 0
|
|
10457
10457
|
});
|
|
10458
10458
|
} catch (err) {
|
|
10459
|
-
logger$
|
|
10459
|
+
logger$36.warn({
|
|
10460
10460
|
err,
|
|
10461
10461
|
storyKey
|
|
10462
10462
|
}, "Failed to write story metrics (best-effort)");
|
|
@@ -10491,7 +10491,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10491
10491
|
token_usage_json: serialized
|
|
10492
10492
|
});
|
|
10493
10493
|
} catch (err) {
|
|
10494
|
-
logger$
|
|
10494
|
+
logger$36.warn("Failed to persist orchestrator state", { err });
|
|
10495
10495
|
}
|
|
10496
10496
|
}
|
|
10497
10497
|
function recordProgress() {
|
|
@@ -10516,7 +10516,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10516
10516
|
const elapsed = Date.now() - _lastProgressTs;
|
|
10517
10517
|
if (elapsed >= WATCHDOG_TIMEOUT_MS) {
|
|
10518
10518
|
for (const [key, s] of _stories) if (s.phase !== "PENDING" && s.phase !== "COMPLETE" && s.phase !== "ESCALATED") {
|
|
10519
|
-
logger$
|
|
10519
|
+
logger$36.warn({
|
|
10520
10520
|
storyKey: key,
|
|
10521
10521
|
phase: s.phase,
|
|
10522
10522
|
elapsedMs: elapsed
|
|
@@ -10552,7 +10552,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10552
10552
|
* exhausted retries the story is ESCALATED.
|
|
10553
10553
|
*/
|
|
10554
10554
|
async function processStory(storyKey) {
|
|
10555
|
-
logger$
|
|
10555
|
+
logger$36.info("Processing story", { storyKey });
|
|
10556
10556
|
await waitIfPaused();
|
|
10557
10557
|
if (_state !== "RUNNING") return;
|
|
10558
10558
|
startPhase(storyKey, "create-story");
|
|
@@ -10567,7 +10567,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10567
10567
|
const match = files.find((f) => f.startsWith(`${storyKey}-`) && f.endsWith(".md"));
|
|
10568
10568
|
if (match) {
|
|
10569
10569
|
storyFilePath = join$1(artifactsDir, match);
|
|
10570
|
-
logger$
|
|
10570
|
+
logger$36.info({
|
|
10571
10571
|
storyKey,
|
|
10572
10572
|
storyFilePath
|
|
10573
10573
|
}, "Found existing story file — skipping create-story");
|
|
@@ -10668,7 +10668,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10668
10668
|
try {
|
|
10669
10669
|
storyContentForAnalysis = await readFile$2(storyFilePath ?? "", "utf-8");
|
|
10670
10670
|
} catch (err) {
|
|
10671
|
-
logger$
|
|
10671
|
+
logger$36.error({
|
|
10672
10672
|
storyKey,
|
|
10673
10673
|
storyFilePath,
|
|
10674
10674
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -10676,7 +10676,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10676
10676
|
}
|
|
10677
10677
|
const analysis = analyzeStoryComplexity(storyContentForAnalysis);
|
|
10678
10678
|
const batches = planTaskBatches(analysis);
|
|
10679
|
-
logger$
|
|
10679
|
+
logger$36.info({
|
|
10680
10680
|
storyKey,
|
|
10681
10681
|
estimatedScope: analysis.estimatedScope,
|
|
10682
10682
|
batchCount: batches.length,
|
|
@@ -10694,7 +10694,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10694
10694
|
if (_state !== "RUNNING") break;
|
|
10695
10695
|
const taskScope = batch.taskIds.map((id, i) => `T${id}: ${batch.taskTitles[i] ?? ""}`).join("\n");
|
|
10696
10696
|
const priorFiles = allFilesModified.size > 0 ? Array.from(allFilesModified) : void 0;
|
|
10697
|
-
logger$
|
|
10697
|
+
logger$36.info({
|
|
10698
10698
|
storyKey,
|
|
10699
10699
|
batchIndex: batch.batchIndex,
|
|
10700
10700
|
taskCount: batch.taskIds.length
|
|
@@ -10718,7 +10718,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10718
10718
|
});
|
|
10719
10719
|
} catch (batchErr) {
|
|
10720
10720
|
const errMsg = batchErr instanceof Error ? batchErr.message : String(batchErr);
|
|
10721
|
-
logger$
|
|
10721
|
+
logger$36.warn({
|
|
10722
10722
|
storyKey,
|
|
10723
10723
|
batchIndex: batch.batchIndex,
|
|
10724
10724
|
error: errMsg
|
|
@@ -10738,7 +10738,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10738
10738
|
filesModified: batchFilesModified,
|
|
10739
10739
|
result: batchResult.result === "success" ? "success" : "failed"
|
|
10740
10740
|
};
|
|
10741
|
-
logger$
|
|
10741
|
+
logger$36.info(batchMetrics, "Batch dev-story metrics");
|
|
10742
10742
|
for (const f of batchFilesModified) allFilesModified.add(f);
|
|
10743
10743
|
if (batchFilesModified.length > 0) batchFileGroups.push({
|
|
10744
10744
|
batchIndex: batch.batchIndex,
|
|
@@ -10760,13 +10760,13 @@ function createImplementationOrchestrator(deps) {
|
|
|
10760
10760
|
})
|
|
10761
10761
|
});
|
|
10762
10762
|
} catch (tokenErr) {
|
|
10763
|
-
logger$
|
|
10763
|
+
logger$36.warn({
|
|
10764
10764
|
storyKey,
|
|
10765
10765
|
batchIndex: batch.batchIndex,
|
|
10766
10766
|
err: tokenErr
|
|
10767
10767
|
}, "Failed to record batch token usage");
|
|
10768
10768
|
}
|
|
10769
|
-
if (batchResult.result === "failed") logger$
|
|
10769
|
+
if (batchResult.result === "failed") logger$36.warn({
|
|
10770
10770
|
storyKey,
|
|
10771
10771
|
batchIndex: batch.batchIndex,
|
|
10772
10772
|
error: batchResult.error
|
|
@@ -10799,7 +10799,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10799
10799
|
result: devResult
|
|
10800
10800
|
});
|
|
10801
10801
|
persistState();
|
|
10802
|
-
if (devResult.result === "failed") logger$
|
|
10802
|
+
if (devResult.result === "failed") logger$36.warn("Dev-story reported failure, proceeding to code review", {
|
|
10803
10803
|
storyKey,
|
|
10804
10804
|
error: devResult.error,
|
|
10805
10805
|
filesModified: devFilesModified.length
|
|
@@ -10856,7 +10856,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10856
10856
|
"NEEDS_MAJOR_REWORK": 2
|
|
10857
10857
|
};
|
|
10858
10858
|
for (const group of batchFileGroups) {
|
|
10859
|
-
logger$
|
|
10859
|
+
logger$36.info({
|
|
10860
10860
|
storyKey,
|
|
10861
10861
|
batchIndex: group.batchIndex,
|
|
10862
10862
|
fileCount: group.files.length
|
|
@@ -10893,7 +10893,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10893
10893
|
rawOutput: lastRawOutput,
|
|
10894
10894
|
tokenUsage: aggregateTokens
|
|
10895
10895
|
};
|
|
10896
|
-
logger$
|
|
10896
|
+
logger$36.info({
|
|
10897
10897
|
storyKey,
|
|
10898
10898
|
batchCount: batchFileGroups.length,
|
|
10899
10899
|
verdict: worstVerdict,
|
|
@@ -10919,7 +10919,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10919
10919
|
const isPhantomReview = reviewResult.verdict !== "SHIP_IT" && (reviewResult.issue_list === void 0 || reviewResult.issue_list.length === 0) && reviewResult.error !== void 0;
|
|
10920
10920
|
if (isPhantomReview && !timeoutRetried) {
|
|
10921
10921
|
timeoutRetried = true;
|
|
10922
|
-
logger$
|
|
10922
|
+
logger$36.warn({
|
|
10923
10923
|
storyKey,
|
|
10924
10924
|
reviewCycles,
|
|
10925
10925
|
error: reviewResult.error
|
|
@@ -10929,7 +10929,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10929
10929
|
verdict = reviewResult.verdict;
|
|
10930
10930
|
issueList = reviewResult.issue_list ?? [];
|
|
10931
10931
|
if (verdict === "NEEDS_MAJOR_REWORK" && reviewCycles > 0 && previousIssueList.length > 0 && issueList.length < previousIssueList.length) {
|
|
10932
|
-
logger$
|
|
10932
|
+
logger$36.info({
|
|
10933
10933
|
storyKey,
|
|
10934
10934
|
originalVerdict: verdict,
|
|
10935
10935
|
issuesBefore: previousIssueList.length,
|
|
@@ -10965,7 +10965,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
10965
10965
|
if (_decomposition !== void 0) parts.push(`decomposed: ${_decomposition.batchCount} batches`);
|
|
10966
10966
|
parts.push(`${fileCount} files`);
|
|
10967
10967
|
parts.push(`${totalTokensK} tokens`);
|
|
10968
|
-
logger$
|
|
10968
|
+
logger$36.info({
|
|
10969
10969
|
storyKey,
|
|
10970
10970
|
verdict,
|
|
10971
10971
|
agentVerdict: reviewResult.agentVerdict
|
|
@@ -11023,7 +11023,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
11023
11023
|
persistState();
|
|
11024
11024
|
return;
|
|
11025
11025
|
}
|
|
11026
|
-
logger$
|
|
11026
|
+
logger$36.info({
|
|
11027
11027
|
storyKey,
|
|
11028
11028
|
reviewCycles: finalReviewCycles,
|
|
11029
11029
|
issueCount: issueList.length
|
|
@@ -11073,7 +11073,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
11073
11073
|
fixPrompt = assembled.prompt;
|
|
11074
11074
|
} catch {
|
|
11075
11075
|
fixPrompt = `Fix story ${storyKey}: verdict=${verdict}, minor fixes needed`;
|
|
11076
|
-
logger$
|
|
11076
|
+
logger$36.warn("Failed to assemble auto-approve fix prompt, using fallback", { storyKey });
|
|
11077
11077
|
}
|
|
11078
11078
|
const handle = dispatcher.dispatch({
|
|
11079
11079
|
prompt: fixPrompt,
|
|
@@ -11090,9 +11090,9 @@ function createImplementationOrchestrator(deps) {
|
|
|
11090
11090
|
output: fixResult.tokenEstimate.output
|
|
11091
11091
|
} : void 0 }
|
|
11092
11092
|
});
|
|
11093
|
-
if (fixResult.status === "timeout") logger$
|
|
11093
|
+
if (fixResult.status === "timeout") logger$36.warn("Auto-approve fix timed out — approving anyway (issues were minor)", { storyKey });
|
|
11094
11094
|
} catch (err) {
|
|
11095
|
-
logger$
|
|
11095
|
+
logger$36.warn("Auto-approve fix dispatch failed — approving anyway (issues were minor)", {
|
|
11096
11096
|
storyKey,
|
|
11097
11097
|
err
|
|
11098
11098
|
});
|
|
@@ -11164,7 +11164,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
11164
11164
|
fixPrompt = assembled.prompt;
|
|
11165
11165
|
} catch {
|
|
11166
11166
|
fixPrompt = `Fix story ${storyKey}: verdict=${verdict}, taskType=${taskType}`;
|
|
11167
|
-
logger$
|
|
11167
|
+
logger$36.warn("Failed to assemble fix prompt, using fallback", {
|
|
11168
11168
|
storyKey,
|
|
11169
11169
|
taskType
|
|
11170
11170
|
});
|
|
@@ -11187,7 +11187,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
11187
11187
|
} : void 0 }
|
|
11188
11188
|
});
|
|
11189
11189
|
if (fixResult.status === "timeout") {
|
|
11190
|
-
logger$
|
|
11190
|
+
logger$36.warn("Fix dispatch timed out — escalating story", {
|
|
11191
11191
|
storyKey,
|
|
11192
11192
|
taskType
|
|
11193
11193
|
});
|
|
@@ -11207,13 +11207,13 @@ function createImplementationOrchestrator(deps) {
|
|
|
11207
11207
|
persistState();
|
|
11208
11208
|
return;
|
|
11209
11209
|
}
|
|
11210
|
-
if (fixResult.status === "failed") logger$
|
|
11210
|
+
if (fixResult.status === "failed") logger$36.warn("Fix dispatch failed", {
|
|
11211
11211
|
storyKey,
|
|
11212
11212
|
taskType,
|
|
11213
11213
|
exitCode: fixResult.exitCode
|
|
11214
11214
|
});
|
|
11215
11215
|
} catch (err) {
|
|
11216
|
-
logger$
|
|
11216
|
+
logger$36.warn("Fix dispatch failed, continuing to next review", {
|
|
11217
11217
|
storyKey,
|
|
11218
11218
|
taskType,
|
|
11219
11219
|
err
|
|
@@ -11266,11 +11266,11 @@ function createImplementationOrchestrator(deps) {
|
|
|
11266
11266
|
}
|
|
11267
11267
|
async function run(storyKeys) {
|
|
11268
11268
|
if (_state === "RUNNING" || _state === "PAUSED") {
|
|
11269
|
-
logger$
|
|
11269
|
+
logger$36.warn("run() called while orchestrator is already running or paused — ignoring", { state: _state });
|
|
11270
11270
|
return getStatus();
|
|
11271
11271
|
}
|
|
11272
11272
|
if (_state === "COMPLETE") {
|
|
11273
|
-
logger$
|
|
11273
|
+
logger$36.warn("run() called on a COMPLETE orchestrator — ignoring", { state: _state });
|
|
11274
11274
|
return getStatus();
|
|
11275
11275
|
}
|
|
11276
11276
|
_state = "RUNNING";
|
|
@@ -11288,13 +11288,13 @@ function createImplementationOrchestrator(deps) {
|
|
|
11288
11288
|
startHeartbeat();
|
|
11289
11289
|
if (projectRoot !== void 0) {
|
|
11290
11290
|
const seedResult = seedMethodologyContext(db, projectRoot);
|
|
11291
|
-
if (seedResult.decisionsCreated > 0) logger$
|
|
11291
|
+
if (seedResult.decisionsCreated > 0) logger$36.info({
|
|
11292
11292
|
decisionsCreated: seedResult.decisionsCreated,
|
|
11293
11293
|
skippedCategories: seedResult.skippedCategories
|
|
11294
11294
|
}, "Methodology context seeded from planning artifacts");
|
|
11295
11295
|
}
|
|
11296
11296
|
const groups = detectConflictGroups(storyKeys);
|
|
11297
|
-
logger$
|
|
11297
|
+
logger$36.info("Orchestrator starting", {
|
|
11298
11298
|
storyCount: storyKeys.length,
|
|
11299
11299
|
groupCount: groups.length,
|
|
11300
11300
|
maxConcurrency: config.maxConcurrency
|
|
@@ -11306,7 +11306,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
11306
11306
|
_state = "FAILED";
|
|
11307
11307
|
_completedAt = new Date().toISOString();
|
|
11308
11308
|
persistState();
|
|
11309
|
-
logger$
|
|
11309
|
+
logger$36.error("Orchestrator failed with unhandled error", { err });
|
|
11310
11310
|
return getStatus();
|
|
11311
11311
|
}
|
|
11312
11312
|
stopHeartbeat();
|
|
@@ -11333,7 +11333,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
11333
11333
|
_pauseGate = createPauseGate();
|
|
11334
11334
|
_state = "PAUSED";
|
|
11335
11335
|
eventBus.emit("orchestrator:paused", {});
|
|
11336
|
-
logger$
|
|
11336
|
+
logger$36.info("Orchestrator paused");
|
|
11337
11337
|
}
|
|
11338
11338
|
function resume() {
|
|
11339
11339
|
if (_state !== "PAUSED") return;
|
|
@@ -11344,7 +11344,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
11344
11344
|
}
|
|
11345
11345
|
_state = "RUNNING";
|
|
11346
11346
|
eventBus.emit("orchestrator:resumed", {});
|
|
11347
|
-
logger$
|
|
11347
|
+
logger$36.info("Orchestrator resumed");
|
|
11348
11348
|
}
|
|
11349
11349
|
return {
|
|
11350
11350
|
run,
|
|
@@ -11982,7 +11982,7 @@ const CritiqueOutputSchema = z.object({
|
|
|
11982
11982
|
|
|
11983
11983
|
//#endregion
|
|
11984
11984
|
//#region src/modules/phase-orchestrator/critique-loop.ts
|
|
11985
|
-
const logger$
|
|
11985
|
+
const logger$8 = createLogger("critique-loop");
|
|
11986
11986
|
/**
|
|
11987
11987
|
* Maps a phase name to the critique prompt template name.
|
|
11988
11988
|
* Falls back to `critique-${phase}` for unknown phases.
|
|
@@ -12035,7 +12035,7 @@ async function runCritiqueLoop(artifact, phaseId, runId, phase, deps, options =
|
|
|
12035
12035
|
critiquePrompt = critiqueTemplate.replace("{{artifact_content}}", currentArtifact).replace("{{project_context}}", projectContext);
|
|
12036
12036
|
} catch (err) {
|
|
12037
12037
|
const message = err instanceof Error ? err.message : String(err);
|
|
12038
|
-
logger$
|
|
12038
|
+
logger$8.warn({
|
|
12039
12039
|
phaseId,
|
|
12040
12040
|
promptName: critiquePromptName,
|
|
12041
12041
|
err: message
|
|
@@ -12063,7 +12063,7 @@ async function runCritiqueLoop(artifact, phaseId, runId, phase, deps, options =
|
|
|
12063
12063
|
critiqueTokens.output += result.tokenEstimate.output;
|
|
12064
12064
|
if (result.status !== "completed" || result.parsed === null) {
|
|
12065
12065
|
const errMsg = result.parseError ?? `Critique dispatch ended with status '${result.status}'`;
|
|
12066
|
-
logger$
|
|
12066
|
+
logger$8.warn({
|
|
12067
12067
|
phaseId,
|
|
12068
12068
|
iteration: i + 1,
|
|
12069
12069
|
err: errMsg
|
|
@@ -12082,7 +12082,7 @@ async function runCritiqueLoop(artifact, phaseId, runId, phase, deps, options =
|
|
|
12082
12082
|
lastCritiqueOutput = critiqueOutput;
|
|
12083
12083
|
} catch (err) {
|
|
12084
12084
|
const message = err instanceof Error ? err.message : String(err);
|
|
12085
|
-
logger$
|
|
12085
|
+
logger$8.warn({
|
|
12086
12086
|
phaseId,
|
|
12087
12087
|
iteration: i + 1,
|
|
12088
12088
|
err: message
|
|
@@ -12122,14 +12122,14 @@ async function runCritiqueLoop(artifact, phaseId, runId, phase, deps, options =
|
|
|
12122
12122
|
});
|
|
12123
12123
|
} catch (err) {
|
|
12124
12124
|
const message = err instanceof Error ? err.message : String(err);
|
|
12125
|
-
logger$
|
|
12125
|
+
logger$8.warn({
|
|
12126
12126
|
phaseId,
|
|
12127
12127
|
iteration: i + 1,
|
|
12128
12128
|
err: message
|
|
12129
12129
|
}, "Critique loop: failed to store critique decision — continuing");
|
|
12130
12130
|
}
|
|
12131
12131
|
if (critiqueOutput.verdict === "pass") {
|
|
12132
|
-
logger$
|
|
12132
|
+
logger$8.info({
|
|
12133
12133
|
phaseId,
|
|
12134
12134
|
iteration: i + 1
|
|
12135
12135
|
}, "Critique loop: artifact passed critique — loop complete");
|
|
@@ -12142,7 +12142,7 @@ async function runCritiqueLoop(artifact, phaseId, runId, phase, deps, options =
|
|
|
12142
12142
|
totalMs: Date.now() - startMs
|
|
12143
12143
|
};
|
|
12144
12144
|
}
|
|
12145
|
-
logger$
|
|
12145
|
+
logger$8.info({
|
|
12146
12146
|
phaseId,
|
|
12147
12147
|
iteration: i + 1,
|
|
12148
12148
|
issueCount: critiqueOutput.issue_count
|
|
@@ -12155,7 +12155,7 @@ async function runCritiqueLoop(artifact, phaseId, runId, phase, deps, options =
|
|
|
12155
12155
|
refinePrompt = refineTemplate.replace("{{original_artifact}}", currentArtifact).replace("{{critique_issues}}", issuesText).replace("{{phase_context}}", phaseContext);
|
|
12156
12156
|
} catch (err) {
|
|
12157
12157
|
const message = err instanceof Error ? err.message : String(err);
|
|
12158
|
-
logger$
|
|
12158
|
+
logger$8.warn({
|
|
12159
12159
|
phaseId,
|
|
12160
12160
|
iteration: i + 1,
|
|
12161
12161
|
err: message
|
|
@@ -12176,7 +12176,7 @@ async function runCritiqueLoop(artifact, phaseId, runId, phase, deps, options =
|
|
|
12176
12176
|
const originalLength = currentArtifact.length;
|
|
12177
12177
|
const refinedLength = refineResult.output.length;
|
|
12178
12178
|
const delta = refinedLength - originalLength;
|
|
12179
|
-
logger$
|
|
12179
|
+
logger$8.info({
|
|
12180
12180
|
phaseId,
|
|
12181
12181
|
iteration: i + 1,
|
|
12182
12182
|
originalLength,
|
|
@@ -12185,7 +12185,7 @@ async function runCritiqueLoop(artifact, phaseId, runId, phase, deps, options =
|
|
|
12185
12185
|
}, "Critique loop: refinement complete");
|
|
12186
12186
|
currentArtifact = refineResult.output;
|
|
12187
12187
|
} else {
|
|
12188
|
-
logger$
|
|
12188
|
+
logger$8.warn({
|
|
12189
12189
|
phaseId,
|
|
12190
12190
|
iteration: i + 1,
|
|
12191
12191
|
status: refineResult.status
|
|
@@ -12194,7 +12194,7 @@ async function runCritiqueLoop(artifact, phaseId, runId, phase, deps, options =
|
|
|
12194
12194
|
}
|
|
12195
12195
|
} catch (err) {
|
|
12196
12196
|
const message = err instanceof Error ? err.message : String(err);
|
|
12197
|
-
logger$
|
|
12197
|
+
logger$8.warn({
|
|
12198
12198
|
phaseId,
|
|
12199
12199
|
iteration: i + 1,
|
|
12200
12200
|
err: message
|
|
@@ -12205,12 +12205,12 @@ async function runCritiqueLoop(artifact, phaseId, runId, phase, deps, options =
|
|
|
12205
12205
|
}
|
|
12206
12206
|
const remainingIssues = lastCritiqueOutput?.issues ?? [];
|
|
12207
12207
|
if (remainingIssues.length > 0) {
|
|
12208
|
-
logger$
|
|
12208
|
+
logger$8.warn({
|
|
12209
12209
|
phaseId,
|
|
12210
12210
|
maxIterations,
|
|
12211
12211
|
issueCount: remainingIssues.length
|
|
12212
12212
|
}, "Critique loop: max iterations reached with unresolved issues");
|
|
12213
|
-
for (const issue of remainingIssues) logger$
|
|
12213
|
+
for (const issue of remainingIssues) logger$8.warn({
|
|
12214
12214
|
phaseId,
|
|
12215
12215
|
severity: issue.severity,
|
|
12216
12216
|
category: issue.category,
|
|
@@ -12229,7 +12229,7 @@ async function runCritiqueLoop(artifact, phaseId, runId, phase, deps, options =
|
|
|
12229
12229
|
|
|
12230
12230
|
//#endregion
|
|
12231
12231
|
//#region src/modules/phase-orchestrator/elicitation-selector.ts
|
|
12232
|
-
const logger$
|
|
12232
|
+
const logger$7 = createLogger("elicitation-selector");
|
|
12233
12233
|
/**
|
|
12234
12234
|
* Affinity scores (0.0–1.0) for each category per content type.
|
|
12235
12235
|
*
|
|
@@ -12351,10 +12351,10 @@ function loadElicitationMethods() {
|
|
|
12351
12351
|
try {
|
|
12352
12352
|
const content = readFileSync(csvPath, "utf-8");
|
|
12353
12353
|
const methods = parseMethodsCsv(content);
|
|
12354
|
-
logger$
|
|
12354
|
+
logger$7.debug({ count: methods.length }, "Loaded elicitation methods");
|
|
12355
12355
|
return methods;
|
|
12356
12356
|
} catch (err) {
|
|
12357
|
-
logger$
|
|
12357
|
+
logger$7.warn({
|
|
12358
12358
|
csvPath,
|
|
12359
12359
|
err
|
|
12360
12360
|
}, "Failed to load elicitation methods CSV");
|
|
@@ -12649,7 +12649,7 @@ const ElicitationOutputSchema = z.object({
|
|
|
12649
12649
|
|
|
12650
12650
|
//#endregion
|
|
12651
12651
|
//#region src/modules/phase-orchestrator/step-runner.ts
|
|
12652
|
-
const logger$
|
|
12652
|
+
const logger$6 = createLogger("step-runner");
|
|
12653
12653
|
/**
|
|
12654
12654
|
* Format an array of decision records into a markdown section for injection.
|
|
12655
12655
|
*
|
|
@@ -12756,7 +12756,7 @@ async function runSteps(steps, deps, runId, phase, params) {
|
|
|
12756
12756
|
if (estimatedTokens > budgetTokens) {
|
|
12757
12757
|
const decisionRefs = step.context.filter((ref) => ref.source.startsWith("decision:"));
|
|
12758
12758
|
if (decisionRefs.length > 0) {
|
|
12759
|
-
logger$
|
|
12759
|
+
logger$6.warn({
|
|
12760
12760
|
step: step.name,
|
|
12761
12761
|
estimatedTokens,
|
|
12762
12762
|
budgetTokens
|
|
@@ -12783,7 +12783,7 @@ async function runSteps(steps, deps, runId, phase, params) {
|
|
|
12783
12783
|
}
|
|
12784
12784
|
prompt = summarizedPrompt;
|
|
12785
12785
|
estimatedTokens = Math.ceil(prompt.length / 4);
|
|
12786
|
-
if (estimatedTokens <= budgetTokens) logger$
|
|
12786
|
+
if (estimatedTokens <= budgetTokens) logger$6.info({
|
|
12787
12787
|
step: step.name,
|
|
12788
12788
|
estimatedTokens,
|
|
12789
12789
|
budgetTokens
|
|
@@ -12964,7 +12964,7 @@ async function runSteps(steps, deps, runId, phase, params) {
|
|
|
12964
12964
|
const critiqueResult = await runCritiqueLoop(artifactContent, phase, runId, phase, deps);
|
|
12965
12965
|
totalInput += critiqueResult.critiqueTokens.input + critiqueResult.refinementTokens.input;
|
|
12966
12966
|
totalOutput += critiqueResult.critiqueTokens.output + critiqueResult.refinementTokens.output;
|
|
12967
|
-
logger$
|
|
12967
|
+
logger$6.info({
|
|
12968
12968
|
step: step.name,
|
|
12969
12969
|
verdict: critiqueResult.verdict,
|
|
12970
12970
|
iterations: critiqueResult.iterations,
|
|
@@ -12972,7 +12972,7 @@ async function runSteps(steps, deps, runId, phase, params) {
|
|
|
12972
12972
|
}, "Step critique loop complete");
|
|
12973
12973
|
} catch (critiqueErr) {
|
|
12974
12974
|
const critiqueMsg = critiqueErr instanceof Error ? critiqueErr.message : String(critiqueErr);
|
|
12975
|
-
logger$
|
|
12975
|
+
logger$6.warn({
|
|
12976
12976
|
step: step.name,
|
|
12977
12977
|
err: critiqueMsg
|
|
12978
12978
|
}, "Step critique loop threw an error — continuing without critique");
|
|
@@ -12982,7 +12982,7 @@ async function runSteps(steps, deps, runId, phase, params) {
|
|
|
12982
12982
|
const contentType = deriveContentType(phase, step.name);
|
|
12983
12983
|
const selectedMethods = selectMethods({ content_type: contentType }, usedElicitationMethods);
|
|
12984
12984
|
if (selectedMethods.length > 0) {
|
|
12985
|
-
logger$
|
|
12985
|
+
logger$6.info({
|
|
12986
12986
|
step: step.name,
|
|
12987
12987
|
methods: selectedMethods.map((m) => m.name),
|
|
12988
12988
|
contentType
|
|
@@ -13021,13 +13021,13 @@ async function runSteps(steps, deps, runId, phase, params) {
|
|
|
13021
13021
|
key: `${phase}-round-${roundIndex}-insights`,
|
|
13022
13022
|
value: elicitParsed.insights
|
|
13023
13023
|
});
|
|
13024
|
-
logger$
|
|
13024
|
+
logger$6.info({
|
|
13025
13025
|
step: step.name,
|
|
13026
13026
|
method: method.name,
|
|
13027
13027
|
roundIndex
|
|
13028
13028
|
}, "Elicitation insights stored in decision store");
|
|
13029
13029
|
}
|
|
13030
|
-
} else logger$
|
|
13030
|
+
} else logger$6.warn({
|
|
13031
13031
|
step: step.name,
|
|
13032
13032
|
method: method.name,
|
|
13033
13033
|
status: elicitResult.status
|
|
@@ -13043,7 +13043,7 @@ async function runSteps(steps, deps, runId, phase, params) {
|
|
|
13043
13043
|
}
|
|
13044
13044
|
} catch (elicitErr) {
|
|
13045
13045
|
const elicitMsg = elicitErr instanceof Error ? elicitErr.message : String(elicitErr);
|
|
13046
|
-
logger$
|
|
13046
|
+
logger$6.warn({
|
|
13047
13047
|
step: step.name,
|
|
13048
13048
|
err: elicitMsg
|
|
13049
13049
|
}, "Step elicitation threw an error — continuing without elicitation");
|
|
@@ -13123,6 +13123,24 @@ const BRIEF_FIELDS$1 = [
|
|
|
13123
13123
|
"constraints",
|
|
13124
13124
|
"technology_constraints"
|
|
13125
13125
|
];
|
|
13126
|
+
/** Pattern matching cloud platforms, languages, frameworks, and infra tech */
|
|
13127
|
+
const TECH_CONSTRAINT_PATTERN = /\b(GCP|AWS|Azure|Google Cloud|Cloud Run|GKE|Cloud SQL|Memorystore|Pub\/Sub|BigQuery|EKS|Lambda|S3|Kotlin|JVM|Java|Go\b|Golang|Rust|Node\.js|JavaScript|TypeScript|Python|C#|\.NET|Spring Boot|Ktor|Micronaut|Quarkus|NestJS|Express|multi-region|active-active|AES-256|TLS\s*1\.[23]|encryption at rest|encryption in transit)/i;
|
|
13128
|
+
/**
|
|
13129
|
+
* Scan constraints for technology-related items and move them to
|
|
13130
|
+
* technology_constraints. Models consistently lump all constraints
|
|
13131
|
+
* together despite prompt instructions to separate them.
|
|
13132
|
+
*/
|
|
13133
|
+
function reclassifyTechnologyConstraints(brief) {
|
|
13134
|
+
if (brief.technology_constraints.length > 0) return;
|
|
13135
|
+
const techItems = [];
|
|
13136
|
+
const nonTechItems = [];
|
|
13137
|
+
for (const c of brief.constraints) if (TECH_CONSTRAINT_PATTERN.test(c)) techItems.push(c);
|
|
13138
|
+
else nonTechItems.push(c);
|
|
13139
|
+
if (techItems.length > 0) {
|
|
13140
|
+
brief.constraints = nonTechItems;
|
|
13141
|
+
brief.technology_constraints = techItems;
|
|
13142
|
+
}
|
|
13143
|
+
}
|
|
13126
13144
|
/**
|
|
13127
13145
|
* Build step definitions for 2-step analysis decomposition.
|
|
13128
13146
|
*/
|
|
@@ -13220,6 +13238,23 @@ async function runAnalysisMultiStep(deps, params) {
|
|
|
13220
13238
|
constraints: scopeOutput.constraints ?? [],
|
|
13221
13239
|
technology_constraints: scopeOutput.technology_constraints ?? []
|
|
13222
13240
|
};
|
|
13241
|
+
reclassifyTechnologyConstraints(brief);
|
|
13242
|
+
if (brief.technology_constraints.length > 0) {
|
|
13243
|
+
upsertDecision(deps.db, {
|
|
13244
|
+
pipeline_run_id: params.runId,
|
|
13245
|
+
phase: "analysis",
|
|
13246
|
+
category: "product-brief",
|
|
13247
|
+
key: "constraints",
|
|
13248
|
+
value: JSON.stringify(brief.constraints)
|
|
13249
|
+
});
|
|
13250
|
+
upsertDecision(deps.db, {
|
|
13251
|
+
pipeline_run_id: params.runId,
|
|
13252
|
+
phase: "analysis",
|
|
13253
|
+
category: "technology-constraints",
|
|
13254
|
+
key: "technology_constraints",
|
|
13255
|
+
value: JSON.stringify(brief.technology_constraints)
|
|
13256
|
+
});
|
|
13257
|
+
}
|
|
13223
13258
|
const analysisResult = {
|
|
13224
13259
|
result: "success",
|
|
13225
13260
|
product_brief: brief,
|
|
@@ -13350,6 +13385,7 @@ async function runAnalysisPhase(deps, params) {
|
|
|
13350
13385
|
|
|
13351
13386
|
//#endregion
|
|
13352
13387
|
//#region src/modules/phase-orchestrator/phases/planning.ts
|
|
13388
|
+
const logger$5 = createLogger("planning-phase");
|
|
13353
13389
|
/** Maximum total prompt length in tokens (3,500 tokens × 4 chars/token = 14,000 chars) */
|
|
13354
13390
|
const MAX_PROMPT_TOKENS = 3500;
|
|
13355
13391
|
const MAX_PROMPT_CHARS = MAX_PROMPT_TOKENS * 4;
|
|
@@ -13370,6 +13406,26 @@ const BRIEF_FIELDS = [
|
|
|
13370
13406
|
"constraints",
|
|
13371
13407
|
"technology_constraints"
|
|
13372
13408
|
];
|
|
13409
|
+
/** Keywords indicating JavaScript/TypeScript/Node.js ecosystem */
|
|
13410
|
+
const JS_TS_PATTERN = /\b(TypeScript|JavaScript|Node\.js|NestJS|Express|Fastify|Hapi|Koa|Next\.js.*backend|Next\.js.*API|Deno|Bun)\b/i;
|
|
13411
|
+
/** Keywords indicating non-JS backend languages that satisfy high-concurrency constraints */
|
|
13412
|
+
const COMPLIANT_LANG_PATTERN = /\b(Kotlin|JVM|Java|Go\b|Golang|Rust|C#|\.NET|Scala|Erlang|Elixir)\b/i;
|
|
13413
|
+
/**
|
|
13414
|
+
* Check whether the tech stack's language/framework fields violate technology
|
|
13415
|
+
* constraints that exclude JavaScript/Node.js from backend services.
|
|
13416
|
+
*
|
|
13417
|
+
* @returns A violation message if detected, or null if compliant.
|
|
13418
|
+
*/
|
|
13419
|
+
function detectTechStackViolation(techStack, technologyConstraints) {
|
|
13420
|
+
const constraintsText = technologyConstraints.map((c) => c.value).join(" ");
|
|
13421
|
+
const excludesJS = /\b(excluded|not.*right choice|not.*recommended|avoid|do not use|prohibited)\b/i.test(constraintsText) && /\b(JavaScript|Node\.js|TypeScript)\b/i.test(constraintsText);
|
|
13422
|
+
const prefersNonJS = COMPLIANT_LANG_PATTERN.test(constraintsText) && /\b(prefer|must|required|evaluate|choose)\b/i.test(constraintsText);
|
|
13423
|
+
if (!excludesJS && !prefersNonJS) return null;
|
|
13424
|
+
const langValue = techStack["language"] ?? "";
|
|
13425
|
+
const frameworkValue = techStack["framework"] ?? techStack["backend_framework"] ?? "";
|
|
13426
|
+
if (JS_TS_PATTERN.test(langValue) || JS_TS_PATTERN.test(frameworkValue)) return `Tech stack violates technology constraints: language="${langValue}", framework="${frameworkValue}". Constraints specify: ${constraintsText.substring(0, 200)}`;
|
|
13427
|
+
return null;
|
|
13428
|
+
}
|
|
13373
13429
|
/**
|
|
13374
13430
|
* Format product brief decisions from the analysis phase into markdown-like text
|
|
13375
13431
|
* suitable for prompt injection.
|
|
@@ -13468,6 +13524,10 @@ function buildPlanningSteps() {
|
|
|
13468
13524
|
{
|
|
13469
13525
|
placeholder: "technology_constraints",
|
|
13470
13526
|
source: "decision:analysis.technology-constraints"
|
|
13527
|
+
},
|
|
13528
|
+
{
|
|
13529
|
+
placeholder: "concept",
|
|
13530
|
+
source: "param:concept"
|
|
13471
13531
|
}
|
|
13472
13532
|
],
|
|
13473
13533
|
persist: [
|
|
@@ -13524,8 +13584,14 @@ async function runPlanningMultiStep(deps, params) {
|
|
|
13524
13584
|
details: "No product brief decisions found in the analysis phase.",
|
|
13525
13585
|
tokenUsage: zeroTokenUsage
|
|
13526
13586
|
};
|
|
13587
|
+
let concept = "";
|
|
13588
|
+
const run = getPipelineRunById(db, runId);
|
|
13589
|
+
if (run?.config_json) try {
|
|
13590
|
+
const config = JSON.parse(run.config_json);
|
|
13591
|
+
concept = config.concept ?? "";
|
|
13592
|
+
} catch {}
|
|
13527
13593
|
const steps = buildPlanningSteps();
|
|
13528
|
-
const result = await runSteps(steps, deps, params.runId, "planning", {});
|
|
13594
|
+
const result = await runSteps(steps, deps, params.runId, "planning", { concept });
|
|
13529
13595
|
if (!result.success) return {
|
|
13530
13596
|
result: "failed",
|
|
13531
13597
|
error: result.error ?? "multi_step_failed",
|
|
@@ -13533,13 +13599,52 @@ async function runPlanningMultiStep(deps, params) {
|
|
|
13533
13599
|
tokenUsage: result.tokenUsage
|
|
13534
13600
|
};
|
|
13535
13601
|
const frsOutput = result.steps[1]?.parsed;
|
|
13536
|
-
|
|
13602
|
+
let nfrsOutput = result.steps[2]?.parsed;
|
|
13603
|
+
let totalTokenUsage = { ...result.tokenUsage };
|
|
13537
13604
|
if (!frsOutput || !nfrsOutput) return {
|
|
13538
13605
|
result: "failed",
|
|
13539
13606
|
error: "incomplete_steps",
|
|
13540
13607
|
details: "Not all planning steps produced output",
|
|
13541
13608
|
tokenUsage: result.tokenUsage
|
|
13542
13609
|
};
|
|
13610
|
+
const techStack = nfrsOutput.tech_stack;
|
|
13611
|
+
if (techStack) {
|
|
13612
|
+
const techConstraintDecisions = allAnalysisDecisions.filter((d) => d.category === "technology-constraints");
|
|
13613
|
+
const violation = detectTechStackViolation(techStack, techConstraintDecisions);
|
|
13614
|
+
if (violation) {
|
|
13615
|
+
logger$5.warn({ violation }, "Tech stack constraint violation detected — retrying step 3 with correction");
|
|
13616
|
+
const correctionPrefix = `CRITICAL CORRECTION: Your previous output was rejected because it violates the stated technology constraints.\n\nViolation: ${violation}\n\nYou MUST NOT use TypeScript, JavaScript, or Node.js for ANY backend service. Choose from Go, Kotlin/JVM, or Rust as stated in the technology constraints.\n\nRe-generate your output with a compliant tech stack. Everything else (NFRs, domain model, out-of-scope) can remain the same.\n\n---\n\n`;
|
|
13617
|
+
const step3Template = await deps.pack.getPrompt("planning-step-3-nfrs");
|
|
13618
|
+
const stepOutputs = new Map();
|
|
13619
|
+
stepOutputs.set("planning-step-1-classification", result.steps[0]?.parsed ?? {});
|
|
13620
|
+
stepOutputs.set("planning-step-2-frs", frsOutput);
|
|
13621
|
+
let correctedPrompt = step3Template;
|
|
13622
|
+
const step3Def = steps[2];
|
|
13623
|
+
for (const ref of step3Def?.context ?? []) {
|
|
13624
|
+
const value = resolveContext(ref, deps, runId, { concept }, stepOutputs);
|
|
13625
|
+
correctedPrompt = correctedPrompt.replace(`{{${ref.placeholder}}}`, value);
|
|
13626
|
+
}
|
|
13627
|
+
correctedPrompt = correctionPrefix + correctedPrompt;
|
|
13628
|
+
const retryHandle = deps.dispatcher.dispatch({
|
|
13629
|
+
prompt: correctedPrompt,
|
|
13630
|
+
agent: "claude-code",
|
|
13631
|
+
taskType: "planning-nfrs",
|
|
13632
|
+
outputSchema: PlanningNFRsOutputSchema
|
|
13633
|
+
});
|
|
13634
|
+
const retryResult = await retryHandle.result;
|
|
13635
|
+
totalTokenUsage.input += retryResult.tokenEstimate.input;
|
|
13636
|
+
totalTokenUsage.output += retryResult.tokenEstimate.output;
|
|
13637
|
+
if (retryResult.status === "completed" && retryResult.parsed !== null && retryResult.parsed.result !== "failed") {
|
|
13638
|
+
const retryParsed = retryResult.parsed;
|
|
13639
|
+
const retryTechStack = retryParsed.tech_stack;
|
|
13640
|
+
const retryViolation = retryTechStack ? detectTechStackViolation(retryTechStack, techConstraintDecisions) : null;
|
|
13641
|
+
if (!retryViolation) {
|
|
13642
|
+
logger$5.info("Retry produced compliant tech stack — using corrected output");
|
|
13643
|
+
nfrsOutput = retryParsed;
|
|
13644
|
+
} else logger$5.warn({ retryViolation }, "Retry still violates constraints — using original output");
|
|
13645
|
+
} else logger$5.warn("Retry dispatch failed — using original output");
|
|
13646
|
+
}
|
|
13647
|
+
}
|
|
13543
13648
|
const frs = frsOutput.functional_requirements;
|
|
13544
13649
|
const nfrs = nfrsOutput.non_functional_requirements;
|
|
13545
13650
|
const userStories = frsOutput.user_stories;
|
|
@@ -13547,13 +13652,13 @@ async function runPlanningMultiStep(deps, params) {
|
|
|
13547
13652
|
result: "failed",
|
|
13548
13653
|
error: "missing_functional_requirements",
|
|
13549
13654
|
details: "FRs step did not return functional_requirements",
|
|
13550
|
-
tokenUsage:
|
|
13655
|
+
tokenUsage: totalTokenUsage
|
|
13551
13656
|
};
|
|
13552
13657
|
if (!nfrs?.length) return {
|
|
13553
13658
|
result: "failed",
|
|
13554
13659
|
error: "missing_non_functional_requirements",
|
|
13555
13660
|
details: "NFRs step did not return non_functional_requirements",
|
|
13556
|
-
tokenUsage:
|
|
13661
|
+
tokenUsage: totalTokenUsage
|
|
13557
13662
|
};
|
|
13558
13663
|
for (const fr of frs) createRequirement(db, {
|
|
13559
13664
|
pipeline_run_id: params.runId,
|
|
@@ -13575,7 +13680,7 @@ async function runPlanningMultiStep(deps, params) {
|
|
|
13575
13680
|
result: "success",
|
|
13576
13681
|
requirements_count: requirementsCount,
|
|
13577
13682
|
user_stories_count: userStoriesCount,
|
|
13578
|
-
tokenUsage:
|
|
13683
|
+
tokenUsage: totalTokenUsage
|
|
13579
13684
|
};
|
|
13580
13685
|
const artifactId = result.steps[2]?.artifactId;
|
|
13581
13686
|
if (artifactId !== void 0) planningResult.artifact_id = artifactId;
|