substrate-ai 0.2.21 → 0.2.23
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 +15 -19
- package/dist/{event-bus-BMxhfxfT.js → errors-CswS7Mzg.js} +93 -715
- package/dist/event-bus-CAvDMst7.js +734 -0
- package/dist/index.js +2 -2
- package/dist/{run-BLIgARum.js → run-BaAws8IQ.js} +180 -39
- package/dist/run-BenC8JuM.js +7 -0
- package/package.json +1 -1
- package/dist/errors-BPqtzQ4U.js +0 -111
- package/dist/run-gmS6DsGT.js +0 -7
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { childLogger, createLogger, logger } from "./logger-D2fS2ccL.js";
|
|
2
|
-
import { AdapterRegistry, ClaudeCodeAdapter, CodexCLIAdapter, GeminiCLIAdapter,
|
|
3
|
-
import {
|
|
2
|
+
import { AdapterRegistry, AdtError, BudgetExceededError, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, GeminiCLIAdapter, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-CswS7Mzg.js";
|
|
3
|
+
import { createEventBus, createTuiApp, isTuiCapable, printNonTtyWarning } from "./event-bus-CAvDMst7.js";
|
|
4
4
|
import { randomUUID } from "crypto";
|
|
5
5
|
|
|
6
6
|
//#region src/utils/helpers.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createLogger } from "./logger-D2fS2ccL.js";
|
|
2
|
-
import {
|
|
2
|
+
import { createEventBus, createTuiApp, isTuiCapable, printNonTtyWarning } from "./event-bus-CAvDMst7.js";
|
|
3
3
|
import { addTokenUsage, createDecision, createPipelineRun, createRequirement, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunningPipelineRuns, getTokenUsageSummary, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision } from "./decisions-Dq4cAA2L.js";
|
|
4
4
|
import { ESCALATION_DIAGNOSIS, OPERATIONAL_FINDING, STORY_METRICS, STORY_OUTCOME, TEST_EXPANSION_FINDING, TEST_PLAN, aggregateTokenUsageForRun, aggregateTokenUsageForStory, getStoryMetricsForRun, writeRunMetrics, writeStoryMetrics } from "./operational-CnMlvWqc.js";
|
|
5
5
|
import { createRequire } from "module";
|
|
@@ -15,7 +15,7 @@ import BetterSqlite3 from "better-sqlite3";
|
|
|
15
15
|
import { fileURLToPath } from "node:url";
|
|
16
16
|
import { existsSync as existsSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1 } from "node:fs";
|
|
17
17
|
import { freemem, platform } from "node:os";
|
|
18
|
-
import { randomUUID } from "node:crypto";
|
|
18
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
19
19
|
import { readFile as readFile$1, stat as stat$1 } from "node:fs/promises";
|
|
20
20
|
|
|
21
21
|
//#region rolldown:runtime
|
|
@@ -3868,7 +3868,7 @@ async function runCreateStory(deps, params) {
|
|
|
3868
3868
|
};
|
|
3869
3869
|
}
|
|
3870
3870
|
const implementationDecisions = getImplementationDecisions(deps);
|
|
3871
|
-
const epicShardContent = getEpicShard(implementationDecisions, epicId, deps.projectRoot);
|
|
3871
|
+
const epicShardContent = getEpicShard(implementationDecisions, epicId, deps.projectRoot, storyKey);
|
|
3872
3872
|
const prevDevNotesContent = getPrevDevNotes(implementationDecisions, epicId);
|
|
3873
3873
|
const archConstraintsContent = getArchConstraints$2(deps);
|
|
3874
3874
|
const storyTemplateContent = await getStoryTemplate(deps);
|
|
@@ -4018,18 +4018,71 @@ function getImplementationDecisions(deps) {
|
|
|
4018
4018
|
}
|
|
4019
4019
|
}
|
|
4020
4020
|
/**
|
|
4021
|
+
* Extract the section for a specific story key from a full epic shard.
|
|
4022
|
+
*
|
|
4023
|
+
* Matches patterns like:
|
|
4024
|
+
* - "Story 23-1:" / "### Story 23-1" / "#### Story 23-1"
|
|
4025
|
+
* - "23-1:" / "**23-1**"
|
|
4026
|
+
*
|
|
4027
|
+
* Returns the matched section content (from heading to next story heading or end),
|
|
4028
|
+
* or null if no matching section is found (caller falls back to full shard).
|
|
4029
|
+
*/
|
|
4030
|
+
function extractStorySection(shardContent, storyKey) {
|
|
4031
|
+
if (!shardContent || !storyKey) return null;
|
|
4032
|
+
const escaped = storyKey.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4033
|
+
const headingPattern = new RegExp(`(?:^#{2,4}\\s+Story\\s+${escaped}\\b|^Story\\s+${escaped}:|^\\*\\*${escaped}\\*\\*|^${escaped}:)`, "mi");
|
|
4034
|
+
const match = headingPattern.exec(shardContent);
|
|
4035
|
+
if (!match) return null;
|
|
4036
|
+
const startIdx = match.index;
|
|
4037
|
+
const rest = shardContent.slice(startIdx + match[0].length);
|
|
4038
|
+
const nextStoryPattern = new RegExp(`(?:^#{2,4}\\s+Story\\s+[\\d]|^Story\\s+[\\d][\\d-]*:|^\\*\\*[\\d][\\d-]*\\*\\*|^[\\d][\\d-]*:)`, "mi");
|
|
4039
|
+
const nextMatch = nextStoryPattern.exec(rest);
|
|
4040
|
+
const endIdx = nextMatch !== null ? startIdx + match[0].length + nextMatch.index : shardContent.length;
|
|
4041
|
+
const section = shardContent.slice(startIdx, endIdx).trim();
|
|
4042
|
+
return section.length > 0 ? section : null;
|
|
4043
|
+
}
|
|
4044
|
+
/**
|
|
4021
4045
|
* Retrieve the epic shard from the pre-fetched implementation decisions.
|
|
4022
4046
|
* Looks for decisions with category='epic-shard', key=epicId.
|
|
4023
4047
|
* Falls back to reading _bmad-output/epics.md on disk if decisions are empty.
|
|
4048
|
+
*
|
|
4049
|
+
* When storyKey is provided, extracts only the section for that story (AC3).
|
|
4024
4050
|
*/
|
|
4025
|
-
function getEpicShard(decisions, epicId, projectRoot) {
|
|
4051
|
+
function getEpicShard(decisions, epicId, projectRoot, storyKey) {
|
|
4026
4052
|
try {
|
|
4027
4053
|
const epicShard = decisions.find((d) => d.category === "epic-shard" && d.key === epicId);
|
|
4028
|
-
|
|
4054
|
+
const shardContent = epicShard?.value;
|
|
4055
|
+
if (shardContent) {
|
|
4056
|
+
if (storyKey) {
|
|
4057
|
+
const storySection = extractStorySection(shardContent, storyKey);
|
|
4058
|
+
if (storySection) {
|
|
4059
|
+
logger$14.debug({
|
|
4060
|
+
epicId,
|
|
4061
|
+
storyKey
|
|
4062
|
+
}, "Extracted per-story section from epic shard");
|
|
4063
|
+
return storySection;
|
|
4064
|
+
}
|
|
4065
|
+
logger$14.debug({
|
|
4066
|
+
epicId,
|
|
4067
|
+
storyKey
|
|
4068
|
+
}, "No matching story section found — using full epic shard");
|
|
4069
|
+
}
|
|
4070
|
+
return shardContent;
|
|
4071
|
+
}
|
|
4029
4072
|
if (projectRoot) {
|
|
4030
4073
|
const fallback = readEpicShardFromFile(projectRoot, epicId);
|
|
4031
4074
|
if (fallback) {
|
|
4032
4075
|
logger$14.info({ epicId }, "Using file-based fallback for epic shard (decisions table empty)");
|
|
4076
|
+
if (storyKey) {
|
|
4077
|
+
const storySection = extractStorySection(fallback, storyKey);
|
|
4078
|
+
if (storySection) {
|
|
4079
|
+
logger$14.debug({
|
|
4080
|
+
epicId,
|
|
4081
|
+
storyKey
|
|
4082
|
+
}, "Extracted per-story section from file-based epic shard");
|
|
4083
|
+
return storySection;
|
|
4084
|
+
}
|
|
4085
|
+
}
|
|
4033
4086
|
return fallback;
|
|
4034
4087
|
}
|
|
4035
4088
|
}
|
|
@@ -4094,7 +4147,7 @@ function readEpicShardFromFile(projectRoot, epicId) {
|
|
|
4094
4147
|
if (!epicsPath) return "";
|
|
4095
4148
|
const content = readFileSync$1(epicsPath, "utf-8");
|
|
4096
4149
|
const epicNum = epicId.replace(/^epic-/i, "");
|
|
4097
|
-
const pattern = new RegExp(
|
|
4150
|
+
const pattern = new RegExp(`^#{2,4}\\s+(?:Epic\\s+)?${epicNum}[.:\\s].*?(?=\\n#{2,4}\\s|$)`, "ms");
|
|
4098
4151
|
const match = pattern.exec(content);
|
|
4099
4152
|
return match ? match[0].trim() : "";
|
|
4100
4153
|
} catch (err) {
|
|
@@ -4138,6 +4191,36 @@ async function getStoryTemplate(deps) {
|
|
|
4138
4191
|
return "";
|
|
4139
4192
|
}
|
|
4140
4193
|
}
|
|
4194
|
+
/**
|
|
4195
|
+
* Validate that an existing story file is non-empty and structurally valid.
|
|
4196
|
+
*
|
|
4197
|
+
* A valid story file must:
|
|
4198
|
+
* 1. Be non-empty (> 0 bytes after trim)
|
|
4199
|
+
* 2. Contain at least one heading (`#`) AND either "Acceptance Criteria" or "AC1"
|
|
4200
|
+
*
|
|
4201
|
+
* @returns `{ valid: true }` or `{ valid: false, reason: 'empty' | 'missing_structure' }`
|
|
4202
|
+
*/
|
|
4203
|
+
async function isValidStoryFile(filePath) {
|
|
4204
|
+
try {
|
|
4205
|
+
const content = await readFile$1(filePath, "utf-8");
|
|
4206
|
+
if (content.trim().length === 0) return {
|
|
4207
|
+
valid: false,
|
|
4208
|
+
reason: "empty"
|
|
4209
|
+
};
|
|
4210
|
+
const hasHeading = content.includes("#");
|
|
4211
|
+
const hasAC = /acceptance criteria|AC1/i.test(content);
|
|
4212
|
+
if (!hasHeading || !hasAC) return {
|
|
4213
|
+
valid: false,
|
|
4214
|
+
reason: "missing_structure"
|
|
4215
|
+
};
|
|
4216
|
+
return { valid: true };
|
|
4217
|
+
} catch {
|
|
4218
|
+
return {
|
|
4219
|
+
valid: false,
|
|
4220
|
+
reason: "empty"
|
|
4221
|
+
};
|
|
4222
|
+
}
|
|
4223
|
+
}
|
|
4141
4224
|
|
|
4142
4225
|
//#endregion
|
|
4143
4226
|
//#region src/modules/compiled-workflows/git-helpers.ts
|
|
@@ -4235,11 +4318,17 @@ async function getGitChangedFiles(workingDirectory = process.cwd()) {
|
|
|
4235
4318
|
*/
|
|
4236
4319
|
async function stageIntentToAdd(files, workingDirectory) {
|
|
4237
4320
|
if (files.length === 0) return;
|
|
4321
|
+
const existing = files.filter((f) => {
|
|
4322
|
+
const exists = existsSync$1(f);
|
|
4323
|
+
if (!exists) logger$13.debug({ file: f }, "Skipping nonexistent file in stageIntentToAdd");
|
|
4324
|
+
return exists;
|
|
4325
|
+
});
|
|
4326
|
+
if (existing.length === 0) return;
|
|
4238
4327
|
await runGitCommand([
|
|
4239
4328
|
"add",
|
|
4240
4329
|
"-N",
|
|
4241
4330
|
"--",
|
|
4242
|
-
...
|
|
4331
|
+
...existing
|
|
4243
4332
|
], workingDirectory, "git-add-intent");
|
|
4244
4333
|
}
|
|
4245
4334
|
/**
|
|
@@ -4816,6 +4905,7 @@ function defaultFailResult(error, tokenUsage) {
|
|
|
4816
4905
|
issues: 0,
|
|
4817
4906
|
issue_list: [],
|
|
4818
4907
|
error,
|
|
4908
|
+
dispatchFailed: true,
|
|
4819
4909
|
tokenUsage
|
|
4820
4910
|
};
|
|
4821
4911
|
}
|
|
@@ -4908,6 +4998,19 @@ async function runCodeReview(deps, params) {
|
|
|
4908
4998
|
gitDiffContent = await getGitDiffStatSummary(cwd);
|
|
4909
4999
|
}
|
|
4910
5000
|
}
|
|
5001
|
+
if (gitDiffContent.trim().length === 0) {
|
|
5002
|
+
logger$10.info({ storyKey }, "Empty git diff — skipping review with SHIP_IT");
|
|
5003
|
+
return {
|
|
5004
|
+
verdict: "SHIP_IT",
|
|
5005
|
+
issues: 0,
|
|
5006
|
+
issue_list: [],
|
|
5007
|
+
notes: "no_changes_to_review",
|
|
5008
|
+
tokenUsage: {
|
|
5009
|
+
input: 0,
|
|
5010
|
+
output: 0
|
|
5011
|
+
}
|
|
5012
|
+
};
|
|
5013
|
+
}
|
|
4911
5014
|
let previousFindingsContent = "";
|
|
4912
5015
|
if (previousIssues !== void 0 && previousIssues.length > 0) previousFindingsContent = [
|
|
4913
5016
|
"The previous code review found these issues. A fix agent has attempted to resolve them.",
|
|
@@ -5787,8 +5890,8 @@ function detectConflictGroups(storyKeys, config) {
|
|
|
5787
5890
|
const logger$7 = createLogger("implementation-orchestrator:seed");
|
|
5788
5891
|
/** Max chars for the architecture summary seeded into decisions */
|
|
5789
5892
|
const MAX_ARCH_CHARS = 6e3;
|
|
5790
|
-
/** Max chars per epic shard */
|
|
5791
|
-
const MAX_EPIC_SHARD_CHARS =
|
|
5893
|
+
/** Max chars per epic shard (fallback when per-story extraction returns null) */
|
|
5894
|
+
const MAX_EPIC_SHARD_CHARS = 12e3;
|
|
5792
5895
|
/** Max chars for test patterns */
|
|
5793
5896
|
const MAX_TEST_PATTERNS_CHARS = 2e3;
|
|
5794
5897
|
/**
|
|
@@ -5872,16 +5975,35 @@ function seedArchitecture(db, projectRoot) {
|
|
|
5872
5975
|
}
|
|
5873
5976
|
/**
|
|
5874
5977
|
* Seed epic shards from epics.md.
|
|
5875
|
-
* Parses each
|
|
5876
|
-
*
|
|
5978
|
+
* Parses each epic section and creates an implementation/epic-shard decision.
|
|
5979
|
+
*
|
|
5980
|
+
* Uses content-hash comparison (AC1, AC2, AC6):
|
|
5981
|
+
* - Computes SHA-256 of the epics file and compares to the stored `epic-shard-hash` decision.
|
|
5982
|
+
* - If hashes match: skip re-seeding (unchanged file).
|
|
5983
|
+
* - If hash differs or no hash stored: delete existing epic-shard decisions and re-seed.
|
|
5984
|
+
*
|
|
5985
|
+
* Returns number of decisions created, or -1 if skipped (hash unchanged).
|
|
5877
5986
|
*/
|
|
5878
5987
|
function seedEpicShards(db, projectRoot) {
|
|
5879
|
-
const existing = getDecisionsByPhase(db, "implementation");
|
|
5880
|
-
if (existing.some((d) => d.category === "epic-shard")) return -1;
|
|
5881
5988
|
const epicsPath = findArtifact(projectRoot, ["_bmad-output/planning-artifacts/epics.md", "_bmad-output/epics.md"]);
|
|
5882
5989
|
if (epicsPath === void 0) return 0;
|
|
5883
5990
|
const content = readFileSync$1(epicsPath, "utf-8");
|
|
5884
5991
|
if (content.length === 0) return 0;
|
|
5992
|
+
const currentHash = createHash("sha256").update(content).digest("hex");
|
|
5993
|
+
const implementationDecisions = getDecisionsByPhase(db, "implementation");
|
|
5994
|
+
const storedHashDecision = implementationDecisions.find((d) => d.category === "epic-shard-hash" && d.key === "epics-file");
|
|
5995
|
+
const storedHash = storedHashDecision?.value;
|
|
5996
|
+
if (storedHash === currentHash) {
|
|
5997
|
+
logger$7.debug({ hash: currentHash }, "Epic shards up-to-date (hash unchanged) — skipping re-seed");
|
|
5998
|
+
return -1;
|
|
5999
|
+
}
|
|
6000
|
+
if (implementationDecisions.some((d) => d.category === "epic-shard")) {
|
|
6001
|
+
logger$7.debug({
|
|
6002
|
+
storedHash,
|
|
6003
|
+
currentHash
|
|
6004
|
+
}, "Epics file changed — deleting stale epic-shard decisions");
|
|
6005
|
+
db.prepare("DELETE FROM decisions WHERE phase = 'implementation' AND category = 'epic-shard'").run();
|
|
6006
|
+
}
|
|
5885
6007
|
const shards = parseEpicShards(content);
|
|
5886
6008
|
let count = 0;
|
|
5887
6009
|
for (const shard of shards) {
|
|
@@ -5895,7 +6017,19 @@ function seedEpicShards(db, projectRoot) {
|
|
|
5895
6017
|
});
|
|
5896
6018
|
count++;
|
|
5897
6019
|
}
|
|
5898
|
-
|
|
6020
|
+
db.prepare("DELETE FROM decisions WHERE phase = 'implementation' AND category = 'epic-shard-hash' AND key = 'epics-file'").run();
|
|
6021
|
+
createDecision(db, {
|
|
6022
|
+
pipeline_run_id: null,
|
|
6023
|
+
phase: "implementation",
|
|
6024
|
+
category: "epic-shard-hash",
|
|
6025
|
+
key: "epics-file",
|
|
6026
|
+
value: currentHash,
|
|
6027
|
+
rationale: "SHA-256 hash of epics file content for change detection"
|
|
6028
|
+
});
|
|
6029
|
+
logger$7.debug({
|
|
6030
|
+
count,
|
|
6031
|
+
hash: currentHash
|
|
6032
|
+
}, "Seeded epic shard decisions");
|
|
5899
6033
|
return count;
|
|
5900
6034
|
}
|
|
5901
6035
|
/**
|
|
@@ -5962,11 +6096,11 @@ function extractSection(content, headingPattern) {
|
|
|
5962
6096
|
}
|
|
5963
6097
|
/**
|
|
5964
6098
|
* Parse epics.md into individual epic shards.
|
|
5965
|
-
* Matches "## Epic N"
|
|
6099
|
+
* Matches "## Epic N", "### Epic N", "#### Epic N", or depth-2 to depth-4 numeric headings.
|
|
5966
6100
|
*/
|
|
5967
6101
|
function parseEpicShards(content) {
|
|
5968
6102
|
const shards = [];
|
|
5969
|
-
const epicPattern =
|
|
6103
|
+
const epicPattern = /^#{2,4}\s+(?:Epic\s+)?(\d+)[.:\s]/gm;
|
|
5970
6104
|
let match;
|
|
5971
6105
|
const matches = [];
|
|
5972
6106
|
while ((match = epicPattern.exec(content)) !== null) {
|
|
@@ -6384,22 +6518,31 @@ function createImplementationOrchestrator(deps) {
|
|
|
6384
6518
|
const files = readdirSync$1(artifactsDir);
|
|
6385
6519
|
const match = files.find((f) => f.startsWith(`${storyKey}-`) && f.endsWith(".md"));
|
|
6386
6520
|
if (match) {
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
storyFilePath
|
|
6391
|
-
}, "Found existing story file — skipping create-story");
|
|
6392
|
-
endPhase(storyKey, "create-story");
|
|
6393
|
-
eventBus.emit("orchestrator:story-phase-complete", {
|
|
6521
|
+
const candidatePath = join$1(artifactsDir, match);
|
|
6522
|
+
const validation = await isValidStoryFile(candidatePath);
|
|
6523
|
+
if (!validation.valid) logger$20.warn({
|
|
6394
6524
|
storyKey,
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6525
|
+
storyFilePath: candidatePath,
|
|
6526
|
+
reason: validation.reason
|
|
6527
|
+
}, `Existing story file for ${storyKey} is invalid (${validation.reason}) — re-creating`);
|
|
6528
|
+
else {
|
|
6529
|
+
storyFilePath = candidatePath;
|
|
6530
|
+
logger$20.info({
|
|
6531
|
+
storyKey,
|
|
6532
|
+
storyFilePath
|
|
6533
|
+
}, "Found existing story file — skipping create-story");
|
|
6534
|
+
endPhase(storyKey, "create-story");
|
|
6535
|
+
eventBus.emit("orchestrator:story-phase-complete", {
|
|
6536
|
+
storyKey,
|
|
6537
|
+
phase: "IN_STORY_CREATION",
|
|
6538
|
+
result: {
|
|
6539
|
+
result: "success",
|
|
6540
|
+
story_file: storyFilePath,
|
|
6541
|
+
story_key: storyKey
|
|
6542
|
+
}
|
|
6543
|
+
});
|
|
6544
|
+
persistState();
|
|
6545
|
+
}
|
|
6403
6546
|
}
|
|
6404
6547
|
} catch {}
|
|
6405
6548
|
if (storyFilePath === void 0) try {
|
|
@@ -6768,7 +6911,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
6768
6911
|
...previousIssueList.length > 0 ? { previousIssues: previousIssueList } : {}
|
|
6769
6912
|
});
|
|
6770
6913
|
}
|
|
6771
|
-
const isPhantomReview = reviewResult.verdict !== "SHIP_IT" && (reviewResult.issue_list === void 0 || reviewResult.issue_list.length === 0) && reviewResult.error !== void 0;
|
|
6914
|
+
const isPhantomReview = reviewResult.dispatchFailed === true || reviewResult.verdict !== "SHIP_IT" && (reviewResult.issue_list === void 0 || reviewResult.issue_list.length === 0) && reviewResult.error !== void 0;
|
|
6772
6915
|
if (isPhantomReview && !timeoutRetried) {
|
|
6773
6916
|
timeoutRetried = true;
|
|
6774
6917
|
logger$20.warn({
|
|
@@ -11674,11 +11817,10 @@ async function runRunAction(options) {
|
|
|
11674
11817
|
});
|
|
11675
11818
|
const eventBus = createEventBus();
|
|
11676
11819
|
const contextCompiler = createContextCompiler({ db });
|
|
11677
|
-
|
|
11678
|
-
if (injectedRegistry === void 0) await adapterRegistry.discoverAndRegister();
|
|
11820
|
+
if (!injectedRegistry) throw new Error("AdapterRegistry is required — must be initialized at CLI startup");
|
|
11679
11821
|
const dispatcher = createDispatcher({
|
|
11680
11822
|
eventBus,
|
|
11681
|
-
adapterRegistry
|
|
11823
|
+
adapterRegistry: injectedRegistry
|
|
11682
11824
|
});
|
|
11683
11825
|
eventBus.on("orchestrator:story-phase-complete", (payload) => {
|
|
11684
11826
|
try {
|
|
@@ -12066,11 +12208,10 @@ async function runFullPipeline(options) {
|
|
|
12066
12208
|
}
|
|
12067
12209
|
const eventBus = createEventBus();
|
|
12068
12210
|
const contextCompiler = createContextCompiler({ db });
|
|
12069
|
-
|
|
12070
|
-
if (injectedRegistry === void 0) await adapterRegistry.discoverAndRegister();
|
|
12211
|
+
if (!injectedRegistry) throw new Error("AdapterRegistry is required — must be initialized at CLI startup");
|
|
12071
12212
|
const dispatcher = createDispatcher({
|
|
12072
12213
|
eventBus,
|
|
12073
|
-
adapterRegistry
|
|
12214
|
+
adapterRegistry: injectedRegistry
|
|
12074
12215
|
});
|
|
12075
12216
|
const phaseDeps = {
|
|
12076
12217
|
db,
|
|
@@ -12384,4 +12525,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
12384
12525
|
|
|
12385
12526
|
//#endregion
|
|
12386
12527
|
export { DatabaseWrapper, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createContextCompiler, createDispatcher, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, runAnalysisPhase, runMigrations, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict };
|
|
12387
|
-
//# sourceMappingURL=run-
|
|
12528
|
+
//# sourceMappingURL=run-BaAws8IQ.js.map
|
package/package.json
CHANGED
package/dist/errors-BPqtzQ4U.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
//#region src/core/errors.ts
|
|
2
|
-
/**
|
|
3
|
-
* Error definitions for Substrate
|
|
4
|
-
* Provides structured error hierarchy for all toolkit operations
|
|
5
|
-
*/
|
|
6
|
-
/** Base error class for all Substrate errors */
|
|
7
|
-
var AdtError = class AdtError extends Error {
|
|
8
|
-
code;
|
|
9
|
-
context;
|
|
10
|
-
constructor(message, code, context = {}) {
|
|
11
|
-
super(message);
|
|
12
|
-
this.name = "AdtError";
|
|
13
|
-
this.code = code;
|
|
14
|
-
this.context = context;
|
|
15
|
-
if (Error.captureStackTrace) Error.captureStackTrace(this, AdtError);
|
|
16
|
-
}
|
|
17
|
-
toJSON() {
|
|
18
|
-
return {
|
|
19
|
-
name: this.name,
|
|
20
|
-
message: this.message,
|
|
21
|
-
code: this.code,
|
|
22
|
-
context: this.context,
|
|
23
|
-
stack: this.stack
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
/** Error thrown when task configuration is invalid */
|
|
28
|
-
var TaskConfigError = class extends AdtError {
|
|
29
|
-
constructor(message, context = {}) {
|
|
30
|
-
super(message, "TASK_CONFIG_ERROR", context);
|
|
31
|
-
this.name = "TaskConfigError";
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
/** Error thrown when a worker/agent operation fails */
|
|
35
|
-
var WorkerError = class extends AdtError {
|
|
36
|
-
constructor(message, context = {}) {
|
|
37
|
-
super(message, "WORKER_ERROR", context);
|
|
38
|
-
this.name = "WorkerError";
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
/** Error thrown when a worker/agent cannot be found */
|
|
42
|
-
var WorkerNotFoundError = class extends AdtError {
|
|
43
|
-
constructor(agentId) {
|
|
44
|
-
super(`Worker agent not found: ${agentId}`, "WORKER_NOT_FOUND", { agentId });
|
|
45
|
-
this.name = "WorkerNotFoundError";
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
/** Error thrown when a task graph is invalid */
|
|
49
|
-
var TaskGraphError = class extends AdtError {
|
|
50
|
-
constructor(message, context = {}) {
|
|
51
|
-
super(message, "TASK_GRAPH_ERROR", context);
|
|
52
|
-
this.name = "TaskGraphError";
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
/** Error thrown when a task graph has cycles (deadlock) */
|
|
56
|
-
var TaskGraphCycleError = class extends TaskGraphError {
|
|
57
|
-
constructor(cycle) {
|
|
58
|
-
super(`Circular dependency detected in task graph: ${cycle.join(" -> ")}`, { cycle });
|
|
59
|
-
this.name = "TaskGraphCycleError";
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
/** Error thrown when a budget limit is exceeded */
|
|
63
|
-
var BudgetExceededError = class extends AdtError {
|
|
64
|
-
constructor(limit, current, context = {}) {
|
|
65
|
-
super(`Budget cap exceeded: current=${String(current)}, limit=${String(limit)}`, "BUDGET_EXCEEDED", {
|
|
66
|
-
limit,
|
|
67
|
-
current,
|
|
68
|
-
...context
|
|
69
|
-
});
|
|
70
|
-
this.name = "BudgetExceededError";
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
/** Error thrown when git operations fail */
|
|
74
|
-
var GitError = class extends AdtError {
|
|
75
|
-
constructor(message, context = {}) {
|
|
76
|
-
super(message, "GIT_ERROR", context);
|
|
77
|
-
this.name = "GitError";
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
/** Error thrown when configuration is invalid or missing */
|
|
81
|
-
var ConfigError = class extends AdtError {
|
|
82
|
-
constructor(message, context = {}) {
|
|
83
|
-
super(message, "CONFIG_ERROR", context);
|
|
84
|
-
this.name = "ConfigError";
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
/** Error thrown when state recovery fails */
|
|
88
|
-
var RecoveryError = class extends AdtError {
|
|
89
|
-
constructor(message, context = {}) {
|
|
90
|
-
super(message, "RECOVERY_ERROR", context);
|
|
91
|
-
this.name = "RecoveryError";
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
/** Error thrown when a config file uses an incompatible format version */
|
|
95
|
-
var ConfigIncompatibleFormatError = class extends AdtError {
|
|
96
|
-
constructor(message, context = {}) {
|
|
97
|
-
super(message, "CONFIG_INCOMPATIBLE_FORMAT", context);
|
|
98
|
-
this.name = "ConfigIncompatibleFormatError";
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
/** Error thrown when a task graph file uses an incompatible format version */
|
|
102
|
-
var TaskGraphIncompatibleFormatError = class extends AdtError {
|
|
103
|
-
constructor(message, context = {}) {
|
|
104
|
-
super(message, "TASK_GRAPH_INCOMPATIBLE_FORMAT", context);
|
|
105
|
-
this.name = "TaskGraphIncompatibleFormatError";
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
//#endregion
|
|
110
|
-
export { AdtError, BudgetExceededError, ConfigError, ConfigIncompatibleFormatError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError };
|
|
111
|
-
//# sourceMappingURL=errors-BPqtzQ4U.js.map
|
package/dist/run-gmS6DsGT.js
DELETED