substrate-ai 0.3.0 → 0.3.1
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, DoltNotInstalled, FileStateStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, checkDoltInstalled, createConfigSystem, createContextCompiler, createDispatcher, createDoltClient, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStateStore, createStopAfterGate, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, initializeDolt, parseDbTimestampAsUtc, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveStoryKeys, runAnalysisPhase, runMigrations, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-
|
|
2
|
+
import { DEFAULT_CONFIG, DEFAULT_ROUTING_POLICY, DatabaseWrapper, DoltNotInstalled, FileStateStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, checkDoltInstalled, createConfigSystem, createContextCompiler, createDispatcher, createDoltClient, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStateStore, createStopAfterGate, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, initializeDolt, parseDbTimestampAsUtc, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveStoryKeys, runAnalysisPhase, runMigrations, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-DNURadtJ.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";
|
|
@@ -681,7 +681,7 @@ async function runInitAction(options) {
|
|
|
681
681
|
process.stderr.write(`✗ Dolt initialization failed: ${msg}\n`);
|
|
682
682
|
return INIT_EXIT_ERROR;
|
|
683
683
|
}
|
|
684
|
-
logger$16.warn("Dolt auto-init failed (non-blocking)"
|
|
684
|
+
logger$16.warn({ error: msg }, "Dolt auto-init failed (non-blocking)");
|
|
685
685
|
}
|
|
686
686
|
}
|
|
687
687
|
else logger$16.debug("Dolt step was skipped (--no-dolt)");
|
|
@@ -1362,7 +1362,7 @@ async function runStatusAction(options) {
|
|
|
1362
1362
|
if (stateStore) try {
|
|
1363
1363
|
storeStories = await stateStore.queryStories({});
|
|
1364
1364
|
} catch (err) {
|
|
1365
|
-
logger$13.debug("StateStore query failed, continuing without store data"
|
|
1365
|
+
logger$13.debug({ err }, "StateStore query failed, continuing without store data");
|
|
1366
1366
|
}
|
|
1367
1367
|
if (outputFormat === "json") {
|
|
1368
1368
|
const statusOutput = buildPipelineStatusOutput(run, tokenSummary, decisionsCount, storiesCount);
|
|
@@ -2664,7 +2664,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
2664
2664
|
const expDb = expDbWrapper.db;
|
|
2665
2665
|
const { runRunAction: runPipeline } = await import(
|
|
2666
2666
|
/* @vite-ignore */
|
|
2667
|
-
"../run-
|
|
2667
|
+
"../run-D6WEx9l2.js"
|
|
2668
2668
|
);
|
|
2669
2669
|
const runStoryFn = async (opts) => {
|
|
2670
2670
|
const exitCode = await runPipeline({
|
|
@@ -3291,8 +3291,12 @@ function registerMigrateCommand(program) {
|
|
|
3291
3291
|
}
|
|
3292
3292
|
const result = await migrateDataToDolt(client, snapshot.storyMetrics, false);
|
|
3293
3293
|
if (result.metricsWritten > 0) try {
|
|
3294
|
-
await client.
|
|
3295
|
-
await client.
|
|
3294
|
+
await client.execArgs(["add", "."]);
|
|
3295
|
+
await client.execArgs([
|
|
3296
|
+
"commit",
|
|
3297
|
+
"-m",
|
|
3298
|
+
"Migrate historical data from SQLite"
|
|
3299
|
+
]);
|
|
3296
3300
|
} catch (execErr) {
|
|
3297
3301
|
const msg = execErr instanceof Error ? execErr.message : String(execErr);
|
|
3298
3302
|
process.stderr.write(`Warning: Dolt commit failed (non-fatal): ${msg}\n`);
|
package/dist/index.d.ts
CHANGED
|
@@ -1227,6 +1227,11 @@ interface OrchestratorEvents {
|
|
|
1227
1227
|
modifiedInterfaces: string[];
|
|
1228
1228
|
potentiallyAffectedTests: string[];
|
|
1229
1229
|
};
|
|
1230
|
+
/** Dolt merge conflict detected when merging a story branch into main */
|
|
1231
|
+
'pipeline:state-conflict': {
|
|
1232
|
+
storyKey: string;
|
|
1233
|
+
conflict: unknown;
|
|
1234
|
+
};
|
|
1230
1235
|
/** Per-story metrics snapshot emitted when a story reaches a terminal state (Story 24-4) */
|
|
1231
1236
|
'story:metrics': {
|
|
1232
1237
|
storyKey: string;
|
|
@@ -7766,7 +7766,8 @@ var DoltStateStore = class DoltStateStore {
|
|
|
7766
7766
|
const entries = [];
|
|
7767
7767
|
for (const row of rows) {
|
|
7768
7768
|
const hash = String(row.commit_hash ?? "");
|
|
7769
|
-
const
|
|
7769
|
+
const dateVal = row.date;
|
|
7770
|
+
const timestamp = dateVal instanceof Date ? dateVal.toISOString() : String(dateVal ?? "");
|
|
7770
7771
|
const message = String(row.message ?? "");
|
|
7771
7772
|
const author = row.committer ? String(row.committer) : void 0;
|
|
7772
7773
|
const storyKeyMatch = /story\/([0-9]+-[0-9]+)/i.exec(message);
|
|
@@ -9241,7 +9242,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
9241
9242
|
storyKey
|
|
9242
9243
|
}, "mergeStory failed");
|
|
9243
9244
|
});
|
|
9244
|
-
else if (updates.phase === "ESCALATED"
|
|
9245
|
+
else if (updates.phase === "ESCALATED") stateStore?.rollbackStory(storyKey).catch((err) => logger$24.warn({
|
|
9245
9246
|
err,
|
|
9246
9247
|
storyKey
|
|
9247
9248
|
}, "rollbackStory failed — branch may persist"));
|
|
@@ -10733,7 +10734,11 @@ function resolveStoryKeys(db, projectRoot, opts) {
|
|
|
10733
10734
|
const allContent = shardRows.map((r) => r.value).join("\n");
|
|
10734
10735
|
if (allContent.length > 0) keys = parseStoryKeysFromEpics(allContent);
|
|
10735
10736
|
} catch {}
|
|
10736
|
-
if (keys.length === 0) keys = discoverPendingStoryKeys(projectRoot);
|
|
10737
|
+
if (keys.length === 0) keys = discoverPendingStoryKeys(projectRoot, opts?.epicNumber);
|
|
10738
|
+
if (opts?.epicNumber !== void 0 && keys.length > 0) {
|
|
10739
|
+
const prefix = `${opts.epicNumber}-`;
|
|
10740
|
+
keys = keys.filter((k) => k.startsWith(prefix));
|
|
10741
|
+
}
|
|
10737
10742
|
if (opts?.filterCompleted === true && keys.length > 0) {
|
|
10738
10743
|
const completedKeys = getCompletedStoryKeys(db);
|
|
10739
10744
|
keys = keys.filter((k) => !completedKeys.has(k));
|
|
@@ -10781,21 +10786,33 @@ function parseStoryKeysFromEpics(content) {
|
|
|
10781
10786
|
* @param projectRoot - Absolute path to the project root directory
|
|
10782
10787
|
* @returns Sorted array of pending story keys in "N-M" format
|
|
10783
10788
|
*/
|
|
10784
|
-
function discoverPendingStoryKeys(projectRoot) {
|
|
10789
|
+
function discoverPendingStoryKeys(projectRoot, epicNumber) {
|
|
10785
10790
|
let allKeys = [];
|
|
10786
|
-
|
|
10787
|
-
if (epicsPath !== void 0) try {
|
|
10788
|
-
const content = readFileSync$1(epicsPath, "utf-8");
|
|
10789
|
-
allKeys = parseStoryKeysFromEpics(content);
|
|
10790
|
-
} catch {}
|
|
10791
|
-
if (allKeys.length === 0) {
|
|
10791
|
+
if (epicNumber !== void 0) {
|
|
10792
10792
|
const epicFiles = findEpicFiles(projectRoot);
|
|
10793
|
-
|
|
10793
|
+
const targetPattern = new RegExp(`^epic-${epicNumber}[^0-9]`);
|
|
10794
|
+
const matched = epicFiles.filter((f) => targetPattern.test(f.split("/").pop()));
|
|
10795
|
+
for (const epicFile of matched) try {
|
|
10794
10796
|
const content = readFileSync$1(epicFile, "utf-8");
|
|
10795
10797
|
const keys = parseStoryKeysFromEpics(content);
|
|
10796
10798
|
allKeys.push(...keys);
|
|
10797
10799
|
} catch {}
|
|
10798
10800
|
allKeys = sortStoryKeys([...new Set(allKeys)]);
|
|
10801
|
+
} else {
|
|
10802
|
+
const epicsPath = findEpicsFile(projectRoot);
|
|
10803
|
+
if (epicsPath !== void 0) try {
|
|
10804
|
+
const content = readFileSync$1(epicsPath, "utf-8");
|
|
10805
|
+
allKeys = parseStoryKeysFromEpics(content);
|
|
10806
|
+
} catch {}
|
|
10807
|
+
if (allKeys.length === 0) {
|
|
10808
|
+
const epicFiles = findEpicFiles(projectRoot);
|
|
10809
|
+
for (const epicFile of epicFiles) try {
|
|
10810
|
+
const content = readFileSync$1(epicFile, "utf-8");
|
|
10811
|
+
const keys = parseStoryKeysFromEpics(content);
|
|
10812
|
+
allKeys.push(...keys);
|
|
10813
|
+
} catch {}
|
|
10814
|
+
allKeys = sortStoryKeys([...new Set(allKeys)]);
|
|
10815
|
+
}
|
|
10799
10816
|
}
|
|
10800
10817
|
if (allKeys.length === 0) return [];
|
|
10801
10818
|
const existingKeys = collectExistingStoryKeys(projectRoot);
|
|
@@ -14884,7 +14901,7 @@ function mapInternalPhaseToEventPhase(internalPhase) {
|
|
|
14884
14901
|
}
|
|
14885
14902
|
}
|
|
14886
14903
|
async function runRunAction(options) {
|
|
14887
|
-
const { pack: packName, from: startPhase, stopAfter, concept: conceptArg, conceptFile, stories: storiesArg, concurrency, outputFormat, projectRoot, events: eventsFlag, verbose: verboseFlag, tui: tuiFlag, skipUx, research: researchFlag, skipResearch: skipResearchFlag, skipPreflight, registry: injectedRegistry } = options;
|
|
14904
|
+
const { pack: packName, from: startPhase, stopAfter, concept: conceptArg, conceptFile, stories: storiesArg, concurrency, outputFormat, projectRoot, events: eventsFlag, verbose: verboseFlag, tui: tuiFlag, skipUx, research: researchFlag, skipResearch: skipResearchFlag, skipPreflight, epic: epicNumber, registry: injectedRegistry } = options;
|
|
14888
14905
|
if (startPhase !== void 0 && !VALID_PHASES.includes(startPhase)) {
|
|
14889
14906
|
const errorMsg = `Invalid phase '${startPhase}'. Valid phases: ${VALID_PHASES.join(", ")}`;
|
|
14890
14907
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, errorMsg) + "\n");
|
|
@@ -15008,6 +15025,7 @@ async function runRunAction(options) {
|
|
|
15008
15025
|
...researchFlag === true ? { research: true } : {},
|
|
15009
15026
|
...skipResearchFlag === true ? { skipResearch: true } : {},
|
|
15010
15027
|
...skipPreflight === true ? { skipPreflight: true } : {},
|
|
15028
|
+
...epicNumber !== void 0 ? { epic: epicNumber } : {},
|
|
15011
15029
|
...injectedRegistry !== void 0 ? { registry: injectedRegistry } : {}
|
|
15012
15030
|
});
|
|
15013
15031
|
let storyKeys = [...parsedStoryKeys];
|
|
@@ -15056,8 +15074,11 @@ async function runRunAction(options) {
|
|
|
15056
15074
|
storyKeys = storyKeys.filter((k) => !completedStoryKeys.has(k));
|
|
15057
15075
|
}
|
|
15058
15076
|
if (storyKeys.length === 0) {
|
|
15059
|
-
storyKeys = discoverPendingStoryKeys(projectRoot);
|
|
15060
|
-
if (storyKeys.length > 0)
|
|
15077
|
+
storyKeys = discoverPendingStoryKeys(projectRoot, epicNumber);
|
|
15078
|
+
if (storyKeys.length > 0) {
|
|
15079
|
+
const scopeLabel = epicNumber !== void 0 ? `epic ${epicNumber}` : "epics.md";
|
|
15080
|
+
process.stdout.write(`Discovered ${storyKeys.length} pending stories from ${scopeLabel}: ${storyKeys.join(", ")}\n`);
|
|
15081
|
+
}
|
|
15061
15082
|
}
|
|
15062
15083
|
if (storyKeys.length === 0) {
|
|
15063
15084
|
if (outputFormat === "human") process.stdout.write("No pending stories found in decision store.\n");
|
|
@@ -15755,7 +15776,10 @@ async function runFullPipeline(options) {
|
|
|
15755
15776
|
process.stdout.write(` [ESCALATED] ${payload.storyKey}: ${payload.lastVerdict}\n`);
|
|
15756
15777
|
});
|
|
15757
15778
|
}
|
|
15758
|
-
const storyKeys = resolveStoryKeys(db, projectRoot, {
|
|
15779
|
+
const storyKeys = resolveStoryKeys(db, projectRoot, {
|
|
15780
|
+
explicit: explicitStories,
|
|
15781
|
+
epicNumber: options.epic
|
|
15782
|
+
});
|
|
15759
15783
|
if (storyKeys.length === 0 && outputFormat === "human") process.stdout.write("[IMPLEMENTATION] No stories found. Run solutioning first or pass --stories.\n");
|
|
15760
15784
|
if (outputFormat === "human") process.stdout.write(`[IMPLEMENTATION] Starting ${storyKeys.length} stories with concurrency=${concurrency}\n`);
|
|
15761
15785
|
await orchestrator.run(storyKeys);
|
|
@@ -15819,7 +15843,7 @@ async function runFullPipeline(options) {
|
|
|
15819
15843
|
}
|
|
15820
15844
|
}
|
|
15821
15845
|
function registerRunCommand(program, _version = "0.0.0", projectRoot = process.cwd(), registry) {
|
|
15822
|
-
program.command("run").description("Run the autonomous pipeline (use --from to start from a specific phase)").option("--pack <name>", "Methodology pack name", "bmad").option("--from <phase>", "Start from this phase: analysis, planning, solutioning, implementation").option("--stop-after <phase>", "Stop pipeline after this phase completes").option("--concept <text>", "Inline concept text (required when --from analysis)").option("--concept-file <path>", "Path to a file containing the concept text").option("--stories <keys>", "Comma-separated story keys (e.g., 10-1,10-2)").option("--concurrency <n>", "Maximum parallel conflict groups", (v) => parseInt(v, 10), 3).option("--project-root <path>", "Project root directory", projectRoot).option("--output-format <format>", "Output format: human (default) or json", "human").option("--events", "Emit structured NDJSON events on stdout for programmatic consumption").option("--verbose", "Show detailed pino log output").option("--help-agent", "Print a machine-optimized prompt fragment for AI agents and exit").option("--tui", "Show TUI dashboard").option("--skip-ux", "Skip the UX design phase even if enabled in the pack manifest").option("--research", "Enable the research phase even if not set in the pack manifest").option("--skip-research", "Skip the research phase even if enabled in the pack manifest").option("--skip-preflight", "Skip the pre-flight build check (escape hatch for known-broken projects)").action(async (opts) => {
|
|
15846
|
+
program.command("run").description("Run the autonomous pipeline (use --from to start from a specific phase)").option("--pack <name>", "Methodology pack name", "bmad").option("--from <phase>", "Start from this phase: analysis, planning, solutioning, implementation").option("--stop-after <phase>", "Stop pipeline after this phase completes").option("--concept <text>", "Inline concept text (required when --from analysis)").option("--concept-file <path>", "Path to a file containing the concept text").option("--stories <keys>", "Comma-separated story keys (e.g., 10-1,10-2)").option("--epic <n>", "Scope story discovery to a single epic number (e.g., 27)", (v) => parseInt(v, 10)).option("--concurrency <n>", "Maximum parallel conflict groups", (v) => parseInt(v, 10), 3).option("--project-root <path>", "Project root directory", projectRoot).option("--output-format <format>", "Output format: human (default) or json", "human").option("--events", "Emit structured NDJSON events on stdout for programmatic consumption").option("--verbose", "Show detailed pino log output").option("--help-agent", "Print a machine-optimized prompt fragment for AI agents and exit").option("--tui", "Show TUI dashboard").option("--skip-ux", "Skip the UX design phase even if enabled in the pack manifest").option("--research", "Enable the research phase even if not set in the pack manifest").option("--skip-research", "Skip the research phase even if enabled in the pack manifest").option("--skip-preflight", "Skip the pre-flight build check (escape hatch for known-broken projects)").action(async (opts) => {
|
|
15823
15847
|
if (opts.helpAgent) {
|
|
15824
15848
|
process.exitCode = await runHelpAgent();
|
|
15825
15849
|
return;
|
|
@@ -15843,6 +15867,7 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
15843
15867
|
concept: opts.concept,
|
|
15844
15868
|
conceptFile: opts.conceptFile,
|
|
15845
15869
|
stories: opts.stories,
|
|
15870
|
+
epic: opts.epic,
|
|
15846
15871
|
concurrency: opts.concurrency,
|
|
15847
15872
|
outputFormat,
|
|
15848
15873
|
projectRoot: opts.projectRoot,
|
|
@@ -15861,4 +15886,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
15861
15886
|
|
|
15862
15887
|
//#endregion
|
|
15863
15888
|
export { DEFAULT_CONFIG, DEFAULT_ROUTING_POLICY, DatabaseWrapper, DoltNotInstalled, FileStateStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, checkDoltInstalled, createConfigSystem, createContextCompiler, createDispatcher, createDoltClient, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStateStore, createStopAfterGate, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, initializeDolt, parseDbTimestampAsUtc, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveStoryKeys, runAnalysisPhase, runMigrations, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict };
|
|
15864
|
-
//# sourceMappingURL=run-
|
|
15889
|
+
//# sourceMappingURL=run-DNURadtJ.js.map
|