substrate-ai 0.19.30 → 0.19.31

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.
@@ -0,0 +1,4 @@
1
+ import { AdapterRegistry } from "./dist-DYcDRyoS.js";
2
+ import "./adapter-registry-DXLMTmfD.js";
3
+
4
+ export { AdapterRegistry };
package/dist/cli/index.js CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import { FileStateStore, RunManifest, SUBSTRATE_OWNED_SETTINGS_KEYS, SupervisorLock, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveRunManifest } from "../health-DKallkoo.js";
2
+ import { FileStateStore, RunManifest, SUBSTRATE_OWNED_SETTINGS_KEYS, SupervisorLock, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveRunManifest } from "../health-DUgvybiN.js";
3
3
  import { createLogger } from "../logger-KeHncl-f.js";
4
4
  import { createEventBus } from "../helpers-CElYrONe.js";
5
- import { AdapterRegistry, BudgetConfigSchema, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, ConfigError, CostTrackerConfigSchema, DEFAULT_CONFIG, DoltClient, DoltNotInstalled, GlobalSettingsSchema, IngestionServer, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProvidersSchema, RoutingRecommender, STORY_METRICS, TelemetryConfigSchema, addTokenUsage, aggregateTokenUsageForRun, checkDoltInstalled, compareRunMetrics, createAmendmentRun, createConfigSystem, createDecision, createDoltClient, createPipelineRun, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, tagRunAsBaseline, updatePipelineRun } from "../dist-R0W4ofKv.js";
5
+ import { AdapterRegistry, BudgetConfigSchema, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, ConfigError, CostTrackerConfigSchema, DEFAULT_CONFIG, DoltClient, DoltNotInstalled, GlobalSettingsSchema, IngestionServer, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProvidersSchema, RoutingRecommender, STORY_METRICS, TelemetryConfigSchema, addTokenUsage, aggregateTokenUsageForRun, checkDoltInstalled, compareRunMetrics, createAmendmentRun, createConfigSystem, createDecision, createDoltClient, createPipelineRun, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, tagRunAsBaseline, updatePipelineRun } from "../dist-DYcDRyoS.js";
6
6
  import "../adapter-registry-DXLMTmfD.js";
7
- import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-B0Pe5kol.js";
8
- import "../errors-BJRMJyGb.js";
7
+ import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-CFmp4-qj.js";
8
+ import "../errors-wOhMgaAU.js";
9
9
  import "../routing-CcBOCuC9.js";
10
10
  import "../decisions-C0pz9Clx.js";
11
11
  import "../version-manager-impl-BmOWu8ml.js";
12
- import { registerUpgradeCommand } from "../upgrade-DwEbjHWg.js";
12
+ import { registerUpgradeCommand } from "../upgrade-Djv-r4rl.js";
13
13
  import { Command } from "commander";
14
14
  import { fileURLToPath } from "url";
15
15
  import { dirname, join, resolve } from "path";
@@ -1157,7 +1157,8 @@ const SubstrateConfigSchema = z.object({
1157
1157
  token_ceilings: TokenCeilingsSchema.optional(),
1158
1158
  dispatch_timeouts: DispatchTimeoutsSchema.optional(),
1159
1159
  telemetry: TelemetryConfigSchema.optional(),
1160
- default_agent: z.string().optional()
1160
+ default_agent: z.string().optional(),
1161
+ supervisor_poll_interval_seconds: z.number().int().positive().optional()
1161
1162
  }).strict();
