substrate-ai 0.2.31 → 0.2.34
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, 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, runAnalysisPhase, runMigrations, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-XNRFAHEx.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";
|
|
@@ -1336,8 +1336,8 @@ async function runStatusAction(options) {
|
|
|
1336
1336
|
});
|
|
1337
1337
|
let pipelineWallClockMs = 0;
|
|
1338
1338
|
try {
|
|
1339
|
-
const createdAt = parseDbTimestampAsUtc(run.created_at);
|
|
1340
|
-
const endTimestamp = run.status === "running" ? new Date() : parseDbTimestampAsUtc(run.updated_at);
|
|
1339
|
+
const createdAt = parseDbTimestampAsUtc(run.created_at ?? "");
|
|
1340
|
+
const endTimestamp = run.status === "running" ? new Date() : parseDbTimestampAsUtc(run.updated_at ?? "");
|
|
1341
1341
|
pipelineWallClockMs = Math.max(0, endTimestamp.getTime() - createdAt.getTime());
|
|
1342
1342
|
} catch {}
|
|
1343
1343
|
const totalReviewCycles = storyMetricsRows.reduce((sum, r) => sum + (r.review_cycles ?? 0), 0);
|
|
@@ -2158,7 +2158,7 @@ function defaultSupervisorDeps() {
|
|
|
2158
2158
|
const dbPath = join(dbRoot, ".substrate", "substrate.db");
|
|
2159
2159
|
cachedDbWrapper = new DatabaseWrapper(dbPath);
|
|
2160
2160
|
}
|
|
2161
|
-
incrementRunRestarts(cachedDbWrapper.
|
|
2161
|
+
incrementRunRestarts(cachedDbWrapper.db, runId);
|
|
2162
2162
|
} catch {
|
|
2163
2163
|
try {
|
|
2164
2164
|
cachedDbWrapper?.close();
|
|
@@ -2585,7 +2585,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
2585
2585
|
const expDb = expDbWrapper.db;
|
|
2586
2586
|
const { runRunAction: runPipeline } = await import(
|
|
2587
2587
|
/* @vite-ignore */
|
|
2588
|
-
"../run-
|
|
2588
|
+
"../run-Cd7sfXzo.js"
|
|
2589
2589
|
);
|
|
2590
2590
|
const runStoryFn = async (opts) => {
|
|
2591
2591
|
const exitCode = await runPipeline({
|
|
@@ -2596,7 +2596,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
2596
2596
|
projectRoot: opts.projectRoot
|
|
2597
2597
|
});
|
|
2598
2598
|
const latestRun = getLatest(expDb);
|
|
2599
|
-
const newRunId = latestRun?.
|
|
2599
|
+
const newRunId = latestRun?.id ?? `experiment-${Date.now()}`;
|
|
2600
2600
|
return {
|
|
2601
2601
|
runId: newRunId,
|
|
2602
2602
|
exitCode
|
|
@@ -971,6 +971,7 @@ function countWords(text) {
|
|
|
971
971
|
}
|
|
972
972
|
/** Default descriptions of what each phase produces for the next phase */
|
|
973
973
|
const NEXT_PHASE_DESCRIPTIONS = {
|
|
974
|
+
research: "Analysis will consume the research findings to evaluate the product concept.",
|
|
974
975
|
analysis: "Planning will consume the product brief to define requirements and user stories.",
|
|
975
976
|
planning: "Solutioning will consume the requirements and user stories to design the technical architecture.",
|
|
976
977
|
solutioning: "Implementation will consume the architecture decisions and story definitions to build the solution.",
|
|
@@ -1326,9 +1327,9 @@ function buildPipelineStatusOutput(run, tokenSummary, decisionsCount, storiesCou
|
|
|
1326
1327
|
decisions_count: decisionsCount,
|
|
1327
1328
|
stories_count: derivedStoriesCount,
|
|
1328
1329
|
stories_completed: derivedStoriesCompleted,
|
|
1329
|
-
last_activity: run.updated_at,
|
|
1330
|
-
staleness_seconds: Math.round((Date.now() - parseDbTimestampAsUtc(run.updated_at).getTime()) / 1e3),
|
|
1331
|
-
last_event_ts: run.updated_at,
|
|
1330
|
+
last_activity: run.updated_at ?? "",
|
|
1331
|
+
staleness_seconds: Math.round((Date.now() - parseDbTimestampAsUtc(run.updated_at ?? "").getTime()) / 1e3),
|
|
1332
|
+
last_event_ts: run.updated_at ?? "",
|
|
1332
1333
|
active_dispatches: activeDispatches,
|
|
1333
1334
|
...storiesSummary !== void 0 ? { stories: storiesSummary } : {}
|
|
1334
1335
|
};
|
|
@@ -3555,7 +3556,7 @@ var DispatcherImpl = class {
|
|
|
3555
3556
|
}
|
|
3556
3557
|
dispatch(request) {
|
|
3557
3558
|
if (this._shuttingDown) {
|
|
3558
|
-
const handle$1 = new MutableDispatchHandle(randomUUID(), "
|
|
3559
|
+
const handle$1 = new MutableDispatchHandle(randomUUID(), "queued", async () => {});
|
|
3559
3560
|
handle$1.status = "failed";
|
|
3560
3561
|
return Object.assign(handle$1, { result: Promise.reject(new DispatcherShuttingDownError()) });
|
|
3561
3562
|
}
|
|
@@ -3966,24 +3967,21 @@ var DispatcherImpl = class {
|
|
|
3966
3967
|
}
|
|
3967
3968
|
}
|
|
3968
3969
|
};
|
|
3969
|
-
/** Default command for the build verification gate */
|
|
3970
|
-
const DEFAULT_VERIFY_COMMAND = "npm run build";
|
|
3971
3970
|
/**
|
|
3972
|
-
* Detect the package manager used in a project
|
|
3971
|
+
* Detect the package manager / build system used in a project.
|
|
3973
3972
|
*
|
|
3974
|
-
*
|
|
3975
|
-
*
|
|
3976
|
-
*
|
|
3977
|
-
*
|
|
3978
|
-
*
|
|
3979
|
-
*
|
|
3973
|
+
* Checks for language-specific markers in priority order:
|
|
3974
|
+
* 1. Node.js lockfiles → corresponding `<pm> run build`
|
|
3975
|
+
* 2. Python markers (pyproject.toml, poetry.lock, setup.py) → skip (no universal build step)
|
|
3976
|
+
* 3. Rust (Cargo.toml) → cargo build
|
|
3977
|
+
* 4. Go (go.mod) → go build ./...
|
|
3978
|
+
* 5. No markers found → skip (empty command)
|
|
3980
3979
|
*
|
|
3981
|
-
*
|
|
3982
|
-
*
|
|
3983
|
-
* real projects.
|
|
3980
|
+
* When a non-Node.js project is detected (or nothing is recognized), the
|
|
3981
|
+
* returned command is '' which causes runBuildVerification() to skip.
|
|
3984
3982
|
*/
|
|
3985
3983
|
function detectPackageManager(projectRoot) {
|
|
3986
|
-
const
|
|
3984
|
+
const nodeCandidates = [
|
|
3987
3985
|
{
|
|
3988
3986
|
file: "pnpm-lock.yaml",
|
|
3989
3987
|
packageManager: "pnpm",
|
|
@@ -4005,15 +4003,27 @@ function detectPackageManager(projectRoot) {
|
|
|
4005
4003
|
command: "npm run build"
|
|
4006
4004
|
}
|
|
4007
4005
|
];
|
|
4008
|
-
|
|
4006
|
+
const nonNodeMarkers = [
|
|
4007
|
+
"pyproject.toml",
|
|
4008
|
+
"poetry.lock",
|
|
4009
|
+
"setup.py",
|
|
4010
|
+
"Cargo.toml",
|
|
4011
|
+
"go.mod"
|
|
4012
|
+
];
|
|
4013
|
+
for (const marker of nonNodeMarkers) if (existsSync$1(join$1(projectRoot, marker))) return {
|
|
4014
|
+
packageManager: "none",
|
|
4015
|
+
lockfile: marker,
|
|
4016
|
+
command: ""
|
|
4017
|
+
};
|
|
4018
|
+
for (const candidate of nodeCandidates) if (existsSync$1(join$1(projectRoot, candidate.file))) return {
|
|
4009
4019
|
packageManager: candidate.packageManager,
|
|
4010
4020
|
lockfile: candidate.file,
|
|
4011
4021
|
command: candidate.command
|
|
4012
4022
|
};
|
|
4013
4023
|
return {
|
|
4014
|
-
packageManager: "
|
|
4024
|
+
packageManager: "none",
|
|
4015
4025
|
lockfile: null,
|
|
4016
|
-
command:
|
|
4026
|
+
command: ""
|
|
4017
4027
|
};
|
|
4018
4028
|
}
|
|
4019
4029
|
/** Default timeout in milliseconds for the build verification gate */
|
|
@@ -4554,11 +4564,11 @@ const TestExpansionResultSchema = z.object({
|
|
|
4554
4564
|
* These match the hardcoded constants previously defined inline in each workflow.
|
|
4555
4565
|
*/
|
|
4556
4566
|
const TOKEN_CEILING_DEFAULTS = {
|
|
4557
|
-
"create-story":
|
|
4558
|
-
"dev-story":
|
|
4567
|
+
"create-story": 1e4,
|
|
4568
|
+
"dev-story": 8e4,
|
|
4559
4569
|
"code-review": 1e5,
|
|
4560
|
-
"test-plan":
|
|
4561
|
-
"test-expansion":
|
|
4570
|
+
"test-plan": 2e4,
|
|
4571
|
+
"test-expansion": 4e4
|
|
4562
4572
|
};
|
|
4563
4573
|
/**
|
|
4564
4574
|
* Resolve the effective token ceiling for a workflow type.
|
|
@@ -7085,7 +7095,7 @@ async function getAutoHealthData(options) {
|
|
|
7085
7095
|
if (runId !== void 0) run = getPipelineRunById(db, runId);
|
|
7086
7096
|
else run = getLatestRun(db);
|
|
7087
7097
|
if (run === void 0) return NO_PIPELINE;
|
|
7088
|
-
const updatedAt = parseDbTimestampAsUtc(run.updated_at);
|
|
7098
|
+
const updatedAt = parseDbTimestampAsUtc(run.updated_at ?? "");
|
|
7089
7099
|
const stalenessSeconds = Math.round((Date.now() - updatedAt.getTime()) / 1e3);
|
|
7090
7100
|
let storyDetails = {};
|
|
7091
7101
|
let active = 0;
|
|
@@ -7123,9 +7133,9 @@ async function getAutoHealthData(options) {
|
|
|
7123
7133
|
verdict,
|
|
7124
7134
|
run_id: run.id,
|
|
7125
7135
|
status: run.status,
|
|
7126
|
-
current_phase: run.current_phase,
|
|
7136
|
+
current_phase: run.current_phase ?? null,
|
|
7127
7137
|
staleness_seconds: stalenessSeconds,
|
|
7128
|
-
last_activity: run.updated_at,
|
|
7138
|
+
last_activity: run.updated_at ?? "",
|
|
7129
7139
|
process: processInfo,
|
|
7130
7140
|
stories: {
|
|
7131
7141
|
active,
|
|
@@ -8059,7 +8069,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
8059
8069
|
token_usage_json: serialized
|
|
8060
8070
|
});
|
|
8061
8071
|
} catch (err) {
|
|
8062
|
-
logger$23.warn("Failed to persist orchestrator state"
|
|
8072
|
+
logger$23.warn({ err }, "Failed to persist orchestrator state");
|
|
8063
8073
|
}
|
|
8064
8074
|
}
|
|
8065
8075
|
function recordProgress() {
|
|
@@ -8180,7 +8190,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
8180
8190
|
* exhausted retries the story is ESCALATED.
|
|
8181
8191
|
*/
|
|
8182
8192
|
async function processStory(storyKey) {
|
|
8183
|
-
logger$23.info("Processing story"
|
|
8193
|
+
logger$23.info({ storyKey }, "Processing story");
|
|
8184
8194
|
{
|
|
8185
8195
|
const memoryOk = await checkMemoryPressure(storyKey);
|
|
8186
8196
|
if (!memoryOk) {
|
|
@@ -8363,7 +8373,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
8363
8373
|
}, {
|
|
8364
8374
|
storyKey,
|
|
8365
8375
|
storyFilePath: storyFilePath ?? "",
|
|
8366
|
-
pipelineRunId: config.pipelineRunId
|
|
8376
|
+
pipelineRunId: config.pipelineRunId ?? ""
|
|
8367
8377
|
});
|
|
8368
8378
|
testPlanPhaseResult = testPlanResult.result;
|
|
8369
8379
|
if (testPlanResult.result === "success") logger$23.info({ storyKey }, "Test plan generated successfully");
|
|
@@ -8528,11 +8538,11 @@ function createImplementationOrchestrator(deps) {
|
|
|
8528
8538
|
});
|
|
8529
8539
|
persistState();
|
|
8530
8540
|
if (devResult.result === "success") devStoryWasSuccess = true;
|
|
8531
|
-
else logger$23.warn(
|
|
8541
|
+
else logger$23.warn({
|
|
8532
8542
|
storyKey,
|
|
8533
8543
|
error: devResult.error,
|
|
8534
8544
|
filesModified: devFilesModified.length
|
|
8535
|
-
});
|
|
8545
|
+
}, "Dev-story reported failure, proceeding to code review");
|
|
8536
8546
|
}
|
|
8537
8547
|
} catch (err) {
|
|
8538
8548
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -8580,7 +8590,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
8580
8590
|
}
|
|
8581
8591
|
endPhase(storyKey, "dev-story");
|
|
8582
8592
|
{
|
|
8583
|
-
const buildVerifyResult = runBuildVerification({
|
|
8593
|
+
const buildVerifyResult = config.skipBuildVerify === true ? { status: "skipped" } : runBuildVerification({
|
|
8584
8594
|
verifyCommand: pack.manifest.verifyCommand,
|
|
8585
8595
|
verifyTimeoutMs: pack.manifest.verifyTimeoutMs,
|
|
8586
8596
|
projectRoot: projectRoot ?? process.cwd()
|
|
@@ -8954,7 +8964,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
8954
8964
|
fixPrompt = assembled.prompt;
|
|
8955
8965
|
} catch {
|
|
8956
8966
|
fixPrompt = `Fix story ${storyKey}: verdict=${verdict}, minor fixes needed`;
|
|
8957
|
-
logger$23.warn("Failed to assemble auto-approve fix prompt, using fallback"
|
|
8967
|
+
logger$23.warn({ storyKey }, "Failed to assemble auto-approve fix prompt, using fallback");
|
|
8958
8968
|
}
|
|
8959
8969
|
const handle = dispatcher.dispatch({
|
|
8960
8970
|
prompt: fixPrompt,
|
|
@@ -8972,12 +8982,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
8972
8982
|
output: fixResult.tokenEstimate.output
|
|
8973
8983
|
} : void 0 }
|
|
8974
8984
|
});
|
|
8975
|
-
if (fixResult.status === "timeout") logger$23.warn("Auto-approve fix timed out — approving anyway (issues were minor)"
|
|
8985
|
+
if (fixResult.status === "timeout") logger$23.warn({ storyKey }, "Auto-approve fix timed out — approving anyway (issues were minor)");
|
|
8976
8986
|
} catch (err) {
|
|
8977
|
-
logger$23.warn(
|
|
8987
|
+
logger$23.warn({
|
|
8978
8988
|
storyKey,
|
|
8979
8989
|
err
|
|
8980
|
-
});
|
|
8990
|
+
}, "Auto-approve fix dispatch failed — approving anyway (issues were minor)");
|
|
8981
8991
|
}
|
|
8982
8992
|
endPhase(storyKey, "code-review");
|
|
8983
8993
|
updateStory(storyKey, {
|
|
@@ -9091,10 +9101,10 @@ function createImplementationOrchestrator(deps) {
|
|
|
9091
9101
|
fixPrompt = assembled.prompt;
|
|
9092
9102
|
} catch {
|
|
9093
9103
|
fixPrompt = `Fix story ${storyKey}: verdict=${verdict}, taskType=${taskType}`;
|
|
9094
|
-
logger$23.warn(
|
|
9104
|
+
logger$23.warn({
|
|
9095
9105
|
storyKey,
|
|
9096
9106
|
taskType
|
|
9097
|
-
});
|
|
9107
|
+
}, "Failed to assemble fix prompt, using fallback");
|
|
9098
9108
|
}
|
|
9099
9109
|
incrementDispatches(storyKey);
|
|
9100
9110
|
const handle = isMajorRework ? dispatcher.dispatch({
|
|
@@ -9123,10 +9133,10 @@ function createImplementationOrchestrator(deps) {
|
|
|
9123
9133
|
} : void 0 }
|
|
9124
9134
|
});
|
|
9125
9135
|
if (fixResult.status === "timeout") {
|
|
9126
|
-
logger$23.warn(
|
|
9136
|
+
logger$23.warn({
|
|
9127
9137
|
storyKey,
|
|
9128
9138
|
taskType
|
|
9129
|
-
});
|
|
9139
|
+
}, "Fix dispatch timed out — escalating story");
|
|
9130
9140
|
endPhase(storyKey, "code-review");
|
|
9131
9141
|
updateStory(storyKey, {
|
|
9132
9142
|
phase: "ESCALATED",
|
|
@@ -9145,10 +9155,10 @@ function createImplementationOrchestrator(deps) {
|
|
|
9145
9155
|
}
|
|
9146
9156
|
if (fixResult.status === "failed") {
|
|
9147
9157
|
if (isMajorRework) {
|
|
9148
|
-
logger$23.warn(
|
|
9158
|
+
logger$23.warn({
|
|
9149
9159
|
storyKey,
|
|
9150
9160
|
exitCode: fixResult.exitCode
|
|
9151
|
-
});
|
|
9161
|
+
}, "Major rework dispatch failed — escalating story");
|
|
9152
9162
|
endPhase(storyKey, "code-review");
|
|
9153
9163
|
updateStory(storyKey, {
|
|
9154
9164
|
phase: "ESCALATED",
|
|
@@ -9165,18 +9175,18 @@ function createImplementationOrchestrator(deps) {
|
|
|
9165
9175
|
persistState();
|
|
9166
9176
|
return;
|
|
9167
9177
|
}
|
|
9168
|
-
logger$23.warn(
|
|
9178
|
+
logger$23.warn({
|
|
9169
9179
|
storyKey,
|
|
9170
9180
|
taskType,
|
|
9171
9181
|
exitCode: fixResult.exitCode
|
|
9172
|
-
});
|
|
9182
|
+
}, "Fix dispatch failed");
|
|
9173
9183
|
}
|
|
9174
9184
|
} catch (err) {
|
|
9175
|
-
logger$23.warn(
|
|
9185
|
+
logger$23.warn({
|
|
9176
9186
|
storyKey,
|
|
9177
9187
|
taskType,
|
|
9178
9188
|
err
|
|
9179
|
-
});
|
|
9189
|
+
}, "Fix dispatch failed, continuing to next review");
|
|
9180
9190
|
}
|
|
9181
9191
|
previousIssueList = issueList.map((issue) => {
|
|
9182
9192
|
const iss = issue;
|
|
@@ -9235,11 +9245,11 @@ function createImplementationOrchestrator(deps) {
|
|
|
9235
9245
|
}
|
|
9236
9246
|
async function run(storyKeys) {
|
|
9237
9247
|
if (_state === "RUNNING" || _state === "PAUSED") {
|
|
9238
|
-
logger$23.warn("run() called while orchestrator is already running or paused — ignoring"
|
|
9248
|
+
logger$23.warn({ state: _state }, "run() called while orchestrator is already running or paused — ignoring");
|
|
9239
9249
|
return getStatus();
|
|
9240
9250
|
}
|
|
9241
9251
|
if (_state === "COMPLETE") {
|
|
9242
|
-
logger$23.warn("run() called on a COMPLETE orchestrator — ignoring"
|
|
9252
|
+
logger$23.warn({ state: _state }, "run() called on a COMPLETE orchestrator — ignoring");
|
|
9243
9253
|
return getStatus();
|
|
9244
9254
|
}
|
|
9245
9255
|
_state = "RUNNING";
|
|
@@ -9287,12 +9297,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
9287
9297
|
contractEdges,
|
|
9288
9298
|
edgeCount: contractEdges.length
|
|
9289
9299
|
}, "Contract dependency edges detected — applying contract-aware dispatch ordering");
|
|
9290
|
-
logger$23.info(
|
|
9300
|
+
logger$23.info({
|
|
9291
9301
|
storyCount: storyKeys.length,
|
|
9292
9302
|
groupCount: batches.reduce((sum, b) => sum + b.length, 0),
|
|
9293
9303
|
batchCount: batches.length,
|
|
9294
9304
|
maxConcurrency: config.maxConcurrency
|
|
9295
|
-
});
|
|
9305
|
+
}, "Orchestrator starting");
|
|
9296
9306
|
if (config.skipPreflight !== true) {
|
|
9297
9307
|
const preFlightResult = runBuildVerification({
|
|
9298
9308
|
verifyCommand: pack.manifest.verifyCommand,
|
|
@@ -9325,7 +9335,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
9325
9335
|
_state = "FAILED";
|
|
9326
9336
|
_completedAt = new Date().toISOString();
|
|
9327
9337
|
persistState();
|
|
9328
|
-
logger$23.error("Orchestrator failed with unhandled error"
|
|
9338
|
+
logger$23.error({ err }, "Orchestrator failed with unhandled error");
|
|
9329
9339
|
return getStatus();
|
|
9330
9340
|
}
|
|
9331
9341
|
stopHeartbeat();
|
|
@@ -9467,15 +9477,14 @@ function collectExistingStoryKeys(projectRoot) {
|
|
|
9467
9477
|
if (!existsSync$1(artifactsDir)) return existing;
|
|
9468
9478
|
let entries;
|
|
9469
9479
|
try {
|
|
9470
|
-
entries = readdirSync$1(artifactsDir);
|
|
9480
|
+
entries = readdirSync$1(artifactsDir, { encoding: "utf-8" });
|
|
9471
9481
|
} catch {
|
|
9472
9482
|
return existing;
|
|
9473
9483
|
}
|
|
9474
9484
|
const filePattern = /^(\d+-\d+)-/;
|
|
9475
9485
|
for (const entry of entries) {
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
const m = filePattern.exec(name);
|
|
9486
|
+
if (!entry.endsWith(".md")) continue;
|
|
9487
|
+
const m = filePattern.exec(entry);
|
|
9479
9488
|
if (m !== null && m[1] !== void 0) existing.add(m[1]);
|
|
9480
9489
|
}
|
|
9481
9490
|
return existing;
|
|
@@ -13941,7 +13950,7 @@ async function runRunAction(options) {
|
|
|
13941
13950
|
else failedKeys.push(key);
|
|
13942
13951
|
try {
|
|
13943
13952
|
const runEndMs = Date.now();
|
|
13944
|
-
const runStartMs = parseDbTimestampAsUtc(pipelineRun.created_at).getTime();
|
|
13953
|
+
const runStartMs = parseDbTimestampAsUtc(pipelineRun.created_at ?? "").getTime();
|
|
13945
13954
|
const tokenAgg = aggregateTokenUsageForRun(db, pipelineRun.id);
|
|
13946
13955
|
const storyMetrics = getStoryMetricsForRun(db, pipelineRun.id);
|
|
13947
13956
|
const totalReviewCycles = storyMetrics.reduce((sum, m) => sum + (m.review_cycles ?? 0), 0);
|
|
@@ -13950,7 +13959,7 @@ async function runRunAction(options) {
|
|
|
13950
13959
|
run_id: pipelineRun.id,
|
|
13951
13960
|
methodology: pack.manifest.name,
|
|
13952
13961
|
status: failedKeys.length > 0 || escalatedKeys.length > 0 ? "failed" : "completed",
|
|
13953
|
-
started_at: pipelineRun.created_at,
|
|
13962
|
+
started_at: pipelineRun.created_at ?? "",
|
|
13954
13963
|
completed_at: new Date().toISOString(),
|
|
13955
13964
|
wall_clock_seconds: Math.round((runEndMs - runStartMs) / 1e3),
|
|
13956
13965
|
total_input_tokens: tokenAgg.input,
|
|
@@ -14368,4 +14377,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
14368
14377
|
|
|
14369
14378
|
//#endregion
|
|
14370
14379
|
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, runAnalysisPhase, runMigrations, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict };
|
|
14371
|
-
//# sourceMappingURL=run-
|
|
14380
|
+
//# sourceMappingURL=run-XNRFAHEx.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "substrate-ai",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.34",
|
|
4
4
|
"description": "Substrate — multi-agent orchestration daemon for AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,6 +47,8 @@
|
|
|
47
47
|
"postbuild": "cp -r src/cli/templates dist/cli/templates",
|
|
48
48
|
"dev": "tsx watch src/cli/index.ts",
|
|
49
49
|
"test": "vitest run --coverage",
|
|
50
|
+
"test:fast": "vitest run --exclude 'src/__tests__/e2e/**' --exclude '**/*integration*' --exclude '**/*e2e*'",
|
|
51
|
+
"test:changed": "vitest run --changed",
|
|
50
52
|
"test:watch": "vitest",
|
|
51
53
|
"test:ui": "vitest --ui",
|
|
52
54
|
"lint": "eslint src test",
|
|
@@ -54,6 +56,7 @@
|
|
|
54
56
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
55
57
|
"format:check": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
56
58
|
"typecheck": "tsc --noEmit",
|
|
59
|
+
"typecheck:gate": "tsc --noEmit -p tsconfig.typecheck.json",
|
|
57
60
|
"clean": "rm -rf dist",
|
|
58
61
|
"substrate:dev": "node dist/cli/index.js"
|
|
59
62
|
},
|