substrate-ai 0.21.13 → 0.21.14
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-CKNJdq03.js → acceptance-judge-D5Iba2D_.js} +1 -1
- package/dist/{acceptance-judge-eIZZha1C.js → acceptance-judge-lAv5EvYA.js} +40 -3
- package/dist/cli/index.js +395 -155
- package/dist/{health-DBBrM_te.js → health-B1Rk7RXw.js} +2 -2
- package/dist/{health-DAOWdkka.js → health-BxH_n5cd.js} +2 -2
- package/dist/{interactive-prompt-CV9rLUNT.js → interactive-prompt-GixkO5-6.js} +2 -2
- package/dist/{manifest-read-Bq2_Ojbv.js → manifest-read-BX_tMdib.js} +49 -2
- package/dist/modules/interactive-prompt/index.js +2 -2
- package/dist/{run-CGuoRwXB.js → run-BnUAxdws.js} +5 -5
- package/dist/{run-B31go5Ud.js → run-DcUXpWwu.js} +5 -5
- package/package.json +1 -1
- package/packs/bmad/manifest.yaml +4 -0
- package/packs/bmad/prompts/acceptance-derive.md +63 -0
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-B1Rk7RXw.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_DEFERRALS_PATH, JOURNEY_REGISTRY_PATH, RunManifest, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, clearGateDemotion, computePrecision, computeRecall, demoteGate, loadAcceptanceContractFromTrustedTree, loadJourneyRegistryFromFile, loadJourneyRegistryFromTrustedTree, parseAcceptanceContract, parseJourneyDeferrals, parseJourneyRegistry, parseRuntimeProbes, readAcceptanceMetrics, readCurrentRunId, readGateState, recordCanary, recordOverride, 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, clearGateDemotion, computePrecision, computeRecall, demoteGate, loadAcceptanceContractFromTrustedTree, loadJourneyRegistryFromFile, loadJourneyRegistryFromTrustedTree, parseAcceptanceContract, parseJourneyDeferrals, parseJourneyRegistry, parseRuntimeProbes, readAcceptanceMetrics, readCurrentRunId, readGateState, recordCanary, recordOverride, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck, runCanary } from "../manifest-read-BX_tMdib.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-DcUXpWwu.js";
|
|
9
9
|
import "../errors-xSeGw6pf.js";
|
|
10
|
-
import { runAcceptanceJudge } from "../acceptance-judge-
|
|
10
|
+
import { AcceptanceDeriveResultSchema, assemblePrompt, getTokenCeiling, runAcceptanceJudge } from "../acceptance-judge-lAv5EvYA.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-GixkO5-6.js";
|
|
16
16
|
import "../recovery-engine-dtLHyV4M.js";
|
|
17
17
|
import "../version-manager-impl-DMTw551Q.js";
|
|
18
18
|
import { registerUpgradeCommand } from "../upgrade-CNGc12AV.js";
|
|
@@ -21,13 +21,13 @@ import { fileURLToPath } from "url";
|
|
|
21
21
|
import { dirname, join, resolve } from "path";
|
|
22
22
|
import { access, mkdir, readFile, readdir, unlink, writeFile } from "fs/promises";
|
|
23
23
|
import { EventEmitter } from "node:events";
|
|
24
|
-
import yaml from "js-yaml";
|
|
24
|
+
import yaml, { dump } from "js-yaml";
|
|
25
25
|
import * as actualFS from "node:fs";
|
|
26
26
|
import { existsSync, promises, readFileSync, writeFileSync } from "node:fs";
|
|
27
27
|
import { execFile, spawnSync } from "node:child_process";
|
|
28
28
|
import * as path$1 from "node:path";
|
|
29
29
|
import { basename as basename$1, dirname as dirname$1, join as join$1, posix, relative, resolve as resolve$1, win32 } from "node:path";
|
|
30
|
-
import { randomUUID } from "node:crypto";
|
|
30
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
31
31
|
import { z } from "zod";
|
|
32
32
|
import * as fs from "node:fs/promises";
|
|
33
33
|
import { lstat, mkdir as mkdir$1, readFile as readFile$1, readdir as readdir$1, readlink, realpath, writeFile as writeFile$1 } from "node:fs/promises";
|
|
@@ -46,14 +46,14 @@ var RecommendationEngine = class {
|
|
|
46
46
|
_filters;
|
|
47
47
|
_historyDays;
|
|
48
48
|
_logger;
|
|
49
|
-
constructor(monitorDb, config = {}, logger$
|
|
49
|
+
constructor(monitorDb, config = {}, logger$20) {
|
|
50
50
|
this._monitorDb = monitorDb;
|
|
51
51
|
this._filters = {
|
|
52
52
|
threshold_percentage: config.recommendation_threshold_percentage ?? 5,
|
|
53
53
|
min_sample_size: config.min_sample_size ?? 10
|
|
54
54
|
};
|
|
55
55
|
this._historyDays = config.recommendation_history_days ?? 90;
|
|
56
|
-
this._logger = logger$
|
|
56
|
+
this._logger = logger$20 ?? createStderrLogger("monitor:recommendation-engine");
|
|
57
57
|
}
|
|
58
58
|
generateRecommendations() {
|
|
59
59
|
const sinceDate = new Date(Date.now() - this._historyDays * 24 * 60 * 60 * 1e3).toISOString();
|
|
@@ -1311,7 +1311,7 @@ function buildStackAwareDevNotes(profile) {
|
|
|
1311
1311
|
|
|
1312
1312
|
//#endregion
|
|
1313
1313
|
//#region src/cli/commands/init.ts
|
|
1314
|
-
const logger$
|
|
1314
|
+
const logger$19 = createLogger("init");
|
|
1315
1315
|
const __dirname = dirname(new URL(import.meta.url).pathname);
|
|
1316
1316
|
const SCAFFOLD_VERSION_REGEX = /<!-- substrate:version=([\d.]+) -->/;
|
|
1317
1317
|
/**
|
|
@@ -1352,7 +1352,7 @@ async function scaffoldBmadFramework(projectRoot, force, outputFormat) {
|
|
|
1352
1352
|
const version = resolveBmadMethodVersion();
|
|
1353
1353
|
if (force && bmadExists) process.stderr.write(`Warning: Replacing existing _bmad/ framework with bmad-method@${version}\n`);
|
|
1354
1354
|
process.stdout.write(`Scaffolding BMAD framework from bmad-method@${version}\n`);
|
|
1355
|
-
logger$
|
|
1355
|
+
logger$19.info({
|
|
1356
1356
|
version,
|
|
1357
1357
|
dest: bmadDest
|
|
1358
1358
|
}, "Scaffolding BMAD framework");
|
|
@@ -1362,7 +1362,7 @@ async function scaffoldBmadFramework(projectRoot, force, outputFormat) {
|
|
|
1362
1362
|
const destDir = join(bmadDest, dir);
|
|
1363
1363
|
mkdirSync$1(destDir, { recursive: true });
|
|
1364
1364
|
cpSync(srcDir, destDir, { recursive: true });
|
|
1365
|
-
logger$
|
|
1365
|
+
logger$19.info({
|
|
1366
1366
|
dir,
|
|
1367
1367
|
dest: destDir
|
|
1368
1368
|
}, "Scaffolded BMAD framework directory");
|
|
@@ -1381,7 +1381,7 @@ async function scaffoldBmadFramework(projectRoot, force, outputFormat) {
|
|
|
1381
1381
|
"document_output_language: English"
|
|
1382
1382
|
].join("\n") + "\n";
|
|
1383
1383
|
await writeFile(configFile, configStub, "utf8");
|
|
1384
|
-
logger$
|
|
1384
|
+
logger$19.info({ configFile }, "Generated _bmad/_config/config.yaml stub");
|
|
1385
1385
|
}
|
|
1386
1386
|
}
|
|
1387
1387
|
const CLAUDE_MD_START_MARKER = "<!-- substrate:start -->";
|
|
@@ -1396,7 +1396,7 @@ async function scaffoldClaudeMd(projectRoot, profile) {
|
|
|
1396
1396
|
try {
|
|
1397
1397
|
sectionContent = await readFile(templatePath, "utf8");
|
|
1398
1398
|
} catch {
|
|
1399
|
-
logger$
|
|
1399
|
+
logger$19.warn({ templatePath }, "CLAUDE.md substrate section template not found; skipping");
|
|
1400
1400
|
return;
|
|
1401
1401
|
}
|
|
1402
1402
|
const substrateVersion = readSubstrateVersion(pkgRoot);
|
|
@@ -1432,7 +1432,7 @@ async function scaffoldClaudeMd(projectRoot, profile) {
|
|
|
1432
1432
|
else newContent = updatedExisting;
|
|
1433
1433
|
}
|
|
1434
1434
|
await writeFile(claudeMdPath, newContent, "utf8");
|
|
1435
|
-
logger$
|
|
1435
|
+
logger$19.info({ claudeMdPath }, "Wrote substrate section to CLAUDE.md");
|
|
1436
1436
|
}
|
|
1437
1437
|
async function scaffoldAgentsMd(projectRoot, profile) {
|
|
1438
1438
|
const agentsMdPath = join(projectRoot, "AGENTS.md");
|
|
@@ -1444,7 +1444,7 @@ async function scaffoldAgentsMd(projectRoot, profile) {
|
|
|
1444
1444
|
try {
|
|
1445
1445
|
sectionContent = await readFile(templatePath, "utf8");
|
|
1446
1446
|
} catch {
|
|
1447
|
-
logger$
|
|
1447
|
+
logger$19.warn({ templatePath }, "AGENTS.md substrate section template not found; skipping");
|
|
1448
1448
|
return;
|
|
1449
1449
|
}
|
|
1450
1450
|
const substrateVersion = readSubstrateVersion(pkgRoot);
|
|
@@ -1465,7 +1465,7 @@ async function scaffoldAgentsMd(projectRoot, profile) {
|
|
|
1465
1465
|
newContent = existingContent + separator + sectionContent;
|
|
1466
1466
|
}
|
|
1467
1467
|
await writeFile(agentsMdPath, newContent, "utf8");
|
|
1468
|
-
logger$
|
|
1468
|
+
logger$19.info({ agentsMdPath }, "Wrote substrate section to AGENTS.md");
|
|
1469
1469
|
}
|
|
1470
1470
|
async function scaffoldGeminiMd(projectRoot, profile) {
|
|
1471
1471
|
const geminiMdPath = join(projectRoot, "GEMINI.md");
|
|
@@ -1477,7 +1477,7 @@ async function scaffoldGeminiMd(projectRoot, profile) {
|
|
|
1477
1477
|
try {
|
|
1478
1478
|
sectionContent = await readFile(templatePath, "utf8");
|
|
1479
1479
|
} catch {
|
|
1480
|
-
logger$
|
|
1480
|
+
logger$19.warn({ templatePath }, "GEMINI.md substrate section template not found; skipping");
|
|
1481
1481
|
return;
|
|
1482
1482
|
}
|
|
1483
1483
|
const substrateVersion = readSubstrateVersion(pkgRoot);
|
|
@@ -1498,7 +1498,7 @@ async function scaffoldGeminiMd(projectRoot, profile) {
|
|
|
1498
1498
|
newContent = existingContent + separator + sectionContent;
|
|
1499
1499
|
}
|
|
1500
1500
|
await writeFile(geminiMdPath, newContent, "utf8");
|
|
1501
|
-
logger$
|
|
1501
|
+
logger$19.info({ geminiMdPath }, "Wrote substrate section to GEMINI.md");
|
|
1502
1502
|
}
|
|
1503
1503
|
async function scaffoldStatuslineScript(projectRoot) {
|
|
1504
1504
|
const pkgRoot = findPackageRoot(__dirname);
|
|
@@ -1509,7 +1509,7 @@ async function scaffoldStatuslineScript(projectRoot) {
|
|
|
1509
1509
|
try {
|
|
1510
1510
|
content = await readFile(templatePath, "utf8");
|
|
1511
1511
|
} catch {
|
|
1512
|
-
logger$
|
|
1512
|
+
logger$19.warn({ templatePath }, "statusline.sh template not found; skipping");
|
|
1513
1513
|
return;
|
|
1514
1514
|
}
|
|
1515
1515
|
const claudeDir = join(projectRoot, ".claude");
|
|
@@ -1517,7 +1517,7 @@ async function scaffoldStatuslineScript(projectRoot) {
|
|
|
1517
1517
|
mkdirSync$1(claudeDir, { recursive: true });
|
|
1518
1518
|
await writeFile(statuslinePath, content, "utf8");
|
|
1519
1519
|
chmodSync(statuslinePath, 493);
|
|
1520
|
-
logger$
|
|
1520
|
+
logger$19.info({ statuslinePath }, "Wrote .claude/statusline.sh");
|
|
1521
1521
|
}
|
|
1522
1522
|
async function scaffoldClaudeSettings(projectRoot) {
|
|
1523
1523
|
const claudeDir = join(projectRoot, ".claude");
|
|
@@ -1533,7 +1533,7 @@ async function scaffoldClaudeSettings(projectRoot) {
|
|
|
1533
1533
|
if (!merged["$schema"]) merged["$schema"] = "https://json.schemastore.org/claude-code-settings.json";
|
|
1534
1534
|
mkdirSync$1(claudeDir, { recursive: true });
|
|
1535
1535
|
await writeFile(settingsPath, JSON.stringify(merged, null, 2) + "\n", "utf8");
|
|
1536
|
-
logger$
|
|
1536
|
+
logger$19.info({ settingsPath }, "Wrote substrate settings to .claude/settings.json");
|
|
1537
1537
|
}
|
|
1538
1538
|
/**
|
|
1539
1539
|
* H5.2 (field finding #2): write substrate's own slash commands
|
|
@@ -1552,7 +1552,7 @@ function scaffoldSubstrateSlashCommands(projectRoot) {
|
|
|
1552
1552
|
let templatesDir = join(pkgRoot, "dist", "cli", "templates", "claude-commands");
|
|
1553
1553
|
if (!existsSync$1(templatesDir)) templatesDir = join(pkgRoot, "src", "cli", "templates", "claude-commands");
|
|
1554
1554
|
if (!existsSync$1(templatesDir)) {
|
|
1555
|
-
logger$
|
|
1555
|
+
logger$19.warn({ templatesDir }, "substrate slash-command templates not found; skipping");
|
|
1556
1556
|
return 0;
|
|
1557
1557
|
}
|
|
1558
1558
|
const commandsDir = join(projectRoot, ".claude", "commands");
|
|
@@ -1564,19 +1564,19 @@ function scaffoldSubstrateSlashCommands(projectRoot) {
|
|
|
1564
1564
|
writeFileSync$1(join(commandsDir, file), readFileSync$1(join(templatesDir, file), "utf8"));
|
|
1565
1565
|
written += 1;
|
|
1566
1566
|
} catch (err) {
|
|
1567
|
-
logger$
|
|
1567
|
+
logger$19.warn({
|
|
1568
1568
|
file,
|
|
1569
1569
|
err
|
|
1570
1570
|
}, "failed to write substrate slash command (init continues)");
|
|
1571
1571
|
}
|
|
1572
1572
|
}
|
|
1573
|
-
logger$
|
|
1573
|
+
logger$19.info({
|
|
1574
1574
|
written,
|
|
1575
1575
|
commandsDir
|
|
1576
1576
|
}, "Scaffolded substrate slash commands");
|
|
1577
1577
|
return written;
|
|
1578
1578
|
} catch (err) {
|
|
1579
|
-
logger$
|
|
1579
|
+
logger$19.warn({ err }, "scaffoldSubstrateSlashCommands failed; init continues");
|
|
1580
1580
|
return 0;
|
|
1581
1581
|
}
|
|
1582
1582
|
}
|
|
@@ -1650,7 +1650,7 @@ async function compileBmadAgents(bmadDir) {
|
|
|
1650
1650
|
writeFileSync$1(mdPath, result.xml, "utf-8");
|
|
1651
1651
|
compiled++;
|
|
1652
1652
|
} catch (compileErr) {
|
|
1653
|
-
logger$
|
|
1653
|
+
logger$19.debug({
|
|
1654
1654
|
err: compileErr,
|
|
1655
1655
|
file
|
|
1656
1656
|
}, "Failed to compile agent YAML");
|
|
@@ -1797,9 +1797,9 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1797
1797
|
const _require = createRequire(join(__dirname, "synthetic.js"));
|
|
1798
1798
|
try {
|
|
1799
1799
|
const compiledCount = await compileBmadAgents(bmadDir);
|
|
1800
|
-
if (compiledCount > 0) logger$
|
|
1800
|
+
if (compiledCount > 0) logger$19.info({ compiledCount }, "Compiled agent YAML files to MD");
|
|
1801
1801
|
} catch (compileErr) {
|
|
1802
|
-
logger$
|
|
1802
|
+
logger$19.warn({ err: compileErr }, "Agent compilation failed; agent commands may be incomplete");
|
|
1803
1803
|
}
|
|
1804
1804
|
const resolveExport = (mod, name) => {
|
|
1805
1805
|
if (typeof mod[name] === "function") return mod[name];
|
|
@@ -1813,7 +1813,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1813
1813
|
const manifestGenPath = join(installerLibPath, "core", "manifest-generator.js");
|
|
1814
1814
|
const pathUtilsPath = join(installerLibPath, "ide", "shared", "path-utils.js");
|
|
1815
1815
|
if (!existsSync$1(agentGenPath)) {
|
|
1816
|
-
logger$
|
|
1816
|
+
logger$19.info("bmad-method generators not available (requires bmad-method with agent/workflow/task-tool generators)");
|
|
1817
1817
|
return;
|
|
1818
1818
|
}
|
|
1819
1819
|
const agentMod = _require(agentGenPath);
|
|
@@ -1823,11 +1823,11 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1823
1823
|
if (existsSync$1(workflowGenPath)) {
|
|
1824
1824
|
const workflowMod = _require(workflowGenPath);
|
|
1825
1825
|
WorkflowCommandGenerator = resolveExport(workflowMod, "WorkflowCommandGenerator");
|
|
1826
|
-
} else logger$
|
|
1826
|
+
} else logger$19.info("bmad-method workflow-command-generator not available; will try skill-based installation");
|
|
1827
1827
|
if (existsSync$1(taskToolGenPath)) {
|
|
1828
1828
|
const taskToolMod = _require(taskToolGenPath);
|
|
1829
1829
|
TaskToolCommandGenerator = resolveExport(taskToolMod, "TaskToolCommandGenerator");
|
|
1830
|
-
} else logger$
|
|
1830
|
+
} else logger$19.info("bmad-method task-tool-command-generator not available; will try skill-based installation");
|
|
1831
1831
|
let ManifestGenerator = null;
|
|
1832
1832
|
if (existsSync$1(manifestGenPath)) {
|
|
1833
1833
|
const manifestMod = _require(manifestGenPath);
|
|
@@ -1859,7 +1859,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1859
1859
|
const manifestGen = new ManifestGenerator();
|
|
1860
1860
|
await manifestGen.generateManifests(bmadDir, allModules, [], { ides: ["claude-code"] });
|
|
1861
1861
|
} catch (manifestErr) {
|
|
1862
|
-
logger$
|
|
1862
|
+
logger$19.warn({ err: manifestErr }, "ManifestGenerator failed; workflow/task commands may be incomplete");
|
|
1863
1863
|
}
|
|
1864
1864
|
const commandsDir = join(projectRoot, ".claude", "commands");
|
|
1865
1865
|
mkdirSync$1(commandsDir, { recursive: true });
|
|
@@ -1887,7 +1887,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1887
1887
|
const total = agentCount + workflowCount + taskToolCount + skillCount;
|
|
1888
1888
|
if (outputFormat !== "json") if (skillCount > 0) process.stdout.write(`Generated ${String(total)} Claude Code commands (${String(agentCount)} agents, ${String(skillCount)} skills)\n`);
|
|
1889
1889
|
else process.stdout.write(`Generated ${String(total)} Claude Code commands (${String(agentCount)} agents, ${String(workflowCount)} workflows, ${String(taskToolCount)} tasks/tools)\n`);
|
|
1890
|
-
logger$
|
|
1890
|
+
logger$19.info({
|
|
1891
1891
|
agentCount,
|
|
1892
1892
|
workflowCount,
|
|
1893
1893
|
taskToolCount,
|
|
@@ -1898,7 +1898,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
|
|
|
1898
1898
|
} catch (err) {
|
|
1899
1899
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1900
1900
|
if (outputFormat !== "json") process.stderr.write(`Warning: .claude/commands/ generation failed: ${msg}\n`);
|
|
1901
|
-
logger$
|
|
1901
|
+
logger$19.warn({ err }, "scaffoldClaudeCommands failed; init continues");
|
|
1902
1902
|
}
|
|
1903
1903
|
}
|
|
1904
1904
|
/**
|
|
@@ -1927,7 +1927,7 @@ function syncCommandsAsPrompts(commandsDir, promptsDir, ownershipPrefixes, nameP
|
|
|
1927
1927
|
unlinkSync$1(join(promptsDir, entry.name));
|
|
1928
1928
|
}
|
|
1929
1929
|
} catch (err) {
|
|
1930
|
-
logger$
|
|
1930
|
+
logger$19.debug({
|
|
1931
1931
|
err,
|
|
1932
1932
|
promptsDir
|
|
1933
1933
|
}, "Failed to prune stale prompts");
|
|
@@ -1970,7 +1970,7 @@ function syncSkillsToTarget(srcSkillsDir, destSkillsDir, ownershipPrefixes, name
|
|
|
1970
1970
|
});
|
|
1971
1971
|
}
|
|
1972
1972
|
} catch (err) {
|
|
1973
|
-
logger$
|
|
1973
|
+
logger$19.debug({
|
|
1974
1974
|
err,
|
|
1975
1975
|
destSkillsDir
|
|
1976
1976
|
}, "Failed to prune stale skills");
|
|
@@ -1996,7 +1996,7 @@ function syncSkillsToTarget(srcSkillsDir, destSkillsDir, ownershipPrefixes, name
|
|
|
1996
1996
|
op: stage,
|
|
1997
1997
|
err: msg
|
|
1998
1998
|
});
|
|
1999
|
-
logger$
|
|
1999
|
+
logger$19.warn({
|
|
2000
2000
|
skill: entry.name,
|
|
2001
2001
|
dest,
|
|
2002
2002
|
stage,
|
|
@@ -2006,7 +2006,7 @@ function syncSkillsToTarget(srcSkillsDir, destSkillsDir, ownershipPrefixes, name
|
|
|
2006
2006
|
}
|
|
2007
2007
|
if (failures.length > 0 && count === 0) {
|
|
2008
2008
|
const first = failures[0];
|
|
2009
|
-
logger$
|
|
2009
|
+
logger$19.warn({
|
|
2010
2010
|
destSkillsDir,
|
|
2011
2011
|
attempted: failures.length,
|
|
2012
2012
|
dominantStage: first.op,
|
|
@@ -2033,7 +2033,7 @@ const PROJECT_OWNERSHIP_PREFIXES = ["bmad-", "substrate-"];
|
|
|
2033
2033
|
function scaffoldCodexProject(projectRoot, outputFormat) {
|
|
2034
2034
|
if (process.env["SUBSTRATE_NO_CODEX_SCAFFOLD"] === "1") {
|
|
2035
2035
|
if (outputFormat !== "json") process.stdout.write(" Skipping .codex/ scaffolding (SUBSTRATE_NO_CODEX_SCAFFOLD=1)\n");
|
|
2036
|
-
logger$
|
|
2036
|
+
logger$19.debug("SUBSTRATE_NO_CODEX_SCAFFOLD=1 — skipping .codex/ scaffolding");
|
|
2037
2037
|
return;
|
|
2038
2038
|
}
|
|
2039
2039
|
const claudeCommandsDir = join(projectRoot, ".claude", "commands");
|
|
@@ -2046,16 +2046,16 @@ function scaffoldCodexProject(projectRoot, outputFormat) {
|
|
|
2046
2046
|
const skillCount = syncSkillsToTarget(claudeSkillsDir, codexSkillsDir, PROJECT_OWNERSHIP_PREFIXES, "");
|
|
2047
2047
|
const total = promptCount + skillCount;
|
|
2048
2048
|
if (outputFormat !== "json" && total > 0) process.stdout.write(`Generated ${String(total)} Codex artifacts (${String(promptCount)} prompts, ${String(skillCount)} skills)\n`);
|
|
2049
|
-
if (total > 0) logger$
|
|
2049
|
+
if (total > 0) logger$19.info({
|
|
2050
2050
|
promptCount,
|
|
2051
2051
|
skillCount,
|
|
2052
2052
|
codexDir
|
|
2053
2053
|
}, "Generated .codex/");
|
|
2054
|
-
else logger$
|
|
2054
|
+
else logger$19.debug({ codexDir }, "No Codex artifacts generated; source Claude content not found");
|
|
2055
2055
|
} catch (err) {
|
|
2056
2056
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2057
2057
|
if (outputFormat !== "json") process.stderr.write(`Warning: .codex/ generation failed: ${msg}\n`);
|
|
2058
|
-
logger$
|
|
2058
|
+
logger$19.warn({ err }, "scaffoldCodexProject failed; init continues");
|
|
2059
2059
|
}
|
|
2060
2060
|
}
|
|
2061
2061
|
/**
|
|
@@ -2073,7 +2073,7 @@ function scaffoldCodexProject(projectRoot, outputFormat) {
|
|
|
2073
2073
|
function scaffoldCodexUser(projectRoot, homeDir, outputFormat) {
|
|
2074
2074
|
if (process.env["SUBSTRATE_NO_CODEX_SCAFFOLD"] === "1") {
|
|
2075
2075
|
if (outputFormat !== "json") process.stdout.write(" Skipping ~/.codex/ scaffolding (SUBSTRATE_NO_CODEX_SCAFFOLD=1)\n");
|
|
2076
|
-
logger$
|
|
2076
|
+
logger$19.debug("SUBSTRATE_NO_CODEX_SCAFFOLD=1 — skipping ~/.codex/ scaffolding");
|
|
2077
2077
|
return;
|
|
2078
2078
|
}
|
|
2079
2079
|
const claudeCommandsDir = join(projectRoot, ".claude", "commands");
|
|
@@ -2086,16 +2086,16 @@ function scaffoldCodexUser(projectRoot, homeDir, outputFormat) {
|
|
|
2086
2086
|
const skillCount = syncSkillsToTarget(claudeSkillsDir, userSkillsDir, ["substrate-"], "substrate-");
|
|
2087
2087
|
const total = promptCount + skillCount;
|
|
2088
2088
|
if (outputFormat !== "json" && total > 0) process.stdout.write(`Installed ${String(total)} Codex artifacts to ${userCodexDir} (${String(promptCount)} prompts, ${String(skillCount)} skills)\n`);
|
|
2089
|
-
if (total > 0) logger$
|
|
2089
|
+
if (total > 0) logger$19.info({
|
|
2090
2090
|
promptCount,
|
|
2091
2091
|
skillCount,
|
|
2092
2092
|
userCodexDir
|
|
2093
2093
|
}, "Installed user-scope Codex content");
|
|
2094
|
-
else logger$
|
|
2094
|
+
else logger$19.debug({ userCodexDir }, "No user-scope Codex content installed; source Claude content not found");
|
|
2095
2095
|
} catch (err) {
|
|
2096
2096
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2097
2097
|
if (outputFormat !== "json") process.stderr.write(`Warning: user-scope Codex install failed: ${msg}\n`);
|
|
2098
|
-
logger$
|
|
2098
|
+
logger$19.warn({ err }, "scaffoldCodexUser failed; init continues");
|
|
2099
2099
|
}
|
|
2100
2100
|
}
|
|
2101
2101
|
const PROVIDER_DEFAULTS = DEFAULT_CONFIG.providers;
|
|
@@ -2216,7 +2216,7 @@ async function runInitAction(options) {
|
|
|
2216
2216
|
discoveryReport = await registry.discoverAndRegister();
|
|
2217
2217
|
} catch (err) {
|
|
2218
2218
|
const message = err instanceof Error ? err.message : String(err);
|
|
2219
|
-
logger$
|
|
2219
|
+
logger$19.error({ err }, "Adapter discovery failed");
|
|
2220
2220
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, `Adapter discovery failed: ${message}`) + "\n");
|
|
2221
2221
|
else process.stderr.write(` Error: adapter discovery failed — ${message}\n`);
|
|
2222
2222
|
return INIT_EXIT_ERROR;
|
|
@@ -2265,7 +2265,7 @@ async function runInitAction(options) {
|
|
|
2265
2265
|
try {
|
|
2266
2266
|
detectedProfile = await detectProjectProfile(dbRoot);
|
|
2267
2267
|
} catch (err) {
|
|
2268
|
-
logger$
|
|
2268
|
+
logger$19.warn({ err }, "Project profile detection failed; skipping");
|
|
2269
2269
|
}
|
|
2270
2270
|
if (detectedProfile === null) {
|
|
2271
2271
|
if (outputFormat !== "json") process.stdout.write(" No project stack detected. Create .substrate/project-profile.yaml manually to enable polyglot support.\n");
|
|
@@ -2299,12 +2299,12 @@ async function runInitAction(options) {
|
|
|
2299
2299
|
return INIT_EXIT_ERROR;
|
|
2300
2300
|
}
|
|
2301
2301
|
if (force && existsSync$1(localManifest)) {
|
|
2302
|
-
logger$
|
|
2302
|
+
logger$19.info({ pack: packName }, "Replacing existing pack with bundled version");
|
|
2303
2303
|
process.stderr.write(`Warning: Replacing existing pack '${packName}' with bundled version\n`);
|
|
2304
2304
|
}
|
|
2305
2305
|
mkdirSync$1(dirname(packPath), { recursive: true });
|
|
2306
2306
|
cpSync(bundledPackPath, packPath, { recursive: true });
|
|
2307
|
-
logger$
|
|
2307
|
+
logger$19.info({
|
|
2308
2308
|
pack: packName,
|
|
2309
2309
|
dest: packPath
|
|
2310
2310
|
}, "Scaffolded methodology pack");
|
|
@@ -2346,10 +2346,10 @@ async function runInitAction(options) {
|
|
|
2346
2346
|
const { content, changed } = computeSubstrateGitignore(existing);
|
|
2347
2347
|
if (changed) {
|
|
2348
2348
|
writeFileSync$1(gitignorePath, content);
|
|
2349
|
-
logger$
|
|
2349
|
+
logger$19.info("Updated .gitignore: track only .substrate/config.yaml");
|
|
2350
2350
|
}
|
|
2351
2351
|
} catch (err) {
|
|
2352
|
-
logger$
|
|
2352
|
+
logger$19.debug({ err }, "Could not update .gitignore (non-fatal)");
|
|
2353
2353
|
}
|
|
2354
2354
|
const doltMode = options.doltMode ?? "auto";
|
|
2355
2355
|
let doltInitialized = false;
|
|
@@ -2363,7 +2363,7 @@ async function runInitAction(options) {
|
|
|
2363
2363
|
process.stderr.write(`${err.message}\n`);
|
|
2364
2364
|
return INIT_EXIT_ERROR;
|
|
2365
2365
|
}
|
|
2366
|
-
logger$
|
|
2366
|
+
logger$19.debug("Dolt not installed, skipping auto-init");
|
|
2367
2367
|
} else {
|
|
2368
2368
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2369
2369
|
if (doltMode === "force") {
|
|
@@ -2373,7 +2373,7 @@ async function runInitAction(options) {
|
|
|
2373
2373
|
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`);
|
|
2374
2374
|
}
|
|
2375
2375
|
}
|
|
2376
|
-
else logger$
|
|
2376
|
+
else logger$19.debug("Dolt step was skipped (--no-dolt)");
|
|
2377
2377
|
const successMsg = `Pack '${packName}' and database initialized successfully at ${dbPath}`;
|
|
2378
2378
|
if (outputFormat === "json") process.stdout.write(formatOutput({
|
|
2379
2379
|
pack: packName,
|
|
@@ -2411,7 +2411,7 @@ async function runInitAction(options) {
|
|
|
2411
2411
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2412
2412
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
2413
2413
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
2414
|
-
logger$
|
|
2414
|
+
logger$19.error({ err }, "init failed");
|
|
2415
2415
|
return INIT_EXIT_ERROR;
|
|
2416
2416
|
}
|
|
2417
2417
|
}
|
|
@@ -2435,7 +2435,7 @@ function registerInitCommand(program, _version, registry) {
|
|
|
2435
2435
|
|
|
2436
2436
|
//#endregion
|
|
2437
2437
|
//#region src/cli/commands/config.ts
|
|
2438
|
-
const logger$
|
|
2438
|
+
const logger$18 = createLogger("config-cmd");
|
|
2439
2439
|
const CONFIG_EXIT_SUCCESS = 0;
|
|
2440
2440
|
const CONFIG_EXIT_ERROR = 1;
|
|
2441
2441
|
const CONFIG_EXIT_INVALID = 2;
|
|
@@ -2461,7 +2461,7 @@ async function runConfigShow(opts = {}) {
|
|
|
2461
2461
|
return CONFIG_EXIT_INVALID;
|
|
2462
2462
|
}
|
|
2463
2463
|
const message = err instanceof Error ? err.message : String(err);
|
|
2464
|
-
logger$
|
|
2464
|
+
logger$18.error({ err }, "Failed to load configuration");
|
|
2465
2465
|
process.stderr.write(` Error loading configuration: ${message}\n`);
|
|
2466
2466
|
return CONFIG_EXIT_ERROR;
|
|
2467
2467
|
}
|
|
@@ -2535,7 +2535,7 @@ async function runConfigExport(opts = {}) {
|
|
|
2535
2535
|
return CONFIG_EXIT_INVALID;
|
|
2536
2536
|
}
|
|
2537
2537
|
const message = err instanceof Error ? err.message : String(err);
|
|
2538
|
-
logger$
|
|
2538
|
+
logger$18.error({ err }, "Failed to load configuration");
|
|
2539
2539
|
process.stderr.write(`Error loading configuration: ${message}\n`);
|
|
2540
2540
|
return CONFIG_EXIT_ERROR;
|
|
2541
2541
|
}
|
|
@@ -6455,7 +6455,7 @@ async function detectManifestDriftAgainstWorkingTree(manifest, projectRoot) {
|
|
|
6455
6455
|
|
|
6456
6456
|
//#endregion
|
|
6457
6457
|
//#region src/cli/commands/resume.ts
|
|
6458
|
-
const logger$
|
|
6458
|
+
const logger$17 = createLogger("resume-cmd");
|
|
6459
6459
|
/**
|
|
6460
6460
|
* Format a human-readable duration from an ISO-8601 timestamp to "now".
|
|
6461
6461
|
*/
|
|
@@ -6525,7 +6525,7 @@ async function runResumeAction(options) {
|
|
|
6525
6525
|
return 1;
|
|
6526
6526
|
}
|
|
6527
6527
|
} catch (driftErr) {
|
|
6528
|
-
logger$
|
|
6528
|
+
logger$17.debug({ err: driftErr }, "manifest drift check failed — proceeding with resume");
|
|
6529
6529
|
}
|
|
6530
6530
|
}
|
|
6531
6531
|
const doltDir = join(dbRoot, ".substrate", "state", ".dolt");
|
|
@@ -6595,15 +6595,15 @@ async function runResumeAction(options) {
|
|
|
6595
6595
|
const manifestStories = manifestData.cli_flags["stories"] ?? manifestData.story_scope;
|
|
6596
6596
|
if (Array.isArray(manifestStories) && manifestStories.length > 0) {
|
|
6597
6597
|
scopedStories = manifestStories;
|
|
6598
|
-
logger$
|
|
6598
|
+
logger$17.debug({
|
|
6599
6599
|
runId,
|
|
6600
6600
|
stories: scopedStories
|
|
6601
6601
|
}, "resume scope loaded from manifest");
|
|
6602
6602
|
}
|
|
6603
6603
|
} catch {
|
|
6604
|
-
logger$
|
|
6604
|
+
logger$17.debug({ runId }, "manifest read failed in resume — using legacy config_json scope");
|
|
6605
6605
|
}
|
|
6606
|
-
else logger$
|
|
6606
|
+
else logger$17.debug({ runId }, "Run manifest not found for scope preservation — using legacy config_json scope");
|
|
6607
6607
|
}
|
|
6608
6608
|
return runFullPipelineFromPhase({
|
|
6609
6609
|
packName,
|
|
@@ -6626,7 +6626,7 @@ async function runResumeAction(options) {
|
|
|
6626
6626
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6627
6627
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
6628
6628
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
6629
|
-
logger$
|
|
6629
|
+
logger$17.error({ err }, "auto resume failed");
|
|
6630
6630
|
return 1;
|
|
6631
6631
|
} finally {
|
|
6632
6632
|
try {
|
|
@@ -6879,11 +6879,11 @@ async function runFullPipelineFromPhase(options) {
|
|
|
6879
6879
|
output_tokens: output,
|
|
6880
6880
|
cost_usd: costUsd
|
|
6881
6881
|
}).catch((err) => {
|
|
6882
|
-
logger$
|
|
6882
|
+
logger$17.warn({ err }, "Failed to record token usage");
|
|
6883
6883
|
});
|
|
6884
6884
|
}
|
|
6885
6885
|
} catch (err) {
|
|
6886
|
-
logger$
|
|
6886
|
+
logger$17.warn({ err }, "Failed to record token usage");
|
|
6887
6887
|
}
|
|
6888
6888
|
});
|
|
6889
6889
|
const storyKeys = await resolveStoryKeys(adapter, projectRoot, {
|
|
@@ -6952,7 +6952,7 @@ async function runFullPipelineFromPhase(options) {
|
|
|
6952
6952
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6953
6953
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
6954
6954
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
6955
|
-
logger$
|
|
6955
|
+
logger$17.error({ err }, "pipeline from phase failed");
|
|
6956
6956
|
return 1;
|
|
6957
6957
|
} finally {
|
|
6958
6958
|
try {
|
|
@@ -6982,7 +6982,7 @@ function registerResumeCommand(program, _version = "0.0.0", projectRoot = proces
|
|
|
6982
6982
|
|
|
6983
6983
|
//#endregion
|
|
6984
6984
|
//#region src/cli/commands/status.ts
|
|
6985
|
-
const logger$
|
|
6985
|
+
const logger$16 = createLogger("status-cmd");
|
|
6986
6986
|
/**
|
|
6987
6987
|
* Map a manifest per-story status string to the appropriate WorkGraphCounts bucket.
|
|
6988
6988
|
* Unknown strings are treated as `inProgress` (safe default).
|
|
@@ -7094,9 +7094,9 @@ async function runStatusAction(options) {
|
|
|
7094
7094
|
const manifestData = await resolvedManifest.read();
|
|
7095
7095
|
manifestPerStoryState = manifestData.per_story_state;
|
|
7096
7096
|
workGraph = buildWorkGraphFromManifest(manifestData.per_story_state);
|
|
7097
|
-
logger$
|
|
7097
|
+
logger$16.debug({ runId: run?.id }, "status: workGraph built from manifest per_story_state");
|
|
7098
7098
|
} catch {
|
|
7099
|
-
logger$
|
|
7099
|
+
logger$16.debug({ runId: run?.id }, "status: manifest read failed — falling back to wg_stories");
|
|
7100
7100
|
}
|
|
7101
7101
|
if (workGraph === void 0) try {
|
|
7102
7102
|
const wgRepo = new WorkGraphRepository(adapter);
|
|
@@ -7133,10 +7133,10 @@ async function runStatusAction(options) {
|
|
|
7133
7133
|
};
|
|
7134
7134
|
}
|
|
7135
7135
|
} catch (err) {
|
|
7136
|
-
logger$
|
|
7136
|
+
logger$16.debug({ err }, "Work graph query failed, continuing without work graph data");
|
|
7137
7137
|
}
|
|
7138
7138
|
if (run === void 0) {
|
|
7139
|
-
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-
|
|
7139
|
+
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-BxH_n5cd.js");
|
|
7140
7140
|
const substrateDirPath = join(projectRoot, ".substrate");
|
|
7141
7141
|
const processInfo = inspectProcessTree$1({
|
|
7142
7142
|
projectRoot,
|
|
@@ -7295,7 +7295,7 @@ async function runStatusAction(options) {
|
|
|
7295
7295
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7296
7296
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
7297
7297
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
7298
|
-
logger$
|
|
7298
|
+
logger$16.error({ err }, "status action failed");
|
|
7299
7299
|
return 1;
|
|
7300
7300
|
} finally {
|
|
7301
7301
|
try {
|
|
@@ -7639,7 +7639,7 @@ Analyze thoroughly and return ONLY the JSON array with no additional text.`;
|
|
|
7639
7639
|
|
|
7640
7640
|
//#endregion
|
|
7641
7641
|
//#region src/cli/commands/amend.ts
|
|
7642
|
-
const logger$
|
|
7642
|
+
const logger$15 = createLogger("amend-cmd");
|
|
7643
7643
|
/**
|
|
7644
7644
|
* Detect and apply supersessions after a phase completes in an amendment run.
|
|
7645
7645
|
*
|
|
@@ -7670,7 +7670,7 @@ async function runPostPhaseSupersessionDetection(adapter, amendmentRunId, curren
|
|
|
7670
7670
|
});
|
|
7671
7671
|
} catch (err) {
|
|
7672
7672
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7673
|
-
logger$
|
|
7673
|
+
logger$15.warn({
|
|
7674
7674
|
err,
|
|
7675
7675
|
originalId: parentMatch.id,
|
|
7676
7676
|
supersedingId: newDec.id
|
|
@@ -7807,7 +7807,7 @@ async function runAmendAction(options) {
|
|
|
7807
7807
|
for (let i = startIdx; i < phaseOrder.length; i++) {
|
|
7808
7808
|
const currentPhase = phaseOrder[i];
|
|
7809
7809
|
const amendmentContext = handler.loadContextForPhase(currentPhase);
|
|
7810
|
-
logger$
|
|
7810
|
+
logger$15.info({
|
|
7811
7811
|
phase: currentPhase,
|
|
7812
7812
|
amendmentContextLen: amendmentContext.length
|
|
7813
7813
|
}, "Amendment context loaded for phase");
|
|
@@ -7928,7 +7928,7 @@ async function runAmendAction(options) {
|
|
|
7928
7928
|
} catch (err) {
|
|
7929
7929
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7930
7930
|
process.stderr.write(`Error: ${msg}\n`);
|
|
7931
|
-
logger$
|
|
7931
|
+
logger$15.error({ err }, "amend failed");
|
|
7932
7932
|
return 1;
|
|
7933
7933
|
} finally {
|
|
7934
7934
|
try {
|
|
@@ -8665,7 +8665,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
8665
8665
|
await initSchema(expAdapter);
|
|
8666
8666
|
const { runRunAction: runPipeline } = await import(
|
|
8667
8667
|
/* @vite-ignore */
|
|
8668
|
-
"../run-
|
|
8668
|
+
"../run-BnUAxdws.js"
|
|
8669
8669
|
);
|
|
8670
8670
|
const runStoryFn = async (opts) => {
|
|
8671
8671
|
const exitCode = await runPipeline({
|
|
@@ -8915,7 +8915,7 @@ function registerSupervisorCommand(program, _version = "0.0.0", projectRoot = pr
|
|
|
8915
8915
|
|
|
8916
8916
|
//#endregion
|
|
8917
8917
|
//#region src/cli/commands/metrics.ts
|
|
8918
|
-
const logger$
|
|
8918
|
+
const logger$14 = createLogger("metrics-cmd");
|
|
8919
8919
|
async function openTelemetryAdapter(basePath) {
|
|
8920
8920
|
try {
|
|
8921
8921
|
const adapter = createDatabaseAdapter({
|
|
@@ -9274,7 +9274,7 @@ async function runMetricsAction(options) {
|
|
|
9274
9274
|
}
|
|
9275
9275
|
}
|
|
9276
9276
|
} catch (err) {
|
|
9277
|
-
logger$
|
|
9277
|
+
logger$14.debug({ err }, "getScenarioResultsForRun failed");
|
|
9278
9278
|
}
|
|
9279
9279
|
if (rows.length === 0) {
|
|
9280
9280
|
const msg = `No factory run found with id: ${run}`;
|
|
@@ -9310,7 +9310,7 @@ async function runMetricsAction(options) {
|
|
|
9310
9310
|
}
|
|
9311
9311
|
}
|
|
9312
9312
|
} catch (err) {
|
|
9313
|
-
logger$
|
|
9313
|
+
logger$14.debug({ err }, "getTwinRunsForRun failed — twin_runs table may not exist yet");
|
|
9314
9314
|
}
|
|
9315
9315
|
}
|
|
9316
9316
|
return 0;
|
|
@@ -9320,7 +9320,7 @@ async function runMetricsAction(options) {
|
|
|
9320
9320
|
try {
|
|
9321
9321
|
factoryRuns$1 = await getFactoryRunSummaries(adapter, limit);
|
|
9322
9322
|
} catch (err) {
|
|
9323
|
-
logger$
|
|
9323
|
+
logger$14.debug({ err }, "getFactoryRunSummaries failed in factory-only mode");
|
|
9324
9324
|
}
|
|
9325
9325
|
if (outputFormat === "json") process.stdout.write(formatOutput({ graph_runs: factoryRuns$1 }, "json", true) + "\n");
|
|
9326
9326
|
else if (factoryRuns$1.length === 0) process.stdout.write("No factory runs recorded yet.\n");
|
|
@@ -9423,7 +9423,7 @@ async function runMetricsAction(options) {
|
|
|
9423
9423
|
try {
|
|
9424
9424
|
factoryRuns = await getFactoryRunSummaries(adapter, limit);
|
|
9425
9425
|
} catch (err) {
|
|
9426
|
-
logger$
|
|
9426
|
+
logger$14.debug({ err }, "getFactoryRunSummaries failed — table may not exist in older databases");
|
|
9427
9427
|
}
|
|
9428
9428
|
if (outputFormat === "json") {
|
|
9429
9429
|
const runsWithBreakdown = runs.map((run$1) => ({
|
|
@@ -9509,7 +9509,7 @@ async function runMetricsAction(options) {
|
|
|
9509
9509
|
const msg = err instanceof Error ? err.message : String(err);
|
|
9510
9510
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
9511
9511
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
9512
|
-
logger$
|
|
9512
|
+
logger$14.error({ err }, "metrics action failed");
|
|
9513
9513
|
return 1;
|
|
9514
9514
|
} finally {
|
|
9515
9515
|
try {
|
|
@@ -9565,7 +9565,7 @@ function registerMetricsCommand(program, _version = "0.0.0", projectRoot = proce
|
|
|
9565
9565
|
function getLatestSessionId(_adapter) {
|
|
9566
9566
|
return null;
|
|
9567
9567
|
}
|
|
9568
|
-
const logger$
|
|
9568
|
+
const logger$13 = createLogger("cost-cmd");
|
|
9569
9569
|
const COST_EXIT_SUCCESS = 0;
|
|
9570
9570
|
const COST_EXIT_ERROR = 1;
|
|
9571
9571
|
/**
|
|
@@ -9809,7 +9809,7 @@ async function runCostAction(options) {
|
|
|
9809
9809
|
} catch (err) {
|
|
9810
9810
|
const message = err instanceof Error ? err.message : String(err);
|
|
9811
9811
|
process.stderr.write(`Error: ${message}\n`);
|
|
9812
|
-
logger$
|
|
9812
|
+
logger$13.error({ err }, "runCostAction failed");
|
|
9813
9813
|
return COST_EXIT_ERROR;
|
|
9814
9814
|
} finally {
|
|
9815
9815
|
if (adapter !== null) try {
|
|
@@ -9843,7 +9843,7 @@ function registerCostCommand(program, version = "0.0.0", projectRoot = process.c
|
|
|
9843
9843
|
|
|
9844
9844
|
//#endregion
|
|
9845
9845
|
//#region src/cli/commands/monitor.ts
|
|
9846
|
-
const logger$
|
|
9846
|
+
const logger$12 = createLogger("monitor-cmd");
|
|
9847
9847
|
const MONITOR_EXIT_SUCCESS = 0;
|
|
9848
9848
|
const MONITOR_EXIT_ERROR = 1;
|
|
9849
9849
|
/**
|
|
@@ -10046,7 +10046,7 @@ async function runMonitorReportAction(options) {
|
|
|
10046
10046
|
} catch (err) {
|
|
10047
10047
|
const message = err instanceof Error ? err.message : String(err);
|
|
10048
10048
|
process.stderr.write(`Error: ${message}\n`);
|
|
10049
|
-
logger$
|
|
10049
|
+
logger$12.error({ err }, "runMonitorReportAction failed");
|
|
10050
10050
|
return MONITOR_EXIT_ERROR;
|
|
10051
10051
|
} finally {
|
|
10052
10052
|
if (monitorDb !== null) try {
|
|
@@ -10108,7 +10108,7 @@ async function runMonitorStatusAction(options) {
|
|
|
10108
10108
|
} catch (err) {
|
|
10109
10109
|
const message = err instanceof Error ? err.message : String(err);
|
|
10110
10110
|
process.stderr.write(`Error: ${message}\n`);
|
|
10111
|
-
logger$
|
|
10111
|
+
logger$12.error({ err }, "runMonitorStatusAction failed");
|
|
10112
10112
|
return MONITOR_EXIT_ERROR;
|
|
10113
10113
|
} finally {
|
|
10114
10114
|
if (monitorDb !== null) try {
|
|
@@ -10143,7 +10143,7 @@ async function runMonitorResetAction(options) {
|
|
|
10143
10143
|
} catch (err) {
|
|
10144
10144
|
const message = err instanceof Error ? err.message : String(err);
|
|
10145
10145
|
process.stderr.write(`Error: ${message}\n`);
|
|
10146
|
-
logger$
|
|
10146
|
+
logger$12.error({ err }, "runMonitorResetAction failed");
|
|
10147
10147
|
return MONITOR_EXIT_ERROR;
|
|
10148
10148
|
} finally {
|
|
10149
10149
|
if (monitorDb !== null) try {
|
|
@@ -10191,7 +10191,7 @@ async function runMonitorRecommendationsAction(options) {
|
|
|
10191
10191
|
} catch (err) {
|
|
10192
10192
|
const message = err instanceof Error ? err.message : String(err);
|
|
10193
10193
|
process.stderr.write(`Error: ${message}\n`);
|
|
10194
|
-
logger$
|
|
10194
|
+
logger$12.error({ err }, "runMonitorRecommendationsAction failed");
|
|
10195
10195
|
return MONITOR_EXIT_ERROR;
|
|
10196
10196
|
} finally {
|
|
10197
10197
|
if (monitorDb !== null) try {
|
|
@@ -10269,7 +10269,7 @@ function registerMonitorCommand(program, version = "0.0.0", projectRoot = proces
|
|
|
10269
10269
|
|
|
10270
10270
|
//#endregion
|
|
10271
10271
|
//#region src/cli/commands/merge.ts
|
|
10272
|
-
const logger$
|
|
10272
|
+
const logger$11 = createLogger("merge-cmd");
|
|
10273
10273
|
const MERGE_EXIT_SUCCESS = 0;
|
|
10274
10274
|
const MERGE_EXIT_CONFLICT = 1;
|
|
10275
10275
|
const MERGE_EXIT_ERROR = 2;
|
|
@@ -10307,7 +10307,7 @@ async function mergeTask(taskId, targetBranch, projectRoot) {
|
|
|
10307
10307
|
projectRoot
|
|
10308
10308
|
});
|
|
10309
10309
|
try {
|
|
10310
|
-
logger$
|
|
10310
|
+
logger$11.info({
|
|
10311
10311
|
taskId,
|
|
10312
10312
|
targetBranch
|
|
10313
10313
|
}, "Running conflict detection...");
|
|
@@ -10329,7 +10329,7 @@ async function mergeTask(taskId, targetBranch, projectRoot) {
|
|
|
10329
10329
|
} catch (err) {
|
|
10330
10330
|
const message = err instanceof Error ? err.message : String(err);
|
|
10331
10331
|
console.error(`Error merging task "${taskId}": ${message}`);
|
|
10332
|
-
logger$
|
|
10332
|
+
logger$11.error({
|
|
10333
10333
|
taskId,
|
|
10334
10334
|
err
|
|
10335
10335
|
}, "merge --task failed");
|
|
@@ -10383,7 +10383,7 @@ async function mergeAll(targetBranch, projectRoot, taskIds) {
|
|
|
10383
10383
|
error: message
|
|
10384
10384
|
});
|
|
10385
10385
|
console.log(` Error for task "${taskId}": ${message}`);
|
|
10386
|
-
logger$
|
|
10386
|
+
logger$11.error({
|
|
10387
10387
|
taskId,
|
|
10388
10388
|
err
|
|
10389
10389
|
}, "merge --all: task failed");
|
|
@@ -10436,7 +10436,7 @@ function registerMergeCommand(program, projectRoot = process.cwd()) {
|
|
|
10436
10436
|
|
|
10437
10437
|
//#endregion
|
|
10438
10438
|
//#region src/cli/commands/worktrees.ts
|
|
10439
|
-
const logger$
|
|
10439
|
+
const logger$10 = createLogger("worktrees-cmd");
|
|
10440
10440
|
const WORKTREES_EXIT_SUCCESS = 0;
|
|
10441
10441
|
const WORKTREES_EXIT_ERROR = 1;
|
|
10442
10442
|
/** Valid task statuses for filtering */
|
|
@@ -10563,7 +10563,7 @@ async function listWorktreesAction(options) {
|
|
|
10563
10563
|
try {
|
|
10564
10564
|
worktreeInfos = await manager.listWorktrees();
|
|
10565
10565
|
} catch (err) {
|
|
10566
|
-
logger$
|
|
10566
|
+
logger$10.error({ err }, "Failed to list worktrees");
|
|
10567
10567
|
const message = err instanceof Error ? err.message : String(err);
|
|
10568
10568
|
process.stderr.write(`Error listing worktrees: ${message}\n`);
|
|
10569
10569
|
return WORKTREES_EXIT_ERROR;
|
|
@@ -10590,7 +10590,7 @@ async function listWorktreesAction(options) {
|
|
|
10590
10590
|
} catch (err) {
|
|
10591
10591
|
const message = err instanceof Error ? err.message : String(err);
|
|
10592
10592
|
process.stderr.write(`Error: ${message}\n`);
|
|
10593
|
-
logger$
|
|
10593
|
+
logger$10.error({ err }, "listWorktreesAction failed");
|
|
10594
10594
|
return WORKTREES_EXIT_ERROR;
|
|
10595
10595
|
}
|
|
10596
10596
|
}
|
|
@@ -10619,7 +10619,7 @@ async function cleanupWorktreesAction(options) {
|
|
|
10619
10619
|
} catch (err) {
|
|
10620
10620
|
const message = err instanceof Error ? err.message : String(err);
|
|
10621
10621
|
process.stderr.write(`Error cleaning up worktree for task "${taskId}": ${message}\n`);
|
|
10622
|
-
logger$
|
|
10622
|
+
logger$10.error({
|
|
10623
10623
|
err,
|
|
10624
10624
|
taskId
|
|
10625
10625
|
}, "cleanupWorktreesAction (single) failed");
|
|
@@ -10633,13 +10633,13 @@ async function cleanupWorktreesAction(options) {
|
|
|
10633
10633
|
} catch (err) {
|
|
10634
10634
|
const message = err instanceof Error ? err.message : String(err);
|
|
10635
10635
|
process.stderr.write(`Error during bulk cleanup: ${message}\n`);
|
|
10636
|
-
logger$
|
|
10636
|
+
logger$10.error({ err }, "cleanupWorktreesAction (bulk) failed");
|
|
10637
10637
|
return WORKTREES_EXIT_ERROR;
|
|
10638
10638
|
}
|
|
10639
10639
|
} catch (err) {
|
|
10640
10640
|
const message = err instanceof Error ? err.message : String(err);
|
|
10641
10641
|
process.stderr.write(`Error: ${message}\n`);
|
|
10642
|
-
logger$
|
|
10642
|
+
logger$10.error({ err }, "cleanupWorktreesAction failed");
|
|
10643
10643
|
return WORKTREES_EXIT_ERROR;
|
|
10644
10644
|
}
|
|
10645
10645
|
}
|
|
@@ -10690,7 +10690,7 @@ function registerWorktreesCommand(program, version = "0.0.0", projectRoot = proc
|
|
|
10690
10690
|
|
|
10691
10691
|
//#endregion
|
|
10692
10692
|
//#region src/cli/commands/brainstorm.ts
|
|
10693
|
-
const logger$
|
|
10693
|
+
const logger$9 = createLogger("brainstorm-cmd");
|
|
10694
10694
|
/**
|
|
10695
10695
|
* Detect whether the project has existing planning artifacts that indicate
|
|
10696
10696
|
* this is an amendment session (vs. a brand-new project brainstorm).
|
|
@@ -10736,13 +10736,13 @@ async function loadAmendmentContextDocuments(projectRoot) {
|
|
|
10736
10736
|
try {
|
|
10737
10737
|
brief = await readFile(briefPath, "utf-8");
|
|
10738
10738
|
} catch {
|
|
10739
|
-
logger$
|
|
10739
|
+
logger$9.warn({ briefPath }, "product-brief.md not found — continuing without brief context");
|
|
10740
10740
|
process.stderr.write(`Warning: product-brief.md not found at ${briefPath}\n`);
|
|
10741
10741
|
}
|
|
10742
10742
|
try {
|
|
10743
10743
|
prd = await readFile(prdPath, "utf-8");
|
|
10744
10744
|
} catch {
|
|
10745
|
-
logger$
|
|
10745
|
+
logger$9.warn({ prdPath }, "requirements.md not found — continuing without PRD context");
|
|
10746
10746
|
process.stderr.write(`Warning: requirements.md not found at ${prdPath}\n`);
|
|
10747
10747
|
}
|
|
10748
10748
|
return {
|
|
@@ -10951,7 +10951,7 @@ async function dispatchToPersonas(userPrompt, context, llmDispatch) {
|
|
|
10951
10951
|
}
|
|
10952
10952
|
];
|
|
10953
10953
|
const defaultDispatch = async (prompt, personaName) => {
|
|
10954
|
-
logger$
|
|
10954
|
+
logger$9.debug({
|
|
10955
10955
|
personaName,
|
|
10956
10956
|
promptLength: prompt.length
|
|
10957
10957
|
}, "Dispatching to persona (stub mode)");
|
|
@@ -10968,7 +10968,7 @@ async function dispatchToPersonas(userPrompt, context, llmDispatch) {
|
|
|
10968
10968
|
};
|
|
10969
10969
|
} catch (err) {
|
|
10970
10970
|
const msg = err instanceof Error ? err.message : String(err);
|
|
10971
|
-
logger$
|
|
10971
|
+
logger$9.error({
|
|
10972
10972
|
err,
|
|
10973
10973
|
personaName: persona.name
|
|
10974
10974
|
}, "Persona dispatch failed");
|
|
@@ -11120,7 +11120,7 @@ async function runBrainstormSession(options, llmDispatch, rlInterface) {
|
|
|
11120
11120
|
}
|
|
11121
11121
|
});
|
|
11122
11122
|
rl.on("error", (err) => {
|
|
11123
|
-
logger$
|
|
11123
|
+
logger$9.error({ err }, "readline error");
|
|
11124
11124
|
if (!sessionEnded) endSession(false);
|
|
11125
11125
|
});
|
|
11126
11126
|
});
|
|
@@ -11161,7 +11161,7 @@ function registerBrainstormCommand(program, _version = "0.0.0", projectRoot = pr
|
|
|
11161
11161
|
|
|
11162
11162
|
//#endregion
|
|
11163
11163
|
//#region src/cli/commands/retry-escalated.ts
|
|
11164
|
-
const logger$
|
|
11164
|
+
const logger$8 = createLogger("retry-escalated-cmd");
|
|
11165
11165
|
async function runRetryEscalatedAction(options) {
|
|
11166
11166
|
const { runId, dryRun, force, outputFormat, projectRoot, concurrency, pack: packName, registry: injectedRegistry, agent: agentId, events: eventsFlag } = options;
|
|
11167
11167
|
const dbRoot = await resolveMainRepoRoot(projectRoot);
|
|
@@ -11202,7 +11202,7 @@ async function runRetryEscalatedAction(options) {
|
|
|
11202
11202
|
process.stdout.write(`[INFO] ${storyKey}: Context ceiling set to ${contextCeiling} tokens due to prior context spike pattern.\n`);
|
|
11203
11203
|
}
|
|
11204
11204
|
} catch (err) {
|
|
11205
|
-
logger$
|
|
11205
|
+
logger$8.warn({
|
|
11206
11206
|
err,
|
|
11207
11207
|
storyKey
|
|
11208
11208
|
}, "Failed to read efficiency profile — skipping gate");
|
|
@@ -11364,11 +11364,11 @@ async function runRetryEscalatedAction(options) {
|
|
|
11364
11364
|
output_tokens: output,
|
|
11365
11365
|
cost_usd: costUsd
|
|
11366
11366
|
}).catch((err) => {
|
|
11367
|
-
logger$
|
|
11367
|
+
logger$8.warn({ err }, "Failed to record token usage");
|
|
11368
11368
|
});
|
|
11369
11369
|
}
|
|
11370
11370
|
} catch (err) {
|
|
11371
|
-
logger$
|
|
11371
|
+
logger$8.warn({ err }, "Failed to record token usage");
|
|
11372
11372
|
}
|
|
11373
11373
|
});
|
|
11374
11374
|
if (outputFormat === "human") {
|
|
@@ -11397,7 +11397,7 @@ async function runRetryEscalatedAction(options) {
|
|
|
11397
11397
|
const msg = err instanceof Error ? err.message : String(err);
|
|
11398
11398
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
|
|
11399
11399
|
else process.stderr.write(`Error: ${msg}\n`);
|
|
11400
|
-
logger$
|
|
11400
|
+
logger$8.error({ err }, "retry-escalated failed");
|
|
11401
11401
|
return 1;
|
|
11402
11402
|
} finally {
|
|
11403
11403
|
try {
|
|
@@ -11430,7 +11430,7 @@ function registerRetryEscalatedCommand(program, _version = "0.0.0", projectRoot
|
|
|
11430
11430
|
|
|
11431
11431
|
//#endregion
|
|
11432
11432
|
//#region src/cli/commands/cancel.ts
|
|
11433
|
-
const logger$
|
|
11433
|
+
const logger$7 = createLogger("cancel-cmd");
|
|
11434
11434
|
async function runCancelAction(options) {
|
|
11435
11435
|
const { outputFormat, projectRoot, force } = options;
|
|
11436
11436
|
const dbRoot = await resolveMainRepoRoot(projectRoot);
|
|
@@ -11469,7 +11469,7 @@ async function runCancelAction(options) {
|
|
|
11469
11469
|
}
|
|
11470
11470
|
} catch (err) {
|
|
11471
11471
|
const msg = err instanceof Error ? err.message : String(err);
|
|
11472
|
-
logger$
|
|
11472
|
+
logger$7.warn({
|
|
11473
11473
|
pid,
|
|
11474
11474
|
err: msg
|
|
11475
11475
|
}, "Failed to kill orchestrator");
|
|
@@ -11499,7 +11499,7 @@ async function runCancelAction(options) {
|
|
|
11499
11499
|
await adapter.close();
|
|
11500
11500
|
}
|
|
11501
11501
|
} catch (err) {
|
|
11502
|
-
logger$
|
|
11502
|
+
logger$7.warn({ err }, "Could not update pipeline run status (non-fatal)");
|
|
11503
11503
|
}
|
|
11504
11504
|
if (outputFormat === "json") process.stdout.write(formatOutput({
|
|
11505
11505
|
cancelled: true,
|
|
@@ -11652,7 +11652,7 @@ function emitDiff(diff, ctx) {
|
|
|
11652
11652
|
|
|
11653
11653
|
//#endregion
|
|
11654
11654
|
//#region src/cli/commands/probe-author.ts
|
|
11655
|
-
const logger$
|
|
11655
|
+
const logger$6 = createLogger("cli:probe-author");
|
|
11656
11656
|
/**
|
|
11657
11657
|
* A minimum-viable logger that routes everything to stderr. Used by the
|
|
11658
11658
|
* subcommand to keep stdout reserved for the JSON result payload.
|
|
@@ -11721,7 +11721,7 @@ async function runProbeAuthorDispatch(opts, projectRoot, registry) {
|
|
|
11721
11721
|
logger: stderrLogger
|
|
11722
11722
|
});
|
|
11723
11723
|
const workingDir = opts.workingDir !== void 0 ? resolve$1(opts.workingDir) : resolve$1(storyFilePath, "..");
|
|
11724
|
-
logger$
|
|
11724
|
+
logger$6.info({
|
|
11725
11725
|
storyKey: opts.storyKey,
|
|
11726
11726
|
storyFile: storyFilePath,
|
|
11727
11727
|
epicFile: epicFilePath,
|
|
@@ -11943,7 +11943,7 @@ function registerHistoryCommand(program) {
|
|
|
11943
11943
|
|
|
11944
11944
|
//#endregion
|
|
11945
11945
|
//#region src/cli/commands/repo-map.ts
|
|
11946
|
-
const logger$
|
|
11946
|
+
const logger$5 = createLogger("cli:repo-map");
|
|
11947
11947
|
/** Validate that a symbol name contains only safe identifier characters. */
|
|
11948
11948
|
function isValidSymbolName(name) {
|
|
11949
11949
|
return /^[a-zA-Z0-9_]+$/.test(name);
|
|
@@ -11978,15 +11978,15 @@ function registerRepoMapCommand(program) {
|
|
|
11978
11978
|
const colRows = await doltClient.query(`SHOW COLUMNS FROM repo_map_symbols LIKE 'dependencies'`);
|
|
11979
11979
|
if (colRows.length === 0) {
|
|
11980
11980
|
await doltClient.query(`ALTER TABLE repo_map_symbols ADD COLUMN dependencies JSON`);
|
|
11981
|
-
logger$
|
|
11981
|
+
logger$5.info("Applied migration: added dependencies column to repo_map_symbols");
|
|
11982
11982
|
}
|
|
11983
11983
|
} catch {
|
|
11984
|
-
logger$
|
|
11984
|
+
logger$5.debug("Skipping repo_map_symbols migration: table not yet created");
|
|
11985
11985
|
}
|
|
11986
|
-
const symbolRepo = new DoltSymbolRepository(doltClient, logger$
|
|
11986
|
+
const symbolRepo = new DoltSymbolRepository(doltClient, logger$5);
|
|
11987
11987
|
const metaRepo = new DoltRepoMapMetaRepository(doltClient);
|
|
11988
|
-
const repoMapModule = new RepoMapModule(metaRepo, logger$
|
|
11989
|
-
const queryEngine = new RepoMapQueryEngine(symbolRepo, logger$
|
|
11988
|
+
const repoMapModule = new RepoMapModule(metaRepo, logger$5);
|
|
11989
|
+
const queryEngine = new RepoMapQueryEngine(symbolRepo, logger$5);
|
|
11990
11990
|
if (options.show === true || !options.update && !options.query && !options.dryRun) {
|
|
11991
11991
|
const meta = await metaRepo.getMeta();
|
|
11992
11992
|
const staleResult = await repoMapModule.checkStaleness();
|
|
@@ -12012,9 +12012,9 @@ function registerRepoMapCommand(program) {
|
|
|
12012
12012
|
return;
|
|
12013
12013
|
}
|
|
12014
12014
|
if (options.update === true) {
|
|
12015
|
-
logger$
|
|
12016
|
-
const gitClient = new GitClient(logger$
|
|
12017
|
-
const grammarLoader = new GrammarLoader(logger$
|
|
12015
|
+
logger$5.info("repo-map --update: triggering incremental update");
|
|
12016
|
+
const gitClient = new GitClient(logger$5);
|
|
12017
|
+
const grammarLoader = new GrammarLoader(logger$5);
|
|
12018
12018
|
if (grammarLoader.getGrammar(".ts") === null) {
|
|
12019
12019
|
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.";
|
|
12020
12020
|
if (options.outputFormat === "json") console.log(JSON.stringify({
|
|
@@ -12025,15 +12025,15 @@ function registerRepoMapCommand(program) {
|
|
|
12025
12025
|
process.exitCode = 1;
|
|
12026
12026
|
return;
|
|
12027
12027
|
}
|
|
12028
|
-
const parser = new SymbolParser(grammarLoader, logger$
|
|
12029
|
-
const storage = new RepoMapStorage(symbolRepo, metaRepo, gitClient, logger$
|
|
12028
|
+
const parser = new SymbolParser(grammarLoader, logger$5);
|
|
12029
|
+
const storage = new RepoMapStorage(symbolRepo, metaRepo, gitClient, logger$5);
|
|
12030
12030
|
let updateWarning;
|
|
12031
12031
|
try {
|
|
12032
12032
|
await storage.incrementalUpdate(dbRoot, parser);
|
|
12033
12033
|
} catch (err) {
|
|
12034
12034
|
if (err instanceof AppError && err.code === ERR_REPO_MAP_STORAGE_WRITE) {
|
|
12035
12035
|
updateWarning = err.message;
|
|
12036
|
-
logger$
|
|
12036
|
+
logger$5.warn({ err }, "repo-map --update: storage write error (partial update)");
|
|
12037
12037
|
} else throw err;
|
|
12038
12038
|
}
|
|
12039
12039
|
const meta = await metaRepo.getMeta();
|
|
@@ -12053,7 +12053,7 @@ function registerRepoMapCommand(program) {
|
|
|
12053
12053
|
return;
|
|
12054
12054
|
}
|
|
12055
12055
|
if (options.query !== void 0) {
|
|
12056
|
-
logger$
|
|
12056
|
+
logger$5.debug({ symbol: options.query }, "repo-map --query");
|
|
12057
12057
|
const result = await queryEngine.query({
|
|
12058
12058
|
symbols: [options.query],
|
|
12059
12059
|
maxTokens: 4e3
|
|
@@ -12075,7 +12075,7 @@ function registerRepoMapCommand(program) {
|
|
|
12075
12075
|
process.exitCode = 1;
|
|
12076
12076
|
return;
|
|
12077
12077
|
}
|
|
12078
|
-
const injector = new RepoMapInjector(queryEngine, logger$
|
|
12078
|
+
const injector = new RepoMapInjector(queryEngine, logger$5);
|
|
12079
12079
|
const injectionResult = await injector.buildContext(storyContent, 2e3);
|
|
12080
12080
|
console.log(JSON.stringify({
|
|
12081
12081
|
text: injectionResult.text,
|
|
@@ -12089,7 +12089,7 @@ function registerRepoMapCommand(program) {
|
|
|
12089
12089
|
|
|
12090
12090
|
//#endregion
|
|
12091
12091
|
//#region src/cli/commands/routing.ts
|
|
12092
|
-
const logger$
|
|
12092
|
+
const logger$4 = createLogger("cli:routing");
|
|
12093
12093
|
function registerRoutingCommand(program) {
|
|
12094
12094
|
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) => {
|
|
12095
12095
|
const dbRoot = await resolveMainRepoRoot(process.cwd());
|
|
@@ -12097,7 +12097,7 @@ function registerRoutingCommand(program) {
|
|
|
12097
12097
|
try {
|
|
12098
12098
|
await store.initialize();
|
|
12099
12099
|
if (options.history === true) {
|
|
12100
|
-
logger$
|
|
12100
|
+
logger$4.debug("routing --history: fetching tune log");
|
|
12101
12101
|
const raw$1 = await store.getMetric("global", "routing_tune_log");
|
|
12102
12102
|
let entries = [];
|
|
12103
12103
|
if (Array.isArray(raw$1)) entries = raw$1.sort((a, b) => b.appliedAt.localeCompare(a.appliedAt));
|
|
@@ -12392,7 +12392,7 @@ function registerFactoryCommand$1(program) {
|
|
|
12392
12392
|
|
|
12393
12393
|
//#endregion
|
|
12394
12394
|
//#region src/cli/commands/reconcile-from-disk.ts
|
|
12395
|
-
const logger$
|
|
12395
|
+
const logger$3 = createLogger("reconcile-from-disk");
|
|
12396
12396
|
/**
|
|
12397
12397
|
* The reconcile write (obs_2026-05-26_031). Keyed on `story_key` ALONE —
|
|
12398
12398
|
* `wg_stories` has no `run_id` column (cols: story_key, epic, title, status,
|
|
@@ -12464,7 +12464,7 @@ async function readRunEntry(dbRoot, resolvedRunId) {
|
|
|
12464
12464
|
stories
|
|
12465
12465
|
};
|
|
12466
12466
|
} catch {
|
|
12467
|
-
logger$
|
|
12467
|
+
logger$3.debug({ runId: resolvedRunId }, "failed to read individual run manifest");
|
|
12468
12468
|
return null;
|
|
12469
12469
|
}
|
|
12470
12470
|
}
|
|
@@ -12599,7 +12599,7 @@ async function runReconcileFromDiskAction(options) {
|
|
|
12599
12599
|
const latestRun = await getLatestRun(probeAdapter);
|
|
12600
12600
|
if (latestRun?.id) resolvedRunId = latestRun.id;
|
|
12601
12601
|
} catch {
|
|
12602
|
-
logger$
|
|
12602
|
+
logger$3.debug("Dolt fallback failed during run-id resolution");
|
|
12603
12603
|
} finally {
|
|
12604
12604
|
await probeAdapter.close().catch(swallowDebug("reconcile-probe-close"));
|
|
12605
12605
|
}
|
|
@@ -12680,7 +12680,7 @@ async function runReconcileFromDiskAction(options) {
|
|
|
12680
12680
|
stdoutTail: failedGateResult?.stdoutTail,
|
|
12681
12681
|
durationMs: durationMs$1
|
|
12682
12682
|
});
|
|
12683
|
-
logger$
|
|
12683
|
+
logger$3.info({
|
|
12684
12684
|
runId: resolvedRunId,
|
|
12685
12685
|
failedGate: failedGateName,
|
|
12686
12686
|
exitCode: failedGateResult?.exitCode
|
|
@@ -12738,7 +12738,7 @@ async function runReconcileFromDiskAction(options) {
|
|
|
12738
12738
|
record.storyKey
|
|
12739
12739
|
]);
|
|
12740
12740
|
});
|
|
12741
|
-
logger$
|
|
12741
|
+
logger$3.info({
|
|
12742
12742
|
runId: resolvedRunId,
|
|
12743
12743
|
affectedStories: reconcilableRecords.map((r) => r.storyKey)
|
|
12744
12744
|
}, "reconcile-from-disk: Dolt update complete");
|
|
@@ -12793,7 +12793,7 @@ function registerReconcileFromDiskCommand(program, _version = "0.0.0", projectRo
|
|
|
12793
12793
|
|
|
12794
12794
|
//#endregion
|
|
12795
12795
|
//#region src/cli/commands/report.ts
|
|
12796
|
-
const logger$
|
|
12796
|
+
const logger$2 = createLogger("report");
|
|
12797
12797
|
/**
|
|
12798
12798
|
* v0.20.110: Minimum output_tokens for a verified/recovered story to be
|
|
12799
12799
|
* trusted as having actually produced work. Below this, the story is flagged
|
|
@@ -12948,7 +12948,7 @@ async function readNotificationsForRun(runId, dbRoot) {
|
|
|
12948
12948
|
const parsed = JSON.parse(raw);
|
|
12949
12949
|
notifications.push(parsed);
|
|
12950
12950
|
} catch (err) {
|
|
12951
|
-
if (err.code !== "ENOENT") logger$
|
|
12951
|
+
if (err.code !== "ENOENT") logger$2.warn({
|
|
12952
12952
|
err,
|
|
12953
12953
|
filePath
|
|
12954
12954
|
}, "failed to read notification file — skipping");
|
|
@@ -12957,7 +12957,7 @@ async function readNotificationsForRun(runId, dbRoot) {
|
|
|
12957
12957
|
try {
|
|
12958
12958
|
await unlink(filePath);
|
|
12959
12959
|
} catch (err) {
|
|
12960
|
-
if (err.code !== "ENOENT") logger$
|
|
12960
|
+
if (err.code !== "ENOENT") logger$2.warn({
|
|
12961
12961
|
err,
|
|
12962
12962
|
filePath
|
|
12963
12963
|
}, "failed to delete notification file — continuing");
|
|
@@ -13290,7 +13290,7 @@ async function resolveLatestRunId(dbRoot) {
|
|
|
13290
13290
|
const latest = await getLatestRun(probeAdapter);
|
|
13291
13291
|
return latest?.id ?? null;
|
|
13292
13292
|
} catch {
|
|
13293
|
-
logger$
|
|
13293
|
+
logger$2.debug("Dolt fallback failed during run-id resolution");
|
|
13294
13294
|
return null;
|
|
13295
13295
|
} finally {
|
|
13296
13296
|
await probeAdapter.close().catch(swallowDebug("report-probe-close"));
|
|
@@ -13301,7 +13301,7 @@ async function runReportAction(options) {
|
|
|
13301
13301
|
const effectiveProjectRoot = process.env["SUBSTRATE_PROJECT_ROOT"] ?? projectRoot;
|
|
13302
13302
|
const dbRoot = _dbRoot ?? await resolveMainRepoRoot(effectiveProjectRoot);
|
|
13303
13303
|
const runsDir = join(dbRoot, ".substrate", "runs");
|
|
13304
|
-
logger$
|
|
13304
|
+
logger$2.debug({
|
|
13305
13305
|
runArg,
|
|
13306
13306
|
effectiveProjectRoot,
|
|
13307
13307
|
dbRoot
|
|
@@ -13316,7 +13316,7 @@ async function runReportAction(options) {
|
|
|
13316
13316
|
const data = await canonical.manifest.read();
|
|
13317
13317
|
manifest = data;
|
|
13318
13318
|
} catch {
|
|
13319
|
-
logger$
|
|
13319
|
+
logger$2.debug({ runId: resolvedRunId }, "canonical manifest read failed — using raw shim");
|
|
13320
13320
|
}
|
|
13321
13321
|
if (!manifest) manifest = await readRawManifest(runsDir, resolvedRunId);
|
|
13322
13322
|
} else {
|
|
@@ -13327,7 +13327,7 @@ async function runReportAction(options) {
|
|
|
13327
13327
|
const data = await canonical.manifest.read();
|
|
13328
13328
|
manifest = data;
|
|
13329
13329
|
} catch {
|
|
13330
|
-
logger$
|
|
13330
|
+
logger$2.debug({ runId: canonical.runId }, "canonical manifest read failed — using raw shim");
|
|
13331
13331
|
manifest = null;
|
|
13332
13332
|
}
|
|
13333
13333
|
}
|
|
@@ -13339,7 +13339,7 @@ async function runReportAction(options) {
|
|
|
13339
13339
|
const data = await reread.manifest.read();
|
|
13340
13340
|
manifest = data;
|
|
13341
13341
|
} catch {
|
|
13342
|
-
logger$
|
|
13342
|
+
logger$2.debug({ runId: resolvedRunId }, "manifest read failed after Dolt resolution");
|
|
13343
13343
|
}
|
|
13344
13344
|
if (!manifest) manifest = await readRawManifest(runsDir, resolvedRunId);
|
|
13345
13345
|
}
|
|
@@ -13368,18 +13368,18 @@ async function runReportAction(options) {
|
|
|
13368
13368
|
const state = manifest.per_story_state[row.story_key];
|
|
13369
13369
|
if (state && !state.completed_at && row.completed_at) state.completed_at = row.completed_at;
|
|
13370
13370
|
}
|
|
13371
|
-
logger$
|
|
13371
|
+
logger$2.debug({ storyCount: rows.length }, "Dolt wg_stories enrichment applied");
|
|
13372
13372
|
}
|
|
13373
13373
|
} catch (err) {
|
|
13374
|
-
logger$
|
|
13374
|
+
logger$2.debug({ err }, "Dolt enrichment unavailable — using manifest-only data (degraded mode)");
|
|
13375
13375
|
} finally {
|
|
13376
13376
|
if (doltClient !== null) await doltClient.close().catch((err) => {
|
|
13377
|
-
logger$
|
|
13377
|
+
logger$2.debug({ err }, "DoltClient.close() failed — non-fatal");
|
|
13378
13378
|
});
|
|
13379
13379
|
}
|
|
13380
13380
|
}
|
|
13381
13381
|
const halts = await readNotificationsForRun(resolvedRunId, dbRoot).catch((err) => {
|
|
13382
|
-
logger$
|
|
13382
|
+
logger$2.debug({ err }, "notification read failed — continuing without halt data");
|
|
13383
13383
|
return [];
|
|
13384
13384
|
});
|
|
13385
13385
|
const storyOutputTokens = new Map();
|
|
@@ -13392,7 +13392,7 @@ async function runReportAction(options) {
|
|
|
13392
13392
|
const storyMetricsRows = await getStoryMetricsForRun(metricsAdapter, resolvedRunId);
|
|
13393
13393
|
for (const row of storyMetricsRows) if (typeof row.output_tokens === "number") storyOutputTokens.set(row.story_key, row.output_tokens);
|
|
13394
13394
|
} catch (err) {
|
|
13395
|
-
logger$
|
|
13395
|
+
logger$2.debug({ err }, "story_metrics read failed — low-output flagging unavailable");
|
|
13396
13396
|
} finally {
|
|
13397
13397
|
await metricsAdapter.close().catch(swallowDebug("report-metrics-close"));
|
|
13398
13398
|
}
|
|
@@ -13406,7 +13406,7 @@ async function runReportAction(options) {
|
|
|
13406
13406
|
const rmData = await rmForAc.read();
|
|
13407
13407
|
acPerStoryState = rmData.per_story_state;
|
|
13408
13408
|
} catch {
|
|
13409
|
-
logger$
|
|
13409
|
+
logger$2.debug({ runId: resolvedRunId }, "RunManifest.read() for --verify-ac failed — using raw manifest fallback");
|
|
13410
13410
|
}
|
|
13411
13411
|
const storyEntries = Object.entries(acPerStoryState);
|
|
13412
13412
|
for (const [storyKey, state] of storyEntries) {
|
|
@@ -13428,7 +13428,7 @@ async function runReportAction(options) {
|
|
|
13428
13428
|
confidence: result.confidence
|
|
13429
13429
|
};
|
|
13430
13430
|
} catch (err) {
|
|
13431
|
-
logger$
|
|
13431
|
+
logger$2.debug({
|
|
13432
13432
|
err,
|
|
13433
13433
|
storyKey
|
|
13434
13434
|
}, "ac traceability check failed for story (skipping)");
|
|
@@ -13461,6 +13461,141 @@ function registerReportCommand(program, _version = "0.0.0", projectRoot = proces
|
|
|
13461
13461
|
});
|
|
13462
13462
|
}
|
|
13463
13463
|
|
|
13464
|
+
//#endregion
|
|
13465
|
+
//#region src/modules/compiled-workflows/acceptance-derive.ts
|
|
13466
|
+
const logger$1 = createLogger("compiled-workflows:acceptance-derive");
|
|
13467
|
+
/** Cap on injected source-document content (chars) — PRDs can be book-length. */
|
|
13468
|
+
const SOURCE_CONTENT_CAP = 12e4;
|
|
13469
|
+
/** Shape problems the schema can't express: duplicate ids, id/end-state prefix drift. */
|
|
13470
|
+
function validateDerivedJourneys(journeys) {
|
|
13471
|
+
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";
|
|
13472
|
+
const seen = new Set();
|
|
13473
|
+
for (const j of journeys) {
|
|
13474
|
+
if (seen.has(j.id)) return `duplicate journey id "${j.id}"`;
|
|
13475
|
+
seen.add(j.id);
|
|
13476
|
+
for (const es of j.end_states) if (!es.id.startsWith(`${j.id}.`)) return `end-state "${es.id}" of journey "${j.id}" must use the "<journey-id>.<letter>" convention`;
|
|
13477
|
+
}
|
|
13478
|
+
return void 0;
|
|
13479
|
+
}
|
|
13480
|
+
async function runAcceptanceDerive(deps, params) {
|
|
13481
|
+
const { prdRelPath, prdContent, uxJourneysContent, existingRegistryYaml } = params;
|
|
13482
|
+
let template;
|
|
13483
|
+
try {
|
|
13484
|
+
template = await deps.pack.getPrompt("acceptance-derive");
|
|
13485
|
+
} catch (err) {
|
|
13486
|
+
return {
|
|
13487
|
+
result: "failed",
|
|
13488
|
+
error: `Failed to retrieve acceptance-derive prompt: ${err instanceof Error ? err.message : String(err)}`,
|
|
13489
|
+
tokenUsage: {
|
|
13490
|
+
input: 0,
|
|
13491
|
+
output: 0
|
|
13492
|
+
}
|
|
13493
|
+
};
|
|
13494
|
+
}
|
|
13495
|
+
const truncated = prdContent.length > SOURCE_CONTENT_CAP;
|
|
13496
|
+
const buildPrompt = (correctivePreamble) => {
|
|
13497
|
+
const { prompt } = assemblePrompt(template, [
|
|
13498
|
+
{
|
|
13499
|
+
name: "source_path",
|
|
13500
|
+
content: prdRelPath,
|
|
13501
|
+
priority: "required"
|
|
13502
|
+
},
|
|
13503
|
+
{
|
|
13504
|
+
name: "source_content",
|
|
13505
|
+
content: (truncated ? `(truncated to first ${String(SOURCE_CONTENT_CAP)} chars)\n` : "") + prdContent.slice(0, SOURCE_CONTENT_CAP),
|
|
13506
|
+
priority: "required"
|
|
13507
|
+
},
|
|
13508
|
+
{
|
|
13509
|
+
name: "ux_journeys",
|
|
13510
|
+
content: uxJourneysContent ?? "(no UX journey artifact provided)",
|
|
13511
|
+
priority: "required"
|
|
13512
|
+
},
|
|
13513
|
+
{
|
|
13514
|
+
name: "existing_registry",
|
|
13515
|
+
content: existingRegistryYaml ?? "(no existing registry — this is a first derivation)",
|
|
13516
|
+
priority: "required"
|
|
13517
|
+
}
|
|
13518
|
+
], getTokenCeiling("acceptance-derive", deps.tokenCeilings).ceiling);
|
|
13519
|
+
return correctivePreamble !== void 0 ? `${correctivePreamble}\n\n${prompt}` : prompt;
|
|
13520
|
+
};
|
|
13521
|
+
let totalTokens = {
|
|
13522
|
+
input: 0,
|
|
13523
|
+
output: 0
|
|
13524
|
+
};
|
|
13525
|
+
let lastProblem = "unknown";
|
|
13526
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
13527
|
+
const prompt = attempt === 0 ? buildPrompt() : buildPrompt(`PREVIOUS ATTEMPT REJECTED: ${lastProblem}. Emit ONLY the YAML block per the Output Contract — unique journey ids, end-state ids prefixed "<journey-id>.", surfaces from the enum.`);
|
|
13528
|
+
const handle = deps.dispatcher.dispatch({
|
|
13529
|
+
prompt,
|
|
13530
|
+
agent: deps.agentId ?? "claude-code",
|
|
13531
|
+
taskType: "acceptance-derive",
|
|
13532
|
+
outputSchema: AcceptanceDeriveResultSchema,
|
|
13533
|
+
maxTurns: 30,
|
|
13534
|
+
...deps.otlpEndpoint !== void 0 ? { otlpEndpoint: deps.otlpEndpoint } : {}
|
|
13535
|
+
});
|
|
13536
|
+
let dispatchResult;
|
|
13537
|
+
try {
|
|
13538
|
+
dispatchResult = await handle.result;
|
|
13539
|
+
} catch (err) {
|
|
13540
|
+
return {
|
|
13541
|
+
result: "failed",
|
|
13542
|
+
error: `Dispatch error: ${err instanceof Error ? err.message : String(err)}`,
|
|
13543
|
+
tokenUsage: totalTokens
|
|
13544
|
+
};
|
|
13545
|
+
}
|
|
13546
|
+
totalTokens = {
|
|
13547
|
+
input: totalTokens.input + dispatchResult.tokenEstimate.input,
|
|
13548
|
+
output: totalTokens.output + dispatchResult.tokenEstimate.output
|
|
13549
|
+
};
|
|
13550
|
+
if (dispatchResult.status === "failed" || dispatchResult.status === "timeout") return {
|
|
13551
|
+
result: "failed",
|
|
13552
|
+
error: `Dispatch status: ${dispatchResult.status}. ${dispatchResult.parseError ?? ""}`.trim(),
|
|
13553
|
+
tokenUsage: totalTokens
|
|
13554
|
+
};
|
|
13555
|
+
const parsed = AcceptanceDeriveResultSchema.safeParse(dispatchResult.parsed);
|
|
13556
|
+
if (!parsed.success) {
|
|
13557
|
+
lastProblem = `output failed schema validation (${parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ").slice(0, 500)})`;
|
|
13558
|
+
logger$1.warn({
|
|
13559
|
+
prdRelPath,
|
|
13560
|
+
attempt,
|
|
13561
|
+
lastProblem
|
|
13562
|
+
}, "RP1.1: derive output invalid");
|
|
13563
|
+
continue;
|
|
13564
|
+
}
|
|
13565
|
+
if (parsed.data.result === "failed") return {
|
|
13566
|
+
result: "failed",
|
|
13567
|
+
error: "acceptance-derive-refused",
|
|
13568
|
+
details: parsed.data.error ?? "derive agent reported failure without a reason",
|
|
13569
|
+
tokenUsage: totalTokens
|
|
13570
|
+
};
|
|
13571
|
+
const shapeProblem = validateDerivedJourneys(parsed.data.journeys);
|
|
13572
|
+
if (shapeProblem !== void 0) {
|
|
13573
|
+
lastProblem = shapeProblem;
|
|
13574
|
+
logger$1.warn({
|
|
13575
|
+
prdRelPath,
|
|
13576
|
+
attempt,
|
|
13577
|
+
shapeProblem
|
|
13578
|
+
}, "RP1.1: derived journeys malformed");
|
|
13579
|
+
continue;
|
|
13580
|
+
}
|
|
13581
|
+
logger$1.info({
|
|
13582
|
+
prdRelPath,
|
|
13583
|
+
journeys: parsed.data.journeys.map((j) => `${j.id}[${j.criticality}]`)
|
|
13584
|
+
}, "RP1.1: derive candidates accepted");
|
|
13585
|
+
return {
|
|
13586
|
+
result: "success",
|
|
13587
|
+
journeys: parsed.data.journeys,
|
|
13588
|
+
tokenUsage: totalTokens
|
|
13589
|
+
};
|
|
13590
|
+
}
|
|
13591
|
+
return {
|
|
13592
|
+
result: "failed",
|
|
13593
|
+
error: "acceptance-derive-invalid",
|
|
13594
|
+
details: `derive agent produced invalid output twice — last problem: ${lastProblem}`,
|
|
13595
|
+
tokenUsage: totalTokens
|
|
13596
|
+
};
|
|
13597
|
+
}
|
|
13598
|
+
|
|
13464
13599
|
//#endregion
|
|
13465
13600
|
//#region src/cli/commands/acceptance.ts
|
|
13466
13601
|
const ACCEPTANCE_EXIT_SUCCESS = 0;
|
|
@@ -13673,6 +13808,111 @@ function registerAcceptanceCommand(program, version, registry) {
|
|
|
13673
13808
|
process.stdout.write(JSON.stringify(output, null, 2) + "\n");
|
|
13674
13809
|
process.exit(result.result === "success" ? ACCEPTANCE_EXIT_SUCCESS : ACCEPTANCE_EXIT_ERROR);
|
|
13675
13810
|
});
|
|
13811
|
+
acceptanceCmd.command("derive").description("Derive a journey-registry CANDIDATE from a PRD (planning-lineage agent). Writes journeys.candidate.yaml — non-authoritative, ignored by the gate, promoted only by your explicit ratify action.").requiredOption("--prd <path>", "source document (PRD) to derive from — project-relative").option("--ux <path>", "optional UX journey artifact to derive alongside the PRD").option("--out <path>", `candidate output path (default: ${JOURNEY_CANDIDATE_PATH})`).option("--force", "overwrite an existing candidate file", false).option("--agent <id>", "agent adapter id", "claude-code").option("--pack <name>", "methodology pack carrying the derive prompt", "bmad").action(async (opts) => {
|
|
13812
|
+
if (process.env.LOG_LEVEL === void 0) process.env.LOG_LEVEL = "silent";
|
|
13813
|
+
if (registry === void 0) {
|
|
13814
|
+
process.stdout.write("acceptance derive: adapter registry unavailable in this invocation context\n");
|
|
13815
|
+
process.exit(ACCEPTANCE_EXIT_ERROR);
|
|
13816
|
+
}
|
|
13817
|
+
const projectRoot = process.cwd();
|
|
13818
|
+
const prdAbs = resolve$1(projectRoot, opts.prd);
|
|
13819
|
+
const prdRel = relative(projectRoot, prdAbs);
|
|
13820
|
+
if (prdRel.startsWith("..") || prdRel === "") {
|
|
13821
|
+
process.stdout.write(`acceptance derive: --prd must resolve inside the project root (got ${prdAbs})\n`);
|
|
13822
|
+
process.exit(ACCEPTANCE_EXIT_ERROR);
|
|
13823
|
+
}
|
|
13824
|
+
let prdContent;
|
|
13825
|
+
try {
|
|
13826
|
+
prdContent = await readFile$1(prdAbs, "utf-8");
|
|
13827
|
+
} catch (err) {
|
|
13828
|
+
process.stdout.write(`acceptance derive: cannot read PRD at ${prdAbs}: ${String(err)}\n`);
|
|
13829
|
+
process.exit(ACCEPTANCE_EXIT_ERROR);
|
|
13830
|
+
return;
|
|
13831
|
+
}
|
|
13832
|
+
let uxContent;
|
|
13833
|
+
if (opts.ux !== void 0) try {
|
|
13834
|
+
uxContent = await readFile$1(resolve$1(projectRoot, opts.ux), "utf-8");
|
|
13835
|
+
} catch (err) {
|
|
13836
|
+
process.stdout.write(`acceptance derive: cannot read UX artifact at ${opts.ux}: ${String(err)}\n`);
|
|
13837
|
+
process.exit(ACCEPTANCE_EXIT_ERROR);
|
|
13838
|
+
return;
|
|
13839
|
+
}
|
|
13840
|
+
let existingRegistryYaml;
|
|
13841
|
+
try {
|
|
13842
|
+
existingRegistryYaml = await readFile$1(join$1(projectRoot, JOURNEY_REGISTRY_PATH), "utf-8");
|
|
13843
|
+
} catch {
|
|
13844
|
+
existingRegistryYaml = void 0;
|
|
13845
|
+
}
|
|
13846
|
+
const outPath = opts.out !== void 0 ? resolve$1(projectRoot, opts.out) : join$1(projectRoot, JOURNEY_CANDIDATE_PATH);
|
|
13847
|
+
if (!opts.force) try {
|
|
13848
|
+
await readFile$1(outPath, "utf-8");
|
|
13849
|
+
process.stdout.write(`acceptance derive: candidate already exists at ${outPath} — review it, or re-run with --force to overwrite\n`);
|
|
13850
|
+
process.exit(ACCEPTANCE_EXIT_ERROR);
|
|
13851
|
+
} catch {}
|
|
13852
|
+
const eventBus = createEventBus();
|
|
13853
|
+
const adapter = new InMemoryDatabaseAdapter();
|
|
13854
|
+
const packLoader = createPackLoader();
|
|
13855
|
+
let pack;
|
|
13856
|
+
try {
|
|
13857
|
+
pack = await packLoader.load(join$1(projectRoot, "packs", opts.pack));
|
|
13858
|
+
} catch (err) {
|
|
13859
|
+
process.stdout.write(`acceptance derive: failed to load pack '${opts.pack}': ${String(err)}\n`);
|
|
13860
|
+
process.exit(ACCEPTANCE_EXIT_ERROR);
|
|
13861
|
+
return;
|
|
13862
|
+
}
|
|
13863
|
+
const contextCompiler = createContextCompiler({ db: adapter });
|
|
13864
|
+
const dispatcher = createDispatcher({
|
|
13865
|
+
eventBus,
|
|
13866
|
+
adapterRegistry: registry,
|
|
13867
|
+
logger: {
|
|
13868
|
+
debug: () => {},
|
|
13869
|
+
info: () => {},
|
|
13870
|
+
warn: () => {},
|
|
13871
|
+
error: () => {}
|
|
13872
|
+
}
|
|
13873
|
+
});
|
|
13874
|
+
process.stderr.write(`deriving journey candidates from ${prdRel} (real agent dispatch — may take a few minutes)…\n`);
|
|
13875
|
+
const result = await runAcceptanceDerive({
|
|
13876
|
+
db: adapter,
|
|
13877
|
+
pack,
|
|
13878
|
+
contextCompiler,
|
|
13879
|
+
dispatcher,
|
|
13880
|
+
agentId: opts.agent
|
|
13881
|
+
}, {
|
|
13882
|
+
prdRelPath: prdRel,
|
|
13883
|
+
prdContent,
|
|
13884
|
+
...uxContent !== void 0 ? { uxJourneysContent: uxContent } : {},
|
|
13885
|
+
...existingRegistryYaml !== void 0 ? { existingRegistryYaml } : {}
|
|
13886
|
+
});
|
|
13887
|
+
await dispatcher.shutdown();
|
|
13888
|
+
if (result.result !== "success" || result.journeys === void 0) {
|
|
13889
|
+
process.stdout.write(`acceptance derive: FAILED — ${result.error ?? "unknown"}${result.details !== void 0 ? `: ${result.details}` : ""}\n`);
|
|
13890
|
+
process.exit(ACCEPTANCE_EXIT_ERROR);
|
|
13891
|
+
return;
|
|
13892
|
+
}
|
|
13893
|
+
const sourceSha = createHash("sha256").update(prdContent, "utf-8").digest("hex");
|
|
13894
|
+
const candidateDoc = {
|
|
13895
|
+
candidate: true,
|
|
13896
|
+
derived_from: prdRel,
|
|
13897
|
+
source_sha256: sourceSha,
|
|
13898
|
+
derived_at: new Date().toISOString(),
|
|
13899
|
+
journeys: result.journeys
|
|
13900
|
+
};
|
|
13901
|
+
const header = "# CANDIDATE journey registry — NOT authoritative.\n# Derived by `substrate acceptance derive`; the acceptance gate IGNORES this file.\n# Review (edit freely), then promote to journeys.yaml via your explicit ratify action.\n";
|
|
13902
|
+
try {
|
|
13903
|
+
await mkdir$1(dirname$1(outPath), { recursive: true });
|
|
13904
|
+
await writeFile$1(outPath, header + dump(candidateDoc, { lineWidth: 120 }), "utf-8");
|
|
13905
|
+
} catch (err) {
|
|
13906
|
+
process.stdout.write(`acceptance derive: failed to write candidate at ${outPath}: ${String(err)}\n`);
|
|
13907
|
+
process.exit(ACCEPTANCE_EXIT_ERROR);
|
|
13908
|
+
return;
|
|
13909
|
+
}
|
|
13910
|
+
const needsElaboration = result.journeys.filter((j) => j.end_states.length === 0);
|
|
13911
|
+
process.stdout.write(`candidate written: ${relative(projectRoot, outPath)}\n ${String(result.journeys.length)} journeys (${String(result.journeys.filter((j) => j.criticality === "critical").length)} critical), ${String(result.journeys.reduce((n, j) => n + j.end_states.length, 0))} end-states` + (needsElaboration.length > 0 ? `, ${String(needsElaboration.length)} journey(s) need end-state elaboration: ${needsElaboration.map((j) => j.id).join(", ")}` : "") + `
|
|
13912
|
+
derived from ${prdRel} (sha256 ${sourceSha.slice(0, 12)}…)\nThis candidate is NOT authoritative and the gate ignores it. Review every journey against the PRD — a journey missing here is invisible to the whole acceptance machinery.
|
|
13913
|
+
`);
|
|
13914
|
+
process.exit(ACCEPTANCE_EXIT_SUCCESS);
|
|
13915
|
+
});
|
|
13676
13916
|
acceptanceCmd.command("canary <journeyId>").description("Self-test the gate: revert a journey's wiring commit(s), re-judge, require the verdict to flip. A miss auto-demotes the gate to advisory. Set LOG_LEVEL=silent for clean JSON.").requiredOption("--wiring-commit <sha...>", "commit SHA(s) that wired the journey (reverted in a scratch clone)").option("--registry-file <path>", `registry YAML (default: ${JOURNEY_REGISTRY_PATH} in cwd)`).option("--agent <id>", "agent adapter id", "claude-code").option("--pack <name>", "methodology pack carrying the judge prompt", "bmad").action(async (journeyId, opts) => {
|
|
13677
13917
|
if (process.env.LOG_LEVEL === void 0) process.env.LOG_LEVEL = "silent";
|
|
13678
13918
|
if (registry === void 0) {
|
|
@@ -13707,7 +13947,7 @@ function registerAcceptanceCommand(program, version, registry) {
|
|
|
13707
13947
|
process.exit(ACCEPTANCE_EXIT_ERROR);
|
|
13708
13948
|
return;
|
|
13709
13949
|
}
|
|
13710
|
-
const { runAcceptanceJudge: runAcceptanceJudge$1 } = await import("../acceptance-judge-
|
|
13950
|
+
const { runAcceptanceJudge: runAcceptanceJudge$1 } = await import("../acceptance-judge-D5Iba2D_.js");
|
|
13711
13951
|
const eventBus = createEventBus();
|
|
13712
13952
|
const adapter = new InMemoryDatabaseAdapter();
|
|
13713
13953
|
const packLoader = createPackLoader();
|