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-
|
|
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-
|
|
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
|
|
11
|
+
substrate run --events
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
To target specific stories (if the user names them):
|
|
15
15
|
```
|
|
16
|
-
substrate
|
|
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
|
|
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` |
|
|
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 |
|
|
@@ -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+)
|
|
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
|
|
9486
|
-
|
|
9487
|
-
|
|
9488
|
-
|
|
9489
|
-
|
|
9490
|
-
|
|
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
|
|
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-
|
|
14565
|
+
//# sourceMappingURL=run-DphVZduv.js.map
|