substrate-ai 0.20.16 → 0.20.18
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
|
@@ -4,7 +4,7 @@ import { createLogger } from "../logger-KeHncl-f.js";
|
|
|
4
4
|
import { createEventBus } from "../helpers-CElYrONe.js";
|
|
5
5
|
import { AdapterRegistry, BudgetConfigSchema, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, ConfigError, CostTrackerConfigSchema, DEFAULT_CONFIG, DoltClient, DoltNotInstalled, GlobalSettingsSchema, IngestionServer, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProvidersSchema, RoutingRecommender, STORY_METRICS, TelemetryConfigSchema, addTokenUsage, aggregateTokenUsageForRun, checkDoltInstalled, compareRunMetrics, createAmendmentRun, createConfigSystem, createDecision, createDoltClient, createPipelineRun, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, tagRunAsBaseline, updatePipelineRun } from "../dist-CqtWS9wF.js";
|
|
6
6
|
import "../adapter-registry-DXLMTmfD.js";
|
|
7
|
-
import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-
|
|
7
|
+
import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-DgaY0RP2.js";
|
|
8
8
|
import "../errors-1uLGqnvr.js";
|
|
9
9
|
import "../routing-CcBOCuC9.js";
|
|
10
10
|
import "../decisions-C0pz9Clx.js";
|
|
@@ -5198,7 +5198,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
5198
5198
|
await initSchema(expAdapter);
|
|
5199
5199
|
const { runRunAction: runPipeline } = await import(
|
|
5200
5200
|
/* @vite-ignore */
|
|
5201
|
-
"../run-
|
|
5201
|
+
"../run-Ds4q0vfb.js"
|
|
5202
5202
|
);
|
|
5203
5203
|
const runStoryFn = async (opts) => {
|
|
5204
5204
|
const exitCode = await runPipeline({
|
|
@@ -7,7 +7,7 @@ import { access, readFile, readdir, stat } from "fs/promises";
|
|
|
7
7
|
import { EventEmitter } from "node:events";
|
|
8
8
|
import yaml from "js-yaml";
|
|
9
9
|
import * as actualFS from "node:fs";
|
|
10
|
-
import { accessSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, statSync, unlinkSync, unwatchFile, watchFile, writeFileSync } from "node:fs";
|
|
10
|
+
import { accessSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, unwatchFile, watchFile, writeFileSync } from "node:fs";
|
|
11
11
|
import { exec, execFile, execFileSync, execSync, spawn } from "node:child_process";
|
|
12
12
|
import path, { basename as basename$1, dirname as dirname$1, extname as extname$1, isAbsolute, join as join$1, posix, resolve as resolve$1, win32 } from "node:path";
|
|
13
13
|
import { tmpdir } from "node:os";
|
|
@@ -5968,27 +5968,24 @@ function getEpicShard(decisions, epicId, projectRoot, storyKey) {
|
|
|
5968
5968
|
}
|
|
5969
5969
|
const epicShard = decisions.find((d) => d.category === "epic-shard" && d.key === epicId);
|
|
5970
5970
|
const shardContent = epicShard?.value;
|
|
5971
|
-
if (shardContent) {
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
if (storySection) {
|
|
5975
|
-
logger$18.debug({
|
|
5976
|
-
epicId,
|
|
5977
|
-
storyKey
|
|
5978
|
-
}, "Extracted per-story section from epic shard (pre-37-0 fallback)");
|
|
5979
|
-
return storySection;
|
|
5980
|
-
}
|
|
5971
|
+
if (shardContent && storyKey) {
|
|
5972
|
+
const storySection = extractStorySection(shardContent, storyKey);
|
|
5973
|
+
if (storySection) {
|
|
5981
5974
|
logger$18.debug({
|
|
5982
5975
|
epicId,
|
|
5983
5976
|
storyKey
|
|
5984
|
-
}, "
|
|
5977
|
+
}, "Extracted per-story section from epic shard (pre-37-0 fallback)");
|
|
5978
|
+
return storySection;
|
|
5985
5979
|
}
|
|
5986
|
-
|
|
5980
|
+
logger$18.info({
|
|
5981
|
+
epicId,
|
|
5982
|
+
storyKey
|
|
5983
|
+
}, "Story section absent in decisions-store shard — attempting file-based fallback before returning stale shard");
|
|
5987
5984
|
}
|
|
5988
5985
|
if (projectRoot) {
|
|
5989
5986
|
const fallback = readEpicShardFromFile(projectRoot, epicId);
|
|
5990
5987
|
if (fallback) {
|
|
5991
|
-
logger$18.info({ epicId }, "Using file-based fallback for epic shard
|
|
5988
|
+
logger$18.info({ epicId }, "Using file-based fallback for epic shard");
|
|
5992
5989
|
if (storyKey) {
|
|
5993
5990
|
const storySection = extractStorySection(fallback, storyKey);
|
|
5994
5991
|
if (storySection) {
|
|
@@ -6002,6 +5999,7 @@ function getEpicShard(decisions, epicId, projectRoot, storyKey) {
|
|
|
6002
5999
|
return fallback;
|
|
6003
6000
|
}
|
|
6004
6001
|
}
|
|
6002
|
+
if (shardContent) return shardContent;
|
|
6005
6003
|
return "";
|
|
6006
6004
|
} catch (err) {
|
|
6007
6005
|
logger$18.warn({
|
|
@@ -12034,7 +12032,8 @@ function createImplementationOrchestrator(deps) {
|
|
|
12034
12032
|
const artifactsDir = projectRoot ? join$1(projectRoot, "_bmad-output", "implementation-artifacts") : void 0;
|
|
12035
12033
|
if (artifactsDir && existsSync(artifactsDir)) try {
|
|
12036
12034
|
const files = readdirSync(artifactsDir);
|
|
12037
|
-
const
|
|
12035
|
+
const STALE_SUFFIX = /\.stale-\d+\.md$/;
|
|
12036
|
+
const match$2 = files.find((f$1) => f$1.startsWith(`${storyKey}-`) && f$1.endsWith(".md") && !STALE_SUFFIX.test(f$1));
|
|
12038
12037
|
if (match$2) {
|
|
12039
12038
|
const candidatePath = join$1(artifactsDir, match$2);
|
|
12040
12039
|
const validation = await isValidStoryFile(candidatePath);
|
|
@@ -12089,6 +12088,20 @@ function createImplementationOrchestrator(deps) {
|
|
|
12089
12088
|
}
|
|
12090
12089
|
});
|
|
12091
12090
|
await persistState();
|
|
12091
|
+
} else try {
|
|
12092
|
+
const ts = Date.now();
|
|
12093
|
+
const staleName = match$2.replace(/\.md$/, `.stale-${ts}.md`);
|
|
12094
|
+
const stalePath = join$1(artifactsDir, staleName);
|
|
12095
|
+
renameSync(candidatePath, stalePath);
|
|
12096
|
+
logger$24.info({
|
|
12097
|
+
storyKey,
|
|
12098
|
+
staleName
|
|
12099
|
+
}, `[orchestrator] story ${storyKey}: renamed drifted artifact to ${staleName} before re-dispatch`);
|
|
12100
|
+
} catch (renameErr) {
|
|
12101
|
+
logger$24.warn({
|
|
12102
|
+
storyKey,
|
|
12103
|
+
err: renameErr
|
|
12104
|
+
}, "Failed to rename stale artifact before create-story re-dispatch; relying on 58-9d fraud-guard");
|
|
12092
12105
|
}
|
|
12093
12106
|
}
|
|
12094
12107
|
}
|
|
@@ -14432,8 +14445,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14432
14445
|
let escalated = 0;
|
|
14433
14446
|
let failed = 0;
|
|
14434
14447
|
for (const s$1 of _stories.values()) if (s$1.phase === "COMPLETE") completed++;
|
|
14435
|
-
else if (s$1.phase === "ESCALATED")
|
|
14436
|
-
else escalated++;
|
|
14448
|
+
else if (s$1.phase === "ESCALATED") escalated++;
|
|
14437
14449
|
else if (s$1.phase === "VERIFICATION_FAILED") failed++;
|
|
14438
14450
|
eventBus.emit("orchestrator:complete", {
|
|
14439
14451
|
totalStories: storyKeys.length,
|
|
@@ -43277,11 +43289,11 @@ async function runRunAction(options) {
|
|
|
43277
43289
|
});
|
|
43278
43290
|
process.on("SIGINT", () => {
|
|
43279
43291
|
ingestionServer.stop();
|
|
43280
|
-
process.exit(130);
|
|
43292
|
+
setTimeout(() => process.exit(130), 6e3).unref();
|
|
43281
43293
|
});
|
|
43282
43294
|
process.on("SIGTERM", () => {
|
|
43283
43295
|
ingestionServer.stop();
|
|
43284
|
-
process.exit(143);
|
|
43296
|
+
setTimeout(() => process.exit(143), 6e3).unref();
|
|
43285
43297
|
});
|
|
43286
43298
|
}
|
|
43287
43299
|
if (telemetryPersistence !== void 0) {
|
|
@@ -43435,8 +43447,7 @@ async function runRunAction(options) {
|
|
|
43435
43447
|
const failedKeys = [];
|
|
43436
43448
|
const escalatedKeys = [];
|
|
43437
43449
|
for (const [key, s$1] of Object.entries(status.stories)) if (s$1.phase === "COMPLETE") succeededKeys.push(key);
|
|
43438
|
-
else if (s$1.phase === "ESCALATED")
|
|
43439
|
-
else escalatedKeys.push(key);
|
|
43450
|
+
else if (s$1.phase === "ESCALATED") escalatedKeys.push(key);
|
|
43440
43451
|
else failedKeys.push(key);
|
|
43441
43452
|
try {
|
|
43442
43453
|
const runEndMs = Date.now();
|
|
@@ -43469,7 +43480,7 @@ async function runRunAction(options) {
|
|
|
43469
43480
|
}
|
|
43470
43481
|
try {
|
|
43471
43482
|
const runsDir = join(dbDir, "runs");
|
|
43472
|
-
const terminalStatus = failedKeys.length > 0 ? "failed" : "completed";
|
|
43483
|
+
const terminalStatus = failedKeys.length > 0 || escalatedKeys.length > 0 ? "failed" : "completed";
|
|
43473
43484
|
await RunManifest.open(pipelineRun.id, runsDir).update({ run_status: terminalStatus });
|
|
43474
43485
|
} catch {}
|
|
43475
43486
|
if (progressRenderer !== void 0) progressRenderer.render({
|
|
@@ -43812,11 +43823,11 @@ async function runFullPipeline(options) {
|
|
|
43812
43823
|
});
|
|
43813
43824
|
process.on("SIGINT", () => {
|
|
43814
43825
|
fpIngestionServer.stop();
|
|
43815
|
-
process.exit(130);
|
|
43826
|
+
setTimeout(() => process.exit(130), 6e3).unref();
|
|
43816
43827
|
});
|
|
43817
43828
|
process.on("SIGTERM", () => {
|
|
43818
43829
|
fpIngestionServer.stop();
|
|
43819
|
-
process.exit(143);
|
|
43830
|
+
setTimeout(() => process.exit(143), 6e3).unref();
|
|
43820
43831
|
});
|
|
43821
43832
|
}
|
|
43822
43833
|
const fpTelemetryPersistence = fullTelemetryEnabled ? new AdapterTelemetryPersistence(adapter) : void 0;
|
|
@@ -43880,8 +43891,7 @@ async function runFullPipeline(options) {
|
|
|
43880
43891
|
const implStatus = await orchestrator.run(storyKeys);
|
|
43881
43892
|
if (outputFormat === "human") process.stdout.write("[IMPLEMENTATION] Complete\n");
|
|
43882
43893
|
for (const [key, s$1] of Object.entries(implStatus.stories)) if (s$1.phase === "COMPLETE") fpSucceededKeys.push(key);
|
|
43883
|
-
else if (s$1.phase === "ESCALATED")
|
|
43884
|
-
else fpEscalatedKeys.push(key);
|
|
43894
|
+
else if (s$1.phase === "ESCALATED") fpEscalatedKeys.push(key);
|
|
43885
43895
|
else fpFailedKeys.push(key);
|
|
43886
43896
|
}
|
|
43887
43897
|
if (fullPipelineNdjsonEmitter !== void 0) fullPipelineNdjsonEmitter.emit({
|
|
@@ -44040,4 +44050,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
44040
44050
|
|
|
44041
44051
|
//#endregion
|
|
44042
44052
|
export { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, normalizeGraphSummaryToStatus, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveMaxReviewCycles, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict, wireNdjsonEmitter };
|
|
44043
|
-
//# sourceMappingURL=run-
|
|
44053
|
+
//# sourceMappingURL=run-DgaY0RP2.js.map
|
|
@@ -2,7 +2,7 @@ import "./health-ZGa9E0D2.js";
|
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
3
|
import "./helpers-CElYrONe.js";
|
|
4
4
|
import "./dist-CqtWS9wF.js";
|
|
5
|
-
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-
|
|
5
|
+
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-DgaY0RP2.js";
|
|
6
6
|
import "./routing-CcBOCuC9.js";
|
|
7
7
|
import "./decisions-C0pz9Clx.js";
|
|
8
8
|
|
package/package.json
CHANGED
|
@@ -29,6 +29,24 @@ Using the context above, write a complete, implementation-ready story file for s
|
|
|
29
29
|
Use the title, description, and acceptance criteria from the Story Definition — do NOT substitute
|
|
30
30
|
a different story from the epic scope. The story key, title, and core scope are non-negotiable.
|
|
31
31
|
|
|
32
|
+
## Input Validation (fail-loud)
|
|
33
|
+
|
|
34
|
+
Before anything else, verify the input contains the source Acceptance Criteria for story `{{story_key}}`. Scan `Epic Scope` and `Story Definition` for BOTH:
|
|
35
|
+
|
|
36
|
+
- A heading matching `Story {{story_key}}` (separators: `-`, `.`, `_`, space).
|
|
37
|
+
- An AC-bearing block within that section (`## Acceptance Criteria`, `### Acceptance Criteria`, `**Acceptance Criteria:**`, etc.).
|
|
38
|
+
|
|
39
|
+
If either is missing — shard truncated, context about other stories only — **do not infer, guess, or hallucinate an AC from the story key or domain priors**. A prior substrate session recorded a shape-specific drift exactly here: no source AC for a "graph builder" story → the agent invented a LanceDB+class-based spec, contradicting the author's explicit "plain JSON adjacency list" directive, purely from a trained pattern.
|
|
40
|
+
|
|
41
|
+
Instead, emit immediately per the Output Contract below:
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
result: failure
|
|
45
|
+
error: source-ac-content-missing
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Do NOT write a partial story file. Do NOT paraphrase surrounding context. Do NOT dispatch Write. The orchestrator treats this as terminal — the correct outcome when the input pipeline has degraded.
|
|
49
|
+
|
|
32
50
|
## Instructions
|
|
33
51
|
|
|
34
52
|
1. **Use the Story Definition as your primary input** — it specifies exactly what this story builds. The epic scope provides surrounding context only.
|