substrate-ai 0.19.14 → 0.19.16

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-C5NDd2T9.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, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot } from "../health-CS3SJ2JD.js";
2
+ import { FileStateStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot } from "../health-H-5xP8Cy.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, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, tagRunAsBaseline, updatePipelineRun } from "../dist-CGOpItka.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, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, tagRunAsBaseline, updatePipelineRun } from "../dist-C5NDd2T9.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-BbZay3p0.js";
8
- import "../errors-DBkOZgD4.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-DwVCcdCk.js";
8
+ import "../errors-CeBKTFSL.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-DaP1jFb9.js";
12
+ import { registerUpgradeCommand } from "../upgrade-DXT62773.js";
13
13
  import { Command } from "commander";
14
14
  import { fileURLToPath } from "url";
15
15
  import { dirname, join, resolve } from "path";
@@ -2811,6 +2811,9 @@ async function runFullPipelineFromPhase(options) {
2811
2811
  dispatcher,
2812
2812
  agentId
2813
2813
  };
2814
+ const agentAdapter = agentId != null ? injectedRegistry.get(agentId) : void 0;
2815
+ const adapterDefaultCycles = agentAdapter?.getCapabilities?.()?.defaultMaxReviewCycles;
2816
+ const effectiveMaxReviewCycles = adapterDefaultCycles != null ? Math.max(maxReviewCycles, adapterDefaultCycles) : maxReviewCycles;
2814
2817
  const phaseOrchestrator = createPhaseOrchestrator({
2815
2818
  db: adapter,
2816
2819
  pack
@@ -2916,7 +2919,7 @@ async function runFullPipelineFromPhase(options) {
2916
2919
  eventBus,
2917
2920
  config: {
2918
2921
  maxConcurrency: concurrency,
2919
- maxReviewCycles,
2922
+ maxReviewCycles: effectiveMaxReviewCycles,
2920
2923
  pipelineRunId: runId,
2921
2924
  enableHeartbeat: eventsFlag === true
2922
2925
  },
@@ -3212,7 +3215,7 @@ async function runStatusAction(options) {
3212
3215
  if (run === void 0) run = await getLatestRun(adapter);
3213
3216
  }
3214
3217
  if (run === void 0) {
3215
- const { inspectProcessTree } = await import("../health-E34oq1s8.js");
3218
+ const { inspectProcessTree } = await import("../health-BBD57TyR.js");
3216
3219
  const substrateDirPath = join(projectRoot, ".substrate");
3217
3220
  const processInfo = inspectProcessTree({
3218
3221
  projectRoot,
@@ -4099,7 +4102,7 @@ function defaultSupervisorDeps() {
4099
4102
  if (cached === null) {
4100
4103
  const { AdapterRegistry: AR } = await import(
4101
4104
  /* @vite-ignore */
4102
- "../adapter-registry-CtlKDROg.js"
4105
+ "../adapter-registry-BhzjPTIB.js"
4103
4106
  );
4104
4107
  cached = new AR();
4105
4108
  await cached.discoverAndRegister();
@@ -4541,11 +4544,11 @@ async function runSupervisorAction(options, deps = {}) {
4541
4544
  try {
4542
4545
  const { createExperimenter } = await import(
4543
4546
  /* @vite-ignore */
4544
- "../experimenter-DFzSRxTS.js"
4547
+ "../experimenter-Ct4YKVLF.js"
4545
4548
  );
4546
4549
  const { getLatestRun: getLatest } = await import(
4547
4550
  /* @vite-ignore */
4548
- "../decisions-BFaxuKlw.js"
4551
+ "../decisions-D7nxZu4W.js"
4549
4552
  );
4550
4553
  const expAdapter = createDatabaseAdapter({
4551
4554
  backend: "auto",
@@ -4555,7 +4558,7 @@ async function runSupervisorAction(options, deps = {}) {
4555
4558
  await initSchema(expAdapter);
4556
4559
  const { runRunAction: runPipeline } = await import(
4557
4560
  /* @vite-ignore */
4558
- "../run-ohGVQc0P.js"
4561
+ "../run-DoQSxg4N.js"
4559
4562
  );
4560
4563
  const runStoryFn = async (opts) => {
4561
4564
  const exitCode = await runPipeline({
@@ -5085,7 +5088,7 @@ async function runMetricsAction(options) {
5085
5088
  const routingConfigPath = join(dbDir, "routing.yml");
5086
5089
  let routingConfig = null;
5087
5090
  if (existsSync$1(routingConfigPath)) try {
5088
- const { loadModelRoutingConfig } = await import("../routing-Bg2Xh6tP.js");
5091
+ const { loadModelRoutingConfig } = await import("../routing-BdC4vctD.js");
5089
5092
  routingConfig = loadModelRoutingConfig(routingConfigPath);
5090
5093
  } catch {}
5091
5094
  if (routingConfig === null) routingConfig = {
@@ -7258,6 +7261,9 @@ async function runRetryEscalatedAction(options) {
7258
7261
  eventBus,
7259
7262
  adapterRegistry: injectedRegistry
7260
7263
  });
7264
+ const agentAdapter = agentId != null ? injectedRegistry.get(agentId) : void 0;
7265
+ const adapterDefaultCycles = agentAdapter?.getCapabilities?.()?.defaultMaxReviewCycles;
7266
+ const effectiveMaxReviewCycles = adapterDefaultCycles != null ? Math.max(2, adapterDefaultCycles) : 2;
7261
7267
  const orchestrator = createImplementationOrchestrator({
7262
7268
  db: adapter,
7263
7269
  pack,
@@ -7266,7 +7272,7 @@ async function runRetryEscalatedAction(options) {
7266
7272
  eventBus,
7267
7273
  config: {
7268
7274
  maxConcurrency: concurrency,
7269
- maxReviewCycles: 2,
7275
+ maxReviewCycles: effectiveMaxReviewCycles,
7270
7276
  pipelineRunId: pipelineRun.id,
7271
7277
  ...Object.keys(perStoryContextCeilings).length > 0 ? { perStoryContextCeilings } : {}
7272
7278
  },
@@ -8163,8 +8169,8 @@ async function createProgram() {
8163
8169
  /** Fire-and-forget startup version check (story 8.3, AC3/AC5) */
8164
8170
  function checkForUpdatesInBackground(currentVersion) {
8165
8171
  if (process.env.SUBSTRATE_NO_UPDATE_CHECK === "1") return;
8166
- import("../upgrade-4QYypG_Z.js").then(async () => {
8167
- const { createVersionManager } = await import("../version-manager-impl-DFnk7mmw.js");
8172
+ import("../upgrade-CQ0O-BHc.js").then(async () => {
8173
+ const { createVersionManager } = await import("../version-manager-impl-ydYX5xJZ.js");
8168
8174
  const vm = createVersionManager();
8169
8175
  const result = await vm.checkForUpdates();
8170
8176
  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-CGOpItka.js";
1
+ import { addTokenUsage, createDecision, createPipelineRun, createRequirement, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunningPipelineRuns, getTokenUsageSummary, listRequirements, registerArtifact, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision } from "./dist-C5NDd2T9.js";
2
2
  import "./decisions-C0pz9Clx.js";
3
3
 
4
4
  export { getLatestRun };
@@ -399,17 +399,59 @@ function detectInterfaceChanges(options) {
399
399
  const SHUTDOWN_GRACE_MS = 1e4;
400
400
  const SHUTDOWN_MAX_WAIT_MS = 3e4;
401
401
  const CHARS_PER_TOKEN$3 = 4;
402
- const YAML_OUTPUT_SUFFIX = `
402
+ /**
403
+ * Extract top-level field names from a Zod schema for prompt injection.
404
+ * Returns field names with type hints (e.g., "result: <string>", "files_modified: <list>").
405
+ */
406
+ function extractSchemaFields(schema) {
407
+ let current = schema;
408
+ let def = current?._def;
409
+ while (def?.typeName === "ZodEffects" && def?.schema != null) {
410
+ current = def.schema;
411
+ def = current?._def;
412
+ }
413
+ const shape = current?.shape;
414
+ if (shape == null || typeof shape !== "object") return [];
415
+ const fields = [];
416
+ for (const [key, fieldDef] of Object.entries(shape)) {
417
+ const typeName = resolveZodTypeName(fieldDef);
418
+ fields.push(`${key}: ${typeName}`);
419
+ }
420
+ return fields;
421
+ }
422
+ /**
423
+ * Resolve a human-readable type hint from a Zod field definition.
424
+ */
425
+ function resolveZodTypeName(fieldDef) {
426
+ const d = fieldDef;
427
+ const typeName = d?._def?.typeName;
428
+ if (typeName === "ZodOptional" || typeName === "ZodDefault") return d._def?.innerType != null ? resolveZodTypeName(d._def.innerType) : "<value>";
429
+ if (typeName === "ZodEffects") return d._def?.schema != null ? resolveZodTypeName(d._def.schema) : "<value>";
430
+ if (typeName === "ZodString") return "<string>";
431
+ if (typeName === "ZodNumber") return "<number>";
432
+ if (typeName === "ZodBoolean") return "<boolean>";
433
+ if (typeName === "ZodEnum") {
434
+ const values = d._def?.values;
435
+ return values != null ? values.join(" | ") : "<enum>";
436
+ }
437
+ if (typeName === "ZodArray") return "<list>";
438
+ if (typeName === "ZodObject") return "<object>";
439
+ return "<value>";
440
+ }
441
+ function buildYamlOutputSuffix(outputSchema) {
442
+ const fields = outputSchema != null ? extractSchemaFields(outputSchema) : [];
443
+ const fieldLines = fields.length > 0 ? fields.map((f) => ` ${f}`).join("\n") : " result: success\n # ... additional fields as specified in the task above";
444
+ return `
403
445
 
404
446
  ---
405
447
  IMPORTANT: When you have completed the task, output your structured result as a fenced YAML block at the END of your response. Use this exact format:
406
448
 
407
449
  \`\`\`yaml
408
- result: success
409
- # ... additional fields as specified in the task above
450
+ ${fieldLines}
410
451
  \`\`\`
411
452
 
412
453
  The YAML block MUST be the last thing in your output. Do not add any text after the closing fence.`;
454
+ }
413
455
  const MIN_FREE_MEMORY_BYTES = (() => {
414
456
  const envMB = process.env["SUBSTRATE_MEMORY_THRESHOLD_MB"];
415
457
  if (envMB) {
@@ -667,7 +709,8 @@ var DispatcherImpl = class {
667
709
  }
668
710
  const worktreePath = workingDirectory ?? process.cwd();
669
711
  const resolvedMaxTurns = maxTurns ?? DEFAULT_MAX_TURNS[taskType];
670
- const effectivePrompt = agent === "claude-code" ? prompt : prompt + YAML_OUTPUT_SUFFIX;
712
+ const capabilities = adapter.getCapabilities();
713
+ const effectivePrompt = capabilities.requiresYamlSuffix === true ? prompt + buildYamlOutputSuffix(outputSchema) : prompt;
671
714
  const cmd = adapter.buildCommand(effectivePrompt, {
672
715
  worktreePath,
673
716
  billingMode: "subscription",
@@ -681,7 +724,7 @@ var DispatcherImpl = class {
681
724
  dispatchId: id
682
725
  });
683
726
  const baseTimeoutMs = timeout ?? this._config.defaultTimeouts[taskType] ?? DEFAULT_TIMEOUTS[taskType] ?? 3e5;
684
- const timeoutMultiplier = adapter.getCapabilities().timeoutMultiplier ?? 1;
727
+ const timeoutMultiplier = capabilities.timeoutMultiplier ?? 1;
685
728
  const timeoutMs = Math.round(baseTimeoutMs * timeoutMultiplier);
686
729
  const env = { ...process.env };
687
730
  const parentNodeOpts = env["NODE_OPTIONS"] ?? "";
@@ -8748,7 +8791,11 @@ var ClaudeCodeAdapter = class {
8748
8791
  "document",
8749
8792
  "analyze"
8750
8793
  ],
8751
- supportedLanguages: ["*"]
8794
+ supportedLanguages: ["*"],
8795
+ supportsSystemPrompt: true,
8796
+ supportsOtlpExport: true,
8797
+ requiresYamlSuffix: false,
8798
+ defaultMaxReviewCycles: 2
8752
8799
  };
8753
8800
  }
8754
8801
  _detectBillingModes(versionOutput) {
@@ -8971,7 +9018,11 @@ var CodexCLIAdapter = class {
8971
9018
  "analyze"
8972
9019
  ],
8973
9020
  supportedLanguages: ["*"],
8974
- timeoutMultiplier: 3
9021
+ timeoutMultiplier: 3,
9022
+ supportsSystemPrompt: false,
9023
+ supportsOtlpExport: false,
9024
+ requiresYamlSuffix: true,
9025
+ defaultMaxReviewCycles: 3
8975
9026
  };
8976
9027
  }
8977
9028
  _buildPlanningPrompt(request) {
@@ -9211,7 +9262,11 @@ var GeminiCLIAdapter = class {
9211
9262
  "document",
9212
9263
  "analyze"
9213
9264
  ],
9214
- supportedLanguages: ["*"]
9265
+ supportedLanguages: ["*"],
9266
+ supportsSystemPrompt: false,
9267
+ supportsOtlpExport: false,
9268
+ requiresYamlSuffix: true,
9269
+ defaultMaxReviewCycles: 3
9215
9270
  };
9216
9271
  }
9217
9272
  _detectBillingModes(versionOutput) {
@@ -10263,4 +10318,4 @@ async function callLLM(params) {
10263
10318
 
10264
10319
  //#endregion
10265
10320
  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 };
10266
- //# sourceMappingURL=dist-CGOpItka.js.map
10321
+ //# sourceMappingURL=dist-C5NDd2T9.js.map
@@ -1,4 +1,4 @@
1
- import { AdtError } from "./dist-CGOpItka.js";
1
+ import { AdtError } from "./dist-C5NDd2T9.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-DBkOZgD4.js.map
74
+ //# sourceMappingURL=errors-CeBKTFSL.js.map
@@ -1,3 +1,3 @@
1
- import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-CGOpItka.js";
1
+ import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-C5NDd2T9.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-CS3SJ2JD.js";
1
+ import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-H-5xP8Cy.js";
2
2
  import "./logger-KeHncl-f.js";
3
- import "./dist-CGOpItka.js";
3
+ import "./dist-C5NDd2T9.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-CGOpItka.js";
2
+ import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-C5NDd2T9.js";
3
3
  import { createRequire } from "module";
4
4
  import { dirname, join } from "path";
5
5
  import { existsSync, readFileSync } from "node:fs";
@@ -1930,4 +1930,4 @@ function registerHealthCommand(program, _version = "0.0.0", projectRoot = proces
1930
1930
 
1931
1931
  //#endregion
1932
1932
  export { BMAD_BASELINE_TOKENS_FULL, DEFAULT_STALL_THRESHOLD_SECONDS, DoltMergeConflict, FileStateStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN$1 as STORY_KEY_PATTERN, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter$1 as createDatabaseAdapter, createStateStore, detectCycles, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, isOrchestratorProcessLine, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, runHealthAction, validateStoryKey };
1933
- //# sourceMappingURL=health-CS3SJ2JD.js.map
1933
+ //# sourceMappingURL=health-H-5xP8Cy.js.map
package/dist/index.d.ts CHANGED
@@ -847,6 +847,30 @@ interface AdapterCapabilities$1 {
847
847
  * Default: 1.0 (no scaling).
848
848
  */
849
849
  timeoutMultiplier?: number;
850
+ /**
851
+ * Whether the agent supports a --system-prompt flag.
852
+ * Claude Code: true. Codex/Gemini: false.
853
+ * When false, system-level instructions must be embedded in the prompt itself.
854
+ */
855
+ supportsSystemPrompt?: boolean;
856
+ /**
857
+ * Whether the agent exports OTLP telemetry (spans, metrics, logs).
858
+ * Claude Code: true. Codex/Gemini: false.
859
+ * When false, telemetry is heuristic-only (character-based token estimates).
860
+ */
861
+ supportsOtlpExport?: boolean;
862
+ /**
863
+ * Whether the dispatcher should append a YAML output format reminder to prompts.
864
+ * Claude Code: false (follows methodology pack format instructions reliably).
865
+ * Codex/Gemini: true (need explicit final nudge to emit fenced YAML blocks).
866
+ */
867
+ requiresYamlSuffix?: boolean;
868
+ /**
869
+ * Default maximum review cycles for this agent backend.
870
+ * Claude Code: 2 (converges quickly). Codex: 3 (needs more iterations).
871
+ * Overridden by explicit --max-review-cycles CLI flag.
872
+ */
873
+ defaultMaxReviewCycles?: number;
850
874
  }
851
875
  /**
852
876
  * Result returned from an adapter health check.
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-CGOpItka.js";
3
+ import { AdapterRegistry, AdtError, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, GeminiCLIAdapter } from "./dist-C5NDd2T9.js";
4
4
  import "./adapter-registry-DXLMTmfD.js";
5
- import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-DBkOZgD4.js";
5
+ import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-CeBKTFSL.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-CGOpItka.js";
1
+ import { ModelRoutingConfigSchema, ProviderPolicySchema, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, TASK_TYPE_PHASE_MAP, getModelTier, loadModelRoutingConfig } from "./dist-C5NDd2T9.js";
2
2
  import "./routing-CcBOCuC9.js";
3
3
 
4
4
  export { loadModelRoutingConfig };
@@ -1,8 +1,8 @@
1
- import "./health-CS3SJ2JD.js";
1
+ import "./health-H-5xP8Cy.js";
2
2
  import "./logger-KeHncl-f.js";
3
3
  import "./helpers-CElYrONe.js";
4
- import "./dist-CGOpItka.js";
5
- import { normalizeGraphSummaryToStatus, registerRunCommand, runRunAction } from "./run-BbZay3p0.js";
4
+ import "./dist-C5NDd2T9.js";
5
+ import { normalizeGraphSummaryToStatus, registerRunCommand, runRunAction } from "./run-DwVCcdCk.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, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter, detectCycles, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, resolveMainRepoRoot, validateStoryKey } from "./health-CS3SJ2JD.js";
1
+ import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter, detectCycles, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, resolveMainRepoRoot, validateStoryKey } from "./health-H-5xP8Cy.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, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-CGOpItka.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, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-C5NDd2T9.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";
@@ -5949,7 +5949,14 @@ async function getProjectFindings(db) {
5949
5949
  sections.push("**Prior escalations:**");
5950
5950
  for (const d of diagnoses.slice(-3)) try {
5951
5951
  const val = JSON.parse(d.value);
5952
- sections.push(`- ${(d.key ?? "").split(":")[0]}: ${val.recommendedAction} — ${val.rationale}`);
5952
+ const storyId = (d.key ?? "").split(":")[0];
5953
+ sections.push(`- ${storyId}: ${val.recommendedAction} — ${val.rationale}`);
5954
+ if (Array.isArray(val.issues) && val.issues.length > 0) for (const issue of val.issues.slice(0, 5)) {
5955
+ const sev = issue.severity ? `[${issue.severity}]` : "";
5956
+ const file = issue.file ? ` (${issue.file})` : "";
5957
+ const desc = issue.description ?? "no description";
5958
+ sections.push(` - ${sev} ${desc}${file}`);
5959
+ }
5953
5960
  } catch {
5954
5961
  sections.push(`- ${d.key ?? "unknown"}: escalated`);
5955
5962
  }
@@ -10677,6 +10684,28 @@ function createImplementationOrchestrator(deps) {
10677
10684
  phaseBreakdown[phase] = endMs !== void 0 ? endMs - startMs : nowMs - startMs;
10678
10685
  }
10679
10686
  }
10687
+ let diffStats;
10688
+ try {
10689
+ const statOutput = execSync("git diff --stat HEAD", {
10690
+ cwd: projectRoot ?? process.cwd(),
10691
+ encoding: "utf-8",
10692
+ timeout: 5e3,
10693
+ stdio: [
10694
+ "ignore",
10695
+ "pipe",
10696
+ "pipe"
10697
+ ]
10698
+ });
10699
+ const summaryLine = statOutput.trim().split("\n").pop() ?? "";
10700
+ const filesMatch = summaryLine.match(/(\d+)\s+files?\s+changed/);
10701
+ const insMatch = summaryLine.match(/(\d+)\s+insertions?/);
10702
+ const delMatch = summaryLine.match(/(\d+)\s+deletions?/);
10703
+ diffStats = {
10704
+ filesChanged: filesMatch ? parseInt(filesMatch[1], 10) : 0,
10705
+ insertions: insMatch ? parseInt(insMatch[1], 10) : 0,
10706
+ deletions: delMatch ? parseInt(delMatch[1], 10) : 0
10707
+ };
10708
+ } catch {}
10680
10709
  eventBus.emit("story:metrics", {
10681
10710
  storyKey,
10682
10711
  wallClockMs,
@@ -10686,7 +10715,8 @@ function createImplementationOrchestrator(deps) {
10686
10715
  output: tokenAgg.output
10687
10716
  },
10688
10717
  reviewCycles,
10689
- dispatches: _storyDispatches.get(storyKey) ?? 0
10718
+ dispatches: _storyDispatches.get(storyKey) ?? 0,
10719
+ ...diffStats !== void 0 ? { diffStats } : {}
10690
10720
  });
10691
10721
  } catch (emitErr) {
10692
10722
  logger$22.warn({
@@ -10741,12 +10771,24 @@ function createImplementationOrchestrator(deps) {
10741
10771
  diagnosis
10742
10772
  });
10743
10773
  if (config.pipelineRunId !== void 0) try {
10774
+ const diagnosisWithIssues = {
10775
+ ...diagnosis,
10776
+ issues: payload.issues.slice(0, 10).map((issue) => {
10777
+ if (typeof issue === "string") return { description: issue };
10778
+ const iss = issue;
10779
+ return {
10780
+ severity: iss.severity,
10781
+ description: iss.description,
10782
+ file: iss.file
10783
+ };
10784
+ })
10785
+ };
10744
10786
  await createDecision(db, {
10745
10787
  pipeline_run_id: config.pipelineRunId,
10746
10788
  phase: "implementation",
10747
10789
  category: ESCALATION_DIAGNOSIS,
10748
10790
  key: `${payload.storyKey}:${config.pipelineRunId}`,
10749
- value: JSON.stringify(diagnosis),
10791
+ value: JSON.stringify(diagnosisWithIssues),
10750
10792
  rationale: `Escalation diagnosis for ${payload.storyKey}: ${diagnosis.recommendedAction} — ${diagnosis.rationale}`
10751
10793
  });
10752
10794
  } catch (err) {
@@ -40165,6 +40207,16 @@ function buildSdlcHandlerRegistry(deps) {
40165
40207
  //#endregion
40166
40208
  //#region src/cli/commands/run.ts
40167
40209
  const logger = createLogger("run-cmd");
40210
+ /**
40211
+ * Resolve effective max review cycles by checking the adapter's default.
40212
+ * Uses Math.max so the adapter's recommendation is a floor, not an override.
40213
+ */
40214
+ function resolveMaxReviewCycles(cliValue, agentId, registry) {
40215
+ if (agentId == null || registry == null) return cliValue;
40216
+ const adapter = registry.get(agentId);
40217
+ const adapterDefault = adapter?.getCapabilities?.()?.defaultMaxReviewCycles;
40218
+ return adapterDefault != null ? Math.max(cliValue, adapterDefault) : cliValue;
40219
+ }
40168
40220
  const VALID_ENGINES = ["linear", "graph"];
40169
40221
  /**
40170
40222
  * Normalizes a `GraphRunSummary` (from GraphOrchestrator.run()) into the same
@@ -40389,6 +40441,7 @@ async function runRunAction(options) {
40389
40441
  else process.stderr.write(`Error: ${errorMsg}\n`);
40390
40442
  return 1;
40391
40443
  }
40444
+ const effectiveMaxReviewCycles = resolveMaxReviewCycles(maxReviewCycles, agentId, injectedRegistry);
40392
40445
  if (startPhase !== void 0 && !VALID_PHASES.includes(startPhase)) {
40393
40446
  const errorMsg = `Invalid phase '${startPhase}'. Valid phases: ${VALID_PHASES.join(", ")}`;
40394
40447
  if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, errorMsg) + "\n");
@@ -40545,7 +40598,7 @@ async function runRunAction(options) {
40545
40598
  telemetryEnabled: true,
40546
40599
  telemetryPort
40547
40600
  } : {},
40548
- maxReviewCycles,
40601
+ maxReviewCycles: effectiveMaxReviewCycles,
40549
40602
  agentId
40550
40603
  });
40551
40604
  let storyKeys = [...parsedStoryKeys];
@@ -41032,7 +41085,7 @@ async function runRunAction(options) {
41032
41085
  runId: pipelineRun.id,
41033
41086
  eventBus,
41034
41087
  pipelineRunId: pipelineRun.id,
41035
- maxReviewCycles,
41088
+ maxReviewCycles: effectiveMaxReviewCycles,
41036
41089
  gcPauseMs: 0
41037
41090
  });
41038
41091
  if (outputFormat === "human" && progressRenderer === void 0 && ndjsonEmitter === void 0) {
@@ -41051,7 +41104,7 @@ async function runRunAction(options) {
41051
41104
  eventBus,
41052
41105
  config: {
41053
41106
  maxConcurrency: concurrency,
41054
- maxReviewCycles,
41107
+ maxReviewCycles: effectiveMaxReviewCycles,
41055
41108
  pipelineRunId: pipelineRun.id,
41056
41109
  enableHeartbeat: eventsFlag === true,
41057
41110
  skipPreflight: skipPreflight === true
@@ -41648,4 +41701,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
41648
41701
 
41649
41702
  //#endregion
41650
41703
  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, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict };
41651
- //# sourceMappingURL=run-BbZay3p0.js.map
41704
+ //# sourceMappingURL=run-DwVCcdCk.js.map
@@ -1,5 +1,5 @@
1
- import "./dist-CGOpItka.js";
1
+ import "./dist-C5NDd2T9.js";
2
2
  import "./version-manager-impl-BmOWu8ml.js";
3
- import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-DaP1jFb9.js";
3
+ import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-DXT62773.js";
4
4
 
5
5
  export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
@@ -1,4 +1,4 @@
1
- import { createVersionManager } from "./dist-CGOpItka.js";
1
+ import { createVersionManager } from "./dist-C5NDd2T9.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-DaP1jFb9.js.map
126
+ //# sourceMappingURL=upgrade-DXT62773.js.map
@@ -1,4 +1,4 @@
1
- import { VersionManagerImpl, createVersionManager } from "./dist-CGOpItka.js";
1
+ import { VersionManagerImpl, createVersionManager } from "./dist-C5NDd2T9.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.14",
3
+ "version": "0.19.16",
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-CGOpItka.js";
2
- import "./adapter-registry-DXLMTmfD.js";
3
-
4
- export { AdapterRegistry };