substrate-ai 0.16.6 → 0.16.7

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
@@ -4,7 +4,7 @@ import { createLogger } from "../logger-KeHncl-f.js";
4
4
  import { createEventBus } from "../helpers-CElYrONe.js";
5
5
  import { AdapterRegistry, BudgetConfigSchema, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, ConfigError, CostTrackerConfigSchema, DEFAULT_CONFIG, DoltClient, DoltNotInstalled, EXPERIMENT_RESULT, 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, listRequirements, listRunMetrics, loadParentRunDecisions, supersedeDecision, tagRunAsBaseline, updatePipelineRun } from "../dist-CLvAwmT7.js";
6
6
  import "../adapter-registry-DXLMTmfD.js";
7
- import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-mKdPlyIj.js";
7
+ import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-BEWyyN-c.js";
8
8
  import "../errors-D1LU8CZ9.js";
9
9
  import "../routing-CcBOCuC9.js";
10
10
  import "../decisions-C0pz9Clx.js";
@@ -4359,7 +4359,7 @@ async function runSupervisorAction(options, deps = {}) {
4359
4359
  await initSchema(expAdapter);
4360
4360
  const { runRunAction: runPipeline } = await import(
4361
4361
  /* @vite-ignore */
4362
- "../run-Cz-Qy4iA.js"
4362
+ "../run-BUMbrMA_.js"
4363
4363
  );
4364
4364
  const runStoryFn = async (opts) => {
4365
4365
  const exitCode = await runPipeline({
@@ -16648,20 +16648,63 @@ function createSdlcPhaseHandler(deps) {
16648
16648
  };
16649
16649
  const runId = context.getString("runId");
16650
16650
  const concept = phaseName === "analysis" ? context.getString("concept", "") : "";
16651
+ const PRE_IMPL_PHASES = [
16652
+ "analysis",
16653
+ "planning",
16654
+ "solutioning"
16655
+ ];
16656
+ const storyKey = context.getString("storyKey", "");
16657
+ if (storyKey && PRE_IMPL_PHASES.includes(phaseName)) return {
16658
+ status: "SUCCESS",
16659
+ notes: `Phase ${phaseName} skipped — explicit story dispatch (storyKey=${storyKey})`
16660
+ };
16651
16661
  const PHASE_ARTIFACT_TYPES = {
16652
- analysis: "product-brief",
16653
- planning: "prd",
16654
- solutioning: "stories"
16662
+ analysis: ["product-brief"],
16663
+ planning: ["prd"],
16664
+ solutioning: ["architecture", "stories"]
16655
16665
  };
16656
- const artifactType = PHASE_ARTIFACT_TYPES[phaseName];
16657
- if (artifactType !== void 0) try {
16666
+ const artifactTypes = PHASE_ARTIFACT_TYPES[phaseName];
16667
+ if (artifactTypes !== void 0) try {
16658
16668
  const db = deps.phaseDeps.db;
16659
16669
  if (db) {
16660
- const rows = await db.query("SELECT id FROM artifacts WHERE phase = ? AND type = ? LIMIT 1", [phaseName, artifactType]);
16661
- if (Array.isArray(rows) && rows.length > 0) return {
16662
- status: "SUCCESS",
16663
- notes: `Phase ${phaseName} already complete artifact '${artifactType}' exists, skipping dispatch`
16664
- };
16670
+ let allExist = true;
16671
+ for (const at of artifactTypes) {
16672
+ const rows = await db.query("SELECT id, path, content_hash, summary FROM artifacts WHERE phase = ? AND type = ? ORDER BY created_at DESC LIMIT 1", [phaseName, at]);
16673
+ if (!Array.isArray(rows) || rows.length === 0) {
16674
+ allExist = false;
16675
+ break;
16676
+ }
16677
+ }
16678
+ if (allExist) {
16679
+ const pipelineRunId = context.getString("pipelineRunId", "");
16680
+ if (pipelineRunId) for (const at of artifactTypes) {
16681
+ const existing = await db.query("SELECT id, path, content_hash, summary FROM artifacts WHERE phase = ? AND type = ? ORDER BY created_at DESC LIMIT 1", [phaseName, at]);
16682
+ const src = existing[0];
16683
+ if (src) {
16684
+ const alreadyRegistered = await db.query("SELECT id FROM artifacts WHERE pipeline_run_id = ? AND phase = ? AND type = ? LIMIT 1", [
16685
+ pipelineRunId,
16686
+ phaseName,
16687
+ at
16688
+ ]);
16689
+ if (!Array.isArray(alreadyRegistered) || alreadyRegistered.length === 0) {
16690
+ const newId = crypto.randomUUID();
16691
+ await db.query("INSERT INTO artifacts (id, pipeline_run_id, phase, type, path, content_hash, summary) VALUES (?, ?, ?, ?, ?, ?, ?)", [
16692
+ newId,
16693
+ pipelineRunId,
16694
+ phaseName,
16695
+ at,
16696
+ src.path,
16697
+ src.content_hash ?? null,
16698
+ src.summary ?? null
16699
+ ]);
16700
+ }
16701
+ }
16702
+ }
16703
+ return {
16704
+ status: "SUCCESS",
16705
+ notes: `Phase ${phaseName} already complete — artifact(s) exist, skipping dispatch`
16706
+ };
16707
+ }
16665
16708
  }
16666
16709
  } catch {}
16667
16710
  const params = phaseName === "analysis" ? {
@@ -17095,8 +17138,10 @@ function createGraphOrchestrator(config) {
17095
17138
  if (!config.graph?.nodes || !config.graph?.edges) throw new GraphOrchestratorInitError("Invalid graph: missing nodes or edges arrays");
17096
17139
  const gcPauseMs = config.gcPauseMs ?? 2e3;
17097
17140
  async function runStoryGraph(storyKey, summary) {
17141
+ const epicId = storyKey.split("-")[0] ?? "";
17098
17142
  const initialContext = {
17099
17143
  storyKey,
17144
+ epicId,
17100
17145
  projectRoot: config.projectRoot,
17101
17146
  methodologyPack: config.methodologyPack,
17102
17147
  ...config.pipelineRunId !== void 0 ? {
@@ -17126,6 +17171,7 @@ function createGraphOrchestrator(config) {
17126
17171
  });
17127
17172
  } catch (err) {
17128
17173
  const errMsg = err instanceof Error ? err.message : String(err);
17174
+ process.stderr.write(`[graph-orchestrator] Story ${storyKey} failed: ${errMsg}\n`);
17129
17175
  summary.stories[storyKey] = {
17130
17176
  outcome: escalated ? "ESCALATED" : "FAILED",
17131
17177
  error: errMsg
@@ -17142,7 +17188,12 @@ function createGraphOrchestrator(config) {
17142
17188
  summary.stories[storyKey] = { outcome: "ESCALATED" };
17143
17189
  summary.f++;
17144
17190
  } else {
17145
- summary.stories[storyKey] = { outcome: "FAILED" };
17191
+ const reason = result.failureReason ?? `status=${result.status}`;
17192
+ process.stderr.write(`[graph-orchestrator] Story ${storyKey} failed: ${reason}\n`);
17193
+ summary.stories[storyKey] = {
17194
+ outcome: "FAILED",
17195
+ error: reason
17196
+ };
17146
17197
  summary.f++;
17147
17198
  }
17148
17199
  }
@@ -22997,6 +23048,7 @@ function createGraphExecutor() {
22997
23048
  let context = new GraphContext(config.initialContext);
22998
23049
  let step = 0;
22999
23050
  const visitCount = new Map();
23051
+ const failRouteCount = new Map();
23000
23052
  let resumeCompletedSet = null;
23001
23053
  let firstResumedFidelity = "";
23002
23054
  let skipCycleCheck = false;
@@ -23254,6 +23306,7 @@ function createGraphExecutor() {
23254
23306
  controller.recordOutcome(nodeToDispatch.id, controllerStatus);
23255
23307
  }
23256
23308
  if (outcome.contextUpdates) for (const [key, value] of Object.entries(outcome.contextUpdates)) context.set(key, value);
23309
+ context.set("outcome", outcome.status.toLowerCase());
23257
23310
  const nodeCost = context.getNumber("factory.lastNodeCostUsd", 0);
23258
23311
  if (nodeCost > 0) pipelineManager.addCost(nodeCost);
23259
23312
  if (config.adapter) {
@@ -23297,11 +23350,24 @@ function createGraphExecutor() {
23297
23350
  currentNode = retryNode;
23298
23351
  continue;
23299
23352
  }
23300
- await persistExit("failed", outcome.failureReason ?? "FAIL");
23301
- return {
23302
- status: "FAIL",
23303
- ...outcome.failureReason !== void 0 && { failureReason: outcome.failureReason }
23304
- };
23353
+ const outgoing = graph.edges.filter((e) => e.fromNode === currentNode.id);
23354
+ const hasConditionalEdge = outgoing.some((e) => e.condition && e.condition.trim() !== "");
23355
+ if (!hasConditionalEdge) {
23356
+ await persistExit("failed", outcome.failureReason ?? "FAIL");
23357
+ return {
23358
+ status: "FAIL",
23359
+ ...outcome.failureReason !== void 0 && { failureReason: outcome.failureReason }
23360
+ };
23361
+ }
23362
+ const routeCount = (failRouteCount.get(currentNode.id) ?? 0) + 1;
23363
+ failRouteCount.set(currentNode.id, routeCount);
23364
+ if (routeCount > Math.max(graph.defaultMaxRetries || 0, 3)) {
23365
+ await persistExit("failed", outcome.failureReason ?? "FAIL");
23366
+ return {
23367
+ status: "FAIL",
23368
+ ...outcome.failureReason !== void 0 && { failureReason: outcome.failureReason }
23369
+ };
23370
+ }
23305
23371
  }
23306
23372
  const edge = selectEdge(currentNode, outcome, context, graph);
23307
23373
  if (!edge) {
@@ -31041,4 +31107,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
31041
31107
 
31042
31108
  //#endregion
31043
31109
  export { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, normalizeGraphSummaryToStatus, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict };
31044
- //# sourceMappingURL=run-mKdPlyIj.js.map
31110
+ //# sourceMappingURL=run-BEWyyN-c.js.map
@@ -2,7 +2,7 @@ import "./health-DswaC1q5.js";
2
2
  import "./logger-KeHncl-f.js";
3
3
  import "./helpers-CElYrONe.js";
4
4
  import "./dist-CLvAwmT7.js";
5
- import { normalizeGraphSummaryToStatus, registerRunCommand, runRunAction } from "./run-mKdPlyIj.js";
5
+ import { normalizeGraphSummaryToStatus, registerRunCommand, runRunAction } from "./run-BEWyyN-c.js";
6
6
  import "./routing-CcBOCuC9.js";
7
7
  import "./decisions-C0pz9Clx.js";
8
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "substrate-ai",
3
- "version": "0.16.6",
3
+ "version": "0.16.7",
4
4
  "description": "Substrate — multi-agent orchestration daemon for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",