substrate-ai 0.2.26 → 0.2.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { DatabaseWrapper, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createContextCompiler, createDispatcher, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, runAnalysisPhase, runMigrations, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-
|
|
2
|
+
import { DatabaseWrapper, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createContextCompiler, createDispatcher, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, parseDbTimestampAsUtc, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, runAnalysisPhase, runMigrations, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-DG5j6vJI.js";
|
|
3
3
|
import { createLogger, deepMask } from "../logger-D2fS2ccL.js";
|
|
4
4
|
import { AdapterRegistry, ConfigError, ConfigIncompatibleFormatError } from "../errors-CswS7Mzg.js";
|
|
5
5
|
import { CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, PartialSubstrateConfigSchema, SUPPORTED_CONFIG_FORMAT_VERSIONS, SubstrateConfigSchema, defaultConfigMigrator } from "../version-manager-impl-CZ6KF1Ds.js";
|
|
@@ -1615,7 +1615,53 @@ async function runStatusAction(options) {
|
|
|
1615
1615
|
const storiesCount = db.prepare(`SELECT COUNT(*) as cnt FROM requirements WHERE pipeline_run_id = ? AND source = 'solutioning-phase'`).get(run.id)?.cnt ?? 0;
|
|
1616
1616
|
if (outputFormat === "json") {
|
|
1617
1617
|
const statusOutput = buildPipelineStatusOutput(run, tokenSummary, decisionsCount, storiesCount);
|
|
1618
|
-
|
|
1618
|
+
const storyMetricsRows = getStoryMetricsForRun(db, run.id);
|
|
1619
|
+
const storyMetricsV2 = storyMetricsRows.map((row) => {
|
|
1620
|
+
const phaseBreakdown = {};
|
|
1621
|
+
try {
|
|
1622
|
+
if (row.phase_durations_json) {
|
|
1623
|
+
const parsed = JSON.parse(row.phase_durations_json);
|
|
1624
|
+
for (const [phase, secs] of Object.entries(parsed)) phaseBreakdown[phase] = Math.round(secs * 1e3);
|
|
1625
|
+
}
|
|
1626
|
+
} catch {}
|
|
1627
|
+
return {
|
|
1628
|
+
story_key: row.story_key,
|
|
1629
|
+
result: row.result,
|
|
1630
|
+
wall_clock_ms: Math.round((row.wall_clock_seconds ?? 0) * 1e3),
|
|
1631
|
+
phase_breakdown: phaseBreakdown,
|
|
1632
|
+
tokens: {
|
|
1633
|
+
input: row.input_tokens ?? 0,
|
|
1634
|
+
output: row.output_tokens ?? 0
|
|
1635
|
+
},
|
|
1636
|
+
review_cycles: row.review_cycles ?? 0,
|
|
1637
|
+
dispatches: row.dispatches ?? 0
|
|
1638
|
+
};
|
|
1639
|
+
});
|
|
1640
|
+
let pipelineWallClockMs = 0;
|
|
1641
|
+
try {
|
|
1642
|
+
const createdAt = parseDbTimestampAsUtc(run.created_at);
|
|
1643
|
+
const endTimestamp = run.status === "running" ? new Date() : parseDbTimestampAsUtc(run.updated_at);
|
|
1644
|
+
pipelineWallClockMs = Math.max(0, endTimestamp.getTime() - createdAt.getTime());
|
|
1645
|
+
} catch {}
|
|
1646
|
+
const totalReviewCycles = storyMetricsRows.reduce((sum, r) => sum + (r.review_cycles ?? 0), 0);
|
|
1647
|
+
const totalInputTokens = storyMetricsRows.reduce((sum, r) => sum + (r.input_tokens ?? 0), 0);
|
|
1648
|
+
const totalOutputTokens = storyMetricsRows.reduce((sum, r) => sum + (r.output_tokens ?? 0), 0);
|
|
1649
|
+
const completedCount = storyMetricsRows.filter((r) => r.result === "success").length;
|
|
1650
|
+
const storiesPerHour = pipelineWallClockMs > 0 ? Math.round(completedCount / (pipelineWallClockMs / 36e5) * 100) / 100 : 0;
|
|
1651
|
+
const totalCostUsd = storyMetricsRows.reduce((sum, r) => sum + (r.cost_usd ?? 0), 0);
|
|
1652
|
+
const enhancedOutput = {
|
|
1653
|
+
...statusOutput,
|
|
1654
|
+
story_metrics: storyMetricsV2,
|
|
1655
|
+
pipeline_metrics: {
|
|
1656
|
+
total_wall_clock_ms: pipelineWallClockMs,
|
|
1657
|
+
total_review_cycles: totalReviewCycles,
|
|
1658
|
+
total_input_tokens: totalInputTokens,
|
|
1659
|
+
total_output_tokens: totalOutputTokens,
|
|
1660
|
+
stories_per_hour: storiesPerHour,
|
|
1661
|
+
cost_usd: totalCostUsd
|
|
1662
|
+
}
|
|
1663
|
+
};
|
|
1664
|
+
process.stdout.write(formatOutput(enhancedOutput, "json", true) + "\n");
|
|
1619
1665
|
} else {
|
|
1620
1666
|
let hasPhaseHistory = false;
|
|
1621
1667
|
try {
|
|
@@ -2842,7 +2888,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
2842
2888
|
const expDb = expDbWrapper.db;
|
|
2843
2889
|
const { runRunAction: runPipeline } = await import(
|
|
2844
2890
|
/* @vite-ignore */
|
|
2845
|
-
"../run-
|
|
2891
|
+
"../run-jLeEo8FW.js"
|
|
2846
2892
|
);
|
|
2847
2893
|
const runStoryFn = async (opts) => {
|
|
2848
2894
|
const exitCode = await runPipeline({
|
package/dist/index.d.ts
CHANGED
|
@@ -210,6 +210,49 @@ interface StoryBuildVerificationPassedEvent {
|
|
|
210
210
|
/** Story key (e.g., "24-2") */
|
|
211
211
|
storyKey: string;
|
|
212
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Emitted (non-blocking) when a dev-story modifies .ts files that export
|
|
215
|
+
* shared TypeScript interfaces or types, and those names are referenced by
|
|
216
|
+
* test files outside the same module.
|
|
217
|
+
*
|
|
218
|
+
* Signals potential stale-mock risk. The story still proceeds to code-review.
|
|
219
|
+
* (Story 24-3)
|
|
220
|
+
*/
|
|
221
|
+
interface StoryInterfaceChangeWarningEvent {
|
|
222
|
+
type: 'story:interface-change-warning';
|
|
223
|
+
/** ISO-8601 timestamp generated at emit time */
|
|
224
|
+
ts: string;
|
|
225
|
+
/** Story key (e.g., "24-3") */
|
|
226
|
+
storyKey: string;
|
|
227
|
+
/** Exported interface/type names found in modified files */
|
|
228
|
+
modifiedInterfaces: string[];
|
|
229
|
+
/** Test file paths (relative to project root) that reference the modified interface names */
|
|
230
|
+
potentiallyAffectedTests: string[];
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Emitted when a story reaches a terminal state (COMPLETE, ESCALATED, or
|
|
234
|
+
* max retries), providing a metrics snapshot for observability (Story 24-4).
|
|
235
|
+
*/
|
|
236
|
+
interface StoryMetricsEvent {
|
|
237
|
+
type: 'story:metrics';
|
|
238
|
+
/** ISO-8601 timestamp generated at emit time */
|
|
239
|
+
ts: string;
|
|
240
|
+
/** Story key (e.g., "24-4") */
|
|
241
|
+
storyKey: string;
|
|
242
|
+
/** Total wall-clock duration in milliseconds */
|
|
243
|
+
wallClockMs: number;
|
|
244
|
+
/** Per-phase duration in milliseconds: phase name → ms */
|
|
245
|
+
phaseBreakdown: Record<string, number>;
|
|
246
|
+
/** Token counts from the adapter (accumulated across all dispatches) */
|
|
247
|
+
tokens: {
|
|
248
|
+
input: number;
|
|
249
|
+
output: number;
|
|
250
|
+
};
|
|
251
|
+
/** Number of code-review cycles completed */
|
|
252
|
+
reviewCycles: number;
|
|
253
|
+
/** Total number of agent dispatches for this story */
|
|
254
|
+
dispatches: number;
|
|
255
|
+
}
|
|
213
256
|
/**
|
|
214
257
|
* Emitted for non-fatal warnings during pipeline execution
|
|
215
258
|
* (e.g., token ceiling truncation, partial batch failures).
|
|
@@ -470,7 +513,7 @@ interface SupervisorExperimentErrorEvent {
|
|
|
470
513
|
* }
|
|
471
514
|
* ```
|
|
472
515
|
*/
|
|
473
|
-
type PipelineEvent = PipelineStartEvent | PipelineCompleteEvent | StoryPhaseEvent | StoryDoneEvent | StoryEscalationEvent | StoryWarnEvent | StoryLogEvent | PipelineHeartbeatEvent | StoryStallEvent | StoryZeroDiffEscalationEvent | StoryBuildVerificationFailedEvent | StoryBuildVerificationPassedEvent | SupervisorPollEvent | SupervisorKillEvent | SupervisorRestartEvent | SupervisorAbortEvent | SupervisorSummaryEvent | SupervisorAnalysisCompleteEvent | SupervisorAnalysisErrorEvent | SupervisorExperimentStartEvent | SupervisorExperimentSkipEvent | SupervisorExperimentRecommendationsEvent | SupervisorExperimentCompleteEvent | SupervisorExperimentErrorEvent; //#endregion
|
|
516
|
+
type PipelineEvent = PipelineStartEvent | PipelineCompleteEvent | StoryPhaseEvent | StoryDoneEvent | StoryEscalationEvent | StoryWarnEvent | StoryLogEvent | PipelineHeartbeatEvent | StoryStallEvent | StoryZeroDiffEscalationEvent | StoryBuildVerificationFailedEvent | StoryBuildVerificationPassedEvent | StoryInterfaceChangeWarningEvent | StoryMetricsEvent | SupervisorPollEvent | SupervisorKillEvent | SupervisorRestartEvent | SupervisorAbortEvent | SupervisorSummaryEvent | SupervisorAnalysisCompleteEvent | SupervisorAnalysisErrorEvent | SupervisorExperimentStartEvent | SupervisorExperimentSkipEvent | SupervisorExperimentRecommendationsEvent | SupervisorExperimentCompleteEvent | SupervisorExperimentErrorEvent; //#endregion
|
|
474
517
|
//#region src/core/errors.d.ts
|
|
475
518
|
|
|
476
519
|
/**
|
|
@@ -1121,6 +1164,24 @@ interface OrchestratorEvents {
|
|
|
1121
1164
|
'story:build-verification-passed': {
|
|
1122
1165
|
storyKey: string;
|
|
1123
1166
|
};
|
|
1167
|
+
/** Non-blocking warning: modified .ts files export shared interfaces referenced by cross-module tests */
|
|
1168
|
+
'story:interface-change-warning': {
|
|
1169
|
+
storyKey: string;
|
|
1170
|
+
modifiedInterfaces: string[];
|
|
1171
|
+
potentiallyAffectedTests: string[];
|
|
1172
|
+
};
|
|
1173
|
+
/** Per-story metrics snapshot emitted when a story reaches a terminal state (Story 24-4) */
|
|
1174
|
+
'story:metrics': {
|
|
1175
|
+
storyKey: string;
|
|
1176
|
+
wallClockMs: number;
|
|
1177
|
+
phaseBreakdown: Record<string, number>;
|
|
1178
|
+
tokens: {
|
|
1179
|
+
input: number;
|
|
1180
|
+
output: number;
|
|
1181
|
+
};
|
|
1182
|
+
reviewCycles: number;
|
|
1183
|
+
dispatches: number;
|
|
1184
|
+
};
|
|
1124
1185
|
}
|
|
1125
1186
|
|
|
1126
1187
|
//#endregion
|