substrate-ai 0.20.91 → 0.20.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +83 -351
- package/dist/cli/templates/claude-md-substrate-section.md +1 -2
- package/dist/{health-KPgV5-4u.js → health-CgY9akax.js} +1 -1
- package/dist/{health-C91xmseT.js → health-dWYa13k4.js} +48 -529
- package/dist/{run-DZz1qqAp.js → run-BXRwQRst.js} +2 -2
- package/dist/{run-Ba-2-qk3.js → run-DPQ4DT5Q.js} +2 -2
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { FileStateStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-
|
|
2
|
+
import { FileStateStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createDoltOperatorReader, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-dWYa13k4.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, createDoltClient, createPipelineRun, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, swallowDebug, tagRunAsBaseline, updatePipelineRun } from "../dist-l0pA6zZF.js";
|
|
6
|
-
import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR, GitClient, GrammarLoader, Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createGitWorktreeManager, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runSolutioningPhase, unescape, validateStopAfterFromConflict } from "../run-
|
|
6
|
+
import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR, GitClient, GrammarLoader, Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createGitWorktreeManager, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runSolutioningPhase, unescape, validateStopAfterFromConflict } from "../run-BXRwQRst.js";
|
|
7
7
|
import "../adapter-registry-DIcrxjH8.js";
|
|
8
8
|
import { RunManifest, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, parseRuntimeProbes, readCurrentRunId, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck } from "../manifest-read-CSmDEOWH.js";
|
|
9
9
|
import "../errors-DZuD2tVU.js";
|
|
@@ -6787,14 +6787,14 @@ function buildWorkGraphFromManifest(perStoryState) {
|
|
|
6787
6787
|
};
|
|
6788
6788
|
}
|
|
6789
6789
|
async function runStatusAction(options) {
|
|
6790
|
-
const { outputFormat, runId, projectRoot,
|
|
6790
|
+
const { outputFormat, runId, projectRoot, historyReader, history } = options;
|
|
6791
6791
|
if (history === true) {
|
|
6792
|
-
if (!
|
|
6792
|
+
if (!historyReader) {
|
|
6793
6793
|
process.stdout.write("History not available with file backend. Use Dolt backend for state history.\n");
|
|
6794
6794
|
return 0;
|
|
6795
6795
|
}
|
|
6796
6796
|
try {
|
|
6797
|
-
const entries = await
|
|
6797
|
+
const entries = await historyReader.getHistory(20);
|
|
6798
6798
|
if (outputFormat === "json") {
|
|
6799
6799
|
process.stdout.write(JSON.stringify(entries, null, 2) + "\n");
|
|
6800
6800
|
return 0;
|
|
@@ -6890,7 +6890,7 @@ async function runStatusAction(options) {
|
|
|
6890
6890
|
logger$15.debug({ err }, "Work graph query failed, continuing without work graph data");
|
|
6891
6891
|
}
|
|
6892
6892
|
if (run === void 0) {
|
|
6893
|
-
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-
|
|
6893
|
+
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-CgY9akax.js");
|
|
6894
6894
|
const substrateDirPath = join(projectRoot, ".substrate");
|
|
6895
6895
|
const processInfo = inspectProcessTree$1({
|
|
6896
6896
|
projectRoot,
|
|
@@ -6916,12 +6916,6 @@ async function runStatusAction(options) {
|
|
|
6916
6916
|
const decisionsCount = decisionsCountRows[0]?.cnt ?? 0;
|
|
6917
6917
|
const storiesCountRows = await adapter.query(`SELECT COUNT(*) as cnt FROM requirements WHERE pipeline_run_id = ? AND source = 'solutioning-phase'`, [run.id]);
|
|
6918
6918
|
const storiesCount = storiesCountRows[0]?.cnt ?? 0;
|
|
6919
|
-
let storeStories = [];
|
|
6920
|
-
if (stateStore) try {
|
|
6921
|
-
storeStories = await stateStore.queryStories({});
|
|
6922
|
-
} catch (err) {
|
|
6923
|
-
logger$15.debug({ err }, "StateStore query failed, continuing without store data");
|
|
6924
|
-
}
|
|
6925
6919
|
if (outputFormat === "json") {
|
|
6926
6920
|
const statusOutput = buildPipelineStatusOutput(run, tokenSummary, decisionsCount, storiesCount);
|
|
6927
6921
|
const storyMetricsRows = await getStoryMetricsForRun(adapter, run.id);
|
|
@@ -6988,7 +6982,6 @@ async function runStatusAction(options) {
|
|
|
6988
6982
|
stories_per_hour: storiesPerHour,
|
|
6989
6983
|
cost_usd: totalCostUsd
|
|
6990
6984
|
},
|
|
6991
|
-
story_states: storeStories,
|
|
6992
6985
|
workGraph: workGraph ?? null,
|
|
6993
6986
|
latest_heartbeat_per_story_state: latestHeartbeatPerStoryState ?? {}
|
|
6994
6987
|
};
|
|
@@ -7032,13 +7025,6 @@ async function runStatusAction(options) {
|
|
|
7032
7025
|
}
|
|
7033
7026
|
}
|
|
7034
7027
|
}
|
|
7035
|
-
if (storeStories.length > 0) {
|
|
7036
|
-
process.stdout.write("\nStateStore Story States:\n");
|
|
7037
|
-
for (const s of storeStories) if (s.phase === "CHECKPOINT") {
|
|
7038
|
-
const filesCount = s.checkpointFilesCount ?? 0;
|
|
7039
|
-
process.stdout.write(` ${s.storyKey}: ${s.phase} (${filesCount} files modified)\n`);
|
|
7040
|
-
} else process.stdout.write(` ${s.storyKey}: ${s.phase} (${s.reviewCycles} review cycles)\n`);
|
|
7041
|
-
}
|
|
7042
7028
|
if (workGraph !== void 0) {
|
|
7043
7029
|
const { summary, readyStories, blockedStories } = workGraph;
|
|
7044
7030
|
process.stdout.write("\nWork Graph:\n");
|
|
@@ -7075,29 +7061,26 @@ function registerStatusCommand(program, _version = "0.0.0", projectRoot = proces
|
|
|
7075
7061
|
program.command("status").description("Show status of the most recent (or specified) pipeline run").option("--run-id <id>", "Pipeline run ID to query (defaults to latest)").option("--project-root <path>", "Project root directory", projectRoot).option("--output-format <format>", "Output format: human (default) or json", "human").option("--history", "Show Dolt commit history for the state store").action(async (opts) => {
|
|
7076
7062
|
const outputFormat = opts.outputFormat === "json" ? "json" : "human";
|
|
7077
7063
|
const root = opts.projectRoot;
|
|
7078
|
-
let
|
|
7064
|
+
let historyReader;
|
|
7079
7065
|
const doltStatePath = join(root, ".substrate", "state", ".dolt");
|
|
7080
7066
|
if (existsSync$1(doltStatePath)) try {
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
basePath: join(root, ".substrate", "state")
|
|
7084
|
-
});
|
|
7085
|
-
await stateStore.initialize();
|
|
7067
|
+
historyReader = createDoltOperatorReader({ basePath: join(root, ".substrate", "state") });
|
|
7068
|
+
await historyReader.initialize();
|
|
7086
7069
|
} catch {
|
|
7087
|
-
|
|
7070
|
+
historyReader = void 0;
|
|
7088
7071
|
}
|
|
7089
7072
|
try {
|
|
7090
7073
|
const exitCode = await runStatusAction({
|
|
7091
7074
|
outputFormat,
|
|
7092
7075
|
runId: opts.runId,
|
|
7093
7076
|
projectRoot: root,
|
|
7094
|
-
|
|
7077
|
+
...historyReader !== void 0 && { historyReader },
|
|
7095
7078
|
history: opts.history
|
|
7096
7079
|
});
|
|
7097
7080
|
process.exitCode = exitCode;
|
|
7098
7081
|
} finally {
|
|
7099
7082
|
try {
|
|
7100
|
-
await
|
|
7083
|
+
await historyReader?.close();
|
|
7101
7084
|
} catch {}
|
|
7102
7085
|
}
|
|
7103
7086
|
});
|
|
@@ -8436,7 +8419,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
8436
8419
|
await initSchema(expAdapter);
|
|
8437
8420
|
const { runRunAction: runPipeline } = await import(
|
|
8438
8421
|
/* @vite-ignore */
|
|
8439
|
-
"../run-
|
|
8422
|
+
"../run-DPQ4DT5Q.js"
|
|
8440
8423
|
);
|
|
8441
8424
|
const runStoryFn = async (opts) => {
|
|
8442
8425
|
const exitCode = await runPipeline({
|
|
@@ -8790,7 +8773,7 @@ function printFactoryRunTable(runs) {
|
|
|
8790
8773
|
}
|
|
8791
8774
|
}
|
|
8792
8775
|
async function runMetricsAction(options) {
|
|
8793
|
-
const { outputFormat, projectRoot, limit = 10, compare, tagBaseline, analysis,
|
|
8776
|
+
const { outputFormat, projectRoot, limit = 10, compare, tagBaseline, analysis, story, efficiency, recommendations, turns, consumers, categories, compareStories, routingRecommendations, run, factory, probeAuthorSummary, probeAuthorClassSummary } = options;
|
|
8794
8777
|
const telemetryModes = [
|
|
8795
8778
|
efficiency,
|
|
8796
8779
|
recommendations,
|
|
@@ -8944,13 +8927,9 @@ async function runMetricsAction(options) {
|
|
|
8944
8927
|
if (routingRecommendations === true) {
|
|
8945
8928
|
const dbRoot$1 = await resolveMainRepoRoot(projectRoot);
|
|
8946
8929
|
const dbDir = join(dbRoot$1, ".substrate");
|
|
8947
|
-
const doltStatePath = join(dbDir, "state", ".dolt");
|
|
8948
|
-
const doltExists = existsSync$1(doltStatePath);
|
|
8949
|
-
const stateBackend = doltExists ? "dolt" : "file";
|
|
8950
|
-
const stateBasePath = join(dbDir, "state");
|
|
8951
8930
|
const stateStore = createStateStore({
|
|
8952
|
-
backend:
|
|
8953
|
-
basePath:
|
|
8931
|
+
backend: "file",
|
|
8932
|
+
basePath: dbDir
|
|
8954
8933
|
});
|
|
8955
8934
|
await stateStore.initialize();
|
|
8956
8935
|
try {
|
|
@@ -9141,26 +9120,6 @@ async function runMetricsAction(options) {
|
|
|
9141
9120
|
return 0;
|
|
9142
9121
|
}
|
|
9143
9122
|
const runs = await listRunMetrics(adapter, limit);
|
|
9144
|
-
let doltMetrics;
|
|
9145
|
-
const doltStatePath = join(dbRoot, ".substrate", "state", ".dolt");
|
|
9146
|
-
const hasDoltFilters = sprint !== void 0 || story !== void 0 || taskType !== void 0 || since !== void 0 || aggregate === true;
|
|
9147
|
-
if (existsSync$1(doltStatePath) && hasDoltFilters) try {
|
|
9148
|
-
const stateStore = createStateStore({
|
|
9149
|
-
backend: "dolt",
|
|
9150
|
-
basePath: join(dbRoot, ".substrate", "state")
|
|
9151
|
-
});
|
|
9152
|
-
await stateStore.initialize();
|
|
9153
|
-
const doltFilter = {};
|
|
9154
|
-
if (sprint !== void 0) doltFilter.sprint = sprint;
|
|
9155
|
-
if (story !== void 0) doltFilter.storyKey = story;
|
|
9156
|
-
if (taskType !== void 0) doltFilter.taskType = taskType;
|
|
9157
|
-
if (since !== void 0) doltFilter.since = since;
|
|
9158
|
-
if (aggregate !== void 0) doltFilter.aggregate = aggregate;
|
|
9159
|
-
doltMetrics = await stateStore.queryMetrics(doltFilter);
|
|
9160
|
-
await stateStore.close();
|
|
9161
|
-
} catch (doltErr) {
|
|
9162
|
-
logger$13.warn({ err: doltErr }, "StateStore query failed — falling back to SQLite metrics only");
|
|
9163
|
-
}
|
|
9164
9123
|
const storyMetricDecisions = await getDecisionsByCategory(adapter, STORY_METRICS);
|
|
9165
9124
|
const storyMetrics = storyMetricDecisions.map((d) => {
|
|
9166
9125
|
const colonIdx = d.key.indexOf(":");
|
|
@@ -9250,8 +9209,8 @@ async function runMetricsAction(options) {
|
|
|
9250
9209
|
};
|
|
9251
9210
|
if (probeAuthorSummary) {
|
|
9252
9211
|
const allMetrics = storyMetricsWithFindings.map((sm) => sm.probe_author);
|
|
9253
|
-
const aggregate
|
|
9254
|
-
jsonPayload.probe_author_summary = aggregate
|
|
9212
|
+
const aggregate = aggregateProbeAuthorMetrics(allMetrics, storyMetricsWithFindings.length);
|
|
9213
|
+
jsonPayload.probe_author_summary = aggregate;
|
|
9255
9214
|
}
|
|
9256
9215
|
if (probeAuthorClassSummary) {
|
|
9257
9216
|
const classSummaryEntries = storyMetricsWithFindings.map((sm) => {
|
|
@@ -9263,26 +9222,9 @@ async function runMetricsAction(options) {
|
|
|
9263
9222
|
});
|
|
9264
9223
|
jsonPayload.probe_author_class_summary = rollupProbeAuthorByClass(classSummaryEntries);
|
|
9265
9224
|
}
|
|
9266
|
-
if (doltMetrics !== void 0) if (aggregate) {
|
|
9267
|
-
const aggregateResults = doltMetrics.map((m) => ({
|
|
9268
|
-
task_type: m.taskType,
|
|
9269
|
-
count: m.count ?? 0,
|
|
9270
|
-
avg_cost_usd: m.costUsd ?? 0,
|
|
9271
|
-
sum_tokens_in: m.tokensIn ?? 0,
|
|
9272
|
-
sum_tokens_out: m.tokensOut ?? 0
|
|
9273
|
-
}));
|
|
9274
|
-
const aggregateTotals = {
|
|
9275
|
-
total_count: aggregateResults.reduce((sum, r) => sum + r.count, 0),
|
|
9276
|
-
total_avg_cost_usd: aggregateResults.reduce((sum, r) => sum + r.avg_cost_usd, 0),
|
|
9277
|
-
total_tokens_in: aggregateResults.reduce((sum, r) => sum + r.sum_tokens_in, 0),
|
|
9278
|
-
total_tokens_out: aggregateResults.reduce((sum, r) => sum + r.sum_tokens_out, 0)
|
|
9279
|
-
};
|
|
9280
|
-
jsonPayload.aggregate_metrics = aggregateResults;
|
|
9281
|
-
jsonPayload.aggregate_totals = aggregateTotals;
|
|
9282
|
-
} else jsonPayload.dolt_metrics = doltMetrics;
|
|
9283
9225
|
process.stdout.write(formatOutput(jsonPayload, "json", true) + "\n");
|
|
9284
9226
|
} else {
|
|
9285
|
-
if (runs.length === 0 && storyMetrics.length === 0 &&
|
|
9227
|
+
if (runs.length === 0 && storyMetrics.length === 0 && factoryRuns.length === 0) {
|
|
9286
9228
|
process.stdout.write("No run metrics recorded yet. Run `substrate run` to generate metrics.\n");
|
|
9287
9229
|
return 0;
|
|
9288
9230
|
}
|
|
@@ -9317,41 +9259,6 @@ async function runMetricsAction(options) {
|
|
|
9317
9259
|
process.stdout.write(` ${sm.story_key.padEnd(16)} ${runShort.padEnd(12)} ${String(sm.wall_clock_seconds).padStart(8)} ${sm.input_tokens.toLocaleString().padStart(10)} ${sm.output_tokens.toLocaleString().padStart(11)} ${String(sm.review_cycles).padStart(7)} ${stalledStr.padStart(8)}${costStr}\n`);
|
|
9318
9260
|
}
|
|
9319
9261
|
}
|
|
9320
|
-
if (doltMetrics !== void 0 && doltMetrics.length > 0) if (aggregate) {
|
|
9321
|
-
process.stdout.write(`\nStateStore Aggregate Metrics (by task type)\n`);
|
|
9322
|
-
process.stdout.write("─".repeat(80) + "\n");
|
|
9323
|
-
process.stdout.write(` ${"Task Type".padEnd(20)} ${"Count".padStart(8)} ${"Avg Cost".padStart(12)} ${"Sum Tokens In".padStart(14)} ${"Sum Tokens Out".padStart(15)}\n`);
|
|
9324
|
-
process.stdout.write(" " + "─".repeat(72) + "\n");
|
|
9325
|
-
let totalCount = 0;
|
|
9326
|
-
let totalCost = 0;
|
|
9327
|
-
let totalTokensIn = 0;
|
|
9328
|
-
let totalTokensOut = 0;
|
|
9329
|
-
for (const m of doltMetrics) {
|
|
9330
|
-
const count = m.count ?? 0;
|
|
9331
|
-
const avgCost = m.costUsd !== void 0 ? `$${m.costUsd.toFixed(4)}` : "-";
|
|
9332
|
-
const sumIn = m.tokensIn !== void 0 ? m.tokensIn.toLocaleString() : "-";
|
|
9333
|
-
const sumOut = m.tokensOut !== void 0 ? m.tokensOut.toLocaleString() : "-";
|
|
9334
|
-
totalCount += count;
|
|
9335
|
-
totalCost += m.costUsd ?? 0;
|
|
9336
|
-
totalTokensIn += m.tokensIn ?? 0;
|
|
9337
|
-
totalTokensOut += m.tokensOut ?? 0;
|
|
9338
|
-
process.stdout.write(` ${m.taskType.padEnd(20)} ${String(count).padStart(8)} ${avgCost.padStart(12)} ${sumIn.padStart(14)} ${sumOut.padStart(15)}\n`);
|
|
9339
|
-
}
|
|
9340
|
-
process.stdout.write(" " + "─".repeat(72) + "\n");
|
|
9341
|
-
process.stdout.write(` ${"TOTAL".padEnd(20)} ${String(totalCount).padStart(8)} ${`$${totalCost.toFixed(4)}`.padStart(12)} ${totalTokensIn.toLocaleString().padStart(14)} ${totalTokensOut.toLocaleString().padStart(15)}\n`);
|
|
9342
|
-
} else {
|
|
9343
|
-
process.stdout.write(`\nStateStore Metrics (${doltMetrics.length} records)\n`);
|
|
9344
|
-
process.stdout.write("─".repeat(80) + "\n");
|
|
9345
|
-
process.stdout.write(` ${"Story".padEnd(16)} ${"Task Type".padEnd(16)} ${"Tokens In".padStart(10)} ${"Tokens Out".padStart(11)} ${"Wall(ms)".padStart(10)} ${"Result".padEnd(12)}\n`);
|
|
9346
|
-
process.stdout.write(" " + "─".repeat(76) + "\n");
|
|
9347
|
-
for (const m of doltMetrics) {
|
|
9348
|
-
const tokIn = m.tokensIn !== void 0 ? m.tokensIn.toLocaleString() : "-";
|
|
9349
|
-
const tokOut = m.tokensOut !== void 0 ? m.tokensOut.toLocaleString() : "-";
|
|
9350
|
-
const wall = m.wallClockMs !== void 0 ? String(m.wallClockMs) : "-";
|
|
9351
|
-
const res = m.result ?? "-";
|
|
9352
|
-
process.stdout.write(` ${m.storyKey.padEnd(16)} ${m.taskType.padEnd(16)} ${tokIn.padStart(10)} ${tokOut.padStart(11)} ${wall.padStart(10)} ${res.padEnd(12)}\n`);
|
|
9353
|
-
}
|
|
9354
|
-
}
|
|
9355
9262
|
if (factoryRuns.length > 0) printFactoryRunTable(factoryRuns);
|
|
9356
9263
|
}
|
|
9357
9264
|
return 0;
|
|
@@ -9368,7 +9275,7 @@ async function runMetricsAction(options) {
|
|
|
9368
9275
|
}
|
|
9369
9276
|
}
|
|
9370
9277
|
function registerMetricsCommand(program, _version = "0.0.0", projectRoot = process.cwd()) {
|
|
9371
|
-
program.command("metrics").description("Show historical pipeline run metrics and cross-run comparison").option("--project-root <path>", "Project root directory", projectRoot).option("--output-format <format>", "Output format: human (default) or json", "human").option("--limit <n>", "Number of runs to show (default: 10)", (v) => parseInt(v, 10), 10).option("--compare <run-id-a,run-id-b>", "Compare two runs side-by-side (comma-separated IDs, e.g. abc123,def456)").option("--tag-baseline <run-id>", "Mark a run as the performance baseline").option("--analysis <run-id>", "Read and output the analysis report for the specified run (AC5 of Story 17-3)").option("--
|
|
9278
|
+
program.command("metrics").description("Show historical pipeline run metrics and cross-run comparison").option("--project-root <path>", "Project root directory", projectRoot).option("--output-format <format>", "Output format: human (default) or json", "human").option("--limit <n>", "Number of runs to show (default: 10)", (v) => parseInt(v, 10), 10).option("--compare <run-id-a,run-id-b>", "Compare two runs side-by-side (comma-separated IDs, e.g. abc123,def456)").option("--tag-baseline <run-id>", "Mark a run as the performance baseline").option("--analysis <run-id>", "Read and output the analysis report for the specified run (AC5 of Story 17-3)").option("--story <story-key>", "Filter recommendations by story key (e.g. 26-1)").option("--efficiency", "Show telemetry efficiency scores for recent stories").option("--recommendations", "Show all telemetry recommendations across stories").option("--turns <storyKey>", "Show per-turn analysis for a specific story").option("--consumers <storyKey>", "Show consumer stats for a specific story").option("--categories", "Show category stats (optionally scoped by --story <storyKey>)").option("--compare-stories <storyA,storyB>", "Compare efficiency scores of two stories side-by-side (comma-separated keys)").option("--routing-recommendations", "Show routing recommendations derived from phase token breakdown history").option("--run <run-id>", "Show per-iteration score history for a specific factory run").option("--factory", "Show only factory graph run metrics (excludes SDLC runs)").option("--probe-author-summary", "Print cross-run probe-author KPI aggregate (Story 60-15)").option("--probe-author-class-summary", "Print cross-run probe-author KPI aggregate broken down by trigger class (Story 65-6)").action(async (opts) => {
|
|
9372
9279
|
const outputFormat = opts.outputFormat === "json" ? "json" : "human";
|
|
9373
9280
|
let compareIds;
|
|
9374
9281
|
if (opts.compare !== void 0) {
|
|
@@ -9392,11 +9299,7 @@ function registerMetricsCommand(program, _version = "0.0.0", projectRoot = proce
|
|
|
9392
9299
|
...compareIds !== void 0 && { compare: compareIds },
|
|
9393
9300
|
...opts.tagBaseline !== void 0 && { tagBaseline: opts.tagBaseline },
|
|
9394
9301
|
...opts.analysis !== void 0 && { analysis: opts.analysis },
|
|
9395
|
-
...opts.sprint !== void 0 && { sprint: opts.sprint },
|
|
9396
9302
|
...opts.story !== void 0 && { story: opts.story },
|
|
9397
|
-
...opts.taskType !== void 0 && { taskType: opts.taskType },
|
|
9398
|
-
...opts.since !== void 0 && { since: opts.since },
|
|
9399
|
-
...opts.aggregate !== void 0 && { aggregate: opts.aggregate },
|
|
9400
9303
|
...opts.efficiency !== void 0 && { efficiency: opts.efficiency },
|
|
9401
9304
|
...opts.recommendations !== void 0 && { recommendations: opts.recommendations },
|
|
9402
9305
|
...opts.turns !== void 0 && { turns: opts.turns },
|
|
@@ -11451,207 +11354,6 @@ function registerCancelCommand(program, projectRoot = process.cwd()) {
|
|
|
11451
11354
|
});
|
|
11452
11355
|
}
|
|
11453
11356
|
|
|
11454
|
-
//#endregion
|
|
11455
|
-
//#region src/cli/commands/contracts.ts
|
|
11456
|
-
function registerContractsCommand(program) {
|
|
11457
|
-
program.command("contracts").description("Show contract declarations and verification status").option("--output-format <format>", "Output format: text or json", "text").action(async (options) => {
|
|
11458
|
-
const dbRoot = await resolveMainRepoRoot(process.cwd());
|
|
11459
|
-
const statePath = join$1(dbRoot, ".substrate", "state");
|
|
11460
|
-
const doltStatePath = join$1(statePath, ".dolt");
|
|
11461
|
-
const storeConfig = existsSync(doltStatePath) ? {
|
|
11462
|
-
backend: "dolt",
|
|
11463
|
-
basePath: statePath
|
|
11464
|
-
} : {
|
|
11465
|
-
backend: "file",
|
|
11466
|
-
basePath: statePath
|
|
11467
|
-
};
|
|
11468
|
-
const store = createStateStore(storeConfig);
|
|
11469
|
-
try {
|
|
11470
|
-
await store.initialize();
|
|
11471
|
-
const contracts = await store.queryContracts();
|
|
11472
|
-
if (contracts.length === 0) {
|
|
11473
|
-
console.log("No contracts stored. Run a pipeline to populate contract data.");
|
|
11474
|
-
return;
|
|
11475
|
-
}
|
|
11476
|
-
const storyKeys = [...new Set(contracts.map((c) => c.storyKey))];
|
|
11477
|
-
const verificationMap = new Map();
|
|
11478
|
-
for (const sk of storyKeys) {
|
|
11479
|
-
const verifications = await store.getContractVerification(sk);
|
|
11480
|
-
const contractVerdicts = new Map();
|
|
11481
|
-
for (const v of verifications) contractVerdicts.set(v.contractName, v.verdict);
|
|
11482
|
-
verificationMap.set(sk, contractVerdicts);
|
|
11483
|
-
}
|
|
11484
|
-
const mergedRecords = contracts.map((c) => {
|
|
11485
|
-
const verdicts = verificationMap.get(c.storyKey);
|
|
11486
|
-
const verdict = verdicts?.get(c.contractName);
|
|
11487
|
-
return {
|
|
11488
|
-
storyKey: c.storyKey,
|
|
11489
|
-
contractName: c.contractName,
|
|
11490
|
-
direction: c.direction,
|
|
11491
|
-
schemaPath: c.schemaPath,
|
|
11492
|
-
verificationStatus: verdict === "pass" ? "✓ pass" : verdict === "fail" ? "✗ fail" : "? pending",
|
|
11493
|
-
verdict: verdict ?? "pending"
|
|
11494
|
-
};
|
|
11495
|
-
});
|
|
11496
|
-
if (options.outputFormat === "json") {
|
|
11497
|
-
console.log(JSON.stringify(mergedRecords, null, 2));
|
|
11498
|
-
return;
|
|
11499
|
-
}
|
|
11500
|
-
const headers = [
|
|
11501
|
-
"Story Key",
|
|
11502
|
-
"Contract Name",
|
|
11503
|
-
"Direction",
|
|
11504
|
-
"Schema Path",
|
|
11505
|
-
"Status"
|
|
11506
|
-
];
|
|
11507
|
-
const rows = mergedRecords.map((r) => [
|
|
11508
|
-
r.storyKey,
|
|
11509
|
-
r.contractName,
|
|
11510
|
-
r.direction,
|
|
11511
|
-
r.schemaPath,
|
|
11512
|
-
r.verificationStatus
|
|
11513
|
-
]);
|
|
11514
|
-
const colWidths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? "").length)));
|
|
11515
|
-
const formatRow$1 = (cells) => cells.map((c, i) => c.padEnd(colWidths[i])).join(" ");
|
|
11516
|
-
console.log(formatRow$1(headers));
|
|
11517
|
-
console.log(colWidths.map((w) => "-".repeat(w)).join(" "));
|
|
11518
|
-
for (const row of rows) console.log(formatRow$1(row));
|
|
11519
|
-
} finally {
|
|
11520
|
-
await store.close();
|
|
11521
|
-
}
|
|
11522
|
-
});
|
|
11523
|
-
}
|
|
11524
|
-
|
|
11525
|
-
//#endregion
|
|
11526
|
-
//#region src/utils/degraded-mode-hint.ts
|
|
11527
|
-
/**
|
|
11528
|
-
* Determine the appropriate degraded-mode hint message based on whether Dolt
|
|
11529
|
-
* is installed and/or initialized at the given state path.
|
|
11530
|
-
*
|
|
11531
|
-
* @param statePath - Absolute path to the substrate state directory
|
|
11532
|
-
* (e.g. `/project/.substrate/state`).
|
|
11533
|
-
*/
|
|
11534
|
-
async function getDegradedModeHint(statePath) {
|
|
11535
|
-
try {
|
|
11536
|
-
await checkDoltInstalled();
|
|
11537
|
-
if (!existsSync(join$1(statePath, ".dolt"))) return {
|
|
11538
|
-
hint: "Note: Dolt is installed but not initialized. Run `substrate init --dolt` to enable diff and history features.",
|
|
11539
|
-
doltInstalled: true
|
|
11540
|
-
};
|
|
11541
|
-
return {
|
|
11542
|
-
hint: "Note: Running on file backend. Diff and history require Dolt.",
|
|
11543
|
-
doltInstalled: true
|
|
11544
|
-
};
|
|
11545
|
-
} catch (err) {
|
|
11546
|
-
if (err instanceof DoltNotInstalled) return {
|
|
11547
|
-
hint: "Note: Dolt is not installed. Install it from https://docs.dolthub.com/introduction/installation, then run `substrate init --dolt` to enable diff and history features.",
|
|
11548
|
-
doltInstalled: false
|
|
11549
|
-
};
|
|
11550
|
-
throw err;
|
|
11551
|
-
}
|
|
11552
|
-
}
|
|
11553
|
-
/**
|
|
11554
|
-
* Emit a degraded-mode hint for the given command.
|
|
11555
|
-
*
|
|
11556
|
-
* - **Text mode**: writes the hint to `process.stderr` (not stdout).
|
|
11557
|
-
* - **JSON mode**: does NOT write to stderr; the caller is responsible for
|
|
11558
|
-
* writing the returned `hint` field to stdout as part of its JSON envelope.
|
|
11559
|
-
*
|
|
11560
|
-
* @param options - Hint options including output format, command name, and
|
|
11561
|
-
* the resolved state directory path.
|
|
11562
|
-
* @returns The hint message and a flag indicating whether Dolt is installed.
|
|
11563
|
-
*/
|
|
11564
|
-
async function emitDegradedModeHint(options) {
|
|
11565
|
-
const { hint, doltInstalled } = await getDegradedModeHint(options.statePath);
|
|
11566
|
-
if (options.outputFormat !== "json") process.stderr.write(`\n${hint}\n`);
|
|
11567
|
-
return {
|
|
11568
|
-
hint,
|
|
11569
|
-
doltInstalled
|
|
11570
|
-
};
|
|
11571
|
-
}
|
|
11572
|
-
|
|
11573
|
-
//#endregion
|
|
11574
|
-
//#region src/cli/commands/diff.ts
|
|
11575
|
-
function registerDiffCommand(program) {
|
|
11576
|
-
program.command("diff [storyKey]").description("Show stat-based diff of database changes for a story or sprint").option("--sprint <sprintId>", "Diff all stories in the specified sprint").option("--output-format <format>", "Output format: text or json", "text").action(async (storyKey, options) => {
|
|
11577
|
-
if (storyKey === void 0 && options.sprint === void 0) {
|
|
11578
|
-
console.error("Error: provide a story key or --sprint <sprintId>");
|
|
11579
|
-
process.exitCode = 1;
|
|
11580
|
-
return;
|
|
11581
|
-
}
|
|
11582
|
-
const dbRoot = await resolveMainRepoRoot(process.cwd());
|
|
11583
|
-
const statePath = join$1(dbRoot, ".substrate", "state");
|
|
11584
|
-
const doltStatePath = join$1(statePath, ".dolt");
|
|
11585
|
-
const storeConfig = existsSync(doltStatePath) ? {
|
|
11586
|
-
backend: "dolt",
|
|
11587
|
-
basePath: statePath
|
|
11588
|
-
} : {
|
|
11589
|
-
backend: "file",
|
|
11590
|
-
basePath: statePath
|
|
11591
|
-
};
|
|
11592
|
-
const store = createStateStore(storeConfig);
|
|
11593
|
-
try {
|
|
11594
|
-
await store.initialize();
|
|
11595
|
-
if (store instanceof FileStateStore) {
|
|
11596
|
-
const result = await emitDegradedModeHint({
|
|
11597
|
-
outputFormat: options.outputFormat,
|
|
11598
|
-
command: "diff",
|
|
11599
|
-
statePath
|
|
11600
|
-
});
|
|
11601
|
-
if (options.outputFormat === "json") console.log(JSON.stringify({
|
|
11602
|
-
backend: "file",
|
|
11603
|
-
hint: result.hint,
|
|
11604
|
-
diff: null
|
|
11605
|
-
}));
|
|
11606
|
-
return;
|
|
11607
|
-
}
|
|
11608
|
-
if (storyKey !== void 0) {
|
|
11609
|
-
const diff = await store.diffStory(storyKey);
|
|
11610
|
-
if (options.outputFormat === "json") {
|
|
11611
|
-
console.log(JSON.stringify(diff, null, 2));
|
|
11612
|
-
return;
|
|
11613
|
-
}
|
|
11614
|
-
console.log(`Diff for story ${storyKey}:`);
|
|
11615
|
-
if (diff.tables.length === 0) console.log(" (no changes)");
|
|
11616
|
-
else for (const t of diff.tables) console.log(` ${t.table}: +${t.added.length} -${t.deleted.length} ~${t.modified.length}`);
|
|
11617
|
-
} else {
|
|
11618
|
-
const stories = await store.queryStories({ sprint: options.sprint });
|
|
11619
|
-
const tableMap = new Map();
|
|
11620
|
-
for (const story of stories) {
|
|
11621
|
-
const diff = await store.diffStory(story.storyKey);
|
|
11622
|
-
for (const t of diff.tables) {
|
|
11623
|
-
const existing = tableMap.get(t.table);
|
|
11624
|
-
if (existing === void 0) tableMap.set(t.table, {
|
|
11625
|
-
table: t.table,
|
|
11626
|
-
added: [...t.added],
|
|
11627
|
-
deleted: [...t.deleted],
|
|
11628
|
-
modified: [...t.modified]
|
|
11629
|
-
});
|
|
11630
|
-
else {
|
|
11631
|
-
existing.added = [...existing.added, ...t.added];
|
|
11632
|
-
existing.deleted = [...existing.deleted, ...t.deleted];
|
|
11633
|
-
existing.modified = [...existing.modified, ...t.modified];
|
|
11634
|
-
}
|
|
11635
|
-
}
|
|
11636
|
-
}
|
|
11637
|
-
const aggregated = Array.from(tableMap.values());
|
|
11638
|
-
if (options.outputFormat === "json") {
|
|
11639
|
-
console.log(JSON.stringify({
|
|
11640
|
-
sprint: options.sprint,
|
|
11641
|
-
tables: aggregated
|
|
11642
|
-
}, null, 2));
|
|
11643
|
-
return;
|
|
11644
|
-
}
|
|
11645
|
-
console.log(`Diff for sprint ${options.sprint}:`);
|
|
11646
|
-
if (aggregated.length === 0) console.log(" (no changes)");
|
|
11647
|
-
else for (const t of aggregated) console.log(` ${t.table}: +${t.added.length} -${t.deleted.length} ~${t.modified.length}`);
|
|
11648
|
-
}
|
|
11649
|
-
} finally {
|
|
11650
|
-
await store.close();
|
|
11651
|
-
}
|
|
11652
|
-
});
|
|
11653
|
-
}
|
|
11654
|
-
|
|
11655
11357
|
//#endregion
|
|
11656
11358
|
//#region src/cli/commands/probes-diff.ts
|
|
11657
11359
|
/**
|
|
@@ -11980,6 +11682,54 @@ function emitError(format, message) {
|
|
|
11980
11682
|
return 1;
|
|
11981
11683
|
}
|
|
11982
11684
|
|
|
11685
|
+
//#endregion
|
|
11686
|
+
//#region src/utils/degraded-mode-hint.ts
|
|
11687
|
+
/**
|
|
11688
|
+
* Determine the appropriate degraded-mode hint message based on whether Dolt
|
|
11689
|
+
* is installed and/or initialized at the given state path.
|
|
11690
|
+
*
|
|
11691
|
+
* @param statePath - Absolute path to the substrate state directory
|
|
11692
|
+
* (e.g. `/project/.substrate/state`).
|
|
11693
|
+
*/
|
|
11694
|
+
async function getDegradedModeHint(statePath) {
|
|
11695
|
+
try {
|
|
11696
|
+
await checkDoltInstalled();
|
|
11697
|
+
if (!existsSync(join$1(statePath, ".dolt"))) return {
|
|
11698
|
+
hint: "Note: Dolt is installed but not initialized. Run `substrate init --dolt` to enable history.",
|
|
11699
|
+
doltInstalled: true
|
|
11700
|
+
};
|
|
11701
|
+
return {
|
|
11702
|
+
hint: "Note: Running on file backend. History requires Dolt.",
|
|
11703
|
+
doltInstalled: true
|
|
11704
|
+
};
|
|
11705
|
+
} catch (err) {
|
|
11706
|
+
if (err instanceof DoltNotInstalled) return {
|
|
11707
|
+
hint: "Note: Dolt is not installed. Install it from https://docs.dolthub.com/introduction/installation, then run `substrate init --dolt` to enable history.",
|
|
11708
|
+
doltInstalled: false
|
|
11709
|
+
};
|
|
11710
|
+
throw err;
|
|
11711
|
+
}
|
|
11712
|
+
}
|
|
11713
|
+
/**
|
|
11714
|
+
* Emit a degraded-mode hint for the given command.
|
|
11715
|
+
*
|
|
11716
|
+
* - **Text mode**: writes the hint to `process.stderr` (not stdout).
|
|
11717
|
+
* - **JSON mode**: does NOT write to stderr; the caller is responsible for
|
|
11718
|
+
* writing the returned `hint` field to stdout as part of its JSON envelope.
|
|
11719
|
+
*
|
|
11720
|
+
* @param options - Hint options including output format, command name, and
|
|
11721
|
+
* the resolved state directory path.
|
|
11722
|
+
* @returns The hint message and a flag indicating whether Dolt is installed.
|
|
11723
|
+
*/
|
|
11724
|
+
async function emitDegradedModeHint(options) {
|
|
11725
|
+
const { hint, doltInstalled } = await getDegradedModeHint(options.statePath);
|
|
11726
|
+
if (options.outputFormat !== "json") process.stderr.write(`\n${hint}\n`);
|
|
11727
|
+
return {
|
|
11728
|
+
hint,
|
|
11729
|
+
doltInstalled
|
|
11730
|
+
};
|
|
11731
|
+
}
|
|
11732
|
+
|
|
11983
11733
|
//#endregion
|
|
11984
11734
|
//#region src/cli/commands/history.ts
|
|
11985
11735
|
function registerHistoryCommand(program) {
|
|
@@ -11988,29 +11738,22 @@ function registerHistoryCommand(program) {
|
|
|
11988
11738
|
const dbRoot = await resolveMainRepoRoot(process.cwd());
|
|
11989
11739
|
const statePath = join$1(dbRoot, ".substrate", "state");
|
|
11990
11740
|
const doltStatePath = join$1(statePath, ".dolt");
|
|
11991
|
-
|
|
11992
|
-
|
|
11993
|
-
|
|
11994
|
-
|
|
11995
|
-
|
|
11996
|
-
|
|
11997
|
-
|
|
11998
|
-
|
|
11741
|
+
if (!existsSync(doltStatePath)) {
|
|
11742
|
+
const result = await emitDegradedModeHint({
|
|
11743
|
+
outputFormat: options.outputFormat,
|
|
11744
|
+
command: "history",
|
|
11745
|
+
statePath
|
|
11746
|
+
});
|
|
11747
|
+
if (options.outputFormat === "json") console.log(JSON.stringify({
|
|
11748
|
+
backend: "file",
|
|
11749
|
+
hint: result.hint,
|
|
11750
|
+
entries: []
|
|
11751
|
+
}));
|
|
11752
|
+
return;
|
|
11753
|
+
}
|
|
11754
|
+
const store = createDoltOperatorReader({ basePath: statePath });
|
|
11999
11755
|
try {
|
|
12000
11756
|
await store.initialize();
|
|
12001
|
-
if (store instanceof FileStateStore) {
|
|
12002
|
-
const result = await emitDegradedModeHint({
|
|
12003
|
-
outputFormat: options.outputFormat,
|
|
12004
|
-
command: "history",
|
|
12005
|
-
statePath
|
|
12006
|
-
});
|
|
12007
|
-
if (options.outputFormat === "json") console.log(JSON.stringify({
|
|
12008
|
-
backend: "file",
|
|
12009
|
-
hint: result.hint,
|
|
12010
|
-
entries: []
|
|
12011
|
-
}));
|
|
12012
|
-
return;
|
|
12013
|
-
}
|
|
12014
11757
|
const entries = await store.getHistory(limit);
|
|
12015
11758
|
if (entries.length === 0) {
|
|
12016
11759
|
console.log("No history available.");
|
|
@@ -12182,16 +11925,7 @@ const logger$3 = createLogger("cli:routing");
|
|
|
12182
11925
|
function registerRoutingCommand(program) {
|
|
12183
11926
|
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) => {
|
|
12184
11927
|
const dbRoot = await resolveMainRepoRoot(process.cwd());
|
|
12185
|
-
const
|
|
12186
|
-
const doltStatePath = join$1(statePath, ".dolt");
|
|
12187
|
-
const storeConfig = existsSync(doltStatePath) ? {
|
|
12188
|
-
backend: "dolt",
|
|
12189
|
-
basePath: statePath
|
|
12190
|
-
} : {
|
|
12191
|
-
backend: "file",
|
|
12192
|
-
basePath: statePath
|
|
12193
|
-
};
|
|
12194
|
-
const store = createStateStore(storeConfig);
|
|
11928
|
+
const store = new FileStateStore({ basePath: join$1(dbRoot, ".substrate") });
|
|
12195
11929
|
try {
|
|
12196
11930
|
await store.initialize();
|
|
12197
11931
|
if (options.history === true) {
|
|
@@ -13562,8 +13296,6 @@ async function createProgram() {
|
|
|
13562
13296
|
registerMetricsCommand(program, version);
|
|
13563
13297
|
registerRetryEscalatedCommand(program, version, process.cwd(), registry);
|
|
13564
13298
|
registerCancelCommand(program, process.cwd());
|
|
13565
|
-
registerContractsCommand(program);
|
|
13566
|
-
registerDiffCommand(program);
|
|
13567
13299
|
registerHistoryCommand(program);
|
|
13568
13300
|
registerMigrateCommand(program);
|
|
13569
13301
|
registerProbesCommand(program);
|
|
@@ -101,7 +101,6 @@ Each dispatched story runs in `.substrate-worktrees/story-<key>` on its own bran
|
|
|
101
101
|
| `substrate metrics --output-format json` | View historical run metrics |
|
|
102
102
|
| `substrate resume` | Resume an interrupted pipeline run |
|
|
103
103
|
| `substrate run --help-agent` | Full agent instruction reference |
|
|
104
|
-
| `substrate diff <story>` | Show row-level state changes for a story (requires Dolt) |
|
|
105
104
|
| `substrate history` | View Dolt commit log for pipeline state changes (requires Dolt) |
|
|
106
105
|
|
|
107
106
|
### Operator Files (`.substrate/`)
|
|
@@ -112,5 +111,5 @@ Each dispatched story runs in `.substrate-worktrees/story-<key>` on its own bran
|
|
|
112
111
|
|
|
113
112
|
### State Backend
|
|
114
113
|
|
|
115
|
-
Substrate uses Dolt for versioned pipeline state by default. Run `substrate init` to set it up automatically if Dolt is on PATH. Features that require Dolt: `substrate
|
|
114
|
+
Substrate uses Dolt for versioned pipeline state by default. Run `substrate init` to set it up automatically if Dolt is on PATH. Features that require Dolt: `substrate history`, OTEL observability persistence, and context engineering repo-map storage.
|
|
116
115
|
<!-- substrate:end -->
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-
|
|
1
|
+
import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-dWYa13k4.js";
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
3
|
import "./dist-l0pA6zZF.js";
|
|
4
4
|
import "./manifest-read-CSmDEOWH.js";
|