substrate-ai 0.2.36 → 0.2.38
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-RJ0EHbfM.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-Q-rgJf4a.js"
|
|
2585
2585
|
);
|
|
2586
2586
|
const runStoryFn = async (opts) => {
|
|
2587
2587
|
const exitCode = await runPipeline({
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
<!-- substrate:start -->
|
|
2
2
|
## Substrate Pipeline
|
|
3
3
|
|
|
4
|
-
This project uses Substrate for automated implementation pipelines.
|
|
4
|
+
This project uses Substrate for automated implementation pipelines. **When the user asks you to implement, build, or run the pipeline — go straight to running substrate. Do NOT explore the codebase, read source files, or plan the implementation yourself.** Substrate orchestrates sub-agents that handle all of that.
|
|
5
5
|
|
|
6
6
|
### Running the Pipeline
|
|
7
7
|
|
|
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
|
-
substrate supervisor --output-format json
|
|
11
|
+
substrate supervisor --output-format json
|
|
11
12
|
```
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
To target specific stories (if the user names them):
|
|
14
15
|
```
|
|
15
|
-
substrate
|
|
16
|
+
substrate supervisor --output-format json --stories 1-1,1-2,1-3
|
|
16
17
|
```
|
|
17
18
|
|
|
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.
|
|
20
|
+
|
|
18
21
|
**CRITICAL execution rules:**
|
|
19
22
|
- Pipeline runs take **5–40 minutes**. You MUST use `run_in_background: true` or `timeout: 600000` (10 min) when invoking via Bash tool. Default 2-minute timeout WILL kill the pipeline.
|
|
20
23
|
- **NEVER pipe substrate output** to `head`, `tail`, `grep`, or any command that may close the pipe early — this causes EPIPE stalls that hang the process.
|
|
@@ -9559,6 +9559,83 @@ function sortStoryKeys(keys) {
|
|
|
9559
9559
|
});
|
|
9560
9560
|
}
|
|
9561
9561
|
|
|
9562
|
+
//#endregion
|
|
9563
|
+
//#region src/modules/phase-orchestrator/phase-detection.ts
|
|
9564
|
+
const PHASE_ARTIFACTS = [
|
|
9565
|
+
{
|
|
9566
|
+
phase: "research",
|
|
9567
|
+
type: "research-findings",
|
|
9568
|
+
optional: true
|
|
9569
|
+
},
|
|
9570
|
+
{
|
|
9571
|
+
phase: "analysis",
|
|
9572
|
+
type: "product-brief",
|
|
9573
|
+
optional: false
|
|
9574
|
+
},
|
|
9575
|
+
{
|
|
9576
|
+
phase: "planning",
|
|
9577
|
+
type: "prd",
|
|
9578
|
+
optional: false
|
|
9579
|
+
},
|
|
9580
|
+
{
|
|
9581
|
+
phase: "solutioning",
|
|
9582
|
+
type: "stories",
|
|
9583
|
+
optional: false
|
|
9584
|
+
}
|
|
9585
|
+
];
|
|
9586
|
+
/**
|
|
9587
|
+
* Detect the next phase to run based on DB state.
|
|
9588
|
+
*
|
|
9589
|
+
* Detection logic:
|
|
9590
|
+
* 1. If stories exist (decisions/epics.md) → implementation
|
|
9591
|
+
* 2. Walk forward through phases checking for completion artifacts
|
|
9592
|
+
* 3. Skip optional phases (research) if no artifact found
|
|
9593
|
+
* 4. The first required phase WITHOUT an artifact is where we start
|
|
9594
|
+
* 5. If nothing exists → analysis (needs concept)
|
|
9595
|
+
*/
|
|
9596
|
+
function detectStartPhase(db, projectRoot) {
|
|
9597
|
+
try {
|
|
9598
|
+
const storyKeys = resolveStoryKeys(db, projectRoot);
|
|
9599
|
+
if (storyKeys.length > 0) return {
|
|
9600
|
+
phase: "implementation",
|
|
9601
|
+
reason: `${storyKeys.length} stories ready for implementation`,
|
|
9602
|
+
needsConcept: false
|
|
9603
|
+
};
|
|
9604
|
+
} catch {}
|
|
9605
|
+
let lastCompletedPhase;
|
|
9606
|
+
try {
|
|
9607
|
+
for (const entry of PHASE_ARTIFACTS) {
|
|
9608
|
+
const row = db.prepare("SELECT id FROM artifacts WHERE phase = ? AND type = ? LIMIT 1").get(entry.phase, entry.type);
|
|
9609
|
+
if (row !== void 0) lastCompletedPhase = entry.phase;
|
|
9610
|
+
else if (!entry.optional) {
|
|
9611
|
+
const needsConcept = entry.phase === "analysis";
|
|
9612
|
+
const reason = lastCompletedPhase !== void 0 ? `${lastCompletedPhase} phase complete — continuing with ${entry.phase}` : "No pipeline state found — starting from the beginning";
|
|
9613
|
+
return {
|
|
9614
|
+
phase: entry.phase,
|
|
9615
|
+
needsConcept,
|
|
9616
|
+
reason
|
|
9617
|
+
};
|
|
9618
|
+
}
|
|
9619
|
+
}
|
|
9620
|
+
} catch {
|
|
9621
|
+
return {
|
|
9622
|
+
phase: "analysis",
|
|
9623
|
+
reason: "No pipeline state found — starting from the beginning",
|
|
9624
|
+
needsConcept: true
|
|
9625
|
+
};
|
|
9626
|
+
}
|
|
9627
|
+
if (lastCompletedPhase !== void 0) return {
|
|
9628
|
+
phase: "solutioning",
|
|
9629
|
+
reason: "All phases completed but no stories found — re-running solutioning",
|
|
9630
|
+
needsConcept: false
|
|
9631
|
+
};
|
|
9632
|
+
return {
|
|
9633
|
+
phase: "analysis",
|
|
9634
|
+
reason: "No pipeline state found — starting from the beginning",
|
|
9635
|
+
needsConcept: true
|
|
9636
|
+
};
|
|
9637
|
+
}
|
|
9638
|
+
|
|
9562
9639
|
//#endregion
|
|
9563
9640
|
//#region src/modules/phase-orchestrator/built-in-phases.ts
|
|
9564
9641
|
function logPhase(message) {
|
|
@@ -13560,12 +13637,37 @@ async function runRunAction(options) {
|
|
|
13560
13637
|
return 1;
|
|
13561
13638
|
}
|
|
13562
13639
|
}
|
|
13563
|
-
|
|
13640
|
+
let effectiveStartPhase = startPhase;
|
|
13641
|
+
if (effectiveStartPhase === void 0) {
|
|
13642
|
+
mkdirSync(dbDir, { recursive: true });
|
|
13643
|
+
try {
|
|
13644
|
+
const detectDb = new DatabaseWrapper(dbPath);
|
|
13645
|
+
try {
|
|
13646
|
+
detectDb.open();
|
|
13647
|
+
runMigrations(detectDb.db);
|
|
13648
|
+
const detection = detectStartPhase(detectDb.db, projectRoot);
|
|
13649
|
+
if (detection.phase !== "implementation") {
|
|
13650
|
+
effectiveStartPhase = detection.phase;
|
|
13651
|
+
if (outputFormat === "human") process.stdout.write(`[AUTO-DETECT] ${detection.reason}\n`);
|
|
13652
|
+
if (detection.needsConcept && concept === void 0) {
|
|
13653
|
+
const errorMsg = `Pipeline needs to start from ${detection.phase} phase, which requires a concept.\nProvide --concept "your idea" or --concept-file path/to/brief.md`;
|
|
13654
|
+
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, errorMsg) + "\n");
|
|
13655
|
+
else process.stderr.write(`Error: ${errorMsg}\n`);
|
|
13656
|
+
detectDb.close();
|
|
13657
|
+
return 1;
|
|
13658
|
+
}
|
|
13659
|
+
} else if (outputFormat === "human") process.stdout.write(`[AUTO-DETECT] ${detection.reason}\n`);
|
|
13660
|
+
} finally {
|
|
13661
|
+
detectDb.close();
|
|
13662
|
+
}
|
|
13663
|
+
} catch {}
|
|
13664
|
+
}
|
|
13665
|
+
if (effectiveStartPhase !== void 0) return runFullPipeline({
|
|
13564
13666
|
packName,
|
|
13565
13667
|
packPath,
|
|
13566
13668
|
dbDir,
|
|
13567
13669
|
dbPath,
|
|
13568
|
-
startPhase,
|
|
13670
|
+
startPhase: effectiveStartPhase,
|
|
13569
13671
|
stopAfter,
|
|
13570
13672
|
concept,
|
|
13571
13673
|
concurrency,
|
|
@@ -14431,4 +14533,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
14431
14533
|
|
|
14432
14534
|
//#endregion
|
|
14433
14535
|
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 };
|
|
14434
|
-
//# sourceMappingURL=run-
|
|
14536
|
+
//# sourceMappingURL=run-RJ0EHbfM.js.map
|