substrate-ai 0.21.16 → 0.21.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/{acceptance-judge-D5Iba2D_.js → acceptance-judge-BStwKVzD.js} +1 -1
- package/dist/{acceptance-judge-lAv5EvYA.js → acceptance-judge-COyOxhQ2.js} +25 -3
- package/dist/cli/index.js +403 -164
- package/dist/{health-C1m6-7WH.js → health-4VCoTtz_.js} +2 -2
- package/dist/{health-CI8pIygU.js → health-Bu5nYB6q.js} +2 -2
- package/dist/index.d.ts +33 -1
- package/dist/{interactive-prompt-BWdH9Lb9.js → interactive-prompt-BbeQO4mm.js} +2 -2
- package/dist/{manifest-read-3cF8yP3_.js → manifest-read-leQdHLyo.js} +37 -2
- package/dist/modules/interactive-prompt/index.js +2 -2
- package/dist/{run-BeYZ5L6d.js → run-BXP4F8a2.js} +738 -554
- package/dist/{run-NlTM7HwK.js → run-CTfGK9yU.js} +5 -5
- package/package.json +1 -1
- package/packs/bmad/manifest.yaml +3 -0
- package/packs/bmad/prompts/acceptance-completeness.md +52 -0
- package/packs/bmad/prompts/ux-step-3-journeys.md +18 -6
package/dist/cli/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { FileKvStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createDoltOperatorReader, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-
|
|
2
|
+
import { FileKvStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createDoltOperatorReader, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-Bu5nYB6q.js";
|
|
3
3
|
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, InMemoryDatabaseAdapter, IngestionServer, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProvidersSchema, RoutingRecommender, STORY_METRICS, TelemetryConfigSchema, addTokenUsage, aggregateTokenUsageForRun, checkDoltInstalled, compareRunMetrics, createAmendmentRun, createConfigSystem, createDecision, createGitWorktreeManager, createPipelineRun, createStderrLogger, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initWorkGraphSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, swallowDebug, tagRunAsBaseline, updatePipelineRun } from "../dist-BZGqn-XQ.js";
|
|
6
6
|
import "../adapter-registry-DXLMTmfD.js";
|
|
7
|
-
import { ACCEPTANCE_CONTRACT_PROFILE_PATH, JOURNEY_CANDIDATE_PATH, JOURNEY_DEFERRALS_PATH, JOURNEY_REGISTRY_PATH, RunManifest, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, checkRegistryStaleness, clearGateDemotion, computePrecision, computeRecall, demoteGate, diffJourneySets, isProjectContainedPath, loadAcceptanceContractFromTrustedTree, loadJourneyRegistryFromFile, loadJourneyRegistryFromTrustedTree, parseAcceptanceContract, parseJourneyCandidate, parseJourneyDeferrals, parseJourneyRegistry, parseRuntimeProbes, ratifyCandidate, readAcceptanceMetrics, readCurrentRunId, readGateState, readTrustedFileContent, recordCanary, recordOverride, renderRegistryDiff, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck, runCanary } from "../manifest-read-
|
|
8
|
-
import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR, GitClient, GrammarLoader, Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runSolutioningPhase, unescape, validateStopAfterFromConflict } from "../run-
|
|
7
|
+
import { ACCEPTANCE_CONTRACT_PROFILE_PATH, JOURNEY_CANDIDATE_PATH, JOURNEY_DEFERRALS_PATH, JOURNEY_REGISTRY_PATH, RunManifest, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, checkRegistryStaleness, clearGateDemotion, computePrecision, computeRecall, demoteGate, diffJourneySets, isProjectContainedPath, loadAcceptanceContractFromTrustedTree, loadJourneyRegistryFromFile, loadJourneyRegistryFromTrustedTree, parseAcceptanceContract, parseJourneyCandidate, parseJourneyDeferrals, parseJourneyRegistry, parseRuntimeProbes, ratifyCandidate, readAcceptanceMetrics, readCurrentRunId, readGateState, readTrustedFileContent, recordCanary, recordOverride, renderRegistryDiff, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck, runCanary } from "../manifest-read-leQdHLyo.js";
|
|
8
|
+
import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR, GitClient, GrammarLoader, Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runSolutioningPhase, unescape, validateStopAfterFromConflict } from "../run-BXP4F8a2.js";
|
|
9
9
|
import "../errors-xSeGw6pf.js";
|
|
10
|
-
import { AcceptanceDeriveResultSchema, assemblePrompt, getTokenCeiling, runAcceptanceJudge } from "../acceptance-judge-
|
|
10
|
+
import { AcceptanceCompletenessResultSchema, AcceptanceDeriveResultSchema, assemblePrompt, getTokenCeiling, runAcceptanceJudge } from "../acceptance-judge-COyOxhQ2.js";
|
|
11
11
|
import "../routing-DZT5PN3N.js";
|
|
12
12
|
import { WorkGraphRepository } from "../work-graph-repository-4cKsf8Lf.js";
|
|
13
13
|
import "../decisions-BAaxpVD0.js";
|
|
14
14
|
import "../decision-router-Dyby0fUf.js";
|
|
15
|
-
import "../interactive-prompt-
|
|
15
|
+
import "../interactive-prompt-BbeQO4mm.js";
|
|
16
16
|
import "../recovery-engine-dtLHyV4M.js";
|
|
17
17
|
import "../version-manager-impl-DMTw551Q.js";
|
|
18
18
|
import { registerUpgradeCommand } from "../upgrade-CNGc12AV.js";
|
|
@@ -47,14 +47,14 @@ var RecommendationEngine = class {
|
|
|
47
47
|
_filters;
|
|
48
48
|
_historyDays;
|
|
49
49
|
_logger;
|
|
50
|
-
constructor(monitorDb, config = {}, logger$
|
|
50
|
+
constructor(monitorDb, config = {}, logger$21) {
|
|
51
51
|
this._monitorDb = monitorDb;
|
|
52
52
|
this._filters = {
|
|
53
53
|
threshold_percentage: config.recommendation_threshold_percentage ?? 5,
|
|
54
54
|
min_sample_size: config.min_sample_size ?? 10
|
|
55
55
|
};
|
|
56
56
|
this._historyDays = config.recommendation_history_days ?? 90;
|
|
57
|
-
this._logger = logger$
|
|
57
|
+
this._logger = logger$21 ?? createStderrLogger("monitor:recommendation-engine");
|
|
58
58
|
}
|
|
59
59
|
generateRecommendations() {
|
|
60
60
|
const sinceDate = new Date(Date.now() - this._historyDays * 24 * 60 * 60 * 1e3).toISOString();
|
|
@@ -1312,7 +1312,7 @@ function buildStackAwareDevNotes(profile) {
|
|
|
1312
1312
|
|
|
1313
1313
|
//#endregion
|
|
1314
1314
|
//#region src/cli/commands/init.ts
|
|
1315
|
-
const logger$
|
|
1315
|
+
const logger$20 = createLogger("init");
|
|
1316
1316
|
const __dirname = dirname(new URL(import.meta.url).pathname);
|
|
1317
1317
|
const SCAFFOLD_VERSION_REGEX = /<!-- substrate:version=([\d.]+) -->/;
|
|
1318
1318
|
/**
|
|
@@ -1353,7 +1353,7 @@ async function scaffoldBmadFramework(projectRoot, force, outputFormat) {
|
|
|
1353
1353
|
const version = resolveBmadMethodVersion();
|
|
1354
1354
|
if (force && bmadExists) process.stderr.write(`Warning: Replacing existing _bmad/ framework with bmad-method@${version}\n`);
|
|
1355
1355
|
process.stdout.write(`Scaffolding BMAD framework from bmad-method@${version}\n`);
|
|
1356
|
-
logger$
|
|
1356
|
+
logger$20.info({
|
|
1357
1357
|
version,
|
|
1358
1358
|
dest: bmadDest
|
|
1359
1359
|
}, "Scaffolding BMAD framework");
|
|
@@ -1363,7 +1363,7 @@ async function scaffoldBmadFramework(projectRoot, force, outputFormat) {
|
|
|
1363
1363
|
const destDir = join(bmadDest, dir);
|
|
1364
1364
|
mkdirSync$1(destDir, { recursive: true });
|
|
1365
1365
|
cpSync(srcDir, destDir, { recursive: true });
|
|
1366
|
-
logger$
|
|
1366
|
+
logger$20.info({
|
|
1367
1367
|
dir,
|
|
1368
1368
|
dest: destDir
|
|
1369
1369
|
}, "Scaffolded BMAD framework directory");
|
|
@@ -1382,7 +1382,7 @@ async function scaffoldBmadFramework(projectRoot, force, outputFormat) {
|
|
|
1382
1382
|
"document_output_language: English"
|
|
1383
1383
|
].join("\n") + "\n";
|
|
1384
1384
|
await writeFile(configFile, configStub, "utf8");
|
|
1385
|
-
logger$
|
|
1385
|
+
logger$20.info({ configFile }, "Generated _bmad/_config/config.yaml stub");
|
|
1386
1386
|
}
|
|
1387
1387
|
}
|
|
1388
1388
|
const CLAUDE_MD_START_MARKER = "<!-- substrate:start -->";
|
|
@@ -1397,7 +1397,7 @@ async function scaffoldClaudeMd(projectRoot, profile) {
|
|
|
1397
1397
|
try {
|
|
1398
1398
|
sectionContent = await readFile(templatePath, "utf8");
|
|
1399
1399
|
} catch {
|
|
1400
|
-
logger$
|
|
1400
|
+
logger$20.warn({ templatePath }, "CLAUDE.md substrate section template not found; skipping");
|
|
1401
1401
|
return;
|
|
1402
1402
|
}
|
|
1403
1403
|
const substrateVersion = readSubstrateVersion(pkgRoot);
|
|
@@ -1433,7 +1433,7 @@ async function scaffoldClaudeMd(projectRoot, profile) {
|
|
|
1433
1433
|
else newContent = updatedExisting;
|
|
1434
1434
|
}
|
|
1435
1435
|
await writeFile(claudeMdPath, newContent, "utf8");
|
|
1436
|
-
logger$
|
|
1436
|
+
logger$20.info({ claudeMdPath }, "Wrote substrate section to CLAUDE.md");
|
|
1437
1437
|
}
|
|
1438
1438
|
async function scaffoldAgentsMd(projectRoot, profile) {
|
|
1439
1439
|
const agentsMdPath = join(projectRoot, "AGENTS.md");
|
|
@@ -1445,7 +1445,7 @@ async function scaffoldAgentsMd(projectRoot, profile) {
|
|
|
1445
1445
|
try {
|
|
1446
1446
|
sectionContent = await readFile(templatePath, "utf8");
|
|
1447
1447
|
} catch {
|
|
1448
|
-
logger$
|
|
1448
|
+
logger$20.warn({ templatePath }, "AGENTS.md substrate section template not found; skipping");
|
|
1449
1449
|
return;
|
|
1450
1450
|
}
|
|
1451
1451
|
const substrateVersion = readSubstrateVersion(pkgRoot);
|
|
@@ -1466,7 +1466,7 @@ async function scaffoldAgentsMd(projectRoot, profile) {
|
|
|
1466
1466
|
newContent = existingContent + separator + sectionContent;
|
|
1467
1467
|
}
|
|
1468
1468
|
await writeFile(agentsMdPath, newContent, "utf8");
|
|
1469
|
-
logger$
|
|
1469
|
+
logger$20.info({ agentsMdPath }, "Wrote substrate section to AGENTS.md");
|
|
1470
1470
|
}
|
|
1471
1471
|
async function scaffoldGeminiMd(projectRoot, profile) {
|
|
1472
1472
|
const geminiMdPath = join(projectRoot, "GEMINI.md");
|
|
@@ -1478,7 +1478,7 @@ async function scaffoldGeminiMd(projectRoot, profile) {
|
|
|
1478
1478
|
try {
|
|
1479
1479
|
sectionContent = await readFile(templatePath, "utf8");
|
|
1480
1480
|
} catch {
|
|
1481
|
-
logger$
|
|
1481
|
+
logger$20.warn({ templatePath }, "GEMINI.md substrate section template not found; skipping");
|
|
1482
1482
|
return;
|
|
1483
1483
|
}
|
|
1484
1484
|
const substrateVersion = readSubstrateVersion(pkgRoot);
|
|
@@ -1499,7 +1499,7 @@ async function scaffoldGeminiMd(projectRoot, profile) {
|
|
|
1499
1499
|
newContent = existingContent + separator + sectionContent;
|
|
1500
1500
|
}
|
|
1501
1501
|
await writeFile(geminiMdPath, newContent, "utf8");
|
|
1502
|
-
logger$
|
|
1502
|
+
logger$20.info({ geminiMdPath }, "Wrote substrate section to GEMINI.md");
|
|
1503
1503
|
}
|
|
1504
1504
|
async function scaffoldStatuslineScript(projectRoot) {
|
|
1505
1505
|
const pkgRoot = findPackageRoot(__dirname);
|
|
@@ -1510,7 +1510,7 @@ async function scaffoldStatuslineScript(projectRoot) {
|
|
|
1510
1510
|
try {
|
|
1511
1511
|
content = await readFile(templatePath, "utf8");
|
|
1512
1512
|
} catch {
|
|
1513
|
-
logger$
|
|
1513
|
+
logger$20.warn({ templatePath }, "statusline.sh template not found; skipping");
|
|
1514
1514
|
return;
|
|
1515
1515
|
}
|
|
1516
1516
|
const claudeDir = join(projectRoot, ".claude");
|
|
@@ -1518,7 +1518,7 @@ async function scaffoldStatuslineScript(projectRoot) {
|
|
|
1518
1518
|
mkdirSync$1(claudeDir, { recursive: true });
|
|
1519
1519
|
await writeFile(statuslinePath, content, "utf8");
|
|
1520
1520
|
chmodSync(statuslinePath, 493);
|
|
1521
|
-
logger$
|
|
1521
|
+
logger$20.info({ statuslinePath }, "Wrote .claude/statusline.sh");
|
|
1522
1522
|
}
|
|
1523
1523
|
async function scaffoldClaudeSettings(projectRoot) {
|
|
1524
1524
|
const claudeDir = join(projectRoot, ".claude");
|
|
@@ -1534,7 +1534,7 @@ async function scaffoldClaudeSettings(projectRoot) {
|
|
|
1534
1534
|
if (!merged["$schema"]) merged["$schema"] = "https://json.schemastore.org/claude-code-settings.json";
|
|
1535
1535
|
mkdirSync$1(claudeDir, { recursive: true });
|
|
1536
1536
|
await writeFile(settingsPath, JSON.stringify(merged, null, 2) + "\n", "utf8");
|
|
1537
|
-
logger$
|
|
1537
|
+
logger$20.info({ settingsPath }, "Wrote substrate settings to .claude/settings.json");
|
|
1538
1538
|
}
|
|
1539
1539
|
/**
|
|
1540
1540
|
* H5.2 (field finding #2): write substrate's own slash commands
|
|
@@ -1553,7 +1553,7 @@ function scaffoldSubstrateSlashCommands(projectRoot) {
|
|
|
1553
1553
|
let templatesDir = join(pkgRoot, "dist", "cli", "templates", "claude-commands");
|
|
1554
1554
|
if (!existsSync$1(templatesDir)) templatesDir = join(pkgRoot, "src", "cli", "templates", "claude-commands");
|
|
1555
1555
|
if (!existsSync$1(templatesDir)) {
|
|
1556
|
-
logger$
|
|
1556
|
+
logger$20.warn({ templatesDir }, "substrate slash-command templates not found; skipping");
|
|
1557
1557
|
return 0;
|
|
1558
1558
|
}
|
|
1559
1559
|
const commandsDir = join(projectRoot, ".claude", "commands");
|
|
@@ -1565,19 +1565,19 @@ function scaffoldSubstrateSlashCommands(projectRoot) {
|
|
|
1565
1565
|
writeFileSync$1(join(commandsDir, file), readFileSync$1(join(templatesDir, file), "utf8"));
|
|
1566
1566
|
written += 1;
|
|
1567
1567
|
} catch (err) {
|
|
1568
|
-
logger$
|
|
1568
|
+
logger$20.warn({
|
|
1569
1569
|
file,
|
|
1570
1570
|
err
|
|
1571
1571
|
}, "failed to write substrate slash command (init continues)");
|
|
1572
1572
|
}
|
|
1573
1573
|
}
|
|
1574
|
-
logger$
|
|
1574
|
+
logger$20.info({
|
|
1575
1575
|
written,
|
|
1576
1576
|
commandsDir
|
|
1577
1577
|
}, "Scaffolded substrate slash commands");
|
|
1578
1578
|
return written;
|
|
1579
1579
|
} catch (err) {
|
|
1580
|
-
logger$
|
|
1580
|
+
logger$20.warn({ err }, "scaffoldSubstrateSlashCommands failed; init continues");
|
|
1581
1581
|
return 0;
|
|
1582
1582
|
}
|
|
1583
1583
|
}
|
|
@@ -1651,7 +1651,7 @@ async function compileBmadAgents(bmadDir) {
|
|
|
1651
1651
|
writeFileSync$1(mdPath, result.xml, "utf-8");
|
|
1652
1652
|
compiled++;
|
|
1653
1653
|
} catch (compileErr) {
|
|
1654
|
-
logger$
|
|
1654
|
+
logger$20.debug({
|
|
1655
1655
|
err: compileErr,
|
|
1656
1656
|
file
|
|
1657
1657
|
}, "Failed to compile agent YAML");
|
|
@@ -1798,9 +1798,9 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1798
1798
|
const _require = createRequire(join(__dirname, "synthetic.js"));
|
|
1799
1799
|
try {
|
|
1800
1800
|
const compiledCount = await compileBmadAgents(bmadDir);
|
|
1801
|
-
if (compiledCount > 0) logger$
|
|
1801
|
+
if (compiledCount > 0) logger$20.info({ compiledCount }, "Compiled agent YAML files to MD");
|
|
1802
1802
|
} catch (compileErr) {
|
|
1803
|
-
logger$
|
|
1803
|
+
logger$20.warn({ err: compileErr }, "Agent compilation failed; agent commands may be incomplete");
|
|
1804
1804
|
}
|
|
1805
1805
|
const resolveExport = (mod, name) => {
|
|
1806
1806
|
if (typeof mod[name] === "function") return mod[name];
|
|
@@ -1814,7 +1814,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1814
1814
|
const manifestGenPath = join(installerLibPath, "core", "manifest-generator.js");
|
|
1815
1815
|
const pathUtilsPath = join(installerLibPath, "ide", "shared", "path-utils.js");
|
|
1816
1816
|
if (!existsSync$1(agentGenPath)) {
|
|
1817
|
-
logger$
|
|
1817
|
+
logger$20.info("bmad-method generators not available (requires bmad-method with agent/workflow/task-tool generators)");
|
|
1818
1818
|
return;
|
|
1819
1819
|
}
|
|
1820
1820
|
const agentMod = _require(agentGenPath);
|
|
@@ -1824,11 +1824,11 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1824
1824
|
if (existsSync$1(workflowGenPath)) {
|
|
1825
1825
|
const workflowMod = _require(workflowGenPath);
|
|
1826
1826
|
WorkflowCommandGenerator = resolveExport(workflowMod, "WorkflowCommandGenerator");
|
|
1827
|
-
} else logger$
|
|
1827
|
+
} else logger$20.info("bmad-method workflow-command-generator not available; will try skill-based installation");
|
|
1828
1828
|
if (existsSync$1(taskToolGenPath)) {
|
|
1829
1829
|
const taskToolMod = _require(taskToolGenPath);
|
|
1830
1830
|
TaskToolCommandGenerator = resolveExport(taskToolMod, "TaskToolCommandGenerator");
|
|
1831
|
-
} else logger$
|
|
1831
|
+
} else logger$20.info("bmad-method task-tool-command-generator not available; will try skill-based installation");
|
|
1832
1832
|
let ManifestGenerator = null;
|
|
1833
1833
|
if (existsSync$1(manifestGenPath)) {
|
|
1834
1834
|
const manifestMod = _require(manifestGenPath);
|
|
@@ -1860,7 +1860,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1860
1860
|
const manifestGen = new ManifestGenerator();
|
|
1861
1861
|
await manifestGen.generateManifests(bmadDir, allModules, [], { ides: ["claude-code"] });
|
|
1862
1862
|
} catch (manifestErr) {
|
|
1863
|
-
logger$
|
|
1863
|
+
logger$20.warn({ err: manifestErr }, "ManifestGenerator failed; workflow/task commands may be incomplete");
|
|
1864
1864
|
}
|
|
1865
1865
|
const commandsDir = join(projectRoot, ".claude", "commands");
|
|
1866
1866
|
mkdirSync$1(commandsDir, { recursive: true });
|
|
@@ -1888,7 +1888,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1888
1888
|
const total = agentCount + workflowCount + taskToolCount + skillCount;
|
|
1889
1889
|
if (outputFormat !== "json") if (skillCount > 0) process.stdout.write(`Generated ${String(total)} Claude Code commands (${String(agentCount)} agents, ${String(skillCount)} skills)\n`);
|
|
1890
1890
|
else process.stdout.write(`Generated ${String(total)} Claude Code commands (${String(agentCount)} agents, ${String(workflowCount)} workflows, ${String(taskToolCount)} tasks/tools)\n`);
|
|
1891
|
-
logger$
|
|
1891
|
+
logger$20.info({
|
|
1892
1892
|
agentCount,
|
|
1893
1893
|
workflowCount,
|
|
1894
1894
|
taskToolCount,
|
|
@@ -1899,7 +1899,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1899
1899
|
} catch (err) {
|
|
1900
1900
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1901
1901
|
if (outputFormat !== "json") process.stderr.write(`Warning: .claude/commands/ generation failed: ${msg}\n`);
|
|
1902
|
-
logger$
|
|
1902
|
+
logger$20.warn({ err }, "scaffoldClaudeCommands failed; init continues");
|
|
1903
1903
|
}
|
|
1904
1904
|
}
|
|
1905
1905
|
/**
|
|
@@ -1928,7 +1928,7 @@ function syncCommandsAsPrompts(commandsDir, promptsDir, ownershipPrefixes, nameP
|
|
|
1928
1928
|
unlinkSync$1(join(promptsDir, entry.name));
|
|
1929
1929
|
}
|
|
1930
1930
|
} catch (err) {
|
|
1931
|
-
logger$
|
|
1931
|
+
logger$20.debug({
|
|
1932
1932
|
err,
|
|
1933
1933
|
promptsDir
|
|
1934
1934
|
}, "Failed to prune stale prompts");
|
|
@@ -1971,7 +1971,7 @@ function syncSkillsToTarget(srcSkillsDir, destSkillsDir, ownershipPrefixes, name
|
|
|
1971
1971
|
});
|
|
1972
1972
|
}
|
|
1973
1973
|
} catch (err) {
|
|
1974
|
-
logger$
|
|
1974
|
+
logger$20.debug({
|
|
1975
1975
|
err,
|
|
1976
1976
|
destSkillsDir
|
|
1977
1977
|
}, "Failed to prune stale skills");
|
|
@@ -1997,7 +1997,7 @@ function syncSkillsToTarget(srcSkillsDir, destSkillsDir, ownershipPrefixes, name
|
|
|
1997
1997
|
op: stage,
|
|
1998
1998
|
err: msg
|
|
1999
1999
|
});
|
|
2000
|
-
logger$
|
|
2000
|
+
logger$20.warn({
|
|
2001
2001
|
skill: entry.name,
|
|
2002
2002
|
dest,
|
|
2003
2003
|
stage,
|
|
@@ -2007,7 +2007,7 @@ function syncSkillsToTarget(srcSkillsDir, destSkillsDir, ownershipPrefixes, name
|
|
|
2007
2007
|
}
|
|
2008
2008
|
if (failures.length > 0 && count === 0) {
|
|
2009
2009
|
const first = failures[0];
|
|
2010
|
-
logger$
|
|
2010
|
+
logger$20.warn({
|
|
2011
2011
|
destSkillsDir,
|
|
2012
2012
|
attempted: failures.length,
|
|
2013
2013
|
dominantStage: first.op,
|
|
@@ -2034,7 +2034,7 @@ const PROJECT_OWNERSHIP_PREFIXES = ["bmad-", "substrate-"];
|
|
|
2034
2034
|
function scaffoldCodexProject(projectRoot, outputFormat) {
|
|
2035
2035
|
if (process.env["SUBSTRATE_NO_CODEX_SCAFFOLD"] === "1") {
|
|
2036
2036
|
if (outputFormat !== "json") process.stdout.write(" Skipping .codex/ scaffolding (SUBSTRATE_NO_CODEX_SCAFFOLD=1)\n");
|
|
2037
|
-
logger$
|
|
2037
|
+
logger$20.debug("SUBSTRATE_NO_CODEX_SCAFFOLD=1 — skipping .codex/ scaffolding");
|
|
2038
2038
|
return;
|
|
2039
2039
|
}
|
|
2040
2040
|
const claudeCommandsDir = join(projectRoot, ".claude", "commands");
|
|
@@ -2047,16 +2047,16 @@ function scaffoldCodexProject(projectRoot, outputFormat) {
|
|
|
2047
2047
|
const skillCount = syncSkillsToTarget(claudeSkillsDir, codexSkillsDir, PROJECT_OWNERSHIP_PREFIXES, "");
|
|
2048
2048
|
const total = promptCount + skillCount;
|
|
2049
2049
|
if (outputFormat !== "json" && total > 0) process.stdout.write(`Generated ${String(total)} Codex artifacts (${String(promptCount)} prompts, ${String(skillCount)} skills)\n`);
|
|
2050
|
-
if (total > 0) logger$
|
|
2050
|
+
if (total > 0) logger$20.info({
|
|
2051
2051
|
promptCount,
|
|
2052
2052
|
skillCount,
|
|
2053
2053
|
codexDir
|
|
2054
2054
|
}, "Generated .codex/");
|
|
2055
|
-
else logger$
|
|
2055
|
+
else logger$20.debug({ codexDir }, "No Codex artifacts generated; source Claude content not found");
|
|
2056
2056
|
} catch (err) {
|
|
2057
2057
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2058
2058
|
if (outputFormat !== "json") process.stderr.write(`Warning: .codex/ generation failed: ${msg}\n`);
|
|
2059
|
-
logger$
|
|
2059
|
+
logger$20.warn({ err }, "scaffoldCodexProject failed; init continues");
|
|
2060
2060
|
}
|
|
2061
2061
|
}
|
|
2062
2062
|
/**
|
|
@@ -2074,7 +2074,7 @@ function scaffoldCodexProject(projectRoot, outputFormat) {
|
|
|
2074
2074
|
function scaffoldCodexUser(projectRoot, homeDir, outputFormat) {
|
|
2075
2075
|
if (process.env["SUBSTRATE_NO_CODEX_SCAFFOLD"] === "1") {
|
|
2076
2076
|
if (outputFormat !== "json") process.stdout.write(" Skipping ~/.codex/ scaffolding (SUBSTRATE_NO_CODEX_SCAFFOLD=1)\n");
|
|
2077
|
-
logger$
|
|
2077
|
+
logger$20.debug("SUBSTRATE_NO_CODEX_SCAFFOLD=1 — skipping ~/.codex/ scaffolding");
|
|
2078
2078
|
return;
|
|
2079
2079
|
}
|
|
2080
2080
|
const claudeCommandsDir = join(projectRoot, ".claude", "commands");
|
|
@@ -2087,16 +2087,16 @@ function scaffoldCodexUser(projectRoot, homeDir, outputFormat) {
|
|
|
2087
2087
|
const skillCount = syncSkillsToTarget(claudeSkillsDir, userSkillsDir, ["substrate-"], "substrate-");
|
|
2088
2088
|
const total = promptCount + skillCount;
|
|
2089
2089
|
if (outputFormat !== "json" && total > 0) process.stdout.write(`Installed ${String(total)} Codex artifacts to ${userCodexDir} (${String(promptCount)} prompts, ${String(skillCount)} skills)\n`);
|
|
2090
|
-
if (total > 0) logger$
|
|
2090
|
+
if (total > 0) logger$20.info({
|
|
2091
2091
|
promptCount,
|
|
2092
2092
|
skillCount,
|
|
2093
2093
|
userCodexDir
|
|
2094
2094
|
}, "Installed user-scope Codex content");
|
|
2095
|
-
else logger$
|
|
2095
|
+
else logger$20.debug({ userCodexDir }, "No user-scope Codex content installed; source Claude content not found");
|
|
2096
2096
|
} catch (err) {
|
|
2097
2097
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2098
2098
|
if (outputFormat !== "json") process.stderr.write(`Warning: user-scope Codex install failed: ${msg}\n`);
|
|
2099
|
-
logger$
|
|
2099
|
+
logger$20.warn({ err }, "scaffoldCodexUser failed; init continues");
|
|
2100
2100
|
}
|
|
2101
2101
|
}
|
|
2102
2102
|
const PROVIDER_DEFAULTS = DEFAULT_CONFIG.providers;
|
|
@@ -2217,7 +2217,7 @@ async function runInitAction(options) {
|
|
|
2217
2217
|
discoveryReport = await registry.discoverAndRegister();
|
|
2218
2218
|
} catch (err) {
|
|
2219
2219
|
const message = err instanceof Error ? err.message : String(err);
|
|
2220
|
-
logger$
|
|
2220
|
+
logger$20.error({ err }, "Adapter discovery failed");
|
|
2221
2221
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, `Adapter discovery failed: ${message}`) + "\n");
|
|
2222
2222
|
else process.stderr.write(` Error: adapter discovery failed — ${message}\n`);
|
|
2223
2223
|
return INIT_EXIT_ERROR;
|
|
@@ -2266,7 +2266,7 @@ async function runInitAction(options) {
|
|
|
2266
2266
|
try {
|
|
2267
2267
|
detectedProfile = await detectProjectProfile(dbRoot);
|
|
2268
2268
|
} catch (err) {
|
|
2269
|
-
logger$
|
|
2269
|
+
logger$20.warn({ err }, "Project profile detection failed; skipping");
|
|
2270
2270
|
}
|
|
2271
2271
|
if (detectedProfile === null) {
|
|
2272
2272
|
if (outputFormat !== "json") process.stdout.write(" No project stack detected. Create .substrate/project-profile.yaml manually to enable polyglot support.\n");
|
|
@@ -2300,12 +2300,12 @@ async function runInitAction(options) {
|
|
|
2300
2300
|
return INIT_EXIT_ERROR;
|
|
2301
2301
|
}
|
|
2302
2302
|
if (force && existsSync$1(localManifest)) {
|
|
2303
|
-
logger$
|
|
2303
|
+
logger$20.info({ pack: packName }, "Replacing existing pack with bundled version");
|
|
2304
2304
|
process.stderr.write(`Warning: Replacing existing pack '${packName}' with bundled version\n`);
|
|
2305
2305
|
}
|
|
2306
2306
|
mkdirSync$1(dirname(packPath), { recursive: true });
|
|
2307
2307
|
cpSync(bundledPackPath, packPath, { recursive: true });
|
|
2308
|
-
logger$
|
|
2308
|
+
logger$20.info({
|
|
2309
2309
|
pack: packName,
|
|
2310
2310
|
dest: packPath
|
|
2311
2311
|
}, "Scaffolded methodology pack");
|
|
@@ -2347,10 +2347,10 @@ async function runInitAction(options) {
|
|
|
2347
2347
|
const { content, changed } = computeSubstrateGitignore(existing);
|
|
2348
2348
|
if (changed) {
|
|
2349
2349
|
writeFileSync$1(gitignorePath, content);
|
|
2350
|
-
logger$
|
|
2350
|
+
logger$20.info("Updated .gitignore: track only .substrate/config.yaml");
|
|
2351
2351
|
}
|
|
2352
2352
|
} catch (err) {
|
|
2353
|
-
logger$
|
|
2353
|
+
logger$20.debug({ err }, "Could not update .gitignore (non-fatal)");
|
|
2354
2354
|
}
|
|
2355
2355
|
const doltMode = options.doltMode ?? "auto";
|
|
2356
2356
|
let doltInitialized = false;
|
|
@@ -2364,7 +2364,7 @@ async function runInitAction(options) {
|
|
|
2364
2364
|
process.stderr.write(`${err.message}\n`);
|
|
2365
2365
|
return INIT_EXIT_ERROR;
|
|
2366
2366
|
}
|
|
2367
|
-
logger$
|
|
2367
|
+
logger$20.debug("Dolt not installed, skipping auto-init");
|
|
2368
2368
|
} else {
|
|
2369
2369
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2370
2370
|
if (doltMode === "force") {
|
|
@@ -2374,7 +2374,7 @@ async function runInitAction(options) {
|
|
|
2374
2374
|
process.stderr.write(`⚠ Dolt state store initialization failed: ${msg}\n Pipeline metrics, cost tracking, and health monitoring will not persist.\n Fix the issue and re-run: substrate init --dolt\n`);
|
|
2375
2375
|
}
|
|
2376
2376
|
}
|
|
2377
|
-
else logger$
|
|
2377
|
+
else logger$20.debug("Dolt step was skipped (--no-dolt)");
|
|
2378
2378
|
const successMsg = `Pack '${packName}' and database initialized successfully at ${dbPath}`;
|
|
2379
2379
|
if (outputFormat === "json") process.stdout.write(formatOutput({
|
|
2380
2380
|
pack: packName,
|
|
@@ -2412,7 +2412,7 @@ async function runInitAction(options) {
|
|
|
2412
2412
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2413
2413
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
2414
2414
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
2415
|
-
logger$
|
|
2415
|
+
logger$20.error({ err }, "init failed");
|
|
2416
2416
|
return INIT_EXIT_ERROR;
|
|
2417
2417
|
}
|
|
2418
2418
|
}
|
|
@@ -2436,7 +2436,7 @@ function registerInitCommand(program, _version, registry) {
|
|
|
2436
2436
|
|
|
2437
2437
|
//#endregion
|
|
2438
2438
|
//#region src/cli/commands/config.ts
|
|
2439
|
-
const logger$
|
|
2439
|
+
const logger$19 = createLogger("config-cmd");
|
|
2440
2440
|
const CONFIG_EXIT_SUCCESS = 0;
|
|
2441
2441
|
const CONFIG_EXIT_ERROR = 1;
|
|
2442
2442
|
const CONFIG_EXIT_INVALID = 2;
|
|
@@ -2462,7 +2462,7 @@ async function runConfigShow(opts = {}) {
|
|
|
2462
2462
|
return CONFIG_EXIT_INVALID;
|
|
2463
2463
|
}
|
|
2464
2464
|
const message = err instanceof Error ? err.message : String(err);
|
|
2465
|
-
logger$
|
|
2465
|
+
logger$19.error({ err }, "Failed to load configuration");
|
|
2466
2466
|
process.stderr.write(` Error loading configuration: ${message}\n`);
|
|
2467
2467
|
return CONFIG_EXIT_ERROR;
|
|
2468
2468
|
}
|
|
@@ -2536,7 +2536,7 @@ async function runConfigExport(opts = {}) {
|
|
|
2536
2536
|
return CONFIG_EXIT_INVALID;
|
|
2537
2537
|
}
|
|
2538
2538
|
const message = err instanceof Error ? err.message : String(err);
|
|
2539
|
-
logger$
|
|
2539
|
+
logger$19.error({ err }, "Failed to load configuration");
|
|
2540
2540
|
process.stderr.write(`Error loading configuration: ${message}\n`);
|
|
2541
2541
|
return CONFIG_EXIT_ERROR;
|
|
2542
2542
|
}
|
|
@@ -6456,7 +6456,7 @@ async function detectManifestDriftAgainstWorkingTree(manifest, projectRoot) {
|
|
|
6456
6456
|
|
|
6457
6457
|
//#endregion
|
|
6458
6458
|
//#region src/cli/commands/resume.ts
|
|
6459
|
-
const logger$
|
|
6459
|
+
const logger$18 = createLogger("resume-cmd");
|
|
6460
6460
|
/**
|
|
6461
6461
|
* Format a human-readable duration from an ISO-8601 timestamp to "now".
|
|
6462
6462
|
*/
|
|
@@ -6526,7 +6526,7 @@ async function runResumeAction(options) {
|
|
|
6526
6526
|
return 1;
|
|
6527
6527
|
}
|
|
6528
6528
|
} catch (driftErr) {
|
|
6529
|
-
logger$
|
|
6529
|
+
logger$18.debug({ err: driftErr }, "manifest drift check failed — proceeding with resume");
|
|
6530
6530
|
}
|
|
6531
6531
|
}
|
|
6532
6532
|
const doltDir = join(dbRoot, ".substrate", "state", ".dolt");
|
|
@@ -6596,15 +6596,15 @@ async function runResumeAction(options) {
|
|
|
6596
6596
|
const manifestStories = manifestData.cli_flags["stories"] ?? manifestData.story_scope;
|
|
6597
6597
|
if (Array.isArray(manifestStories) && manifestStories.length > 0) {
|
|
6598
6598
|
scopedStories = manifestStories;
|
|
6599
|
-
logger$
|
|
6599
|
+
logger$18.debug({
|
|
6600
6600
|
runId,
|
|
6601
6601
|
stories: scopedStories
|
|
6602
6602
|
}, "resume scope loaded from manifest");
|
|
6603
6603
|
}
|
|
6604
6604
|
} catch {
|
|
6605
|
-
logger$
|
|
6605
|
+
logger$18.debug({ runId }, "manifest read failed in resume — using legacy config_json scope");
|
|
6606
6606
|
}
|
|
6607
|
-
else logger$
|
|
6607
|
+
else logger$18.debug({ runId }, "Run manifest not found for scope preservation — using legacy config_json scope");
|
|
6608
6608
|
}
|
|
6609
6609
|
return runFullPipelineFromPhase({
|
|
6610
6610
|
packName,
|
|
@@ -6627,7 +6627,7 @@ async function runResumeAction(options) {
|
|
|
6627
6627
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6628
6628
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
6629
6629
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
6630
|
-
logger$
|
|
6630
|
+
logger$18.error({ err }, "auto resume failed");
|
|
6631
6631
|
return 1;
|
|
6632
6632
|
} finally {
|
|
6633
6633
|
try {
|
|
@@ -6667,7 +6667,8 @@ async function runFullPipelineFromPhase(options) {
|
|
|
6667
6667
|
pack,
|
|
6668
6668
|
contextCompiler,
|
|
6669
6669
|
dispatcher,
|
|
6670
|
-
agentId
|
|
6670
|
+
agentId,
|
|
6671
|
+
eventBus
|
|
6671
6672
|
};
|
|
6672
6673
|
const agentAdapter = agentId != null ? injectedRegistry.get(agentId) : void 0;
|
|
6673
6674
|
const adapterDefaultCycles = agentAdapter?.getCapabilities?.()?.defaultMaxReviewCycles;
|
|
@@ -6880,11 +6881,11 @@ async function runFullPipelineFromPhase(options) {
|
|
|
6880
6881
|
output_tokens: output,
|
|
6881
6882
|
cost_usd: costUsd
|
|
6882
6883
|
}).catch((err) => {
|
|
6883
|
-
logger$
|
|
6884
|
+
logger$18.warn({ err }, "Failed to record token usage");
|
|
6884
6885
|
});
|
|
6885
6886
|
}
|
|
6886
6887
|
} catch (err) {
|
|
6887
|
-
logger$
|
|
6888
|
+
logger$18.warn({ err }, "Failed to record token usage");
|
|
6888
6889
|
}
|
|
6889
6890
|
});
|
|
6890
6891
|
const storyKeys = await resolveStoryKeys(adapter, projectRoot, {
|
|
@@ -6953,7 +6954,7 @@ async function runFullPipelineFromPhase(options) {
|
|
|
6953
6954
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6954
6955
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
6955
6956
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
6956
|
-
logger$
|
|
6957
|
+
logger$18.error({ err }, "pipeline from phase failed");
|
|
6957
6958
|
return 1;
|
|
6958
6959
|
} finally {
|
|
6959
6960
|
try {
|
|
@@ -6983,7 +6984,7 @@ function registerResumeCommand(program, _version = "0.0.0", projectRoot = proces
|
|
|
6983
6984
|
|
|
6984
6985
|
//#endregion
|
|
6985
6986
|
//#region src/cli/commands/status.ts
|
|
6986
|
-
const logger$
|
|
6987
|
+
const logger$17 = createLogger("status-cmd");
|
|
6987
6988
|
/**
|
|
6988
6989
|
* Map a manifest per-story status string to the appropriate WorkGraphCounts bucket.
|
|
6989
6990
|
* Unknown strings are treated as `inProgress` (safe default).
|
|
@@ -7095,9 +7096,9 @@ async function runStatusAction(options) {
|
|
|
7095
7096
|
const manifestData = await resolvedManifest.read();
|
|
7096
7097
|
manifestPerStoryState = manifestData.per_story_state;
|
|
7097
7098
|
workGraph = buildWorkGraphFromManifest(manifestData.per_story_state);
|
|
7098
|
-
logger$
|
|
7099
|
+
logger$17.debug({ runId: run?.id }, "status: workGraph built from manifest per_story_state");
|
|
7099
7100
|
} catch {
|
|
7100
|
-
logger$
|
|
7101
|
+
logger$17.debug({ runId: run?.id }, "status: manifest read failed — falling back to wg_stories");
|
|
7101
7102
|
}
|
|
7102
7103
|
if (workGraph === void 0) try {
|
|
7103
7104
|
const wgRepo = new WorkGraphRepository(adapter);
|
|
@@ -7134,10 +7135,10 @@ async function runStatusAction(options) {
|
|
|
7134
7135
|
};
|
|
7135
7136
|
}
|
|
7136
7137
|
} catch (err) {
|
|
7137
|
-
logger$
|
|
7138
|
+
logger$17.debug({ err }, "Work graph query failed, continuing without work graph data");
|
|
7138
7139
|
}
|
|
7139
7140
|
if (run === void 0) {
|
|
7140
|
-
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-
|
|
7141
|
+
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-4VCoTtz_.js");
|
|
7141
7142
|
const substrateDirPath = join(projectRoot, ".substrate");
|
|
7142
7143
|
const processInfo = inspectProcessTree$1({
|
|
7143
7144
|
projectRoot,
|
|
@@ -7296,7 +7297,7 @@ async function runStatusAction(options) {
|
|
|
7296
7297
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7297
7298
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
7298
7299
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
7299
|
-
logger$
|
|
7300
|
+
logger$17.error({ err }, "status action failed");
|
|
7300
7301
|
return 1;
|
|
7301
7302
|
} finally {
|
|
7302
7303
|
try {
|
|
@@ -7640,7 +7641,7 @@ Analyze thoroughly and return ONLY the JSON array with no additional text.`;
|
|
|
7640
7641
|
|
|
7641
7642
|
//#endregion
|
|
7642
7643
|
//#region src/cli/commands/amend.ts
|
|
7643
|
-
const logger$
|
|
7644
|
+
const logger$16 = createLogger("amend-cmd");
|
|
7644
7645
|
/**
|
|
7645
7646
|
* Detect and apply supersessions after a phase completes in an amendment run.
|
|
7646
7647
|
*
|
|
@@ -7671,7 +7672,7 @@ async function runPostPhaseSupersessionDetection(adapter, amendmentRunId, curren
|
|
|
7671
7672
|
});
|
|
7672
7673
|
} catch (err) {
|
|
7673
7674
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7674
|
-
logger$
|
|
7675
|
+
logger$16.warn({
|
|
7675
7676
|
err,
|
|
7676
7677
|
originalId: parentMatch.id,
|
|
7677
7678
|
supersedingId: newDec.id
|
|
@@ -7779,7 +7780,8 @@ async function runAmendAction(options) {
|
|
|
7779
7780
|
pack,
|
|
7780
7781
|
contextCompiler,
|
|
7781
7782
|
dispatcher,
|
|
7782
|
-
agentId
|
|
7783
|
+
agentId,
|
|
7784
|
+
eventBus
|
|
7783
7785
|
};
|
|
7784
7786
|
const phaseOrder = [
|
|
7785
7787
|
"analysis",
|
|
@@ -7808,7 +7810,7 @@ async function runAmendAction(options) {
|
|
|
7808
7810
|
for (let i = startIdx; i < phaseOrder.length; i++) {
|
|
7809
7811
|
const currentPhase = phaseOrder[i];
|
|
7810
7812
|
const amendmentContext = handler.loadContextForPhase(currentPhase);
|
|
7811
|
-
logger$
|
|
7813
|
+
logger$16.info({
|
|
7812
7814
|
phase: currentPhase,
|
|
7813
7815
|
amendmentContextLen: amendmentContext.length
|
|
7814
7816
|
}, "Amendment context loaded for phase");
|
|
@@ -7929,7 +7931,7 @@ async function runAmendAction(options) {
|
|
|
7929
7931
|
} catch (err) {
|
|
7930
7932
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7931
7933
|
process.stderr.write(`Error: ${msg}\n`);
|
|
7932
|
-
logger$
|
|
7934
|
+
logger$16.error({ err }, "amend failed");
|
|
7933
7935
|
return 1;
|
|
7934
7936
|
} finally {
|
|
7935
7937
|
try {
|
|
@@ -8666,7 +8668,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
8666
8668
|
await initSchema(expAdapter);
|
|
8667
8669
|
const { runRunAction: runPipeline } = await import(
|
|
8668
8670
|
/* @vite-ignore */
|
|
8669
|
-
"../run-
|
|
8671
|
+
"../run-CTfGK9yU.js"
|
|
8670
8672
|
);
|
|
8671
8673
|
const runStoryFn = async (opts) => {
|
|
8672
8674
|
const exitCode = await runPipeline({
|
|
@@ -8916,7 +8918,7 @@ function registerSupervisorCommand(program, _version = "0.0.0", projectRoot = pr
|
|
|
8916
8918
|
|
|
8917
8919
|
//#endregion
|
|
8918
8920
|
//#region src/cli/commands/metrics.ts
|
|
8919
|
-
const logger$
|
|
8921
|
+
const logger$15 = createLogger("metrics-cmd");
|
|
8920
8922
|
async function openTelemetryAdapter(basePath) {
|
|
8921
8923
|
try {
|
|
8922
8924
|
const adapter = createDatabaseAdapter({
|
|
@@ -9275,7 +9277,7 @@ async function runMetricsAction(options) {
|
|
|
9275
9277
|
}
|
|
9276
9278
|
}
|
|
9277
9279
|
} catch (err) {
|
|
9278
|
-
logger$
|
|
9280
|
+
logger$15.debug({ err }, "getScenarioResultsForRun failed");
|
|
9279
9281
|
}
|
|
9280
9282
|
if (rows.length === 0) {
|
|
9281
9283
|
const msg = `No factory run found with id: ${run}`;
|
|
@@ -9311,7 +9313,7 @@ async function runMetricsAction(options) {
|
|
|
9311
9313
|
}
|
|
9312
9314
|
}
|
|
9313
9315
|
} catch (err) {
|
|
9314
|
-
logger$
|
|
9316
|
+
logger$15.debug({ err }, "getTwinRunsForRun failed — twin_runs table may not exist yet");
|
|
9315
9317
|
}
|
|
9316
9318
|
}
|
|
9317
9319
|
return 0;
|
|
@@ -9321,7 +9323,7 @@ async function runMetricsAction(options) {
|
|
|
9321
9323
|
try {
|
|
9322
9324
|
factoryRuns$1 = await getFactoryRunSummaries(adapter, limit);
|
|
9323
9325
|
} catch (err) {
|
|
9324
|
-
logger$
|
|
9326
|
+
logger$15.debug({ err }, "getFactoryRunSummaries failed in factory-only mode");
|
|
9325
9327
|
}
|
|
9326
9328
|
if (outputFormat === "json") process.stdout.write(formatOutput({ graph_runs: factoryRuns$1 }, "json", true) + "\n");
|
|
9327
9329
|
else if (factoryRuns$1.length === 0) process.stdout.write("No factory runs recorded yet.\n");
|
|
@@ -9424,7 +9426,7 @@ async function runMetricsAction(options) {
|
|
|
9424
9426
|
try {
|
|
9425
9427
|
factoryRuns = await getFactoryRunSummaries(adapter, limit);
|
|
9426
9428
|
} catch (err) {
|
|
9427
|
-
logger$
|
|
9429
|
+
logger$15.debug({ err }, "getFactoryRunSummaries failed — table may not exist in older databases");
|
|
9428
9430
|
}
|
|
9429
9431
|
if (outputFormat === "json") {
|
|
9430
9432
|
const runsWithBreakdown = runs.map((run$1) => ({
|
|
@@ -9510,7 +9512,7 @@ async function runMetricsAction(options) {
|
|
|
9510
9512
|
const msg = err instanceof Error ? err.message : String(err);
|
|
9511
9513
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
9512
9514
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
9513
|
-
logger$
|
|
9515
|
+
logger$15.error({ err }, "metrics action failed");
|
|
9514
9516
|
return 1;
|
|
9515
9517
|
} finally {
|
|
9516
9518
|
try {
|
|
@@ -9566,7 +9568,7 @@ function registerMetricsCommand(program, _version = "0.0.0", projectRoot = proce
|
|
|
9566
9568
|
function getLatestSessionId(_adapter) {
|
|
9567
9569
|
return null;
|
|
9568
9570
|
}
|
|
9569
|
-
const logger$
|
|
9571
|
+
const logger$14 = createLogger("cost-cmd");
|
|
9570
9572
|
const COST_EXIT_SUCCESS = 0;
|
|
9571
9573
|
const COST_EXIT_ERROR = 1;
|
|
9572
9574
|
/**
|
|
@@ -9810,7 +9812,7 @@ async function runCostAction(options) {
|
|
|
9810
9812
|
} catch (err) {
|
|
9811
9813
|
const message = err instanceof Error ? err.message : String(err);
|
|
9812
9814
|
process.stderr.write(`Error: ${message}\n`);
|
|
9813
|
-
logger$
|
|
9815
|
+
logger$14.error({ err }, "runCostAction failed");
|
|
9814
9816
|
return COST_EXIT_ERROR;
|
|
9815
9817
|
} finally {
|
|
9816
9818
|
if (adapter !== null) try {
|
|
@@ -9844,7 +9846,7 @@ function registerCostCommand(program, version = "0.0.0", projectRoot = process.c
|
|
|
9844
9846
|
|
|
9845
9847
|
//#endregion
|
|
9846
9848
|
//#region src/cli/commands/monitor.ts
|
|
9847
|
-
const logger$
|
|
9849
|
+
const logger$13 = createLogger("monitor-cmd");
|
|
9848
9850
|
const MONITOR_EXIT_SUCCESS = 0;
|
|
9849
9851
|
const MONITOR_EXIT_ERROR = 1;
|
|
9850
9852
|
/**
|
|
@@ -10047,7 +10049,7 @@ async function runMonitorReportAction(options) {
|
|
|
10047
10049
|
} catch (err) {
|
|
10048
10050
|
const message = err instanceof Error ? err.message : String(err);
|
|
10049
10051
|
process.stderr.write(`Error: ${message}\n`);
|
|
10050
|
-
logger$
|
|
10052
|
+
logger$13.error({ err }, "runMonitorReportAction failed");
|
|
10051
10053
|
return MONITOR_EXIT_ERROR;
|
|
10052
10054
|
} finally {
|
|
10053
10055
|
if (monitorDb !== null) try {
|
|
@@ -10109,7 +10111,7 @@ async function runMonitorStatusAction(options) {
|
|
|
10109
10111
|
} catch (err) {
|
|
10110
10112
|
const message = err instanceof Error ? err.message : String(err);
|
|
10111
10113
|
process.stderr.write(`Error: ${message}\n`);
|
|
10112
|
-
logger$
|
|
10114
|
+
logger$13.error({ err }, "runMonitorStatusAction failed");
|
|
10113
10115
|
return MONITOR_EXIT_ERROR;
|
|
10114
10116
|
} finally {
|
|
10115
10117
|
if (monitorDb !== null) try {
|
|
@@ -10144,7 +10146,7 @@ async function runMonitorResetAction(options) {
|
|
|
10144
10146
|
} catch (err) {
|
|
10145
10147
|
const message = err instanceof Error ? err.message : String(err);
|
|
10146
10148
|
process.stderr.write(`Error: ${message}\n`);
|
|
10147
|
-
logger$
|
|
10149
|
+
logger$13.error({ err }, "runMonitorResetAction failed");
|
|
10148
10150
|
return MONITOR_EXIT_ERROR;
|
|
10149
10151
|
} finally {
|
|
10150
10152
|
if (monitorDb !== null) try {
|
|
@@ -10192,7 +10194,7 @@ async function runMonitorRecommendationsAction(options) {
|
|
|
10192
10194
|
} catch (err) {
|
|
10193
10195
|
const message = err instanceof Error ? err.message : String(err);
|
|
10194
10196
|
process.stderr.write(`Error: ${message}\n`);
|
|
10195
|
-
logger$
|
|
10197
|
+
logger$13.error({ err }, "runMonitorRecommendationsAction failed");
|
|
10196
10198
|
return MONITOR_EXIT_ERROR;
|
|
10197
10199
|
} finally {
|
|
10198
10200
|
if (monitorDb !== null) try {
|
|
@@ -10270,7 +10272,7 @@ function registerMonitorCommand(program, version = "0.0.0", projectRoot = proces
|
|
|
10270
10272
|
|
|
10271
10273
|
//#endregion
|
|
10272
10274
|
//#region src/cli/commands/merge.ts
|
|
10273
|
-
const logger$
|
|
10275
|
+
const logger$12 = createLogger("merge-cmd");
|
|
10274
10276
|
const MERGE_EXIT_SUCCESS = 0;
|
|
10275
10277
|
const MERGE_EXIT_CONFLICT = 1;
|
|
10276
10278
|
const MERGE_EXIT_ERROR = 2;
|
|
@@ -10308,7 +10310,7 @@ async function mergeTask(taskId, targetBranch, projectRoot) {
|
|
|
10308
10310
|
projectRoot
|
|
10309
10311
|
});
|
|
10310
10312
|
try {
|
|
10311
|
-
logger$
|
|
10313
|
+
logger$12.info({
|
|
10312
10314
|
taskId,
|
|
10313
10315
|
targetBranch
|
|
10314
10316
|
}, "Running conflict detection...");
|
|
@@ -10330,7 +10332,7 @@ async function mergeTask(taskId, targetBranch, projectRoot) {
|
|
|
10330
10332
|
} catch (err) {
|
|
10331
10333
|
const message = err instanceof Error ? err.message : String(err);
|
|
10332
10334
|
console.error(`Error merging task "${taskId}": ${message}`);
|
|
10333
|
-
logger$
|
|
10335
|
+
logger$12.error({
|
|
10334
10336
|
taskId,
|
|
10335
10337
|
err
|
|
10336
10338
|
}, "merge --task failed");
|
|
@@ -10384,7 +10386,7 @@ async function mergeAll(targetBranch, projectRoot, taskIds) {
|
|
|
10384
10386
|
error: message
|
|
10385
10387
|
});
|
|
10386
10388
|
console.log(` Error for task "${taskId}": ${message}`);
|
|
10387
|
-
logger$
|
|
10389
|
+
logger$12.error({
|
|
10388
10390
|
taskId,
|
|
10389
10391
|
err
|
|
10390
10392
|
}, "merge --all: task failed");
|
|
@@ -10437,7 +10439,7 @@ function registerMergeCommand(program, projectRoot = process.cwd()) {
|
|
|
10437
10439
|
|
|
10438
10440
|
//#endregion
|
|
10439
10441
|
//#region src/cli/commands/worktrees.ts
|
|
10440
|
-
const logger$
|
|
10442
|
+
const logger$11 = createLogger("worktrees-cmd");
|
|
10441
10443
|
const WORKTREES_EXIT_SUCCESS = 0;
|
|
10442
10444
|
const WORKTREES_EXIT_ERROR = 1;
|
|
10443
10445
|
/** Valid task statuses for filtering */
|
|
@@ -10564,7 +10566,7 @@ async function listWorktreesAction(options) {
|
|
|
10564
10566
|
try {
|
|
10565
10567
|
worktreeInfos = await manager.listWorktrees();
|
|
10566
10568
|
} catch (err) {
|
|
10567
|
-
logger$
|
|
10569
|
+
logger$11.error({ err }, "Failed to list worktrees");
|
|
10568
10570
|
const message = err instanceof Error ? err.message : String(err);
|
|
10569
10571
|
process.stderr.write(`Error listing worktrees: ${message}\n`);
|
|
10570
10572
|
return WORKTREES_EXIT_ERROR;
|
|
@@ -10591,7 +10593,7 @@ async function listWorktreesAction(options) {
|
|
|
10591
10593
|
} catch (err) {
|
|
10592
10594
|
const message = err instanceof Error ? err.message : String(err);
|
|
10593
10595
|
process.stderr.write(`Error: ${message}\n`);
|
|
10594
|
-
logger$
|
|
10596
|
+
logger$11.error({ err }, "listWorktreesAction failed");
|
|
10595
10597
|
return WORKTREES_EXIT_ERROR;
|
|
10596
10598
|
}
|
|
10597
10599
|
}
|
|
@@ -10620,7 +10622,7 @@ async function cleanupWorktreesAction(options) {
|
|
|
10620
10622
|
} catch (err) {
|
|
10621
10623
|
const message = err instanceof Error ? err.message : String(err);
|
|
10622
10624
|
process.stderr.write(`Error cleaning up worktree for task "${taskId}": ${message}\n`);
|
|
10623
|
-
logger$
|
|
10625
|
+
logger$11.error({
|
|
10624
10626
|
err,
|
|
10625
10627
|
taskId
|
|
10626
10628
|
}, "cleanupWorktreesAction (single) failed");
|
|
@@ -10634,13 +10636,13 @@ async function cleanupWorktreesAction(options) {
|
|
|
10634
10636
|
} catch (err) {
|
|
10635
10637
|
const message = err instanceof Error ? err.message : String(err);
|
|
10636
10638
|
process.stderr.write(`Error during bulk cleanup: ${message}\n`);
|
|
10637
|
-
logger$
|
|
10639
|
+
logger$11.error({ err }, "cleanupWorktreesAction (bulk) failed");
|
|
10638
10640
|
return WORKTREES_EXIT_ERROR;
|
|
10639
10641
|
}
|
|
10640
10642
|
} catch (err) {
|
|
10641
10643
|
const message = err instanceof Error ? err.message : String(err);
|
|
10642
10644
|
process.stderr.write(`Error: ${message}\n`);
|
|
10643
|
-
logger$
|
|
10645
|
+
logger$11.error({ err }, "cleanupWorktreesAction failed");
|
|
10644
10646
|
return WORKTREES_EXIT_ERROR;
|
|
10645
10647
|
}
|
|
10646
10648
|
}
|
|
@@ -10691,7 +10693,7 @@ function registerWorktreesCommand(program, version = "0.0.0", projectRoot = proc
|
|
|
10691
10693
|
|
|
10692
10694
|
//#endregion
|
|
10693
10695
|
//#region src/cli/commands/brainstorm.ts
|
|
10694
|
-
const logger$
|
|
10696
|
+
const logger$10 = createLogger("brainstorm-cmd");
|
|
10695
10697
|
/**
|
|
10696
10698
|
* Detect whether the project has existing planning artifacts that indicate
|
|
10697
10699
|
* this is an amendment session (vs. a brand-new project brainstorm).
|
|
@@ -10737,13 +10739,13 @@ async function loadAmendmentContextDocuments(projectRoot) {
|
|
|
10737
10739
|
try {
|
|
10738
10740
|
brief = await readFile(briefPath, "utf-8");
|
|
10739
10741
|
} catch {
|
|
10740
|
-
logger$
|
|
10742
|
+
logger$10.warn({ briefPath }, "product-brief.md not found — continuing without brief context");
|
|
10741
10743
|
process.stderr.write(`Warning: product-brief.md not found at ${briefPath}\n`);
|
|
10742
10744
|
}
|
|
10743
10745
|
try {
|
|
10744
10746
|
prd = await readFile(prdPath, "utf-8");
|
|
10745
10747
|
} catch {
|
|
10746
|
-
logger$
|
|
10748
|
+
logger$10.warn({ prdPath }, "requirements.md not found — continuing without PRD context");
|
|
10747
10749
|
process.stderr.write(`Warning: requirements.md not found at ${prdPath}\n`);
|
|
10748
10750
|
}
|
|
10749
10751
|
return {
|
|
@@ -10952,7 +10954,7 @@ async function dispatchToPersonas(userPrompt, context, llmDispatch) {
|
|
|
10952
10954
|
}
|
|
10953
10955
|
];
|
|
10954
10956
|
const defaultDispatch = async (prompt, personaName) => {
|
|
10955
|
-
logger$
|
|
10957
|
+
logger$10.debug({
|
|
10956
10958
|
personaName,
|
|
10957
10959
|
promptLength: prompt.length
|
|
10958
10960
|
}, "Dispatching to persona (stub mode)");
|
|
@@ -10969,7 +10971,7 @@ async function dispatchToPersonas(userPrompt, context, llmDispatch) {
|
|
|
10969
10971
|
};
|
|
10970
10972
|
} catch (err) {
|
|
10971
10973
|
const msg = err instanceof Error ? err.message : String(err);
|
|
10972
|
-
logger$
|
|
10974
|
+
logger$10.error({
|
|
10973
10975
|
err,
|
|
10974
10976
|
personaName: persona.name
|
|
10975
10977
|
}, "Persona dispatch failed");
|
|
@@ -11121,7 +11123,7 @@ async function runBrainstormSession(options, llmDispatch, rlInterface) {
|
|
|
11121
11123
|
}
|
|
11122
11124
|
});
|
|
11123
11125
|
rl.on("error", (err) => {
|
|
11124
|
-
logger$
|
|
11126
|
+
logger$10.error({ err }, "readline error");
|
|
11125
11127
|
if (!sessionEnded) endSession(false);
|
|
11126
11128
|
});
|
|
11127
11129
|
});
|
|
@@ -11162,7 +11164,7 @@ function registerBrainstormCommand(program, _version = "0.0.0", projectRoot = pr
|
|
|
11162
11164
|
|
|
11163
11165
|
//#endregion
|
|
11164
11166
|
//#region src/cli/commands/retry-escalated.ts
|
|
11165
|
-
const logger$
|
|
11167
|
+
const logger$9 = createLogger("retry-escalated-cmd");
|
|
11166
11168
|
async function runRetryEscalatedAction(options) {
|
|
11167
11169
|
const { runId, dryRun, force, outputFormat, projectRoot, concurrency, pack: packName, registry: injectedRegistry, agent: agentId, events: eventsFlag } = options;
|
|
11168
11170
|
const dbRoot = await resolveMainRepoRoot(projectRoot);
|
|
@@ -11203,7 +11205,7 @@ async function runRetryEscalatedAction(options) {
|
|
|
11203
11205
|
process.stdout.write(`[INFO] ${storyKey}: Context ceiling set to ${contextCeiling} tokens due to prior context spike pattern.\n`);
|
|
11204
11206
|
}
|
|
11205
11207
|
} catch (err) {
|
|
11206
|
-
logger$
|
|
11208
|
+
logger$9.warn({
|
|
11207
11209
|
err,
|
|
11208
11210
|
storyKey
|
|
11209
11211
|
}, "Failed to read efficiency profile — skipping gate");
|
|
@@ -11365,11 +11367,11 @@ async function runRetryEscalatedAction(options) {
|
|
|
11365
11367
|
output_tokens: output,
|
|
11366
11368
|
cost_usd: costUsd
|
|
11367
11369
|
}).catch((err) => {
|
|
11368
|
-
logger$
|
|
11370
|
+
logger$9.warn({ err }, "Failed to record token usage");
|
|
11369
11371
|
});
|
|
11370
11372
|
}
|
|
11371
11373
|
} catch (err) {
|
|
11372
|
-
logger$
|
|
11374
|
+
logger$9.warn({ err }, "Failed to record token usage");
|
|
11373
11375
|
}
|
|
11374
11376
|
});
|
|
11375
11377
|
if (outputFormat === "human") {
|
|
@@ -11398,7 +11400,7 @@ async function runRetryEscalatedAction(options) {
|
|
|
11398
11400
|
const msg = err instanceof Error ? err.message : String(err);
|
|
11399
11401
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
11400
11402
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
11401
|
-
logger$
|
|
11403
|
+
logger$9.error({ err }, "retry-escalated failed");
|
|
11402
11404
|
return 1;
|
|
11403
11405
|
} finally {
|
|
11404
11406
|
try {
|
|
@@ -11431,7 +11433,7 @@ function registerRetryEscalatedCommand(program, _version = "0.0.0", projectRoot
|
|
|
11431
11433
|
|
|
11432
11434
|
//#endregion
|
|
11433
11435
|
//#region src/cli/commands/cancel.ts
|
|
11434
|
-
const logger$
|
|
11436
|
+
const logger$8 = createLogger("cancel-cmd");
|
|
11435
11437
|
async function runCancelAction(options) {
|
|
11436
11438
|
const { outputFormat, projectRoot, force } = options;
|
|
11437
11439
|
const dbRoot = await resolveMainRepoRoot(projectRoot);
|
|
@@ -11470,7 +11472,7 @@ async function runCancelAction(options) {
|
|
|
11470
11472
|
}
|
|
11471
11473
|
} catch (err) {
|
|
11472
11474
|
const msg = err instanceof Error ? err.message : String(err);
|
|
11473
|
-
logger$
|
|
11475
|
+
logger$8.warn({
|
|
11474
11476
|
pid,
|
|
11475
11477
|
err: msg
|
|
11476
11478
|
}, "Failed to kill orchestrator");
|
|
@@ -11500,7 +11502,7 @@ async function runCancelAction(options) {
|
|
|
11500
11502
|
await adapter.close();
|
|
11501
11503
|
}
|
|
11502
11504
|
} catch (err) {
|
|
11503
|
-
logger$
|
|
11505
|
+
logger$8.warn({ err }, "Could not update pipeline run status (non-fatal)");
|
|
11504
11506
|
}
|
|
11505
11507
|
if (outputFormat === "json") process.stdout.write(formatOutput({
|
|
11506
11508
|
cancelled: true,
|
|
@@ -11653,7 +11655,7 @@ function emitDiff(diff, ctx) {
|
|
|
11653
11655
|
|
|
11654
11656
|
//#endregion
|
|
11655
11657
|
//#region src/cli/commands/probe-author.ts
|
|
11656
|
-
const logger$
|
|
11658
|
+
const logger$7 = createLogger("cli:probe-author");
|
|
11657
11659
|
/**
|
|
11658
11660
|
* A minimum-viable logger that routes everything to stderr. Used by the
|
|
11659
11661
|
* subcommand to keep stdout reserved for the JSON result payload.
|
|
@@ -11722,7 +11724,7 @@ async function runProbeAuthorDispatch(opts, projectRoot, registry) {
|
|
|
11722
11724
|
logger: stderrLogger
|
|
11723
11725
|
});
|
|
11724
11726
|
const workingDir = opts.workingDir !== void 0 ? resolve$1(opts.workingDir) : resolve$1(storyFilePath, "..");
|
|
11725
|
-
logger$
|
|
11727
|
+
logger$7.info({
|
|
11726
11728
|
storyKey: opts.storyKey,
|
|
11727
11729
|
storyFile: storyFilePath,
|
|
11728
11730
|
epicFile: epicFilePath,
|
|
@@ -11944,7 +11946,7 @@ function registerHistoryCommand(program) {
|
|
|
11944
11946
|
|
|
11945
11947
|
//#endregion
|
|
11946
11948
|
//#region src/cli/commands/repo-map.ts
|
|
11947
|
-
const logger$
|
|
11949
|
+
const logger$6 = createLogger("cli:repo-map");
|
|
11948
11950
|
/** Validate that a symbol name contains only safe identifier characters. */
|
|
11949
11951
|
function isValidSymbolName(name) {
|
|
11950
11952
|
return /^[a-zA-Z0-9_]+$/.test(name);
|
|
@@ -11979,15 +11981,15 @@ function registerRepoMapCommand(program) {
|
|
|
11979
11981
|
const colRows = await doltClient.query(`SHOW COLUMNS FROM repo_map_symbols LIKE 'dependencies'`);
|
|
11980
11982
|
if (colRows.length === 0) {
|
|
11981
11983
|
await doltClient.query(`ALTER TABLE repo_map_symbols ADD COLUMN dependencies JSON`);
|
|
11982
|
-
logger$
|
|
11984
|
+
logger$6.info("Applied migration: added dependencies column to repo_map_symbols");
|
|
11983
11985
|
}
|
|
11984
11986
|
} catch {
|
|
11985
|
-
logger$
|
|
11987
|
+
logger$6.debug("Skipping repo_map_symbols migration: table not yet created");
|
|
11986
11988
|
}
|
|
11987
|
-
const symbolRepo = new DoltSymbolRepository(doltClient, logger$
|
|
11989
|
+
const symbolRepo = new DoltSymbolRepository(doltClient, logger$6);
|
|
11988
11990
|
const metaRepo = new DoltRepoMapMetaRepository(doltClient);
|
|
11989
|
-
const repoMapModule = new RepoMapModule(metaRepo, logger$
|
|
11990
|
-
const queryEngine = new RepoMapQueryEngine(symbolRepo, logger$
|
|
11991
|
+
const repoMapModule = new RepoMapModule(metaRepo, logger$6);
|
|
11992
|
+
const queryEngine = new RepoMapQueryEngine(symbolRepo, logger$6);
|
|
11991
11993
|
if (options.show === true || !options.update && !options.query && !options.dryRun) {
|
|
11992
11994
|
const meta = await metaRepo.getMeta();
|
|
11993
11995
|
const staleResult = await repoMapModule.checkStaleness();
|
|
@@ -12013,9 +12015,9 @@ function registerRepoMapCommand(program) {
|
|
|
12013
12015
|
return;
|
|
12014
12016
|
}
|
|
12015
12017
|
if (options.update === true) {
|
|
12016
|
-
logger$
|
|
12017
|
-
const gitClient = new GitClient(logger$
|
|
12018
|
-
const grammarLoader = new GrammarLoader(logger$
|
|
12018
|
+
logger$6.info("repo-map --update: triggering incremental update");
|
|
12019
|
+
const gitClient = new GitClient(logger$6);
|
|
12020
|
+
const grammarLoader = new GrammarLoader(logger$6);
|
|
12019
12021
|
if (grammarLoader.getGrammar(".ts") === null) {
|
|
12020
12022
|
const msg = "tree-sitter grammars not installed. Run `npm install tree-sitter tree-sitter-typescript tree-sitter-javascript tree-sitter-python` in the substrate installation directory.";
|
|
12021
12023
|
if (options.outputFormat === "json") console.log(JSON.stringify({
|
|
@@ -12026,15 +12028,15 @@ function registerRepoMapCommand(program) {
|
|
|
12026
12028
|
process.exitCode = 1;
|
|
12027
12029
|
return;
|
|
12028
12030
|
}
|
|
12029
|
-
const parser = new SymbolParser(grammarLoader, logger$
|
|
12030
|
-
const storage = new RepoMapStorage(symbolRepo, metaRepo, gitClient, logger$
|
|
12031
|
+
const parser = new SymbolParser(grammarLoader, logger$6);
|
|
12032
|
+
const storage = new RepoMapStorage(symbolRepo, metaRepo, gitClient, logger$6);
|
|
12031
12033
|
let updateWarning;
|
|
12032
12034
|
try {
|
|
12033
12035
|
await storage.incrementalUpdate(dbRoot, parser);
|
|
12034
12036
|
} catch (err) {
|
|
12035
12037
|
if (err instanceof AppError && err.code === ERR_REPO_MAP_STORAGE_WRITE) {
|
|
12036
12038
|
updateWarning = err.message;
|
|
12037
|
-
logger$
|
|
12039
|
+
logger$6.warn({ err }, "repo-map --update: storage write error (partial update)");
|
|
12038
12040
|
} else throw err;
|
|
12039
12041
|
}
|
|
12040
12042
|
const meta = await metaRepo.getMeta();
|
|
@@ -12054,7 +12056,7 @@ function registerRepoMapCommand(program) {
|
|
|
12054
12056
|
return;
|
|
12055
12057
|
}
|
|
12056
12058
|
if (options.query !== void 0) {
|
|
12057
|
-
logger$
|
|
12059
|
+
logger$6.debug({ symbol: options.query }, "repo-map --query");
|
|
12058
12060
|
const result = await queryEngine.query({
|
|
12059
12061
|
symbols: [options.query],
|
|
12060
12062
|
maxTokens: 4e3
|
|
@@ -12076,7 +12078,7 @@ function registerRepoMapCommand(program) {
|
|
|
12076
12078
|
process.exitCode = 1;
|
|
12077
12079
|
return;
|
|
12078
12080
|
}
|
|
12079
|
-
const injector = new RepoMapInjector(queryEngine, logger$
|
|
12081
|
+
const injector = new RepoMapInjector(queryEngine, logger$6);
|
|
12080
12082
|
const injectionResult = await injector.buildContext(storyContent, 2e3);
|
|
12081
12083
|
console.log(JSON.stringify({
|
|
12082
12084
|
text: injectionResult.text,
|
|
@@ -12090,7 +12092,7 @@ function registerRepoMapCommand(program) {
|
|
|
12090
12092
|
|
|
12091
12093
|
//#endregion
|
|
12092
12094
|
//#region src/cli/commands/routing.ts
|
|
12093
|
-
const logger$
|
|
12095
|
+
const logger$5 = createLogger("cli:routing");
|
|
12094
12096
|
function registerRoutingCommand(program) {
|
|
12095
12097
|
program.command("routing").description("Show routing configuration and auto-tune history").option("--history", "Show the routing auto-tune log (model changes applied)").option("--output-format <format>", "Output format: text or json", "text").action(async (options) => {
|
|
12096
12098
|
const dbRoot = await resolveMainRepoRoot(process.cwd());
|
|
@@ -12098,7 +12100,7 @@ function registerRoutingCommand(program) {
|
|
|
12098
12100
|
try {
|
|
12099
12101
|
await store.initialize();
|
|
12100
12102
|
if (options.history === true) {
|
|
12101
|
-
logger$
|
|
12103
|
+
logger$5.debug("routing --history: fetching tune log");
|
|
12102
12104
|
const raw$1 = await store.getMetric("global", "routing_tune_log");
|
|
12103
12105
|
let entries = [];
|
|
12104
12106
|
if (Array.isArray(raw$1)) entries = raw$1.sort((a, b) => b.appliedAt.localeCompare(a.appliedAt));
|
|
@@ -12393,7 +12395,7 @@ function registerFactoryCommand$1(program) {
|
|
|
12393
12395
|
|
|
12394
12396
|
//#endregion
|
|
12395
12397
|
//#region src/cli/commands/reconcile-from-disk.ts
|
|
12396
|
-
const logger$
|
|
12398
|
+
const logger$4 = createLogger("reconcile-from-disk");
|
|
12397
12399
|
/**
|
|
12398
12400
|
* The reconcile write (obs_2026-05-26_031). Keyed on `story_key` ALONE —
|
|
12399
12401
|
* `wg_stories` has no `run_id` column (cols: story_key, epic, title, status,
|
|
@@ -12465,7 +12467,7 @@ async function readRunEntry(dbRoot, resolvedRunId) {
|
|
|
12465
12467
|
stories
|
|
12466
12468
|
};
|
|
12467
12469
|
} catch {
|
|
12468
|
-
logger$
|
|
12470
|
+
logger$4.debug({ runId: resolvedRunId }, "failed to read individual run manifest");
|
|
12469
12471
|
return null;
|
|
12470
12472
|
}
|
|
12471
12473
|
}
|
|
@@ -12600,7 +12602,7 @@ async function runReconcileFromDiskAction(options) {
|
|
|
12600
12602
|
const latestRun = await getLatestRun(probeAdapter);
|
|
12601
12603
|
if (latestRun?.id) resolvedRunId = latestRun.id;
|
|
12602
12604
|
} catch {
|
|
12603
|
-
logger$
|
|
12605
|
+
logger$4.debug("Dolt fallback failed during run-id resolution");
|
|
12604
12606
|
} finally {
|
|
12605
12607
|
await probeAdapter.close().catch(swallowDebug("reconcile-probe-close"));
|
|
12606
12608
|
}
|
|
@@ -12681,7 +12683,7 @@ async function runReconcileFromDiskAction(options) {
|
|
|
12681
12683
|
stdoutTail: failedGateResult?.stdoutTail,
|
|
12682
12684
|
durationMs: durationMs$1
|
|
12683
12685
|
});
|
|
12684
|
-
logger$
|
|
12686
|
+
logger$4.info({
|
|
12685
12687
|
runId: resolvedRunId,
|
|
12686
12688
|
failedGate: failedGateName,
|
|
12687
12689
|
exitCode: failedGateResult?.exitCode
|
|
@@ -12739,7 +12741,7 @@ async function runReconcileFromDiskAction(options) {
|
|
|
12739
12741
|
record.storyKey
|
|
12740
12742
|
]);
|
|
12741
12743
|
});
|
|
12742
|
-
logger$
|
|
12744
|
+
logger$4.info({
|
|
12743
12745
|
runId: resolvedRunId,
|
|
12744
12746
|
affectedStories: reconcilableRecords.map((r) => r.storyKey)
|
|
12745
12747
|
}, "reconcile-from-disk: Dolt update complete");
|
|
@@ -12794,7 +12796,7 @@ function registerReconcileFromDiskCommand(program, _version = "0.0.0", projectRo
|
|
|
12794
12796
|
|
|
12795
12797
|
//#endregion
|
|
12796
12798
|
//#region src/cli/commands/report.ts
|
|
12797
|
-
const logger$
|
|
12799
|
+
const logger$3 = createLogger("report");
|
|
12798
12800
|
/**
|
|
12799
12801
|
* v0.20.110: Minimum output_tokens for a verified/recovered story to be
|
|
12800
12802
|
* trusted as having actually produced work. Below this, the story is flagged
|
|
@@ -12949,7 +12951,7 @@ async function readNotificationsForRun(runId, dbRoot) {
|
|
|
12949
12951
|
const parsed = JSON.parse(raw);
|
|
12950
12952
|
notifications.push(parsed);
|
|
12951
12953
|
} catch (err) {
|
|
12952
|
-
if (err.code !== "ENOENT") logger$
|
|
12954
|
+
if (err.code !== "ENOENT") logger$3.warn({
|
|
12953
12955
|
err,
|
|
12954
12956
|
filePath
|
|
12955
12957
|
}, "failed to read notification file — skipping");
|
|
@@ -12958,7 +12960,7 @@ async function readNotificationsForRun(runId, dbRoot) {
|
|
|
12958
12960
|
try {
|
|
12959
12961
|
await unlink(filePath);
|
|
12960
12962
|
} catch (err) {
|
|
12961
|
-
if (err.code !== "ENOENT") logger$
|
|
12963
|
+
if (err.code !== "ENOENT") logger$3.warn({
|
|
12962
12964
|
err,
|
|
12963
12965
|
filePath
|
|
12964
12966
|
}, "failed to delete notification file — continuing");
|
|
@@ -13291,7 +13293,7 @@ async function resolveLatestRunId(dbRoot) {
|
|
|
13291
13293
|
const latest = await getLatestRun(probeAdapter);
|
|
13292
13294
|
return latest?.id ?? null;
|
|
13293
13295
|
} catch {
|
|
13294
|
-
logger$
|
|
13296
|
+
logger$3.debug("Dolt fallback failed during run-id resolution");
|
|
13295
13297
|
return null;
|
|
13296
13298
|
} finally {
|
|
13297
13299
|
await probeAdapter.close().catch(swallowDebug("report-probe-close"));
|
|
@@ -13302,7 +13304,7 @@ async function runReportAction(options) {
|
|
|
13302
13304
|
const effectiveProjectRoot = process.env["SUBSTRATE_PROJECT_ROOT"] ?? projectRoot;
|
|
13303
13305
|
const dbRoot = _dbRoot ?? await resolveMainRepoRoot(effectiveProjectRoot);
|
|
13304
13306
|
const runsDir = join(dbRoot, ".substrate", "runs");
|
|
13305
|
-
logger$
|
|
13307
|
+
logger$3.debug({
|
|
13306
13308
|
runArg,
|
|
13307
13309
|
effectiveProjectRoot,
|
|
13308
13310
|
dbRoot
|
|
@@ -13317,7 +13319,7 @@ async function runReportAction(options) {
|
|
|
13317
13319
|
const data = await canonical.manifest.read();
|
|
13318
13320
|
manifest = data;
|
|
13319
13321
|
} catch {
|
|
13320
|
-
logger$
|
|
13322
|
+
logger$3.debug({ runId: resolvedRunId }, "canonical manifest read failed — using raw shim");
|
|
13321
13323
|
}
|
|
13322
13324
|
if (!manifest) manifest = await readRawManifest(runsDir, resolvedRunId);
|
|
13323
13325
|
} else {
|
|
@@ -13328,7 +13330,7 @@ async function runReportAction(options) {
|
|
|
13328
13330
|
const data = await canonical.manifest.read();
|
|
13329
13331
|
manifest = data;
|
|
13330
13332
|
} catch {
|
|
13331
|
-
logger$
|
|
13333
|
+
logger$3.debug({ runId: canonical.runId }, "canonical manifest read failed — using raw shim");
|
|
13332
13334
|
manifest = null;
|
|
13333
13335
|
}
|
|
13334
13336
|
}
|
|
@@ -13340,7 +13342,7 @@ async function runReportAction(options) {
|
|
|
13340
13342
|
const data = await reread.manifest.read();
|
|
13341
13343
|
manifest = data;
|
|
13342
13344
|
} catch {
|
|
13343
|
-
logger$
|
|
13345
|
+
logger$3.debug({ runId: resolvedRunId }, "manifest read failed after Dolt resolution");
|
|
13344
13346
|
}
|
|
13345
13347
|
if (!manifest) manifest = await readRawManifest(runsDir, resolvedRunId);
|
|
13346
13348
|
}
|
|
@@ -13369,18 +13371,18 @@ async function runReportAction(options) {
|
|
|
13369
13371
|
const state = manifest.per_story_state[row.story_key];
|
|
13370
13372
|
if (state && !state.completed_at && row.completed_at) state.completed_at = row.completed_at;
|
|
13371
13373
|
}
|
|
13372
|
-
logger$
|
|
13374
|
+
logger$3.debug({ storyCount: rows.length }, "Dolt wg_stories enrichment applied");
|
|
13373
13375
|
}
|
|
13374
13376
|
} catch (err) {
|
|
13375
|
-
logger$
|
|
13377
|
+
logger$3.debug({ err }, "Dolt enrichment unavailable — using manifest-only data (degraded mode)");
|
|
13376
13378
|
} finally {
|
|
13377
13379
|
if (doltClient !== null) await doltClient.close().catch((err) => {
|
|
13378
|
-
logger$
|
|
13380
|
+
logger$3.debug({ err }, "DoltClient.close() failed — non-fatal");
|
|
13379
13381
|
});
|
|
13380
13382
|
}
|
|
13381
13383
|
}
|
|
13382
13384
|
const halts = await readNotificationsForRun(resolvedRunId, dbRoot).catch((err) => {
|
|
13383
|
-
logger$
|
|
13385
|
+
logger$3.debug({ err }, "notification read failed — continuing without halt data");
|
|
13384
13386
|
return [];
|
|
13385
13387
|
});
|
|
13386
13388
|
const storyOutputTokens = new Map();
|
|
@@ -13393,7 +13395,7 @@ async function runReportAction(options) {
|
|
|
13393
13395
|
const storyMetricsRows = await getStoryMetricsForRun(metricsAdapter, resolvedRunId);
|
|
13394
13396
|
for (const row of storyMetricsRows) if (typeof row.output_tokens === "number") storyOutputTokens.set(row.story_key, row.output_tokens);
|
|
13395
13397
|
} catch (err) {
|
|
13396
|
-
logger$
|
|
13398
|
+
logger$3.debug({ err }, "story_metrics read failed — low-output flagging unavailable");
|
|
13397
13399
|
} finally {
|
|
13398
13400
|
await metricsAdapter.close().catch(swallowDebug("report-metrics-close"));
|
|
13399
13401
|
}
|
|
@@ -13407,7 +13409,7 @@ async function runReportAction(options) {
|
|
|
13407
13409
|
const rmData = await rmForAc.read();
|
|
13408
13410
|
acPerStoryState = rmData.per_story_state;
|
|
13409
13411
|
} catch {
|
|
13410
|
-
logger$
|
|
13412
|
+
logger$3.debug({ runId: resolvedRunId }, "RunManifest.read() for --verify-ac failed — using raw manifest fallback");
|
|
13411
13413
|
}
|
|
13412
13414
|
const storyEntries = Object.entries(acPerStoryState);
|
|
13413
13415
|
for (const [storyKey, state] of storyEntries) {
|
|
@@ -13429,7 +13431,7 @@ async function runReportAction(options) {
|
|
|
13429
13431
|
confidence: result.confidence
|
|
13430
13432
|
};
|
|
13431
13433
|
} catch (err) {
|
|
13432
|
-
logger$
|
|
13434
|
+
logger$3.debug({
|
|
13433
13435
|
err,
|
|
13434
13436
|
storyKey
|
|
13435
13437
|
}, "ac traceability check failed for story (skipping)");
|
|
@@ -13464,9 +13466,9 @@ function registerReportCommand(program, _version = "0.0.0", projectRoot = proces
|
|
|
13464
13466
|
|
|
13465
13467
|
//#endregion
|
|
13466
13468
|
//#region src/modules/compiled-workflows/acceptance-derive.ts
|
|
13467
|
-
const logger$
|
|
13469
|
+
const logger$2 = createLogger("compiled-workflows:acceptance-derive");
|
|
13468
13470
|
/** Cap on injected source-document content (chars) — PRDs can be book-length. */
|
|
13469
|
-
const SOURCE_CONTENT_CAP = 12e4;
|
|
13471
|
+
const SOURCE_CONTENT_CAP$1 = 12e4;
|
|
13470
13472
|
/** Shape problems the schema can't express: duplicate ids, id/end-state prefix drift. */
|
|
13471
13473
|
function validateDerivedJourneys(journeys) {
|
|
13472
13474
|
if (journeys.length === 0) return "derive produced zero journeys — a PRD with no identifiable user journeys should be reported via result: failed with an error, not an empty success";
|
|
@@ -13493,7 +13495,7 @@ async function runAcceptanceDerive(deps, params) {
|
|
|
13493
13495
|
}
|
|
13494
13496
|
};
|
|
13495
13497
|
}
|
|
13496
|
-
const truncated = prdContent.length > SOURCE_CONTENT_CAP;
|
|
13498
|
+
const truncated = prdContent.length > SOURCE_CONTENT_CAP$1;
|
|
13497
13499
|
const buildPrompt = (correctivePreamble) => {
|
|
13498
13500
|
const { prompt } = assemblePrompt(template, [
|
|
13499
13501
|
{
|
|
@@ -13503,7 +13505,7 @@ async function runAcceptanceDerive(deps, params) {
|
|
|
13503
13505
|
},
|
|
13504
13506
|
{
|
|
13505
13507
|
name: "source_content",
|
|
13506
|
-
content: (truncated ? `(truncated to first ${String(SOURCE_CONTENT_CAP)} chars)\n` : "") + prdContent.slice(0, SOURCE_CONTENT_CAP),
|
|
13508
|
+
content: (truncated ? `(truncated to first ${String(SOURCE_CONTENT_CAP$1)} chars)\n` : "") + prdContent.slice(0, SOURCE_CONTENT_CAP$1),
|
|
13507
13509
|
priority: "required"
|
|
13508
13510
|
},
|
|
13509
13511
|
{
|
|
@@ -13556,7 +13558,7 @@ async function runAcceptanceDerive(deps, params) {
|
|
|
13556
13558
|
const parsed = AcceptanceDeriveResultSchema.safeParse(dispatchResult.parsed);
|
|
13557
13559
|
if (!parsed.success) {
|
|
13558
13560
|
lastProblem = `output failed schema validation (${parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ").slice(0, 500)})`;
|
|
13559
|
-
logger$
|
|
13561
|
+
logger$2.warn({
|
|
13560
13562
|
prdRelPath,
|
|
13561
13563
|
attempt,
|
|
13562
13564
|
lastProblem
|
|
@@ -13572,14 +13574,14 @@ async function runAcceptanceDerive(deps, params) {
|
|
|
13572
13574
|
const shapeProblem = validateDerivedJourneys(parsed.data.journeys);
|
|
13573
13575
|
if (shapeProblem !== void 0) {
|
|
13574
13576
|
lastProblem = shapeProblem;
|
|
13575
|
-
logger$
|
|
13577
|
+
logger$2.warn({
|
|
13576
13578
|
prdRelPath,
|
|
13577
13579
|
attempt,
|
|
13578
13580
|
shapeProblem
|
|
13579
13581
|
}, "RP1.1: derived journeys malformed");
|
|
13580
13582
|
continue;
|
|
13581
13583
|
}
|
|
13582
|
-
logger$
|
|
13584
|
+
logger$2.info({
|
|
13583
13585
|
prdRelPath,
|
|
13584
13586
|
journeys: parsed.data.journeys.map((j) => `${j.id}[${j.criticality}]`)
|
|
13585
13587
|
}, "RP1.1: derive candidates accepted");
|
|
@@ -13597,6 +13599,159 @@ async function runAcceptanceDerive(deps, params) {
|
|
|
13597
13599
|
};
|
|
13598
13600
|
}
|
|
13599
13601
|
|
|
13602
|
+
//#endregion
|
|
13603
|
+
//#region src/modules/compiled-workflows/acceptance-completeness.ts
|
|
13604
|
+
const logger$1 = createLogger("compiled-workflows:acceptance-completeness");
|
|
13605
|
+
const SOURCE_CONTENT_CAP = 12e4;
|
|
13606
|
+
function normalizeForGrounding(s) {
|
|
13607
|
+
return s.replace(/\s+/g, " ").trim().toLowerCase();
|
|
13608
|
+
}
|
|
13609
|
+
/**
|
|
13610
|
+
* Validate claims against the registry and the PRD (deterministic, no LLM):
|
|
13611
|
+
* - registered claims must cite a real journey id
|
|
13612
|
+
* - excluded claims must cite a real exclusion candidate
|
|
13613
|
+
* - every prd_span must ground in the document (≥0.6 substantive-token
|
|
13614
|
+
* overlap — the judge's F7-calibrated threshold; verbatim quotes of a
|
|
13615
|
+
* 120k-char document ground trivially, fabrications don't)
|
|
13616
|
+
*/
|
|
13617
|
+
function validateCompletenessClaims(claims, registry, prdContent) {
|
|
13618
|
+
const registered = new Set(registry.journeys.map((j) => j.id));
|
|
13619
|
+
const excluded = new Set((registry.provenance?.excluded ?? []).map((e) => e.candidate));
|
|
13620
|
+
const haystack = ` ${normalizeForGrounding(prdContent)} `;
|
|
13621
|
+
for (const claim of claims) {
|
|
13622
|
+
if (claim.disposition === "registered") {
|
|
13623
|
+
if (claim.registry_ref === void 0 || !registered.has(claim.registry_ref)) return `claim "${claim.description}" says registered but cites no real registry id (got ${JSON.stringify(claim.registry_ref)})`;
|
|
13624
|
+
}
|
|
13625
|
+
if (claim.disposition === "excluded") {
|
|
13626
|
+
if (claim.registry_ref === void 0 || !excluded.has(claim.registry_ref)) return `claim "${claim.description}" says excluded but cites no real exclusion candidate (got ${JSON.stringify(claim.registry_ref)})`;
|
|
13627
|
+
}
|
|
13628
|
+
const tokens = normalizeForGrounding(claim.prd_span).split(" ").map((t) => t.replace(/[^a-z0-9]/g, "")).filter((t) => t.length >= 4);
|
|
13629
|
+
if (tokens.length < 2) return `claim "${claim.description}" cites too thin a prd_span ("${claim.prd_span}") — quote a substantive span of the document`;
|
|
13630
|
+
const present = tokens.filter((t) => haystack.includes(t)).length;
|
|
13631
|
+
if (present / tokens.length < .6) return `claim "${claim.description}" prd_span does not appear in the document (only ${String(present)}/${String(tokens.length)} tokens present — fabricated citation?)`;
|
|
13632
|
+
}
|
|
13633
|
+
return void 0;
|
|
13634
|
+
}
|
|
13635
|
+
function renderRegistryForPrompt(registry) {
|
|
13636
|
+
const journeys = registry.journeys.map((j) => `- id: ${j.id}\n title: ${j.title}\n criticality: ${j.criticality}`).join("\n");
|
|
13637
|
+
const excluded = (registry.provenance?.excluded ?? []).map((e) => `- candidate: ${e.candidate}\n reason: ${e.reason}`).join("\n");
|
|
13638
|
+
return `Registered journeys (version ${String(registry.version)}):\n${journeys || "(none)"}\n\nOperator-excluded candidates:\n${excluded || "(none)"}`;
|
|
13639
|
+
}
|
|
13640
|
+
async function runCompletenessCheck(deps, params) {
|
|
13641
|
+
const { prdRelPath, prdContent, registry } = params;
|
|
13642
|
+
let template;
|
|
13643
|
+
try {
|
|
13644
|
+
template = await deps.pack.getPrompt("acceptance-completeness");
|
|
13645
|
+
} catch (err) {
|
|
13646
|
+
return {
|
|
13647
|
+
result: "failed",
|
|
13648
|
+
error: `Failed to retrieve acceptance-completeness prompt: ${err instanceof Error ? err.message : String(err)}`,
|
|
13649
|
+
tokenUsage: {
|
|
13650
|
+
input: 0,
|
|
13651
|
+
output: 0
|
|
13652
|
+
}
|
|
13653
|
+
};
|
|
13654
|
+
}
|
|
13655
|
+
const truncated = prdContent.length > SOURCE_CONTENT_CAP;
|
|
13656
|
+
const buildPrompt = (correctivePreamble) => {
|
|
13657
|
+
const { prompt } = assemblePrompt(template, [
|
|
13658
|
+
{
|
|
13659
|
+
name: "source_path",
|
|
13660
|
+
content: prdRelPath,
|
|
13661
|
+
priority: "required"
|
|
13662
|
+
},
|
|
13663
|
+
{
|
|
13664
|
+
name: "source_content",
|
|
13665
|
+
content: (truncated ? `(truncated to first ${String(SOURCE_CONTENT_CAP)} chars)\n` : "") + prdContent.slice(0, SOURCE_CONTENT_CAP),
|
|
13666
|
+
priority: "required"
|
|
13667
|
+
},
|
|
13668
|
+
{
|
|
13669
|
+
name: "registry_summary",
|
|
13670
|
+
content: renderRegistryForPrompt(registry),
|
|
13671
|
+
priority: "required"
|
|
13672
|
+
}
|
|
13673
|
+
], getTokenCeiling("acceptance-completeness", deps.tokenCeilings).ceiling);
|
|
13674
|
+
return correctivePreamble !== void 0 ? `${correctivePreamble}\n\n${prompt}` : prompt;
|
|
13675
|
+
};
|
|
13676
|
+
let totalTokens = {
|
|
13677
|
+
input: 0,
|
|
13678
|
+
output: 0
|
|
13679
|
+
};
|
|
13680
|
+
let lastProblem = "unknown";
|
|
13681
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
13682
|
+
const prompt = attempt === 0 ? buildPrompt() : buildPrompt(`PREVIOUS ATTEMPT REJECTED: ${lastProblem}. Emit ONLY the YAML block per the Output Contract — every claim with a VERBATIM prd_span; registered/excluded claims must cite real registry_ref values.`);
|
|
13683
|
+
const handle = deps.dispatcher.dispatch({
|
|
13684
|
+
prompt,
|
|
13685
|
+
agent: deps.agentId ?? "claude-code",
|
|
13686
|
+
taskType: "acceptance-completeness",
|
|
13687
|
+
outputSchema: AcceptanceCompletenessResultSchema,
|
|
13688
|
+
maxTurns: 30,
|
|
13689
|
+
...deps.otlpEndpoint !== void 0 ? { otlpEndpoint: deps.otlpEndpoint } : {}
|
|
13690
|
+
});
|
|
13691
|
+
let dispatchResult;
|
|
13692
|
+
try {
|
|
13693
|
+
dispatchResult = await handle.result;
|
|
13694
|
+
} catch (err) {
|
|
13695
|
+
return {
|
|
13696
|
+
result: "failed",
|
|
13697
|
+
error: `Dispatch error: ${err instanceof Error ? err.message : String(err)}`,
|
|
13698
|
+
tokenUsage: totalTokens
|
|
13699
|
+
};
|
|
13700
|
+
}
|
|
13701
|
+
totalTokens = {
|
|
13702
|
+
input: totalTokens.input + dispatchResult.tokenEstimate.input,
|
|
13703
|
+
output: totalTokens.output + dispatchResult.tokenEstimate.output
|
|
13704
|
+
};
|
|
13705
|
+
if (dispatchResult.status === "failed" || dispatchResult.status === "timeout") return {
|
|
13706
|
+
result: "failed",
|
|
13707
|
+
error: `Dispatch status: ${dispatchResult.status}. ${dispatchResult.parseError ?? ""}`.trim(),
|
|
13708
|
+
tokenUsage: totalTokens
|
|
13709
|
+
};
|
|
13710
|
+
const parsed = AcceptanceCompletenessResultSchema.safeParse(dispatchResult.parsed);
|
|
13711
|
+
if (!parsed.success) {
|
|
13712
|
+
lastProblem = `output failed schema validation (${parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ").slice(0, 500)})`;
|
|
13713
|
+
logger$1.warn({
|
|
13714
|
+
prdRelPath,
|
|
13715
|
+
attempt,
|
|
13716
|
+
lastProblem
|
|
13717
|
+
}, "RP3.2: completeness output invalid");
|
|
13718
|
+
continue;
|
|
13719
|
+
}
|
|
13720
|
+
if (parsed.data.result === "failed") return {
|
|
13721
|
+
result: "failed",
|
|
13722
|
+
error: "acceptance-completeness-refused",
|
|
13723
|
+
details: parsed.data.error ?? "checker reported failure without a reason",
|
|
13724
|
+
tokenUsage: totalTokens
|
|
13725
|
+
};
|
|
13726
|
+
const problem = validateCompletenessClaims(parsed.data.claims, registry, prdContent);
|
|
13727
|
+
if (problem !== void 0) {
|
|
13728
|
+
lastProblem = problem;
|
|
13729
|
+
logger$1.warn({
|
|
13730
|
+
prdRelPath,
|
|
13731
|
+
attempt,
|
|
13732
|
+
problem
|
|
13733
|
+
}, "RP3.2: completeness claims failed validation");
|
|
13734
|
+
continue;
|
|
13735
|
+
}
|
|
13736
|
+
logger$1.info({
|
|
13737
|
+
prdRelPath,
|
|
13738
|
+
claims: parsed.data.claims.length,
|
|
13739
|
+
undispositioned: parsed.data.claims.filter((c) => c.disposition === "undispositioned").length
|
|
13740
|
+
}, "RP3.2: completeness claims accepted");
|
|
13741
|
+
return {
|
|
13742
|
+
result: "success",
|
|
13743
|
+
claims: parsed.data.claims,
|
|
13744
|
+
tokenUsage: totalTokens
|
|
13745
|
+
};
|
|
13746
|
+
}
|
|
13747
|
+
return {
|
|
13748
|
+
result: "failed",
|
|
13749
|
+
error: "acceptance-completeness-invalid",
|
|
13750
|
+
details: `checker produced invalid output twice — last problem: ${lastProblem}`,
|
|
13751
|
+
tokenUsage: totalTokens
|
|
13752
|
+
};
|
|
13753
|
+
}
|
|
13754
|
+
|
|
13600
13755
|
//#endregion
|
|
13601
13756
|
//#region src/cli/commands/acceptance.ts
|
|
13602
13757
|
const ACCEPTANCE_EXIT_SUCCESS = 0;
|
|
@@ -13649,7 +13804,7 @@ async function listFilesRecursive(root, base = root) {
|
|
|
13649
13804
|
}
|
|
13650
13805
|
function registerAcceptanceCommand(program, version, registry) {
|
|
13651
13806
|
const acceptanceCmd = program.command("acceptance").description("Acceptance Gate — journey registry tools (the missing sprint demo)");
|
|
13652
|
-
acceptanceCmd.command("validate").description(`Lint ${JOURNEY_REGISTRY_PATH} with actionable, pathed errors`).option("--ref <ref>", "validate the COMMITTED registry at a git ref (trusted-tree read) instead of the working tree").option("--output-format <format>", "Output format: text (default) or json", "text").action(async (opts) => {
|
|
13807
|
+
acceptanceCmd.command("validate").description(`Lint ${JOURNEY_REGISTRY_PATH} with actionable, pathed errors`).option("--ref <ref>", "validate the COMMITTED registry at a git ref (trusted-tree read) instead of the working tree").option("--against-prd [path]", "RP3.2: run the completeness checker agent — every PRD journey must be registered or excluded (advisory findings; defaults to provenance.derived_from)").option("--agent <id>", "agent adapter id for --against-prd", "claude-code").option("--pack <name>", "methodology pack carrying the completeness prompt", "bmad").option("--output-format <format>", "Output format: text (default) or json", "text").action(async (opts) => {
|
|
13653
13808
|
const projectRoot = process.cwd();
|
|
13654
13809
|
const source = opts.ref !== void 0 ? `committed @ ${opts.ref}` : "working tree";
|
|
13655
13810
|
const result = opts.ref !== void 0 ? await loadJourneyRegistryFromTrustedTree(projectRoot, opts.ref) : await loadJourneyRegistryFromFile(projectRoot);
|
|
@@ -13675,6 +13830,82 @@ function registerAcceptanceCommand(program, version, registry) {
|
|
|
13675
13830
|
}
|
|
13676
13831
|
staleness = checkRegistryStaleness(result.registry, sourceContent);
|
|
13677
13832
|
}
|
|
13833
|
+
let completeness;
|
|
13834
|
+
if (opts.againstPrd !== void 0 && opts.againstPrd !== false) if (result.status !== "ok") completeness = {
|
|
13835
|
+
status: "failed",
|
|
13836
|
+
error: "registry must validate before a completeness check"
|
|
13837
|
+
};
|
|
13838
|
+
else if (registry === void 0) completeness = {
|
|
13839
|
+
status: "failed",
|
|
13840
|
+
error: "adapter registry unavailable in this invocation context"
|
|
13841
|
+
};
|
|
13842
|
+
else {
|
|
13843
|
+
const prdRel = typeof opts.againstPrd === "string" ? opts.againstPrd : result.registry.provenance?.derived_from;
|
|
13844
|
+
if (prdRel === void 0) completeness = {
|
|
13845
|
+
status: "failed",
|
|
13846
|
+
error: "no PRD path — pass --against-prd <path> or ratify with provenance first"
|
|
13847
|
+
};
|
|
13848
|
+
else if (!isProjectContainedPath(prdRel)) completeness = {
|
|
13849
|
+
status: "failed",
|
|
13850
|
+
error: `PRD path "${prdRel}" resolves outside the project`
|
|
13851
|
+
};
|
|
13852
|
+
else {
|
|
13853
|
+
let prdContent;
|
|
13854
|
+
try {
|
|
13855
|
+
prdContent = await readFile$1(join$1(projectRoot, prdRel), "utf-8");
|
|
13856
|
+
} catch (err) {
|
|
13857
|
+
completeness = {
|
|
13858
|
+
status: "failed",
|
|
13859
|
+
error: `cannot read PRD at ${prdRel}: ${String(err)}`
|
|
13860
|
+
};
|
|
13861
|
+
}
|
|
13862
|
+
if (prdContent !== void 0) {
|
|
13863
|
+
if (process.env.LOG_LEVEL === void 0) process.env.LOG_LEVEL = "silent";
|
|
13864
|
+
const eventBus = createEventBus();
|
|
13865
|
+
const adapter = new InMemoryDatabaseAdapter();
|
|
13866
|
+
const packLoader = createPackLoader();
|
|
13867
|
+
try {
|
|
13868
|
+
const pack = await packLoader.load(join$1(projectRoot, "packs", opts.pack));
|
|
13869
|
+
const contextCompiler = createContextCompiler({ db: adapter });
|
|
13870
|
+
const dispatcher = createDispatcher({
|
|
13871
|
+
eventBus,
|
|
13872
|
+
adapterRegistry: registry,
|
|
13873
|
+
logger: {
|
|
13874
|
+
debug: () => {},
|
|
13875
|
+
info: () => {},
|
|
13876
|
+
warn: () => {},
|
|
13877
|
+
error: () => {}
|
|
13878
|
+
}
|
|
13879
|
+
});
|
|
13880
|
+
process.stderr.write(`completeness check against ${prdRel} (real agent dispatch — may take a few minutes)…\n`);
|
|
13881
|
+
const check = await runCompletenessCheck({
|
|
13882
|
+
db: adapter,
|
|
13883
|
+
pack,
|
|
13884
|
+
contextCompiler,
|
|
13885
|
+
dispatcher,
|
|
13886
|
+
agentId: opts.agent
|
|
13887
|
+
}, {
|
|
13888
|
+
prdRelPath: prdRel,
|
|
13889
|
+
prdContent,
|
|
13890
|
+
registry: result.registry
|
|
13891
|
+
});
|
|
13892
|
+
await dispatcher.shutdown();
|
|
13893
|
+
completeness = check.result === "success" && check.claims !== void 0 ? {
|
|
13894
|
+
status: "ran",
|
|
13895
|
+
claims: check.claims
|
|
13896
|
+
} : {
|
|
13897
|
+
status: "failed",
|
|
13898
|
+
error: `${check.error ?? "unknown"}${check.details !== void 0 ? `: ${check.details}` : ""}`
|
|
13899
|
+
};
|
|
13900
|
+
} catch (err) {
|
|
13901
|
+
completeness = {
|
|
13902
|
+
status: "failed",
|
|
13903
|
+
error: `failed to load pack '${opts.pack}': ${String(err)}`
|
|
13904
|
+
};
|
|
13905
|
+
}
|
|
13906
|
+
}
|
|
13907
|
+
}
|
|
13908
|
+
}
|
|
13678
13909
|
if (opts.outputFormat === "json") {
|
|
13679
13910
|
const output = buildJsonOutput("substrate acceptance validate", {
|
|
13680
13911
|
source,
|
|
@@ -13683,7 +13914,8 @@ function registerAcceptanceCommand(program, version, registry) {
|
|
|
13683
13914
|
provenance: {
|
|
13684
13915
|
status: result.status === "ok" && result.registry.provenance !== void 0 ? "present" : "absent",
|
|
13685
13916
|
...staleness !== void 0 ? { staleness: staleness.status } : {}
|
|
13686
|
-
}
|
|
13917
|
+
},
|
|
13918
|
+
...completeness !== void 0 ? { completeness } : {}
|
|
13687
13919
|
}, version);
|
|
13688
13920
|
process.stdout.write(JSON.stringify(output, null, 2) + "\n");
|
|
13689
13921
|
process.exit(result.status === "ok" ? ACCEPTANCE_EXIT_SUCCESS : ACCEPTANCE_EXIT_ERROR);
|
|
@@ -13712,6 +13944,13 @@ function registerAcceptanceCommand(program, version, registry) {
|
|
|
13712
13944
|
for (const issue of contract.issues) process.stdout.write(` ${issue.path}: ${issue.message}\n`);
|
|
13713
13945
|
} else if (contract.status === "absent") process.stdout.write(`contract: ABSENT — no acceptance: block in ${ACCEPTANCE_CONTRACT_PROFILE_PATH}. Claimed journeys can never be walked (acceptance-unrunnable in blocking mode).
|
|
13714
13946
|
`);
|
|
13947
|
+
if (completeness !== void 0) if (completeness.status === "failed") process.stdout.write(`completeness: CHECK FAILED — ${completeness.error}\n`);
|
|
13948
|
+
else {
|
|
13949
|
+
const undispositioned = completeness.claims.filter((c) => c.disposition === "undispositioned");
|
|
13950
|
+
process.stdout.write(`completeness: ${String(completeness.claims.length)} journey-shaped claim(s) in the PRD — ${String(completeness.claims.filter((c) => c.disposition === "registered").length)} registered, ${String(completeness.claims.filter((c) => c.disposition === "excluded").length)} excluded, ${String(undispositioned.length)} UNDISPOSITIONED\n`);
|
|
13951
|
+
for (const c of completeness.claims) if (c.disposition === "undispositioned") process.stdout.write(` journey-undispositioned (advisory): "${c.description}"\n PRD span: "${c.prd_span}"\n resolve: register it (derive + ratify) or exclude it with a reason (ratify --exclude)\n`);
|
|
13952
|
+
else process.stdout.write(` ${c.disposition}: "${c.description}" → ${c.registry_ref ?? ""}\n`);
|
|
13953
|
+
}
|
|
13715
13954
|
process.exit(exitCode);
|
|
13716
13955
|
});
|
|
13717
13956
|
acceptanceCmd.command("defer <journeyId>").description("Record an operator deferral for a journey — the coverage audit reports it `deferred` instead of unclaimed/unwalked. Writes to the working tree; COMMIT the file for the audit (trusted tree) to honor it.").requiredOption("--reason <text>", "why this journey is deferred (the operator ack is the point)").action(async (journeyId, opts) => {
|
|
@@ -14094,7 +14333,7 @@ function registerAcceptanceCommand(program, version, registry) {
|
|
|
14094
14333
|
process.exit(ACCEPTANCE_EXIT_ERROR);
|
|
14095
14334
|
return;
|
|
14096
14335
|
}
|
|
14097
|
-
const { runAcceptanceJudge: runAcceptanceJudge$1 } = await import("../acceptance-judge-
|
|
14336
|
+
const { runAcceptanceJudge: runAcceptanceJudge$1 } = await import("../acceptance-judge-BStwKVzD.js");
|
|
14098
14337
|
const eventBus = createEventBus();
|
|
14099
14338
|
const adapter = new InMemoryDatabaseAdapter();
|
|
14100
14339
|
const packLoader = createPackLoader();
|