1162
1163
  const PartialSubstrateConfigSchema = z.object({
1163
1164
  config_format_version: z.enum(["1"]).optional(),
@@ -1173,7 +1174,8 @@ const PartialSubstrateConfigSchema = z.object({
1173
1174
  token_ceilings: TokenCeilingsSchema.optional(),
1174
1175
  dispatch_timeouts: DispatchTimeoutsSchema.optional(),
1175
1176
  telemetry: TelemetryConfigSchema.partial().optional(),
1176
- default_agent: z.string().optional()
1177
+ default_agent: z.string().optional(),
1178
+ supervisor_poll_interval_seconds: z.number().int().positive().optional()
1177
1179
  }).strict();
1178
1180
 
1179
1181
  //#endregion
@@ -3303,7 +3305,7 @@ async function runStatusAction(options) {
3303
3305
  logger$12.debug({ err }, "Work graph query failed, continuing without work graph data");
3304
3306
  }
3305
3307
  if (run === void 0) {
3306
- const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-Bb5KxPlE.js");
3308
+ const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-C96NMCJX.js");
3307
3309
  const substrateDirPath = join(projectRoot, ".substrate");
3308
3310
  const processInfo = inspectProcessTree$1({
3309
3311
  projectRoot,
@@ -4117,6 +4119,63 @@ function registerAmendCommand(program, _version = "0.0.0", projectRoot = process
4117
4119
  });
4118
4120
  }
4119
4121
 
4122
+ //#endregion
4123
+ //#region src/modules/supervisor/stall-detector.ts
4124
+ /**
4125
+ * Default phase-aware stall thresholds (seconds).
4126
+ * Stored in the run manifest cli_flags so they can be overridden per-run.
4127
+ */
4128
+ const DEFAULT_STALL_THRESHOLDS = {
4129
+ "create-story": 300,
4130
+ "dev-story": 900,
4131
+ "code-review": 900,
4132
+ "test-plan": 600
4133
+ };
4134
+ var StallDetector = class {
4135
+ constructor(thresholds) {
4136
+ this.thresholds = thresholds;
4137
+ }
4138
+ /**
4139
+ * Return the base threshold (seconds) for a given phase.
4140
+ * Falls back to the maximum configured value for unknown phases.
4141
+ */
4142
+ getThreshold(phase) {
4143
+ if (Object.prototype.hasOwnProperty.call(this.thresholds, phase)) return this.thresholds[phase];
4144
+ const values = Object.values(this.thresholds);
4145
+ return values.length > 0 ? Math.max(...values) : 600;
4146
+ }
4147
+ /**
4148
+ * Return the effective threshold after applying the backend's timeout multiplier.
4149
+ */
4150
+ getEffectiveThreshold(phase, multiplier) {
4151
+ return this.getThreshold(phase) * multiplier;
4152
+ }
4153
+ /**
4154
+ * Evaluate whether the pipeline is stalled based on phase and staleness.
4155
+ */
4156
+ evaluate(input) {
4157
+ const effectiveThreshold = this.getEffectiveThreshold(input.phase, input.timeoutMultiplier);
4158
+ return {
4159
+ isStalled: input.staleness_seconds >= effectiveThreshold,
4160
+ effectiveThreshold,
4161
+ phase: input.phase,
4162
+ timeoutMultiplier: input.timeoutMultiplier
4163
+ };
4164
+ }
4165
+ /**
4166
+ * Return an adaptive poll interval based on the backend multiplier.
4167
+ *
4168
+ * When all effective thresholds exceed 600 s (e.g. Codex with 3× multiplier),
4169
+ * the poll interval is doubled to reduce unnecessary overhead.
4170
+ */
4171
+ getAdaptivePollInterval(baseSeconds, multiplier) {
4172
+ const values = Object.values(this.thresholds);
4173
+ if (values.length === 0) return baseSeconds;
4174
+ const minEffective = Math.min(...values.map((v) => v * multiplier));
4175
+ return minEffective > 600 ? baseSeconds * 2 : baseSeconds;
4176
+ }
4177
+ };
4178
+
4120
4179
  //#endregion
4121
4180
  //#region src/cli/commands/supervisor.ts
4122
4181
  const supervisorLogger = createLogger("supervisor-cmd");
@@ -4191,7 +4250,7 @@ function defaultSupervisorDeps() {
4191
4250
  if (cached === null) {
4192
4251
  const { AdapterRegistry: AR } = await import(
4193
4252
  /* @vite-ignore */
4194
- "../adapter-registry-S_u-oxuM.js"
4253
+ "../adapter-registry-CAN7nZQ7.js"
4195
4254
  );
4196
4255
  cached = new AR();
4197
4256
  await cached.discoverAndRegister();
@@ -4381,10 +4440,27 @@ async function handleStallRecovery(health, state, config, deps, io) {
4381
4440
  const { projectRoot } = state;
4382
4441
  const REVIEW_PHASES = new Set(["IN_REVIEW", "code-review"]);
4383
4442
  const activePhases = Object.values(health.stories.details ?? {}).map((s) => s.phase);
4384
- const inReviewPhase = activePhases.some((p) => REVIEW_PHASES.has(p));
4385
4443
  const orchestratorIdle = health.process.child_pids.length === 0 && health.stories.active > 0;
4386
- const effectiveThreshold = inReviewPhase && !orchestratorIdle ? stallThreshold * 2 : stallThreshold;
4387
- if (health.staleness_seconds < effectiveThreshold) return null;
4444
+ const activePhase = orchestratorIdle ? "dev-story" : activePhases.some((p) => REVIEW_PHASES.has(p)) ? "code-review" : "dev-story";
4445
+ const resolvedThresholds = config.stallThresholds ?? {
4446
+ "create-story": stallThreshold,
4447
+ "dev-story": stallThreshold,
4448
+ "code-review": stallThreshold * 2,
4449
+ "test-plan": stallThreshold
4450
+ };
4451
+ const detector = new StallDetector(resolvedThresholds);
4452
+ let timeoutMultiplier = 1;
4453
+ try {
4454
+ const registryForTimeout = await getRegistry();
4455
+ const defaultAdapter = registryForTimeout.get("claude-code") ?? registryForTimeout.getAll()[0];
4456
+ timeoutMultiplier = defaultAdapter?.getCapabilities().timeoutMultiplier ?? 1;
4457
+ } catch {}
4458
+ const { isStalled, effectiveThreshold } = detector.evaluate({
4459
+ phase: activePhase,
4460
+ staleness_seconds: health.staleness_seconds,
4461
+ timeoutMultiplier
4462
+ });
4463
+ if (!isStalled) return null;
4388
4464
  if (state.runId !== void 0 && health.run_id !== null && health.run_id !== state.runId) {
4389
4465
  log("Supervisor skipping kill — active pipeline belongs to a different session");
4390
4466
  return null;
@@ -4400,7 +4476,7 @@ async function handleStallRecovery(health, state, config, deps, io) {
4400
4476
  staleness_seconds: health.staleness_seconds,
4401
4477
  pids
4402
4478
  });
4403
- log(`Supervisor: Stall confirmed (${health.staleness_seconds}s ≥ ${stallThreshold}s threshold). Killing PIDs: ${pids.join(", ") || "none"}`);
4479
+ log(`Supervisor: Stall confirmed (${health.staleness_seconds}s ≥ ${effectiveThreshold}s threshold). Killing PIDs: ${pids.join(", ") || "none"}`);
4404
4480
  for (const pid of pids) try {
4405
4481
  killPid(pid, "SIGTERM");
4406
4482
  } catch {}
@@ -4540,6 +4616,47 @@ async function runSupervisorAction(options, deps = {}) {
4540
4616
  };
4541
4617
  let maxRestartsExhausted = false;
4542
4618
  const startTime = Date.now();
4619
+ let resolvedPollInterval = pollInterval;
4620
+ try {
4621
+ const dbRoot = await resolveMainRepoRoot(projectRoot).catch(() => projectRoot);
4622
+ const configSystem = createConfigSystem({ projectConfigDir: join(dbRoot, ".substrate") });
4623
+ await configSystem.load();
4624
+ const supervisorCfg = configSystem.getConfig();
4625
+ if (typeof supervisorCfg.supervisor_poll_interval_seconds === "number") resolvedPollInterval = supervisorCfg.supervisor_poll_interval_seconds;
4626
+ } catch {}
4627
+ let stallThresholds = void 0;
4628
+ async function resolveManifestThresholds(targetRunId) {
4629
+ try {
4630
+ const manifest = RunManifest.open(targetRunId, join(projectRoot, ".substrate", "runs"));
4631
+ const data = await manifest.read();
4632
+ const cliFlags = data?.cli_flags;
4633
+ const manifestThresholds = cliFlags?.stall_thresholds;
4634
+ if (manifestThresholds !== null && typeof manifestThresholds === "object" && !Array.isArray(manifestThresholds) && Object.keys(manifestThresholds).length > 0) stallThresholds = manifestThresholds;
4635
+ else {
4636
+ const existingFlags = cliFlags ?? {};
4637
+ await manifest.update({ cli_flags: {
4638
+ ...existingFlags,
4639
+ stall_thresholds: DEFAULT_STALL_THRESHOLDS
4640
+ } }).catch(() => {});
4641
+ stallThresholds = DEFAULT_STALL_THRESHOLDS;
4642
+ }
4643
+ } catch {}
4644
+ }
4645
+ if (runId !== void 0) await resolveManifestThresholds(runId);
4646
+ let effectivePollInterval = resolvedPollInterval;
4647
+ try {
4648
+ const initRegistry = await resolvedDeps.getRegistry();
4649
+ const initAdapter = initRegistry.get("claude-code") ?? initRegistry.getAll()[0];
4650
+ const initMultiplier = initAdapter?.getCapabilities().timeoutMultiplier ?? 1;
4651
+ const adaptiveThresholds = stallThresholds ?? {
4652
+ "create-story": stallThreshold,
4653
+ "dev-story": stallThreshold,
4654
+ "code-review": stallThreshold * 2,
4655
+ "test-plan": stallThreshold
4656
+ };
4657
+ const pollDetector = new StallDetector(adaptiveThresholds);
4658
+ effectivePollInterval = pollDetector.getAdaptivePollInterval(resolvedPollInterval, initMultiplier);
4659
+ } catch {}
4543
4660
  const sessionId = randomUUID();
4544
4661
  let supervisorLock = null;
4545
4662
  /** Track whether process exit handlers have been registered for this supervisor. */
@@ -4621,6 +4738,7 @@ async function runSupervisorAction(options, deps = {}) {
4621
4738
  };
4622
4739
  log(`Supervisor: auto-bound to active run ${health.run_id}`);
4623
4740
  await acquireLockForRun(health.run_id);
4741
+ await resolveManifestThresholds(health.run_id);
4624
4742
  }
4625
4743
  if (outputFormat === "json") {
4626
4744
  const tokenSnapshot = health.run_id !== null ? await getTokenSnapshot(health.run_id, projectRoot) : {
@@ -4699,11 +4817,11 @@ async function runSupervisorAction(options, deps = {}) {
4699
4817
  try {
4700
4818
  const { createExperimenter } = await import(
4701
4819
  /* @vite-ignore */
4702
- "../experimenter-Sq8sNz9y.js"
4820
+ "../experimenter-ll3qdoo1.js"
4703
4821
  );
4704
4822
  const { getLatestRun: getLatest } = await import(
4705
4823
  /* @vite-ignore */
4706
- "../decisions-CnvFtZ7P.js"
4824
+ "../decisions-DIMNco6x.js"
4707
4825
  );
4708
4826
  const expAdapter = createDatabaseAdapter({
4709
4827
  backend: "auto",
@@ -4713,7 +4831,7 @@ async function runSupervisorAction(options, deps = {}) {
4713
4831
  await initSchema(expAdapter);
4714
4832
  const { runRunAction: runPipeline } = await import(
4715
4833
  /* @vite-ignore */
4716
- "../run-BIVex2-V.js"
4834
+ "../run-Bb51aPNw.js"
4717
4835
  );
4718
4836
  const runStoryFn = async (opts) => {
4719
4837
  const exitCode = await runPipeline({
@@ -4783,7 +4901,8 @@ async function runSupervisorAction(options, deps = {}) {
4783
4901
  stallThreshold,
4784
4902
  maxRestarts,
4785
4903
  pack,
4786
- outputFormat
4904
+ outputFormat,
4905
+ stallThresholds
4787
4906
  }, {
4788
4907
  killPid: resolvedDeps.killPid,
4789
4908
  resumePipeline: resolvedDeps.resumePipeline,
@@ -4799,7 +4918,7 @@ async function runSupervisorAction(options, deps = {}) {
4799
4918
  });
4800
4919
  if (stallResult !== null) if (stallResult.maxRestartsExceeded) maxRestartsExhausted = true;
4801
4920
  else state = stallResult.state;
4802
- await sleep(pollInterval * 1e3);
4921
+ await sleep(effectivePollInterval * 1e3);
4803
4922
  }
4804
4923
  }
4805
4924
  /**
@@ -5244,7 +5363,7 @@ async function runMetricsAction(options) {
5244
5363
  const routingConfigPath = join(dbDir, "routing.yml");
5245
5364
  let routingConfig = null;
5246
5365
  if (existsSync$1(routingConfigPath)) try {
5247
- const { loadModelRoutingConfig } = await import("../routing-CRjtRmIl.js");
5366
+ const { loadModelRoutingConfig } = await import("../routing-CBjZdPqf.js");
5248
5367
  routingConfig = loadModelRoutingConfig(routingConfigPath);
5249
5368
  } catch {}
5250
5369
  if (routingConfig === null) routingConfig = {
@@ -8499,8 +8618,8 @@ async function createProgram() {
8499
8618
  /** Fire-and-forget startup version check (story 8.3, AC3/AC5) */
8500
8619
  function checkForUpdatesInBackground(currentVersion) {
8501
8620
  if (process.env.SUBSTRATE_NO_UPDATE_CHECK === "1") return;
8502
- import("../upgrade-Q9YROhpA.js").then(async () => {
8503
- const { createVersionManager } = await import("../version-manager-impl-DReRXdW7.js");
8621
+ import("../upgrade-Cex3qbdI.js").then(async () => {
8622
+ const { createVersionManager } = await import("../version-manager-impl-D0JrUpB-.js");
8504
8623
  const vm = createVersionManager();
8505
8624
  const result = await vm.checkForUpdates();
8506
8625
  if (result.updateAvailable) {
@@ -1,4 +1,4 @@
1
- import { addTokenUsage, createDecision, createPipelineRun, createRequirement, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunningPipelineRuns, getTokenUsageSummary, listRequirements, registerArtifact, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision } from "./dist-R0W4ofKv.js";
1
+ import { addTokenUsage, createDecision, createPipelineRun, createRequirement, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunningPipelineRuns, getTokenUsageSummary, listRequirements, registerArtifact, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision } from "./dist-DYcDRyoS.js";
2
2
  import "./decisions-C0pz9Clx.js";
3
3
 
4
4
  export { getLatestRun };
@@ -93,7 +93,7 @@ var DispatcherShuttingDownError = class extends Error {
93
93
 
94
94
  //#endregion
95
95
  //#region packages/core/dist/dispatch/yaml-parser.js
96
- const YAML_ANCHOR_KEYS = [
96
+ const YAML_ANCHOR_KEYS$1 = [
97
97
  "result:",
98
98
  "verdict:",
99
99
  "story_file:",
@@ -118,7 +118,7 @@ function extractYamlBlock(output) {
118
118
  const stripped = stripTrailingFence(output);
119
119
  const unfenced = extractUnfencedYaml(stripped);
120
120
  if (unfenced !== null) return unfenced;
121
- return extractJsonAsYaml(output);
121
+ return extractJsonAsYaml$1(output);
122
122
  }
123
123
  /**
124
124
  * Strip a trailing markdown fence that wraps the entire remaining output.
@@ -180,13 +180,13 @@ function extractUnfencedYaml(output) {
180
180
  * anchor key. Tries the last such object. Converts via yaml.dump so
181
181
  * downstream parseYamlResult can validate it with the same Zod schema.
182
182
  */
183
- function extractJsonAsYaml(output) {
183
+ function extractJsonAsYaml$1(output) {
184
184
  const jsonPattern = /\{[\s\S]*?\n\}/g;
185
185
  let lastJsonObj = null;
186
186
  let match;
187
187
  while ((match = jsonPattern.exec(output)) !== null) {
188
188
  const candidate = match[0];
189
- if (!YAML_ANCHOR_KEYS.some((key) => candidate.includes(key.replace(":", "")))) continue;
189
+ if (!YAML_ANCHOR_KEYS$1.some((key) => candidate.includes(key.replace(":", "")))) continue;
190
190
  try {
191
191
  const parsed = JSON.parse(candidate);
192
192
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) lastJsonObj = parsed;
@@ -204,13 +204,13 @@ function extractJsonAsYaml(output) {
204
204
  */
205
205
  function isAnchorLine(line) {
206
206
  const trimmed = line.trim();
207
- return YAML_ANCHOR_KEYS.some((key) => trimmed.startsWith(key));
207
+ return YAML_ANCHOR_KEYS$1.some((key) => trimmed.startsWith(key));
208
208
  }
209
209
  /**
210
210
  * Check if text content contains at least one anchor key.
211
211
  */
212
212
  function containsAnchorKey(content) {
213
- return YAML_ANCHOR_KEYS.some((key) => content.includes(key));
213
+ return YAML_ANCHOR_KEYS$1.some((key) => content.includes(key));
214
214
  }
215
215
  /**
216
216
  * Merge duplicate top-level YAML keys by concatenating their array values.
@@ -566,6 +566,221 @@ function estimateOutputQuality(output) {
566
566
  };
567
567
  }
568
568
 
569
+ //#endregion
570
+ //#region packages/core/dist/adapters/adapter-format-error.js
571
+ /**
572
+ * AdapterFormatError — raised when all normalization strategies are exhausted.
573
+ *
574
+ * Carries structured context for downstream classifiers and observability.
575
+ * The `rootCause` literal enables story 53-5's classifyFailure() to detect
576
+ * adapter-format failures without duplicating the string constant.
577
+ *
578
+ * Always use the constructor — do not construct via object spread. The
579
+ * constructor auto-truncates rawOutput to 500 chars for the snippet field.
580
+ */
581
+ var AdapterFormatError = class extends Error {
582
+ /** The adapter identifier that produced the unrecognizable output */
583
+ adapter_id;
584
+ /**
585
+ * First 500 chars of the raw output.
586
+ * Capped at 500 chars — never log full raw output (can be 100K+ chars).
587
+ */
588
+ raw_output_snippet;
589
+ /** Labels for each strategy that was attempted before giving up */
590
+ tried_strategies;
591
+ /** The last parse error message encountered */
592
+ extraction_error;
593
+ /**
594
+ * Root cause literal for downstream classifier integration (story 53-5).
595
+ * Downstream classifiers reference this literal without duplicating the string.
596
+ */
597
+ rootCause = "adapter-format";
598
+ constructor(opts) {
599
+ super(`AdapterFormatError [${opts.adapter_id}]: exhausted all normalization strategies. Tried: ${opts.tried_strategies.join(", ")}. Last error: ${opts.extraction_error}`);
600
+ this.name = "AdapterFormatError";
601
+ this.adapter_id = opts.adapter_id;
602
+ this.raw_output_snippet = opts.rawOutput.slice(0, 500);
603
+ this.tried_strategies = [...opts.tried_strategies];
604
+ this.extraction_error = opts.extraction_error;
605
+ }
606
+ };
607
+
608
+ //#endregion
609
+ //#region packages/core/dist/adapters/adapter-output-normalizer.js
610
+ const YAML_ANCHOR_KEYS = [
611
+ "result:",
612
+ "verdict:",
613
+ "story_file:",
614
+ "expansion_priority:"
615
+ ];
616
+ const YAML_ANCHOR_KEYS_BARE = YAML_ANCHOR_KEYS.map((k) => k.replace(":", ""));
617
+ /**
618
+ * Multi-strategy YAML extractor for adapter output.
619
+ *
620
+ * Inject into DispatcherImpl via constructor parameter so it can be mocked in
621
+ * unit tests. Default to `new AdapterOutputNormalizer()` if not provided.
622
+ */
623
+ var AdapterOutputNormalizer = class {
624
+ _logger;
625
+ constructor(logger = console) {
626
+ this._logger = logger;
627
+ }
628
+ /**
629
+ * Attempt to extract valid YAML from raw adapter output.
630
+ *
631
+ * Tries strategies in order and returns the first successful extraction.
632
+ * If all strategies are exhausted, returns an AdapterFormatError (does NOT throw).
633
+ *
634
+ * @param rawOutput - Full stdout string from the adapter process
635
+ * @param adapterId - Adapter identifier for error diagnostics and logging
636
+ * @returns `{ yaml: string; strategy: string }` on success, or `AdapterFormatError` on exhaustion
637
+ */
638
+ normalize(rawOutput, adapterId) {
639
+ const tried = [];
640
+ let lastError = "no_yaml_block";
641
+ {
642
+ const strategy = "standard";
643
+ tried.push(strategy);
644
+ const result = extractYamlBlock(rawOutput);
645
+ if (result !== null) return {
646
+ yaml: result,
647
+ strategy
648
+ };
649
+ this._logger.debug({
650
+ adapterId,
651
+ strategy
652
+ }, "Normalizer strategy failed");
653
+ lastError = "extractYamlBlock returned null";
654
+ }
655
+ {
656
+ const strategy = "strip-prose";
657
+ tried.push(strategy);
658
+ const stripped = stripLeadingProse(rawOutput);
659
+ if (stripped !== rawOutput) {
660
+ const result = extractYamlBlock(stripped);
661
+ if (result !== null) return {
662
+ yaml: result,
663
+ strategy
664
+ };
665
+ }
666
+ this._logger.debug({
667
+ adapterId,
668
+ strategy
669
+ }, "Normalizer strategy failed");
670
+ lastError = "strip-prose: extractYamlBlock returned null after prose removal";
671
+ }
672
+ {
673
+ const strategy = "strip-markdown";
674
+ tried.push(strategy);
675
+ const cleaned = stripMarkdownArtifacts(rawOutput);
676
+ if (cleaned !== rawOutput) {
677
+ const result = extractYamlBlock(cleaned);
678
+ if (result !== null) return {
679
+ yaml: result,
680
+ strategy
681
+ };
682
+ }
683
+ this._logger.debug({
684
+ adapterId,
685
+ strategy
686
+ }, "Normalizer strategy failed");
687
+ lastError = "strip-markdown: extractYamlBlock returned null after markdown removal";
688
+ }
689
+ {
690
+ const strategy = "json-fallback";
691
+ tried.push(strategy);
692
+ const result = extractJsonAsYaml(rawOutput);
693
+ if (result !== null) return {
694
+ yaml: result,
695
+ strategy
696
+ };
697
+ this._logger.debug({
698
+ adapterId,
699
+ strategy
700
+ }, "Normalizer strategy failed");
701
+ lastError = "json-fallback: no JSON object with anchor keys found";
702
+ }
703
+ this._logger.warn({
704
+ adapter_id: adapterId,
705
+ tried_strategies: tried,
706
+ snippet: rawOutput.slice(0, 500)
707
+ }, "AdapterOutputNormalizer exhausted all strategies — adapter format unrecognized");
708
+ return new AdapterFormatError({
709
+ adapter_id: adapterId,
710
+ rawOutput,
711
+ tried_strategies: tried,
712
+ extraction_error: lastError
713
+ });
714
+ }
715
+ };
716
+ /**
717
+ * Strip leading lines that do not look like YAML content.
718
+ *
719
+ * A line is considered "YAML content" if it:
720
+ * - Starts with a known anchor key (result:, verdict:, etc.)
721
+ * - Starts with a code fence marker (```)
722
+ * - Starts with a YAML document separator (---)
723
+ * - Is blank (may be whitespace between prose and YAML)
724
+ * - Starts with whitespace (indented YAML value)
725
+ *
726
+ * Lines before the first YAML-looking line are removed.
727
+ */
728
+ function stripLeadingProse(text) {
729
+ const lines = text.split("\n");
730
+ for (let i = 0; i < lines.length; i++) {
731
+ const line = lines[i];
732
+ if (line === void 0) continue;
733
+ const trimmed = line.trim();
734
+ if (trimmed === "") continue;
735
+ if (trimmed.startsWith("```") || trimmed.startsWith("---")) return lines.slice(i).join("\n");
736
+ if (YAML_ANCHOR_KEYS.some((k) => trimmed.startsWith(k))) return lines.slice(i).join("\n");
737
+ if (/^\s+\S/.test(line)) return lines.slice(i).join("\n");
738
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*:/.test(trimmed)) return lines.slice(i).join("\n");
739
+ }
740
+ return text;
741
+ }
742
+ /**
743
+ * Strip line-leading markdown artifacts.
744
+ *
745
+ * Handles:
746
+ * - Blockquote prefix: `> ` → ``
747
+ * - Heading markers: `## ` → ``
748
+ * - Bold/italic: `**` or `*` at start → ``
749
+ * - Underscore italic: `_` at start → ``
750
+ */
751
+ function stripMarkdownArtifacts(text) {
752
+ return text.split("\n").map((line) => {
753
+ return line.replace(/^>\s?/, "").replace(/^#{1,6}\s+/, "").replace(/^\*{1,2}/, "").replace(/^_/, "");
754
+ }).join("\n");
755
+ }
756
+ /**
757
+ * Scan the text for an embedded JSON object containing at least one anchor key,
758
+ * then dump it to YAML via js-yaml for downstream parseYamlResult().
759
+ *
760
+ * Uses a greedy { ... } scan to find candidate JSON objects. The last matching
761
+ * object is used (consistent with yaml-parser.ts's "take the last block" rule).
762
+ */
763
+ function extractJsonAsYaml(text) {
764
+ const jsonPattern = /\{[\s\S]*?\n\}/g;
765
+ let lastMatch = null;
766
+ let match;
767
+ while ((match = jsonPattern.exec(text)) !== null) {
768
+ const candidate = match[0];
769
+ const hasAnchorKey = YAML_ANCHOR_KEYS_BARE.some((key) => candidate.includes(`"${key}"`) || candidate.includes(`'${key}'`));
770
+ if (!hasAnchorKey) continue;
771
+ try {
772
+ const parsed = JSON.parse(candidate);
773
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) lastMatch = parsed;
774
+ } catch {}
775
+ }
776
+ if (lastMatch === null) return null;
777
+ try {
778
+ return yaml.dump(lastMatch, { lineWidth: -1 });
779
+ } catch {
780
+ return null;
781
+ }
782
+ }
783
+
569
784
  //#endregion
570
785
  //#region packages/core/dist/dispatch/dispatcher-impl.js
571
786
  const SHUTDOWN_GRACE_MS = 1e4;
@@ -722,16 +937,18 @@ var DispatcherImpl = class {
722
937
  _adapterRegistry;
723
938
  _config;
724
939
  _logger;
940
+ _normalizer;
725
941
  _running = new Map();
726
942
  _queue = [];
727
943
  _shuttingDown = false;
728
944
  _memoryPressureTimer = null;
729
945
  _memoryPressureHoldStart = null;
730
- constructor(eventBus, adapterRegistry, config, logger = console) {
946
+ constructor(eventBus, adapterRegistry, config, logger = console, normalizer = new AdapterOutputNormalizer()) {
731
947
  this._eventBus = eventBus;
732
948
  this._adapterRegistry = adapterRegistry;
733
949
  this._config = config;
734
950
  this._logger = logger;
951
+ this._normalizer = normalizer;
735
952
  }
736
953
  dispatch(request) {
737
954
  if (this._shuttingDown) {
@@ -1031,14 +1248,52 @@ var DispatcherImpl = class {
1031
1248
  this._running.delete(id);
1032
1249
  this._drainQueue();
1033
1250
  if (code === 0) {
1034
- const yamlBlock = extractYamlBlock(stdout);
1251
+ const normalizeResult = this._normalizer.normalize(stdout, agent);
1035
1252
  let parsed = null;
1036
1253
  let parseError = null;
1037
- if (yamlBlock !== null) {
1038
- const parseResult = parseYamlResult(yamlBlock, outputSchema);
1039
- parsed = parseResult.parsed;
1040
- parseError = parseResult.error;
1041
- } else parseError = "no_yaml_block";
1254
+ if (normalizeResult instanceof AdapterFormatError) {
1255
+ const errMsg = [
1256
+ normalizeResult.adapter_id,
1257
+ normalizeResult.tried_strategies.join(","),
1258
+ normalizeResult.raw_output_snippet
1259
+ ].join(" | ");
1260
+ const quality$1 = estimateOutputQuality(stdout);
1261
+ this._eventBus.emit("agent:completed", {
1262
+ dispatchId: id,
1263
+ exitCode: code,
1264
+ output: stdout,
1265
+ inputTokens,
1266
+ outputTokens: Math.ceil(stdout.length / CHARS_PER_TOKEN$3),
1267
+ qualityScore: quality$1.qualityScore
1268
+ });
1269
+ this._logger.warn({
1270
+ id,
1271
+ agent,
1272
+ taskType,
1273
+ adapterError: true,
1274
+ snippet: normalizeResult.raw_output_snippet
1275
+ }, "Adapter format error — all normalization strategies exhausted");
1276
+ resolve$2({
1277
+ id,
1278
+ status: "completed",
1279
+ exitCode: code,
1280
+ output: stdout,
1281
+ parsed: null,
1282
+ parseError: errMsg,
1283
+ adapterError: true,
1284
+ verdict: "error",
1285
+ errorMessage: errMsg,
1286
+ durationMs,
1287
+ tokenEstimate: {
1288
+ input: inputTokens,
1289
+ output: Math.ceil(stdout.length / CHARS_PER_TOKEN$3)
1290
+ }
1291
+ });
1292
+ return;
1293
+ }
1294
+ const parseResult = parseYamlResult(normalizeResult.yaml, outputSchema);
1295
+ parsed = parseResult.parsed;
1296
+ parseError = parseResult.error;
1042
1297
  const quality = estimateOutputQuality(stdout);
1043
1298
  if (quality.hedgingCount > 0 || quality.qualityScore < 40) this._logger.warn({
1044
1299
  id,
@@ -10518,4 +10773,4 @@ async function callLLM(params) {
10518
10773
 
10519
10774
  //#endregion
10520
10775
  export { ADVISORY_NOTES, AdapterRegistry, AdtError, BudgetConfigSchema, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, Categorizer, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, ConsumerAnalyzer, CostTrackerConfigSchema, DEFAULT_CONFIG, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, DoltNotInstalled, DoltQueryError, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, GeminiCLIAdapter, GlobalSettingsSchema, IngestionServer, LogTurnAnalyzer, ModelRoutingConfigSchema, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProviderPolicySchema, ProvidersSchema, Recommender, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TASK_TYPE_PHASE_MAP, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryConfigSchema, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, VersionManagerImpl, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, callLLM, checkDoltInstalled, compareRunMetrics, createAmendmentRun, createConfigSystem, createDatabaseAdapter as createDatabaseAdapter$1, createDecision, createDoltClient, createExperimenter, createPipelineRun, createRequirement, createVersionManager, detectInterfaceChanges, determineVerdict, getActiveDecisions, getAllCostEntriesFiltered, getArtifactByTypeForRun, getArtifactsByRun, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getModelTier, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRequirements, listRunMetrics, loadModelRoutingConfig, loadParentRunDecisions, registerArtifact, resolvePromptFile, supersedeDecision, tagRunAsBaseline, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics };
10521
- //# sourceMappingURL=dist-R0W4ofKv.js.map
10776
+ //# sourceMappingURL=dist-DYcDRyoS.js.map
@@ -1,4 +1,4 @@
1
- import { AdtError } from "./dist-R0W4ofKv.js";
1
+ import { AdtError } from "./dist-DYcDRyoS.js";
2
2
 
3
3
  //#region src/core/errors.ts
4
4
  /** Error thrown when task configuration is invalid */
@@ -71,4 +71,4 @@ var TaskGraphIncompatibleFormatError = class extends AdtError {
71
71
 
72
72
  //#endregion
73
73
  export { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError };
74
- //# sourceMappingURL=errors-BJRMJyGb.js.map
74
+ //# sourceMappingURL=errors-wOhMgaAU.js.map
@@ -1,3 +1,3 @@
1
- import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-R0W4ofKv.js";
1
+ import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-DYcDRyoS.js";
2
2
 
3
3
  export { createExperimenter };
@@ -1,6 +1,6 @@
1
- import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-DKallkoo.js";
1
+ import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-DUgvybiN.js";
2
2
  import "./logger-KeHncl-f.js";
3
- import "./dist-R0W4ofKv.js";
3
+ import "./dist-DYcDRyoS.js";
4
4
  import "./decisions-C0pz9Clx.js";
5
5
 
6
6
  export { inspectProcessTree };
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from "./logger-KeHncl-f.js";
2
- import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-R0W4ofKv.js";
2
+ import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-DYcDRyoS.js";
3
3
  import { createRequire } from "module";
4
4
  import { dirname, join } from "path";
5
5
  import { readFile } from "fs/promises";
@@ -3145,4 +3145,4 @@ function registerHealthCommand(program, _version = "0.0.0", projectRoot = proces
3145
3145
 
3146
3146
  //#endregion
3147
3147
  export { BMAD_BASELINE_TOKENS_FULL, DEFAULT_STALL_THRESHOLD_SECONDS, DoltMergeConflict, FileStateStore, RunManifest, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN$1 as STORY_KEY_PATTERN, SUBSTRATE_OWNED_SETTINGS_KEYS, SupervisorLock, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter$1 as createDatabaseAdapter, createGraphOrchestrator, createStateStore, detectCycles, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, isOrchestratorProcessLine, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveGraphPath, resolveMainRepoRoot, resolveRunManifest, runHealthAction, validateStoryKey };
3148
- //# sourceMappingURL=health-DKallkoo.js.map
3148
+ //# sourceMappingURL=health-DUgvybiN.js.map
package/dist/index.d.ts CHANGED
@@ -975,6 +975,13 @@ interface TaskResult$2 {
975
975
  executionTime?: number;
976
976
  tokensUsed?: TokenEstimate$1;
977
977
  };
978
+ /**
979
+ * True when the dispatcher's AdapterOutputNormalizer exhausted all
980
+ * normalization strategies without extracting parseable YAML.
981
+ * Authoritative signal for the 'adapter-format' root cause category (story 53-10).
982
+ * Optional — existing callers without the field continue to compile unchanged.
983
+ */
984
+ adapterError?: boolean;
978
985
  }
979
986
  /**
980
987
  * Token usage estimate for budget tracking.
@@ -1634,6 +1641,7 @@ declare const SubstrateConfigSchema: z.ZodObject<{
1634
1641
  projectId: z.ZodOptional<z.ZodString>;
1635
1642
  }, z.core.$strict>>;
1636
1643
  default_agent: z.ZodOptional<z.ZodString>;
1644
+ supervisor_poll_interval_seconds: z.ZodOptional<z.ZodNumber>;
1637
1645
  }, z.core.$strict>;
1638
1646
  type SubstrateConfig = z.infer<typeof SubstrateConfigSchema>;
1639
1647
 
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { childLogger, createLogger, logger } from "./logger-KeHncl-f.js";
2
2
  import { assertDefined, createEventBus, createTuiApp, deepClone, formatDuration, generateId, isPlainObject, isTuiCapable, printNonTtyWarning, sleep, withRetry } from "./helpers-CElYrONe.js";
3
- import { AdapterRegistry, AdtError, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, GeminiCLIAdapter } from "./dist-R0W4ofKv.js";
3
+ import { AdapterRegistry, AdtError, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, GeminiCLIAdapter } from "./dist-DYcDRyoS.js";
4
4
  import "./adapter-registry-DXLMTmfD.js";
5
- import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-BJRMJyGb.js";
5
+ import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-wOhMgaAU.js";
6
6
 
7
7
  //#region src/core/di.ts
8
8
  /**
@@ -1,4 +1,4 @@
1
- import { ModelRoutingConfigSchema, ProviderPolicySchema, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, TASK_TYPE_PHASE_MAP, getModelTier, loadModelRoutingConfig } from "./dist-R0W4ofKv.js";
1
+ import { ModelRoutingConfigSchema, ProviderPolicySchema, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, TASK_TYPE_PHASE_MAP, getModelTier, loadModelRoutingConfig } from "./dist-DYcDRyoS.js";
2
2
  import "./routing-CcBOCuC9.js";
3
3
 
4
4
  export { loadModelRoutingConfig };
@@ -1,8 +1,8 @@
1
- import "./health-DKallkoo.js";
1
+ import "./health-DUgvybiN.js";
2
2
  import "./logger-KeHncl-f.js";
3
3
  import "./helpers-CElYrONe.js";
4
- import "./dist-R0W4ofKv.js";
5
- import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-B0Pe5kol.js";
4
+ import "./dist-DYcDRyoS.js";
5
+ import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-CFmp4-qj.js";
6
6
  import "./routing-CcBOCuC9.js";
7
7
  import "./decisions-C0pz9Clx.js";
8
8
 
@@ -1,7 +1,7 @@
1
- import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, RunManifest, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter, createGraphOrchestrator, detectCycles, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, resolveGraphPath, resolveMainRepoRoot, validateStoryKey } from "./health-DKallkoo.js";
1
+ import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, RunManifest, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter, createGraphOrchestrator, detectCycles, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, resolveGraphPath, resolveMainRepoRoot, validateStoryKey } from "./health-DUgvybiN.js";
2
2
  import { createLogger } from "./logger-KeHncl-f.js";
3
3
  import { TypedEventBusImpl, createEventBus, createTuiApp, isTuiCapable, printNonTtyWarning, sleep } from "./helpers-CElYrONe.js";
4
- import { ADVISORY_NOTES, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-R0W4ofKv.js";
4
+ import { ADVISORY_NOTES, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-DYcDRyoS.js";
5
5
  import { basename, dirname, extname, join } from "path";
6
6
  import { access, readFile, readdir, stat } from "fs/promises";
7
7
  import { EventEmitter } from "node:events";
@@ -41938,6 +41938,7 @@ async function runRunAction(options) {
41938
41938
  projectRoot,
41939
41939
  tokenCeilings,
41940
41940
  agentId,
41941
+ runManifest: RunManifest.open(pipelineRun.id, join(dbDir, "runs")),
41941
41942
  ...ingestionServer !== void 0 ? { ingestionServer } : {},
41942
41943
  ...telemetryPersistence !== void 0 ? { telemetryPersistence } : {},
41943
41944
  ...repoMapInjector !== void 0 ? {
@@ -42363,6 +42364,7 @@ async function runFullPipeline(options) {
42363
42364
  projectRoot,
42364
42365
  tokenCeilings,
42365
42366
  agentId,
42367
+ runManifest: RunManifest.open(runId, join(dbDir, "runs")),
42366
42368
  ...fpIngestionServer !== void 0 ? { ingestionServer: fpIngestionServer } : {},
42367
42369
  ...fpTelemetryPersistence !== void 0 ? { telemetryPersistence: fpTelemetryPersistence } : {}
42368
42370
  });
@@ -42556,4 +42558,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
42556
42558
 
42557
42559
  //#endregion
42558
42560
  export { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, normalizeGraphSummaryToStatus, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveMaxReviewCycles, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict, wireNdjsonEmitter };
42559
- //# sourceMappingURL=run-B0Pe5kol.js.map
42561
+ //# sourceMappingURL=run-CFmp4-qj.js.map
@@ -1,5 +1,5 @@
1
- import "./dist-R0W4ofKv.js";
1
+ import "./dist-DYcDRyoS.js";
2
2
  import "./version-manager-impl-BmOWu8ml.js";
3
- import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-DwEbjHWg.js";
3
+ import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-Djv-r4rl.js";
4
4
 
5
5
  export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
@@ -1,4 +1,4 @@
1
- import { createVersionManager } from "./dist-R0W4ofKv.js";
1
+ import { createVersionManager } from "./dist-DYcDRyoS.js";
2
2
  import { execSync, spawn } from "child_process";
3
3
  import * as readline from "readline";
4
4
 
@@ -123,4 +123,4 @@ function registerUpgradeCommand(program) {
123
123
 
124
124
  //#endregion
125
125
  export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
126
- //# sourceMappingURL=upgrade-DwEbjHWg.js.map
126
+ //# sourceMappingURL=upgrade-Djv-r4rl.js.map
@@ -1,4 +1,4 @@
1
- import { VersionManagerImpl, createVersionManager } from "./dist-R0W4ofKv.js";
1
+ import { VersionManagerImpl, createVersionManager } from "./dist-DYcDRyoS.js";
2
2
  import "./version-manager-impl-BmOWu8ml.js";
3
3
 
4
4
  export { createVersionManager };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "substrate-ai",
3
- "version": "0.19.30",
3
+ "version": "0.19.31",
4
4
  "description": "Substrate — multi-agent orchestration daemon for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,4 +0,0 @@
1
- import { AdapterRegistry } from "./dist-R0W4ofKv.js";
2
- import "./adapter-registry-DXLMTmfD.js";
3
-
4
- export { AdapterRegistry };