substrate-ai 0.2.38 → 0.2.40

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
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { DEFAULT_CONFIG, DEFAULT_ROUTING_POLICY, DatabaseWrapper, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createConfigSystem, createContextCompiler, createDispatcher, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, parseDbTimestampAsUtc, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveStoryKeys, runAnalysisPhase, runMigrations, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-RJ0EHbfM.js";
2
+ import { DEFAULT_CONFIG, DEFAULT_ROUTING_POLICY, DatabaseWrapper, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createConfigSystem, createContextCompiler, createDispatcher, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, parseDbTimestampAsUtc, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveStoryKeys, runAnalysisPhase, runMigrations, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-DphVZduv.js";
3
3
  import { createLogger } from "../logger-D2fS2ccL.js";
4
4
  import { AdapterRegistry } from "../adapter-registry-PsWhP_1Q.js";
5
5
  import { CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, PartialSubstrateConfigSchema } from "../config-migrator-DSi8KhQC.js";
@@ -2581,7 +2581,7 @@ async function runSupervisorAction(options, deps = {}) {
2581
2581
  const expDb = expDbWrapper.db;
2582
2582
  const { runRunAction: runPipeline } = await import(
2583
2583
  /* @vite-ignore */
2584
- "../run-Q-rgJf4a.js"
2584
+ "../run-CwENzFYi.js"
2585
2585
  );
2586
2586
  const runStoryFn = async (opts) => {
2587
2587
  const exitCode = await runPipeline({
@@ -8,12 +8,12 @@ This project uses Substrate for automated implementation pipelines. **When the u
8
8
  **Just run it.** Substrate auto-detects which pipeline phase to start from (analysis → planning → solutioning → implementation) and auto-discovers pending stories. You do not need to determine the phase or find story keys manually.
9
9
 
10
10
  ```
11
- substrate supervisor --output-format json
11
+ substrate run --events
12
12
  ```
13
13
 
14
14
  To target specific stories (if the user names them):
15
15
  ```
16
- substrate supervisor --output-format json --stories 1-1,1-2,1-3
16
+ substrate run --events --stories 1-1,1-2,1-3
17
17
  ```
18
18
 
19
19
  If substrate needs input it can't auto-detect (e.g., a project concept for analysis), it will exit with a clear error message telling you what to provide.
@@ -36,13 +36,18 @@ Check process health if pipeline seems quiet:
36
36
  substrate health --output-format json
37
37
  ```
38
38
 
39
+ For long-running pipelines, attach the **supervisor** for automatic stall detection, kill-and-restart recovery, and post-run analysis. The supervisor monitors an active run — it does not start one. Start it alongside `substrate run`:
40
+ ```
41
+ substrate supervisor --output-format json
42
+ ```
43
+
39
44
  **Interpreting silence:** No output for 5 minutes = normal (agent is working). No output for 15+ minutes = likely stalled. Use `substrate health` to confirm, then consider killing and resuming.
40
45
 
41
46
  ### After Pipeline Completes
42
47
 
43
48
  1. **Summarize results** conversationally: X succeeded, Y failed, Z escalated
44
49
  2. **Check metrics**: `substrate metrics --output-format json`
45
- 3. **Read analysis** (if supervisor mode): `substrate metrics --analysis <run_id> --output-format json`
50
+ 3. **Read analysis** (if supervisor was attached): `substrate metrics --analysis <run_id> --output-format json`
46
51
 
47
52
  ### Handling Escalations and Failures
48
53
 
@@ -57,7 +62,7 @@ substrate health --output-format json
57
62
  | Command | Purpose |
58
63
  |---|---|
59
64
  | `substrate run --events` | Run pipeline with NDJSON event stream |
60
- | `substrate supervisor --output-format json` | Run with auto-recovery and analysis |
65
+ | `substrate supervisor --output-format json` | Monitor active run with auto-recovery and post-run analysis |
61
66
  | `substrate status --output-format json` | Poll current pipeline state |
62
67
  | `substrate health --output-format json` | Check process health and stall detection |
63
68
  | `substrate metrics --output-format json` | View historical run metrics |
@@ -1,4 +1,4 @@
1
- import { registerRunCommand, runRunAction } from "./run-RJ0EHbfM.js";
1
+ import { registerRunCommand, runRunAction } from "./run-DphVZduv.js";
2
2
  import "./logger-D2fS2ccL.js";
3
3
  import "./config-migrator-DSi8KhQC.js";
4
4
  import "./helpers-RL22dYtn.js";
@@ -9460,8 +9460,10 @@ function parseStoryKeysFromEpics(content) {
9460
9460
  const explicitKeyPattern = /\*\*Story key:\*\*\s*`?(\d+-\d+)(?:-[^`\s]*)?`?/g;
9461
9461
  let match;
9462
9462
  while ((match = explicitKeyPattern.exec(content)) !== null) if (match[1] !== void 0) keys.add(match[1]);
9463
- const headingPattern = /^###\s+Story\s+(\d+)\.(\d+)/gm;
9463
+ const headingPattern = /^###\s+Story\s+(\d+)[.\-](\d+)/gm;
9464
9464
  while ((match = headingPattern.exec(content)) !== null) if (match[1] !== void 0 && match[2] !== void 0) keys.add(`${match[1]}-${match[2]}`);
9465
+ const inlineStoryPattern = /Story\s+(\d+)-(\d+)[:\s]/g;
9466
+ while ((match = inlineStoryPattern.exec(content)) !== null) if (match[1] !== void 0 && match[2] !== void 0) keys.add(`${match[1]}-${match[2]}`);
9465
9467
  const filePathPattern = /_bmad-output\/implementation-artifacts\/(\d+-\d+)-/g;
9466
9468
  while ((match = filePathPattern.exec(content)) !== null) if (match[1] !== void 0) keys.add(match[1]);
9467
9469
  return sortStoryKeys(Array.from(keys));
@@ -9481,21 +9483,34 @@ function parseStoryKeysFromEpics(content) {
9481
9483
  * @returns Sorted array of pending story keys in "N-M" format
9482
9484
  */
9483
9485
  function discoverPendingStoryKeys(projectRoot) {
9486
+ let allKeys = [];
9484
9487
  const epicsPath = findEpicsFile(projectRoot);
9485
- if (epicsPath === void 0) return [];
9486
- let content;
9487
- try {
9488
- content = readFileSync$1(epicsPath, "utf-8");
9489
- } catch {
9490
- return [];
9488
+ if (epicsPath !== void 0) try {
9489
+ const content = readFileSync$1(epicsPath, "utf-8");
9490
+ allKeys = parseStoryKeysFromEpics(content);
9491
+ } catch {}
9492
+ if (allKeys.length === 0) {
9493
+ const epicFiles = findEpicFiles(projectRoot);
9494
+ for (const epicFile of epicFiles) try {
9495
+ const content = readFileSync$1(epicFile, "utf-8");
9496
+ const keys = parseStoryKeysFromEpics(content);
9497
+ allKeys.push(...keys);
9498
+ } catch {}
9499
+ allKeys = sortStoryKeys([...new Set(allKeys)]);
9491
9500
  }
9492
- const allKeys = parseStoryKeysFromEpics(content);
9493
9501
  if (allKeys.length === 0) return [];
9494
9502
  const existingKeys = collectExistingStoryKeys(projectRoot);
9495
9503
  return allKeys.filter((k) => !existingKeys.has(k));
9496
9504
  }
9497
9505
  /**
9498
- * Find epics.md from known candidate paths relative to projectRoot.
9506
+ * Find epic files from known candidate paths relative to projectRoot.
9507
+ *
9508
+ * Checks for:
9509
+ * 1. epics.md (consolidated epic file)
9510
+ * 2. Individual epic-*.md files in planning-artifacts/
9511
+ *
9512
+ * Returns a single path for epics.md, or undefined if not found.
9513
+ * For individual epic files, use findEpicFiles() instead.
9499
9514
  */
9500
9515
  function findEpicsFile(projectRoot) {
9501
9516
  const candidates = ["_bmad-output/planning-artifacts/epics.md", "_bmad-output/epics.md"];
@@ -9506,6 +9521,20 @@ function findEpicsFile(projectRoot) {
9506
9521
  return void 0;
9507
9522
  }
9508
9523
  /**
9524
+ * Find individual epic-*.md files in the planning artifacts directory.
9525
+ * Returns paths sorted alphabetically.
9526
+ */
9527
+ function findEpicFiles(projectRoot) {
9528
+ const planningDir = join$1(projectRoot, "_bmad-output", "planning-artifacts");
9529
+ if (!existsSync$1(planningDir)) return [];
9530
+ try {
9531
+ const entries = readdirSync$1(planningDir, { encoding: "utf-8" });
9532
+ return entries.filter((e) => /^epic-\d+.*\.md$/.test(e)).sort().map((e) => join$1(planningDir, e));
9533
+ } catch {
9534
+ return [];
9535
+ }
9536
+ }
9537
+ /**
9509
9538
  * Collect story keys that already have implementation artifact files.
9510
9539
  * Scans _bmad-output/implementation-artifacts/ for files matching N-M-*.md.
9511
9540
  */
@@ -14533,4 +14562,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
14533
14562
 
14534
14563
  //#endregion
14535
14564
  export { DEFAULT_CONFIG, DEFAULT_ROUTING_POLICY, DatabaseWrapper, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createConfigSystem, createContextCompiler, createDispatcher, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, parseDbTimestampAsUtc, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveStoryKeys, runAnalysisPhase, runMigrations, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict };
14536
- //# sourceMappingURL=run-RJ0EHbfM.js.map
14565
+ //# sourceMappingURL=run-DphVZduv.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "substrate-ai",
3
- "version": "0.2.38",
3
+ "version": "0.2.40",
4
4
  "description": "Substrate — multi-agent orchestration daemon for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",