substrate-ai 0.1.23 → 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$34 = createLogger("init");
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$34.error({ err }, "Adapter discovery failed");
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$34.error({ err }, "Failed to write config files");
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$33 = createLogger("config");
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$33.warn({ errors: parsed.error.issues }, "Invalid environment variable overrides ignored");
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$33.debug("Configuration loaded successfully");
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$33.info({
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$32 = createLogger("config-cmd");
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$32.error({ err }, "Failed to load configuration");
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$32.error({ err }, "Failed to load configuration");
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$31 = createLogger("merge-cmd");
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$31.info({
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$31.error({
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$31.error({
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$30 = createLogger("worktrees-cmd");
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$30.error({ err }, "Failed to list worktrees");
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$30.error({ err }, "listWorktreesAction failed");
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$29 = createLogger("cost-cmd");
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$29.error({ err }, "runCostAction failed");
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$28 = createLogger("crash-recovery");
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$28.warn({ err }, "Worktree cleanup failed during recovery (non-fatal)");
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$28.info({
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$28.info({ count }, "Cleaned up orphaned worktrees");
2134
+ logger$29.info({ count }, "Cleaned up orphaned worktrees");
2135
2135
  return count;
2136
2136
  } catch (err) {
2137
- logger$28.warn({ err }, "Failed to clean up orphaned worktrees — continuing");
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$27 = createLogger("start-cmd");
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$27.info("Config hot-reload disabled (--no-watch-config).");
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$27.info({
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$27.error({
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$27.info({ sessionId: interruptedSession.id }, "session:resumed");
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$27.error({ err }, "runStartAction failed");
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$26 = createLogger("status-cmd");
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$26.error({ err }, "runStatusAction failed");
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$25 = createLogger("pause-cmd");
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$25.error({ err }, "runPauseAction failed");
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$24 = createLogger("resume-cmd");
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$24.error({ err }, "runResumeAction failed");
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$23 = createLogger("cancel-cmd");
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$23.error({ err }, "runCancelAction failed");
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$22 = createLogger("retry-cmd");
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$22.error({ err }, "runRetryAction failed");
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$22.info("SIGINT received — initiating graceful shutdown");
3500
+ logger$23.info("SIGINT received — initiating graceful shutdown");
3501
3501
  taskGraphEngine.cancelAll();
3502
3502
  };
3503
3503
  const sigtermHandler = () => {
3504
- logger$22.info("SIGTERM received — initiating graceful shutdown");
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$22.error({ err }, "runFollowMode failed");
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$21 = createLogger("plan-generator");
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$21.warn({
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$20 = createLogger("plan-refiner");
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$20.info({
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$20.info({
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$19 = createLogger("plan-refine-cmd");
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$19.info({
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$19.error({ err }, "runPlanRefineAction failed");
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$18 = createLogger("plan-diff-cmd");
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$18.error({ err }, "runPlanDiffAction failed");
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$17 = createLogger("plan-rollback-cmd");
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$17.info({
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$17.error({ err }, "runPlanRollbackAction failed");
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$16 = createLogger("plan-cmd");
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$16.error({ err }, "runPlanReviewAction failed");
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$16.warn("Could not read generated plan file for DB storage");
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$15 = createLogger("context-compiler");
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$15.warn({
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$15.warn({
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$15.warn({
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$14 = createLogger("agent-dispatch");
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$14.debug({
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$14.info({
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$14.info("Dispatcher shutdown complete");
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$14.warn({
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$14.error({
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$14.warn({
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$14.debug({
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$14.warn({
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$14.debug({
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$14.debug({
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$14.debug({
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$13 = createLogger("compiled-workflows:prompt-assembler");
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$13.warn({
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$13.warn({ sectionName: section.name }, "Section eliminated to fit token budget");
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$13.warn({
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$13.warn({
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$12 = createLogger("compiled-workflows:create-story");
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$12.debug({
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$12.error({ error }, "Failed to retrieve create-story prompt template");
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$12.debug({
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$12.error({
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$12.warn({
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$12.warn({
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$12.warn({
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$12.warn({
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$12.info({
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$12.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve implementation decisions");
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$12.info({ epicId }, "Using file-based fallback for epic shard (decisions table empty)");
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$12.warn({
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$12.warn({
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$12.info("Using file-based fallback for architecture constraints (decisions table empty)");
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$12.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve architecture constraints");
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$12.warn({
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$12.warn({ error: err instanceof Error ? err.message : String(err) }, "File-based architecture fallback failed");
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$12.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve story template from pack");
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$11 = createLogger("compiled-workflows:git-helpers");
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$11.warn({
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$11.warn({
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$10 = createLogger("compiled-workflows:dev-story");
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$10.info({
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$10.debug({ storyKey }, "Retrieved dev-story prompt template from pack");
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$10.error({
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$10.error({
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$10.error({
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$10.error({
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$10.debug({
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$10.debug({ storyKey }, "No test-pattern decisions found — using default Vitest patterns");
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$10.warn({
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$10.info({
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$10.error({
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$10.error({
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$10.info({
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$10.error({
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$10.info({
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$10.error({
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$10.info({
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$10.warn({
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$10.info({
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$9 = createLogger("compiled-workflows:code-review");
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$9.debug({
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$9.error({ error }, "Failed to retrieve code-review prompt template");
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$9.error({
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$9.debug({
9571
+ logger$10.debug({
9572
9572
  fileCount: filesModified.length,
9573
9573
  tokenCount: scopedTotal
9574
9574
  }, "Using scoped file diff");
9575
9575
  } else {
9576
- logger$9.warn({
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$9.warn({
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$9.warn({
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$9.debug({
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$9.error({
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$9.warn({
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$9.warn({ storyKey }, "Code-review dispatch timed out");
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$9.warn({
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$9.warn({
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$9.info({
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$9.info({
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$9.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve architecture constraints");
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$8 = createLogger("implementation-orchestrator:seed");
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$8.info({
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$8.warn({ error: err instanceof Error ? err.message : String(err) }, "Methodology context seeding failed (non-fatal)");
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$8.debug({ count }, "Seeded architecture decisions");
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$8.debug({ count }, "Seeded epic shard decisions");
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$8.debug("Seeded test patterns decision");
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$35 = createLogger("implementation-orchestrator");
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$35.warn({
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$35.warn("Failed to persist orchestrator state", { err });
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$35.warn({
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$35.info("Processing story", { storyKey });
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$35.info({
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$35.error({
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$35.info({
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$35.info({
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$35.warn({
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$35.info(batchMetrics, "Batch dev-story metrics");
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$35.warn({
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$35.warn({
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$35.warn("Dev-story reported failure, proceeding to code review", {
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$35.info({
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$35.info({
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$35.warn({
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$35.info({
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$35.info({
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$35.info({
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$35.warn("Failed to assemble auto-approve fix prompt, using fallback", { storyKey });
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$35.warn("Auto-approve fix timed out — approving anyway (issues were minor)", { storyKey });
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$35.warn("Auto-approve fix dispatch failed — approving anyway (issues were minor)", {
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$35.warn("Failed to assemble fix prompt, using fallback", {
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$35.warn("Fix dispatch timed out — escalating story", {
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$35.warn("Fix dispatch failed", {
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$35.warn("Fix dispatch failed, continuing to next review", {
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$35.warn("run() called while orchestrator is already running or paused — ignoring", { state: _state });
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$35.warn("run() called on a COMPLETE orchestrator — ignoring", { state: _state });
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$35.info({
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$35.info("Orchestrator starting", {
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$35.error("Orchestrator failed with unhandled error", { err });
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$35.info("Orchestrator paused");
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$35.info("Orchestrator resumed");
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$7 = createLogger("critique-loop");
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$7.warn({
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$7.warn({
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$7.warn({
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$7.warn({
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$7.info({
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$7.info({
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$7.warn({
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$7.info({
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$7.warn({
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$7.warn({
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$7.warn({
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$7.warn({
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$6 = createLogger("elicitation-selector");
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$6.debug({ count: methods.length }, "Loaded elicitation methods");
12354
+ logger$7.debug({ count: methods.length }, "Loaded elicitation methods");
12355
12355
  return methods;
12356
12356
  } catch (err) {
12357
- logger$6.warn({
12357
+ logger$7.warn({
12358
12358
  csvPath,
12359
12359
  err
12360
12360
  }, "Failed to load elicitation methods CSV");
@@ -12438,7 +12438,8 @@ const ProductBriefSchema = z.object({
12438
12438
  target_users: z.array(z.string().min(1)).min(1),
12439
12439
  core_features: z.array(z.string().min(1)).min(1),
12440
12440
  success_metrics: z.array(z.string().min(1)).min(1),
12441
- constraints: z.array(z.string()).default([])
12441
+ constraints: z.array(z.string()).default([]),
12442
+ technology_constraints: z.array(z.string()).optional().default([])
12442
12443
  });
12443
12444
  /**
12444
12445
  * Zod schema for the full YAML output emitted by the analysis agent.
@@ -12465,7 +12466,8 @@ const AnalysisScopeOutputSchema = z.object({
12465
12466
  result: z.enum(["success", "failed"]),
12466
12467
  core_features: z.array(z.string().min(1)).min(1).optional(),
12467
12468
  success_metrics: z.array(z.string().min(1)).min(1).optional(),
12468
- constraints: z.array(z.string()).default([])
12469
+ constraints: z.array(z.string()).default([]),
12470
+ technology_constraints: z.array(z.string()).optional().default([])
12469
12471
  });
12470
12472
  /**
12471
12473
  * Zod schema for a single functional requirement.
@@ -12647,7 +12649,7 @@ const ElicitationOutputSchema = z.object({
12647
12649
 
12648
12650
  //#endregion
12649
12651
  //#region src/modules/phase-orchestrator/step-runner.ts
12650
- const logger$5 = createLogger("step-runner");
12652
+ const logger$6 = createLogger("step-runner");
12651
12653
  /**
12652
12654
  * Format an array of decision records into a markdown section for injection.
12653
12655
  *
@@ -12754,7 +12756,7 @@ async function runSteps(steps, deps, runId, phase, params) {
12754
12756
  if (estimatedTokens > budgetTokens) {
12755
12757
  const decisionRefs = step.context.filter((ref) => ref.source.startsWith("decision:"));
12756
12758
  if (decisionRefs.length > 0) {
12757
- logger$5.warn({
12759
+ logger$6.warn({
12758
12760
  step: step.name,
12759
12761
  estimatedTokens,
12760
12762
  budgetTokens
@@ -12781,7 +12783,7 @@ async function runSteps(steps, deps, runId, phase, params) {
12781
12783
  }
12782
12784
  prompt = summarizedPrompt;
12783
12785
  estimatedTokens = Math.ceil(prompt.length / 4);
12784
- if (estimatedTokens <= budgetTokens) logger$5.info({
12786
+ if (estimatedTokens <= budgetTokens) logger$6.info({
12785
12787
  step: step.name,
12786
12788
  estimatedTokens,
12787
12789
  budgetTokens
@@ -12962,7 +12964,7 @@ async function runSteps(steps, deps, runId, phase, params) {
12962
12964
  const critiqueResult = await runCritiqueLoop(artifactContent, phase, runId, phase, deps);
12963
12965
  totalInput += critiqueResult.critiqueTokens.input + critiqueResult.refinementTokens.input;
12964
12966
  totalOutput += critiqueResult.critiqueTokens.output + critiqueResult.refinementTokens.output;
12965
- logger$5.info({
12967
+ logger$6.info({
12966
12968
  step: step.name,
12967
12969
  verdict: critiqueResult.verdict,
12968
12970
  iterations: critiqueResult.iterations,
@@ -12970,7 +12972,7 @@ async function runSteps(steps, deps, runId, phase, params) {
12970
12972
  }, "Step critique loop complete");
12971
12973
  } catch (critiqueErr) {
12972
12974
  const critiqueMsg = critiqueErr instanceof Error ? critiqueErr.message : String(critiqueErr);
12973
- logger$5.warn({
12975
+ logger$6.warn({
12974
12976
  step: step.name,
12975
12977
  err: critiqueMsg
12976
12978
  }, "Step critique loop threw an error — continuing without critique");
@@ -12980,7 +12982,7 @@ async function runSteps(steps, deps, runId, phase, params) {
12980
12982
  const contentType = deriveContentType(phase, step.name);
12981
12983
  const selectedMethods = selectMethods({ content_type: contentType }, usedElicitationMethods);
12982
12984
  if (selectedMethods.length > 0) {
12983
- logger$5.info({
12985
+ logger$6.info({
12984
12986
  step: step.name,
12985
12987
  methods: selectedMethods.map((m) => m.name),
12986
12988
  contentType
@@ -13019,13 +13021,13 @@ async function runSteps(steps, deps, runId, phase, params) {
13019
13021
  key: `${phase}-round-${roundIndex}-insights`,
13020
13022
  value: elicitParsed.insights
13021
13023
  });
13022
- logger$5.info({
13024
+ logger$6.info({
13023
13025
  step: step.name,
13024
13026
  method: method.name,
13025
13027
  roundIndex
13026
13028
  }, "Elicitation insights stored in decision store");
13027
13029
  }
13028
- } else logger$5.warn({
13030
+ } else logger$6.warn({
13029
13031
  step: step.name,
13030
13032
  method: method.name,
13031
13033
  status: elicitResult.status
@@ -13041,7 +13043,7 @@ async function runSteps(steps, deps, runId, phase, params) {
13041
13043
  }
13042
13044
  } catch (elicitErr) {
13043
13045
  const elicitMsg = elicitErr instanceof Error ? elicitErr.message : String(elicitErr);
13044
- logger$5.warn({
13046
+ logger$6.warn({
13045
13047
  step: step.name,
13046
13048
  err: elicitMsg
13047
13049
  }, "Step elicitation threw an error — continuing without elicitation");
@@ -13118,8 +13120,27 @@ const BRIEF_FIELDS$1 = [
13118
13120
  "target_users",
13119
13121
  "core_features",
13120
13122
  "success_metrics",
13121
- "constraints"
13123
+ "constraints",
13124
+ "technology_constraints"
13122
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
+ }
13123
13144
  /**
13124
13145
  * Build step definitions for 2-step analysis decomposition.
13125
13146
  */
@@ -13167,6 +13188,11 @@ function buildAnalysisSteps() {
13167
13188
  field: "constraints",
13168
13189
  category: "product-brief",
13169
13190
  key: "constraints"
13191
+ },
13192
+ {
13193
+ field: "technology_constraints",
13194
+ category: "technology-constraints",
13195
+ key: "technology_constraints"
13170
13196
  }
13171
13197
  ],
13172
13198
  registerArtifact: {
@@ -13188,10 +13214,8 @@ async function runAnalysisMultiStep(deps, params) {
13188
13214
  output: 0
13189
13215
  };
13190
13216
  try {
13191
- let effectiveConcept = params.concept;
13192
- if (params.concept.length > MAX_CONCEPT_CHARS) effectiveConcept = params.concept.slice(0, MAX_CONCEPT_CHARS) + "...";
13193
13217
  const steps = buildAnalysisSteps();
13194
- const result = await runSteps(steps, deps, params.runId, "analysis", { concept: effectiveConcept });
13218
+ const result = await runSteps(steps, deps, params.runId, "analysis", { concept: params.concept });
13195
13219
  if (!result.success) return {
13196
13220
  result: "failed",
13197
13221
  error: result.error ?? "multi_step_failed",
@@ -13211,8 +13235,26 @@ async function runAnalysisMultiStep(deps, params) {
13211
13235
  target_users: visionOutput.target_users,
13212
13236
  core_features: scopeOutput.core_features,
13213
13237
  success_metrics: scopeOutput.success_metrics,
13214
- constraints: scopeOutput.constraints ?? []
13238
+ constraints: scopeOutput.constraints ?? [],
13239
+ technology_constraints: scopeOutput.technology_constraints ?? []
13215
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
+ }
13216
13258
  const analysisResult = {
13217
13259
  result: "success",
13218
13260
  product_brief: brief,
@@ -13343,6 +13385,7 @@ async function runAnalysisPhase(deps, params) {
13343
13385
 
13344
13386
  //#endregion
13345
13387
  //#region src/modules/phase-orchestrator/phases/planning.ts
13388
+ const logger$5 = createLogger("planning-phase");
13346
13389
  /** Maximum total prompt length in tokens (3,500 tokens × 4 chars/token = 14,000 chars) */
13347
13390
  const MAX_PROMPT_TOKENS = 3500;
13348
13391
  const MAX_PROMPT_CHARS = MAX_PROMPT_TOKENS * 4;
@@ -13360,8 +13403,29 @@ const BRIEF_FIELDS = [
13360
13403
  "target_users",
13361
13404
  "core_features",
13362
13405
  "success_metrics",
13363
- "constraints"
13406
+ "constraints",
13407
+ "technology_constraints"
13364
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
+ }
13365
13429
  /**
13366
13430
  * Format product brief decisions from the analysis phase into markdown-like text
13367
13431
  * suitable for prompt injection.
@@ -13456,6 +13520,14 @@ function buildPlanningSteps() {
13456
13520
  {
13457
13521
  placeholder: "functional_requirements",
13458
13522
  source: "step:planning-step-2-frs"
13523
+ },
13524
+ {
13525
+ placeholder: "technology_constraints",
13526
+ source: "decision:analysis.technology-constraints"
13527
+ },
13528
+ {
13529
+ placeholder: "concept",
13530
+ source: "param:concept"
13459
13531
  }
13460
13532
  ],
13461
13533
  persist: [
@@ -13512,8 +13584,14 @@ async function runPlanningMultiStep(deps, params) {
13512
13584
  details: "No product brief decisions found in the analysis phase.",
13513
13585
  tokenUsage: zeroTokenUsage
13514
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 {}
13515
13593
  const steps = buildPlanningSteps();
13516
- const result = await runSteps(steps, deps, params.runId, "planning", {});
13594
+ const result = await runSteps(steps, deps, params.runId, "planning", { concept });
13517
13595
  if (!result.success) return {
13518
13596
  result: "failed",
13519
13597
  error: result.error ?? "multi_step_failed",
@@ -13521,13 +13599,52 @@ async function runPlanningMultiStep(deps, params) {
13521
13599
  tokenUsage: result.tokenUsage
13522
13600
  };
13523
13601
  const frsOutput = result.steps[1]?.parsed;
13524
- const nfrsOutput = result.steps[2]?.parsed;
13602
+ let nfrsOutput = result.steps[2]?.parsed;
13603
+ let totalTokenUsage = { ...result.tokenUsage };
13525
13604
  if (!frsOutput || !nfrsOutput) return {
13526
13605
  result: "failed",
13527
13606
  error: "incomplete_steps",
13528
13607
  details: "Not all planning steps produced output",
13529
13608
  tokenUsage: result.tokenUsage
13530
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
+ }
13531
13648
  const frs = frsOutput.functional_requirements;
13532
13649
  const nfrs = nfrsOutput.non_functional_requirements;
13533
13650
  const userStories = frsOutput.user_stories;
@@ -13535,13 +13652,13 @@ async function runPlanningMultiStep(deps, params) {
13535
13652
  result: "failed",
13536
13653
  error: "missing_functional_requirements",
13537
13654
  details: "FRs step did not return functional_requirements",
13538
- tokenUsage: result.tokenUsage
13655
+ tokenUsage: totalTokenUsage
13539
13656
  };
13540
13657
  if (!nfrs?.length) return {
13541
13658
  result: "failed",
13542
13659
  error: "missing_non_functional_requirements",
13543
13660
  details: "NFRs step did not return non_functional_requirements",
13544
- tokenUsage: result.tokenUsage
13661
+ tokenUsage: totalTokenUsage
13545
13662
  };
13546
13663
  for (const fr of frs) createRequirement(db, {
13547
13664
  pipeline_run_id: params.runId,
@@ -13563,7 +13680,7 @@ async function runPlanningMultiStep(deps, params) {
13563
13680
  result: "success",
13564
13681
  requirements_count: requirementsCount,
13565
13682
  user_stories_count: userStoriesCount,
13566
- tokenUsage: result.tokenUsage
13683
+ tokenUsage: totalTokenUsage
13567
13684
  };
13568
13685
  const artifactId = result.steps[2]?.artifactId;
13569
13686
  if (artifactId !== void 0) planningResult.artifact_id = artifactId;