substrate-ai 0.13.0 → 0.14.0
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/adapter-registry-DbLuI3IA.js +4 -0
- package/dist/cli/index.js +17 -13
- package/dist/{decisions-0VsbM-3Z.js → decisions-CGNEausW.js} +1 -1
- package/dist/{dist-DKG5lyUw.js → dist-CLvAwmT7.js} +12 -4
- package/dist/{errors-CQKOiaYV.js → errors-D1LU8CZ9.js} +2 -2
- package/dist/{experimenter-DAIK4Ljm.js → experimenter-D0k2wT3I.js} +1 -1
- package/dist/{health-BR5GD5Ge.js → health-DswaC1q5.js} +2 -2
- package/dist/{health-DXNHn938.js → health-GEDGgGan.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/{routing-h9IhuF0i.js → routing-B1aoIz7L.js} +1 -1
- package/dist/{run-zWACyS3w.js → run-CUMPhuVq.js} +521 -49
- package/dist/run-CZo7hpsh.js +9 -0
- package/dist/schema.sql +5 -0
- package/dist/{upgrade-D0JTv4uQ.js → upgrade-DPdh5w4p.js} +2 -2
- package/dist/{upgrade-CBE6JaxX.js → upgrade-DT0I_-1E.js} +2 -2
- package/dist/{version-manager-impl-CxCB4SPB.js → version-manager-impl-BHnUB2tl.js} +1 -1
- package/package.json +1 -1
- package/dist/adapter-registry-B19pDsb2.js +0 -4
- package/dist/run-C3HrjTtt.js +0 -9
package/dist/cli/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { FileStateStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, detectCycles, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot } from "../health-
|
|
2
|
+
import { FileStateStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, detectCycles, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot } from "../health-DswaC1q5.js";
|
|
3
3
|
import { createLogger } from "../logger-KeHncl-f.js";
|
|
4
4
|
import { createEventBus } from "../helpers-CElYrONe.js";
|
|
5
|
-
import { AdapterRegistry, BudgetConfigSchema, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, ConfigError, CostTrackerConfigSchema, DEFAULT_CONFIG, DoltClient, DoltNotInstalled, EXPERIMENT_RESULT, GlobalSettingsSchema, 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, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRequirements, listRunMetrics, loadParentRunDecisions, supersedeDecision, tagRunAsBaseline, updatePipelineRun } from "../dist-
|
|
5
|
+
import { AdapterRegistry, BudgetConfigSchema, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, ConfigError, CostTrackerConfigSchema, DEFAULT_CONFIG, DoltClient, DoltNotInstalled, EXPERIMENT_RESULT, GlobalSettingsSchema, 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, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRequirements, listRunMetrics, loadParentRunDecisions, supersedeDecision, tagRunAsBaseline, updatePipelineRun } from "../dist-CLvAwmT7.js";
|
|
6
6
|
import "../adapter-registry-DXLMTmfD.js";
|
|
7
|
-
import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-
|
|
8
|
-
import "../errors-
|
|
7
|
+
import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-CUMPhuVq.js";
|
|
8
|
+
import "../errors-D1LU8CZ9.js";
|
|
9
9
|
import "../routing-CcBOCuC9.js";
|
|
10
10
|
import "../decisions-C0pz9Clx.js";
|
|
11
11
|
import "../version-manager-impl-BmOWu8ml.js";
|
|
12
|
-
import { registerUpgradeCommand } from "../upgrade-
|
|
12
|
+
import { registerUpgradeCommand } from "../upgrade-DT0I_-1E.js";
|
|
13
13
|
import { Command } from "commander";
|
|
14
14
|
import { fileURLToPath } from "url";
|
|
15
15
|
import { dirname, join, resolve } from "path";
|
|
@@ -3025,7 +3025,7 @@ async function runStatusAction(options) {
|
|
|
3025
3025
|
if (run === void 0) run = await getLatestRun(adapter);
|
|
3026
3026
|
}
|
|
3027
3027
|
if (run === void 0) {
|
|
3028
|
-
const { inspectProcessTree } = await import("../health-
|
|
3028
|
+
const { inspectProcessTree } = await import("../health-GEDGgGan.js");
|
|
3029
3029
|
const substrateDirPath = join(projectRoot, ".substrate");
|
|
3030
3030
|
const processInfo = inspectProcessTree({
|
|
3031
3031
|
projectRoot,
|
|
@@ -3910,7 +3910,7 @@ function defaultSupervisorDeps() {
|
|
|
3910
3910
|
if (cached === null) {
|
|
3911
3911
|
const { AdapterRegistry: AR } = await import(
|
|
3912
3912
|
/* @vite-ignore */
|
|
3913
|
-
"../adapter-registry-
|
|
3913
|
+
"../adapter-registry-DbLuI3IA.js"
|
|
3914
3914
|
);
|
|
3915
3915
|
cached = new AR();
|
|
3916
3916
|
await cached.discoverAndRegister();
|
|
@@ -4104,6 +4104,10 @@ async function handleStallRecovery(health, state, config, deps, io) {
|
|
|
4104
4104
|
const orchestratorIdle = health.process.child_pids.length === 0 && health.stories.active > 0;
|
|
4105
4105
|
const effectiveThreshold = inReviewPhase && !orchestratorIdle ? stallThreshold * 2 : stallThreshold;
|
|
4106
4106
|
if (health.staleness_seconds < effectiveThreshold) return null;
|
|
4107
|
+
if (state.runId !== void 0 && health.run_id !== null && health.run_id !== state.runId) {
|
|
4108
|
+
log("Supervisor skipping kill — active pipeline belongs to a different session");
|
|
4109
|
+
return null;
|
|
4110
|
+
}
|
|
4107
4111
|
const directPids = [...health.process.orchestrator_pid !== null ? [health.process.orchestrator_pid] : [], ...health.process.child_pids];
|
|
4108
4112
|
const descendantPids = getAllDescendants(directPids);
|
|
4109
4113
|
const directPidSet = new Set(directPids);
|
|
@@ -4341,11 +4345,11 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
4341
4345
|
try {
|
|
4342
4346
|
const { createExperimenter } = await import(
|
|
4343
4347
|
/* @vite-ignore */
|
|
4344
|
-
"../experimenter-
|
|
4348
|
+
"../experimenter-D0k2wT3I.js"
|
|
4345
4349
|
);
|
|
4346
4350
|
const { getLatestRun: getLatest } = await import(
|
|
4347
4351
|
/* @vite-ignore */
|
|
4348
|
-
"../decisions-
|
|
4352
|
+
"../decisions-CGNEausW.js"
|
|
4349
4353
|
);
|
|
4350
4354
|
const expAdapter = createDatabaseAdapter({
|
|
4351
4355
|
backend: "auto",
|
|
@@ -4355,7 +4359,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
4355
4359
|
await initSchema(expAdapter);
|
|
4356
4360
|
const { runRunAction: runPipeline } = await import(
|
|
4357
4361
|
/* @vite-ignore */
|
|
4358
|
-
"../run-
|
|
4362
|
+
"../run-CZo7hpsh.js"
|
|
4359
4363
|
);
|
|
4360
4364
|
const runStoryFn = async (opts) => {
|
|
4361
4365
|
const exitCode = await runPipeline({
|
|
@@ -4871,7 +4875,7 @@ async function runMetricsAction(options) {
|
|
|
4871
4875
|
const routingConfigPath = join(dbDir, "routing.yml");
|
|
4872
4876
|
let routingConfig = null;
|
|
4873
4877
|
if (existsSync$1(routingConfigPath)) try {
|
|
4874
|
-
const { loadModelRoutingConfig } = await import("../routing-
|
|
4878
|
+
const { loadModelRoutingConfig } = await import("../routing-B1aoIz7L.js");
|
|
4875
4879
|
routingConfig = loadModelRoutingConfig(routingConfigPath);
|
|
4876
4880
|
} catch {}
|
|
4877
4881
|
if (routingConfig === null) routingConfig = {
|
|
@@ -8621,8 +8625,8 @@ async function createProgram() {
|
|
|
8621
8625
|
/** Fire-and-forget startup version check (story 8.3, AC3/AC5) */
|
|
8622
8626
|
function checkForUpdatesInBackground(currentVersion) {
|
|
8623
8627
|
if (process.env.SUBSTRATE_NO_UPDATE_CHECK === "1") return;
|
|
8624
|
-
import("../upgrade-
|
|
8625
|
-
const { createVersionManager } = await import("../version-manager-impl-
|
|
8628
|
+
import("../upgrade-DPdh5w4p.js").then(async () => {
|
|
8629
|
+
const { createVersionManager } = await import("../version-manager-impl-BHnUB2tl.js");
|
|
8626
8630
|
const vm = createVersionManager();
|
|
8627
8631
|
const result = await vm.checkForUpdates();
|
|
8628
8632
|
if (result.updateAvailable) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addTokenUsage, createDecision, createPipelineRun, createRequirement, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunningPipelineRuns, getTokenUsageSummary, listRequirements, registerArtifact, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision } from "./dist-
|
|
1
|
+
import { addTokenUsage, createDecision, createPipelineRun, createRequirement, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunningPipelineRuns, getTokenUsageSummary, listRequirements, registerArtifact, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision } from "./dist-CLvAwmT7.js";
|
|
2
2
|
import "./decisions-C0pz9Clx.js";
|
|
3
3
|
|
|
4
4
|
export { getLatestRun };
|
|
@@ -1871,11 +1871,19 @@ var InMemoryDatabaseAdapter = class {
|
|
|
1871
1871
|
|
|
1872
1872
|
//#endregion
|
|
1873
1873
|
//#region packages/core/dist/persistence/adapter.js
|
|
1874
|
-
function
|
|
1874
|
+
function isDoltBinaryAvailable() {
|
|
1875
1875
|
const result = spawnSync("dolt", ["version"], { stdio: "ignore" });
|
|
1876
|
-
|
|
1876
|
+
return result.error == null && result.status === 0;
|
|
1877
|
+
}
|
|
1878
|
+
function isDoltAvailable(basePath) {
|
|
1877
1879
|
const stateDoltDir = join$1(basePath, ".substrate", "state", ".dolt");
|
|
1878
|
-
|
|
1880
|
+
if (!existsSync(stateDoltDir)) return false;
|
|
1881
|
+
if (isDoltBinaryAvailable()) return true;
|
|
1882
|
+
console.warn("[persistence:adapter] Dolt directory found but dolt binary unavailable — retrying once...");
|
|
1883
|
+
spawnSync("sleep", ["1"], { stdio: "ignore" });
|
|
1884
|
+
if (isDoltBinaryAvailable()) return true;
|
|
1885
|
+
console.warn("[persistence:adapter] Dolt still unavailable after retry — falling back to InMemoryDatabaseAdapter. Telemetry and cost data will NOT persist.");
|
|
1886
|
+
return false;
|
|
1879
1887
|
}
|
|
1880
1888
|
function createDatabaseAdapter(config = { backend: "auto" }, doltClientFactory) {
|
|
1881
1889
|
const backend = config.backend ?? "auto";
|
|
@@ -10228,4 +10236,4 @@ async function callLLM(params) {
|
|
|
10228
10236
|
|
|
10229
10237
|
//#endregion
|
|
10230
10238
|
export { ADVISORY_NOTES, AdapterRegistry, AdtError, BudgetConfigSchema, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, Categorizer, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, ConsumerAnalyzer, CostTrackerConfigSchema, DEFAULT_CONFIG, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, DoltNotInstalled, DoltQueryError, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, GeminiCLIAdapter, GlobalSettingsSchema, IngestionServer, LogTurnAnalyzer, ModelRoutingConfigSchema, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProviderPolicySchema, ProvidersSchema, Recommender, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TASK_TYPE_PHASE_MAP, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryConfigSchema, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, VersionManagerImpl, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, callLLM, checkDoltInstalled, compareRunMetrics, createAmendmentRun, createConfigSystem, createDatabaseAdapter as createDatabaseAdapter$1, createDecision, createDoltClient, createExperimenter, createPipelineRun, createRequirement, createVersionManager, detectInterfaceChanges, determineVerdict, getActiveDecisions, getAllCostEntriesFiltered, getArtifactByTypeForRun, getArtifactsByRun, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getModelTier, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRequirements, listRunMetrics, loadModelRoutingConfig, loadParentRunDecisions, registerArtifact, resolvePromptFile, supersedeDecision, tagRunAsBaseline, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics };
|
|
10231
|
-
//# sourceMappingURL=dist-
|
|
10239
|
+
//# sourceMappingURL=dist-CLvAwmT7.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AdtError } from "./dist-
|
|
1
|
+
import { AdtError } from "./dist-CLvAwmT7.js";
|
|
2
2
|
|
|
3
3
|
//#region src/core/errors.ts
|
|
4
4
|
/** Error thrown when task configuration is invalid */
|
|
@@ -71,4 +71,4 @@ var TaskGraphIncompatibleFormatError = class extends AdtError {
|
|
|
71
71
|
|
|
72
72
|
//#endregion
|
|
73
73
|
export { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError };
|
|
74
|
-
//# sourceMappingURL=errors-
|
|
74
|
+
//# sourceMappingURL=errors-D1LU8CZ9.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-
|
|
1
|
+
import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-CLvAwmT7.js";
|
|
2
2
|
|
|
3
3
|
export { createExperimenter };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createLogger } from "./logger-KeHncl-f.js";
|
|
2
|
-
import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-
|
|
2
|
+
import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-CLvAwmT7.js";
|
|
3
3
|
import { createRequire } from "module";
|
|
4
4
|
import { dirname, join } from "path";
|
|
5
5
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -1930,4 +1930,4 @@ function registerHealthCommand(program, _version = "0.0.0", projectRoot = proces
|
|
|
1930
1930
|
|
|
1931
1931
|
//#endregion
|
|
1932
1932
|
export { BMAD_BASELINE_TOKENS_FULL, DEFAULT_STALL_THRESHOLD_SECONDS, DoltMergeConflict, FileStateStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN$1 as STORY_KEY_PATTERN, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter$1 as createDatabaseAdapter, createStateStore, detectCycles, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, isOrchestratorProcessLine, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, runHealthAction, validateStoryKey };
|
|
1933
|
-
//# sourceMappingURL=health-
|
|
1933
|
+
//# sourceMappingURL=health-DswaC1q5.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
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-DswaC1q5.js";
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
|
-
import "./dist-
|
|
3
|
+
import "./dist-CLvAwmT7.js";
|
|
4
4
|
import "./decisions-C0pz9Clx.js";
|
|
5
5
|
|
|
6
6
|
export { inspectProcessTree };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { childLogger, createLogger, logger } from "./logger-KeHncl-f.js";
|
|
2
2
|
import { assertDefined, createEventBus, createTuiApp, deepClone, formatDuration, generateId, isPlainObject, isTuiCapable, printNonTtyWarning, sleep, withRetry } from "./helpers-CElYrONe.js";
|
|
3
|
-
import { AdapterRegistry, AdtError, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, GeminiCLIAdapter } from "./dist-
|
|
3
|
+
import { AdapterRegistry, AdtError, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, GeminiCLIAdapter } from "./dist-CLvAwmT7.js";
|
|
4
4
|
import "./adapter-registry-DXLMTmfD.js";
|
|
5
|
-
import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-
|
|
5
|
+
import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-D1LU8CZ9.js";
|
|
6
6
|
|
|
7
7
|
//#region src/core/di.ts
|
|
8
8
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ModelRoutingConfigSchema, ProviderPolicySchema, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, TASK_TYPE_PHASE_MAP, getModelTier, loadModelRoutingConfig } from "./dist-
|
|
1
|
+
import { ModelRoutingConfigSchema, ProviderPolicySchema, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, TASK_TYPE_PHASE_MAP, getModelTier, loadModelRoutingConfig } from "./dist-CLvAwmT7.js";
|
|
2
2
|
import "./routing-CcBOCuC9.js";
|
|
3
3
|
|
|
4
4
|
export { loadModelRoutingConfig };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, resolveMainRepoRoot, validateStoryKey } from "./health-
|
|
1
|
+
import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, resolveMainRepoRoot, validateStoryKey } from "./health-DswaC1q5.js";
|
|
2
2
|
import { createLogger } from "./logger-KeHncl-f.js";
|
|
3
3
|
import { TypedEventBusImpl, createEventBus, createTuiApp, isTuiCapable, printNonTtyWarning, sleep } from "./helpers-CElYrONe.js";
|
|
4
|
-
import { ADVISORY_NOTES, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, createConfigSystem, createDecision, createPipelineRun, createRequirement, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getPipelineRunById, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, loadModelRoutingConfig, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-
|
|
4
|
+
import { ADVISORY_NOTES, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, createConfigSystem, createDecision, createPipelineRun, createRequirement, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getPipelineRunById, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, loadModelRoutingConfig, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-CLvAwmT7.js";
|
|
5
5
|
import { basename, dirname, extname, join } from "path";
|
|
6
6
|
import { access, readFile, readdir, stat } from "fs/promises";
|
|
7
7
|
import { EventEmitter } from "node:events";
|
|
@@ -10893,11 +10893,23 @@ function createImplementationOrchestrator(deps) {
|
|
|
10893
10893
|
checkpointHandled = true;
|
|
10894
10894
|
}
|
|
10895
10895
|
if (!checkpointHandled) if (devResult.result === "success") devStoryWasSuccess = true;
|
|
10896
|
-
else
|
|
10897
|
-
|
|
10898
|
-
|
|
10899
|
-
|
|
10900
|
-
|
|
10896
|
+
else {
|
|
10897
|
+
logger$21.warn({
|
|
10898
|
+
storyKey,
|
|
10899
|
+
error: devResult.error,
|
|
10900
|
+
filesModified: devFilesModified.length
|
|
10901
|
+
}, "Dev-story reported failure, proceeding to code review");
|
|
10902
|
+
if (!devResult.error?.startsWith("dispatch_timeout")) {
|
|
10903
|
+
logger$21.warn({
|
|
10904
|
+
storyKey,
|
|
10905
|
+
error: devResult.error
|
|
10906
|
+
}, "Agent process failure (non-timeout) — story will proceed to code review with partial work");
|
|
10907
|
+
eventBus.emit("orchestrator:story-warn", {
|
|
10908
|
+
storyKey,
|
|
10909
|
+
msg: "agent process failure (non-timeout)"
|
|
10910
|
+
});
|
|
10911
|
+
}
|
|
10912
|
+
}
|
|
10901
10913
|
}
|
|
10902
10914
|
} catch (err) {
|
|
10903
10915
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -10974,9 +10986,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
10974
10986
|
if (buildVerifyResult.status === "passed") {
|
|
10975
10987
|
const resolvedRootForTsc = projectRoot ?? process.cwd();
|
|
10976
10988
|
const tscBin = join$1(resolvedRootForTsc, "node_modules", ".bin", "tsc");
|
|
10977
|
-
const
|
|
10989
|
+
const typecheckConfig = join$1(resolvedRootForTsc, "tsconfig.typecheck.json");
|
|
10990
|
+
const defaultConfig = join$1(resolvedRootForTsc, "tsconfig.json");
|
|
10991
|
+
const tscConfigFlag = existsSync(typecheckConfig) ? ` -p ${typecheckConfig}` : "";
|
|
10992
|
+
const hasTsc = existsSync(tscBin) && (existsSync(typecheckConfig) || existsSync(defaultConfig));
|
|
10978
10993
|
if (hasTsc) try {
|
|
10979
|
-
execSync(`"${tscBin}" --noEmit`, {
|
|
10994
|
+
execSync(`"${tscBin}" --noEmit${tscConfigFlag}`, {
|
|
10980
10995
|
cwd: resolvedRootForTsc,
|
|
10981
10996
|
timeout: 12e4,
|
|
10982
10997
|
encoding: "utf-8",
|
|
@@ -16735,15 +16750,34 @@ function createSdlcDevStoryHandler(options) {
|
|
|
16735
16750
|
};
|
|
16736
16751
|
try {
|
|
16737
16752
|
const workflowResult = await options.runDevStory(options.deps, devStoryParams);
|
|
16738
|
-
if (workflowResult.result === "success")
|
|
16739
|
-
|
|
16740
|
-
|
|
16741
|
-
|
|
16742
|
-
|
|
16743
|
-
|
|
16753
|
+
if (workflowResult.result === "success") {
|
|
16754
|
+
if (options.buildVerifier) {
|
|
16755
|
+
const projectRoot = context.getString("projectRoot", "");
|
|
16756
|
+
if (projectRoot) {
|
|
16757
|
+
const buildResult = options.buildVerifier(projectRoot);
|
|
16758
|
+
if (buildResult.status === "failed" || buildResult.status === "timeout") {
|
|
16759
|
+
outcome = {
|
|
16760
|
+
status: "FAILURE",
|
|
16761
|
+
failureReason: `build verification failed after dev-story: ${buildResult.output?.slice(0, 500) ?? "no output"}`,
|
|
16762
|
+
contextUpdates: {
|
|
16763
|
+
filesModified: workflowResult.files_modified,
|
|
16764
|
+
devStoryFilesModified: workflowResult.files_modified,
|
|
16765
|
+
devStoryAcFailures: ["build-verification"]
|
|
16766
|
+
}
|
|
16767
|
+
};
|
|
16768
|
+
return outcome;
|
|
16769
|
+
}
|
|
16770
|
+
}
|
|
16744
16771
|
}
|
|
16745
|
-
|
|
16746
|
-
|
|
16772
|
+
outcome = {
|
|
16773
|
+
status: "SUCCESS",
|
|
16774
|
+
contextUpdates: {
|
|
16775
|
+
filesModified: workflowResult.files_modified,
|
|
16776
|
+
acMet: workflowResult.ac_met,
|
|
16777
|
+
devStoryFilesModified: workflowResult.files_modified
|
|
16778
|
+
}
|
|
16779
|
+
};
|
|
16780
|
+
} else {
|
|
16747
16781
|
const failureReason = workflowResult.error ?? (workflowResult.ac_failures.length > 0 ? `dev-story failed ACs: ${workflowResult.ac_failures.join(", ")}` : "dev-story workflow failed");
|
|
16748
16782
|
outcome = {
|
|
16749
16783
|
status: "FAILURE",
|
|
@@ -16973,12 +17007,12 @@ function createSdlcEventBridge(opts) {
|
|
|
16973
17007
|
});
|
|
16974
17008
|
};
|
|
16975
17009
|
const onGoalGateUnsatisfied = (data) => {
|
|
16976
|
-
const
|
|
16977
|
-
if (nodeId === "dev_story") sdlcBus.emit("orchestrator:story-escalated", {
|
|
17010
|
+
const evt = data;
|
|
17011
|
+
if (evt.nodeId === "dev_story") sdlcBus.emit("orchestrator:story-escalated", {
|
|
16978
17012
|
storyKey,
|
|
16979
|
-
lastVerdict: "NEEDS_MAJOR_REWORK",
|
|
16980
|
-
reviewCycles: devStoryRetries,
|
|
16981
|
-
issues: []
|
|
17013
|
+
lastVerdict: evt.lastVerdict ?? "NEEDS_MAJOR_REWORK",
|
|
17014
|
+
reviewCycles: evt.reviewCycles ?? devStoryRetries,
|
|
17015
|
+
issues: evt.issues ?? []
|
|
16982
17016
|
});
|
|
16983
17017
|
};
|
|
16984
17018
|
graphEvents.on("graph:node-started", onNodeStarted);
|
|
@@ -17041,6 +17075,10 @@ function createGraphOrchestrator(config) {
|
|
|
17041
17075
|
sdlcBus: config.eventBus,
|
|
17042
17076
|
graphEvents: factoryBus
|
|
17043
17077
|
}) : void 0;
|
|
17078
|
+
let escalated = false;
|
|
17079
|
+
factoryBus.on("graph:goal-gate-unsatisfied", () => {
|
|
17080
|
+
escalated = true;
|
|
17081
|
+
});
|
|
17044
17082
|
let result;
|
|
17045
17083
|
try {
|
|
17046
17084
|
result = await config.executor.run(config.graph, {
|
|
@@ -17053,7 +17091,7 @@ function createGraphOrchestrator(config) {
|
|
|
17053
17091
|
} catch (err) {
|
|
17054
17092
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
17055
17093
|
summary.stories[storyKey] = {
|
|
17056
|
-
outcome: "FAILED",
|
|
17094
|
+
outcome: escalated ? "ESCALATED" : "FAILED",
|
|
17057
17095
|
error: errMsg
|
|
17058
17096
|
};
|
|
17059
17097
|
summary.f++;
|
|
@@ -17064,6 +17102,9 @@ function createGraphOrchestrator(config) {
|
|
|
17064
17102
|
if (result.status === "SUCCESS") {
|
|
17065
17103
|
summary.stories[storyKey] = { outcome: "SUCCESS" };
|
|
17066
17104
|
summary.s++;
|
|
17105
|
+
} else if (escalated) {
|
|
17106
|
+
summary.stories[storyKey] = { outcome: "ESCALATED" };
|
|
17107
|
+
summary.f++;
|
|
17067
17108
|
} else {
|
|
17068
17109
|
summary.stories[storyKey] = { outcome: "FAILED" };
|
|
17069
17110
|
summary.f++;
|
|
@@ -22121,6 +22162,10 @@ var RunStateManager = class {
|
|
|
22121
22162
|
*/
|
|
22122
22163
|
function createConvergenceController() {
|
|
22123
22164
|
const outcomes = new Map();
|
|
22165
|
+
/** Returns true only when id is non-empty AND exists in graph.nodes. */
|
|
22166
|
+
function isValidTarget(id, graph) {
|
|
22167
|
+
return id !== "" && graph.nodes.has(id);
|
|
22168
|
+
}
|
|
22124
22169
|
return {
|
|
22125
22170
|
recordOutcome(nodeId, status) {
|
|
22126
22171
|
outcomes.set(nodeId, status);
|
|
@@ -22136,9 +22181,386 @@ function createConvergenceController() {
|
|
|
22136
22181
|
satisfied: failingNodes.length === 0,
|
|
22137
22182
|
failingNodes
|
|
22138
22183
|
};
|
|
22184
|
+
},
|
|
22185
|
+
checkGoalGates(graph, runId, eventBus) {
|
|
22186
|
+
const failedGates = [];
|
|
22187
|
+
for (const [id, node] of graph.nodes) {
|
|
22188
|
+
if (!node.goalGate) continue;
|
|
22189
|
+
const status = outcomes.get(id);
|
|
22190
|
+
const satisfied = status === "SUCCESS" || status === "PARTIAL_SUCCESS";
|
|
22191
|
+
eventBus?.emit("graph:goal-gate-checked", {
|
|
22192
|
+
runId,
|
|
22193
|
+
nodeId: id,
|
|
22194
|
+
satisfied
|
|
22195
|
+
});
|
|
22196
|
+
if (!satisfied) failedGates.push(id);
|
|
22197
|
+
}
|
|
22198
|
+
return {
|
|
22199
|
+
satisfied: failedGates.length === 0,
|
|
22200
|
+
failedGates
|
|
22201
|
+
};
|
|
22202
|
+
},
|
|
22203
|
+
resolveRetryTarget(failedNode, graph) {
|
|
22204
|
+
const candidates = [
|
|
22205
|
+
failedNode.retryTarget,
|
|
22206
|
+
failedNode.fallbackRetryTarget,
|
|
22207
|
+
graph.retryTarget,
|
|
22208
|
+
graph.fallbackRetryTarget
|
|
22209
|
+
];
|
|
22210
|
+
for (const candidate of candidates) if (isValidTarget(candidate, graph)) return candidate;
|
|
22211
|
+
return null;
|
|
22212
|
+
}
|
|
22213
|
+
};
|
|
22214
|
+
}
|
|
22215
|
+
|
|
22216
|
+
//#endregion
|
|
22217
|
+
//#region packages/factory/dist/convergence/budget.js
|
|
22218
|
+
const DEFAULT_BACKOFF = {
|
|
22219
|
+
initialDelay: 200,
|
|
22220
|
+
factor: 2,
|
|
22221
|
+
maxDelay: 6e4,
|
|
22222
|
+
jitterFactor: .5
|
|
22223
|
+
};
|
|
22224
|
+
/**
|
|
22225
|
+
* Compute the delay (in milliseconds) before the next retry attempt.
|
|
22226
|
+
*
|
|
22227
|
+
* Formula (before jitter):
|
|
22228
|
+
* `baseDelay = initialDelay * factor^attemptIndex`
|
|
22229
|
+
* `cappedDelay = Math.min(baseDelay, maxDelay)`
|
|
22230
|
+
*
|
|
22231
|
+
* Jitter:
|
|
22232
|
+
* `jitter = (Math.random() * 2 - 1) * jitterFactor * cappedDelay`
|
|
22233
|
+
* `delay = Math.max(0, Math.round(cappedDelay + jitter))`
|
|
22234
|
+
*
|
|
22235
|
+
* Passing `{ jitterFactor: 0 }` disables jitter for deterministic tests.
|
|
22236
|
+
*
|
|
22237
|
+
* @param attemptIndex - Zero-based index of the current attempt (0 = first retry).
|
|
22238
|
+
* @param options - Optional overrides for the backoff parameters.
|
|
22239
|
+
*/
|
|
22240
|
+
function computeBackoffDelay(attemptIndex, options) {
|
|
22241
|
+
const { initialDelay, factor, maxDelay, jitterFactor } = {
|
|
22242
|
+
...DEFAULT_BACKOFF,
|
|
22243
|
+
...options
|
|
22244
|
+
};
|
|
22245
|
+
const baseDelay = initialDelay * Math.pow(factor, attemptIndex);
|
|
22246
|
+
const cappedDelay = Math.min(baseDelay, maxDelay);
|
|
22247
|
+
const jitter = (Math.random() * 2 - 1) * jitterFactor * cappedDelay;
|
|
22248
|
+
return Math.max(0, Math.round(cappedDelay + jitter));
|
|
22249
|
+
}
|
|
22250
|
+
/**
|
|
22251
|
+
* Determine whether a pipeline is permitted to dispatch the next node.
|
|
22252
|
+
*
|
|
22253
|
+
* **Unlimited mode:** When `cap === 0` the function returns `{ allowed: true }`
|
|
22254
|
+
* immediately, regardless of `accumulatedCost`. This matches the
|
|
22255
|
+
* `FactoryConfigSchema` default of `budget_cap_usd: 0` which means "no limit".
|
|
22256
|
+
*
|
|
22257
|
+
* **Strict greater-than boundary:** Enforcement triggers only when
|
|
22258
|
+
* `accumulatedCost > cap`. A cost that exactly equals the cap is still allowed,
|
|
22259
|
+
* consistent with the PRD wording "halts *before* dispatching further nodes
|
|
22260
|
+
* when accumulated cost **exceeds** the cap."
|
|
22261
|
+
*
|
|
22262
|
+
* @param accumulatedCost - Total cost (USD) spent so far during this pipeline run.
|
|
22263
|
+
* @param cap - Maximum allowed cost (USD). `0` disables enforcement.
|
|
22264
|
+
* @returns `{ allowed: true }` when the pipeline may continue, or
|
|
22265
|
+
* `{ allowed: false, reason: '...' }` when the budget is exhausted.
|
|
22266
|
+
*/
|
|
22267
|
+
function checkPipelineBudget(accumulatedCost, cap) {
|
|
22268
|
+
if (cap === 0) return { allowed: true };
|
|
22269
|
+
if (accumulatedCost > cap) return {
|
|
22270
|
+
allowed: false,
|
|
22271
|
+
reason: `pipeline budget exhausted: $${accumulatedCost.toFixed(2)} > $${cap.toFixed(2)}`
|
|
22272
|
+
};
|
|
22273
|
+
return { allowed: true };
|
|
22274
|
+
}
|
|
22275
|
+
/**
|
|
22276
|
+
* Tracks accumulated cost for a single pipeline run and enforces a configurable
|
|
22277
|
+
* spending cap via `checkPipelineBudget`.
|
|
22278
|
+
*
|
|
22279
|
+
* **Lifecycle:** Create one instance per pipeline run. Story 45-8 will call
|
|
22280
|
+
* `addCost()` after each node dispatch completes and `checkBudget()` before
|
|
22281
|
+
* the next dispatch. Call `reset()` between pipeline runs or in tests to clear
|
|
22282
|
+
* accumulated state.
|
|
22283
|
+
*/
|
|
22284
|
+
var PipelineBudgetManager = class {
|
|
22285
|
+
totalCost = 0;
|
|
22286
|
+
/**
|
|
22287
|
+
* Add `amount` USD to the running total for this pipeline run.
|
|
22288
|
+
*
|
|
22289
|
+
* @param amount - Cost (USD) for the just-completed node dispatch.
|
|
22290
|
+
*/
|
|
22291
|
+
addCost(amount) {
|
|
22292
|
+
this.totalCost += amount;
|
|
22293
|
+
}
|
|
22294
|
+
/**
|
|
22295
|
+
* Return the total cost (USD) accumulated so far during this pipeline run.
|
|
22296
|
+
*/
|
|
22297
|
+
getTotalCost() {
|
|
22298
|
+
return this.totalCost;
|
|
22299
|
+
}
|
|
22300
|
+
/**
|
|
22301
|
+
* Reset the accumulated cost to zero.
|
|
22302
|
+
* Useful for test isolation and future pipeline reuse scenarios.
|
|
22303
|
+
*/
|
|
22304
|
+
reset() {
|
|
22305
|
+
this.totalCost = 0;
|
|
22306
|
+
}
|
|
22307
|
+
/**
|
|
22308
|
+
* Determine whether the pipeline may dispatch the next node, delegating to
|
|
22309
|
+
* `checkPipelineBudget` with the current accumulated cost.
|
|
22310
|
+
*
|
|
22311
|
+
* @param cap - Maximum allowed cost (USD). `0` disables enforcement.
|
|
22312
|
+
*/
|
|
22313
|
+
checkBudget(cap) {
|
|
22314
|
+
return checkPipelineBudget(this.totalCost, cap);
|
|
22315
|
+
}
|
|
22316
|
+
};
|
|
22317
|
+
/**
|
|
22318
|
+
* Determine whether a pipeline session is permitted to dispatch the next node
|
|
22319
|
+
* based on wall-clock elapsed time.
|
|
22320
|
+
*
|
|
22321
|
+
* **Unlimited mode:** When `capMs === 0` the function returns `{ allowed: true }`
|
|
22322
|
+
* immediately, regardless of `elapsedMs`. This matches the `FactoryConfigSchema`
|
|
22323
|
+
* default of `wall_clock_cap_seconds: 0` which means "no limit".
|
|
22324
|
+
*
|
|
22325
|
+
* **Strict greater-than boundary:** Enforcement triggers only when
|
|
22326
|
+
* `elapsedMs > capMs`. An elapsed time that exactly equals the cap is still
|
|
22327
|
+
* allowed, consistent with the PRD wording "halts *before* dispatching further
|
|
22328
|
+
* nodes when elapsed time **exceeds** the cap."
|
|
22329
|
+
*
|
|
22330
|
+
* @param elapsedMs - Milliseconds elapsed since the pipeline session started.
|
|
22331
|
+
* @param capMs - Maximum allowed elapsed time in milliseconds. `0` disables
|
|
22332
|
+
* enforcement (unlimited mode).
|
|
22333
|
+
* @returns `{ allowed: true }` when the session may continue, or
|
|
22334
|
+
* `{ allowed: false, reason: 'wall clock budget exhausted' }` when the
|
|
22335
|
+
* cap has been exceeded.
|
|
22336
|
+
*/
|
|
22337
|
+
function checkSessionBudget(elapsedMs, capMs) {
|
|
22338
|
+
if (capMs === 0) return { allowed: true };
|
|
22339
|
+
if (elapsedMs > capMs) return {
|
|
22340
|
+
allowed: false,
|
|
22341
|
+
reason: "wall clock budget exhausted"
|
|
22342
|
+
};
|
|
22343
|
+
return { allowed: true };
|
|
22344
|
+
}
|
|
22345
|
+
/**
|
|
22346
|
+
* Tracks wall-clock elapsed time for a single pipeline session and enforces a
|
|
22347
|
+
* configurable time cap via `checkSessionBudget`.
|
|
22348
|
+
*
|
|
22349
|
+
* **Lifecycle:** Create one instance per pipeline run, constructed at pipeline
|
|
22350
|
+
* launch. Story 45-8 will call `checkBudget()` before each node dispatch as
|
|
22351
|
+
* the highest-priority budget check (before `PipelineBudgetManager`).
|
|
22352
|
+
* Call `reset()` between pipeline runs or in tests for
|
|
22353
|
+
* isolation.
|
|
22354
|
+
*
|
|
22355
|
+
* **Cap 0 means unlimited:** A `capSeconds` value of `0` passed to `checkBudget`
|
|
22356
|
+
* disables all wall-clock enforcement and always returns `{ allowed: true }`.
|
|
22357
|
+
*/
|
|
22358
|
+
var SessionBudgetManager = class {
|
|
22359
|
+
startTime;
|
|
22360
|
+
constructor() {
|
|
22361
|
+
this.startTime = Date.now();
|
|
22362
|
+
}
|
|
22363
|
+
/**
|
|
22364
|
+
* Return the number of milliseconds elapsed since this manager was constructed
|
|
22365
|
+
* (or since the last `reset()` call). Always returns a non-negative number.
|
|
22366
|
+
*/
|
|
22367
|
+
getElapsedMs() {
|
|
22368
|
+
return Date.now() - this.startTime;
|
|
22369
|
+
}
|
|
22370
|
+
/**
|
|
22371
|
+
* Reset the session start timestamp to the current time. Subsequent calls to
|
|
22372
|
+
* `getElapsedMs()` will measure from this new baseline. Useful for test
|
|
22373
|
+
* isolation and future pipeline reuse scenarios.
|
|
22374
|
+
*/
|
|
22375
|
+
reset() {
|
|
22376
|
+
this.startTime = Date.now();
|
|
22377
|
+
}
|
|
22378
|
+
/**
|
|
22379
|
+
* Determine whether the pipeline session may dispatch the next node, delegating
|
|
22380
|
+
* to `checkSessionBudget` with the current elapsed time converted from seconds
|
|
22381
|
+
* to milliseconds.
|
|
22382
|
+
*
|
|
22383
|
+
* @param capSeconds - Maximum allowed elapsed time in **seconds** (as stored in
|
|
22384
|
+
* `FactoryConfig.wall_clock_cap_seconds`). A value of `0`
|
|
22385
|
+
* disables enforcement.
|
|
22386
|
+
*/
|
|
22387
|
+
checkBudget(capSeconds) {
|
|
22388
|
+
return checkSessionBudget(this.getElapsedMs(), capSeconds * 1e3);
|
|
22389
|
+
}
|
|
22390
|
+
};
|
|
22391
|
+
|
|
22392
|
+
//#endregion
|
|
22393
|
+
//#region packages/factory/dist/convergence/plateau.js
|
|
22394
|
+
/**
|
|
22395
|
+
* Plateau detection for the convergence loop.
|
|
22396
|
+
* Story 45-6: provides pure plateau detection primitives — no I/O, no side effects.
|
|
22397
|
+
*
|
|
22398
|
+
* Algorithm: Track the last N satisfaction scores (N = `window`, default 3).
|
|
22399
|
+
* If max−min of the window falls strictly below threshold, declare plateau.
|
|
22400
|
+
*
|
|
22401
|
+
* Consumed by:
|
|
22402
|
+
* - Story 45-8 (convergence controller integration)
|
|
22403
|
+
*/
|
|
22404
|
+
const DEFAULT_WINDOW = 3;
|
|
22405
|
+
const DEFAULT_THRESHOLD = .05;
|
|
22406
|
+
/**
|
|
22407
|
+
* Create a new PlateauDetector with the given options.
|
|
22408
|
+
*
|
|
22409
|
+
* **Defaults:** `window=3`, `threshold=0.05` — matching `FactoryConfigSchema.plateau_window`
|
|
22410
|
+
* and `FactoryConfigSchema.plateau_threshold`. Story 45-8 will read these values from
|
|
22411
|
+
* `FactoryConfig` and pass them in.
|
|
22412
|
+
*
|
|
22413
|
+
* **Insufficient-data guard:** `isPlateaued()` always returns `false` when fewer than
|
|
22414
|
+
* `window` scores have been recorded. A plateau can only be declared once the window is full.
|
|
22415
|
+
*
|
|
22416
|
+
* @param options - Optional configuration for window size and threshold.
|
|
22417
|
+
*/
|
|
22418
|
+
function createPlateauDetector(options) {
|
|
22419
|
+
const window = options?.window ?? DEFAULT_WINDOW;
|
|
22420
|
+
const threshold = options?.threshold ?? DEFAULT_THRESHOLD;
|
|
22421
|
+
let scores = [];
|
|
22422
|
+
return {
|
|
22423
|
+
recordScore(_iteration, score) {
|
|
22424
|
+
scores.push(score);
|
|
22425
|
+
scores = scores.slice(-window);
|
|
22426
|
+
},
|
|
22427
|
+
isPlateaued() {
|
|
22428
|
+
if (scores.length < window) return false;
|
|
22429
|
+
const delta = Math.max(...scores) - Math.min(...scores);
|
|
22430
|
+
return delta < threshold;
|
|
22431
|
+
},
|
|
22432
|
+
getWindow() {
|
|
22433
|
+
return window;
|
|
22434
|
+
},
|
|
22435
|
+
getScores() {
|
|
22436
|
+
return [...scores];
|
|
22139
22437
|
}
|
|
22140
22438
|
};
|
|
22141
22439
|
}
|
|
22440
|
+
/**
|
|
22441
|
+
* Check whether the detector has reached a plateau and, if so, emit the
|
|
22442
|
+
* `convergence:plateau-detected` event on the provided event bus.
|
|
22443
|
+
*
|
|
22444
|
+
* This mirrors the `checkGoalGates()` pattern:
|
|
22445
|
+
* - Pure detection is isolated in `PlateauDetector` (no side effects).
|
|
22446
|
+
* - Event emission is isolated here in this wrapper.
|
|
22447
|
+
* - Callers may omit `eventBus` for pure check behavior (no event is emitted).
|
|
22448
|
+
*
|
|
22449
|
+
* @param detector - A `PlateauDetector` instance.
|
|
22450
|
+
* @param context - Run/node identifiers and an optional event bus.
|
|
22451
|
+
* @returns `{ plateaued: true, scores }` with event emitted when plateaued;
|
|
22452
|
+
* `{ plateaued: false, scores }` with no event emitted otherwise.
|
|
22453
|
+
*/
|
|
22454
|
+
function checkPlateauAndEmit(detector, context) {
|
|
22455
|
+
const { runId, nodeId, eventBus } = context;
|
|
22456
|
+
const scores = detector.getScores();
|
|
22457
|
+
if (detector.isPlateaued()) {
|
|
22458
|
+
eventBus?.emit("convergence:plateau-detected", {
|
|
22459
|
+
runId,
|
|
22460
|
+
nodeId,
|
|
22461
|
+
scores,
|
|
22462
|
+
window: detector.getWindow()
|
|
22463
|
+
});
|
|
22464
|
+
return {
|
|
22465
|
+
plateaued: true,
|
|
22466
|
+
scores
|
|
22467
|
+
};
|
|
22468
|
+
}
|
|
22469
|
+
return {
|
|
22470
|
+
plateaued: false,
|
|
22471
|
+
scores
|
|
22472
|
+
};
|
|
22473
|
+
}
|
|
22474
|
+
|
|
22475
|
+
//#endregion
|
|
22476
|
+
//#region packages/factory/dist/convergence/remediation.js
|
|
22477
|
+
/**
|
|
22478
|
+
* Remediation context injection for the convergence loop.
|
|
22479
|
+
* Story 45-7: builds structured remediation context from failure data and
|
|
22480
|
+
* injects it into a retried node's IGraphContext.
|
|
22481
|
+
*
|
|
22482
|
+
* Architecture reference: Section 6.5 — Remediation Context fields
|
|
22483
|
+
*
|
|
22484
|
+
* Pure functions (`formatScenarioDiff`, `deriveFixScope`, `buildRemediationContext`)
|
|
22485
|
+
* have no I/O and no side effects.
|
|
22486
|
+
* Only `injectRemediationContext` mutates state (the IGraphContext).
|
|
22487
|
+
*
|
|
22488
|
+
* Consumed by:
|
|
22489
|
+
* - Story 45-8 (convergence controller integration with executor)
|
|
22490
|
+
* - CodergenBackend handlers (via `getRemediationContext`)
|
|
22491
|
+
*/
|
|
22492
|
+
/**
|
|
22493
|
+
* The agreed key under which remediation context is stored in `IGraphContext`.
|
|
22494
|
+
* Namespaced under `convergence.` to avoid collision with user-defined context keys.
|
|
22495
|
+
* Story 45-8 writes this key; CodergenBackend handlers read it via `getRemediationContext()`.
|
|
22496
|
+
*/
|
|
22497
|
+
const REMEDIATION_CONTEXT_KEY = "convergence.remediation";
|
|
22498
|
+
/**
|
|
22499
|
+
* Formats a human-readable diff of failed scenarios from a ScenarioRunResult.
|
|
22500
|
+
*
|
|
22501
|
+
* This is a pure formatting function with no side effects. For each failed
|
|
22502
|
+
* scenario it produces a line `"- {name}: {stderr || stdout || '(no output)'}"`,
|
|
22503
|
+
* preferring stderr (most useful for debugging), falling back to stdout
|
|
22504
|
+
* (some tools write errors to stdout), then to the literal `'(no output)'`.
|
|
22505
|
+
*
|
|
22506
|
+
* Returns `"All scenarios passed"` when there are no failures.
|
|
22507
|
+
*/
|
|
22508
|
+
function formatScenarioDiff(results) {
|
|
22509
|
+
const failed = results.scenarios.filter((s$1) => s$1.status === "fail");
|
|
22510
|
+
if (failed.length === 0) return "All scenarios passed";
|
|
22511
|
+
const lines = failed.map((s$1) => {
|
|
22512
|
+
const output = s$1.stderr || s$1.stdout || "(no output)";
|
|
22513
|
+
return `- ${s$1.name}: ${output}`;
|
|
22514
|
+
});
|
|
22515
|
+
return lines.join("\n");
|
|
22516
|
+
}
|
|
22517
|
+
/**
|
|
22518
|
+
* Derives a focused fix instruction string from failed scenarios.
|
|
22519
|
+
*
|
|
22520
|
+
* This function produces human-readable fix instructions for the retried agent.
|
|
22521
|
+
* Returns `"Fix {n} failing scenario{s}: {name1}, {name2}, ..."` when there are
|
|
22522
|
+
* failures, or `""` when all scenarios pass.
|
|
22523
|
+
*
|
|
22524
|
+
* Pluralization: singular "scenario" when n === 1, plural "scenarios" otherwise.
|
|
22525
|
+
*/
|
|
22526
|
+
function deriveFixScope(results) {
|
|
22527
|
+
const failed = results.scenarios.filter((s$1) => s$1.status === "fail");
|
|
22528
|
+
if (failed.length === 0) return "";
|
|
22529
|
+
const n$1 = failed.length;
|
|
22530
|
+
const plural = n$1 === 1 ? "scenario" : "scenarios";
|
|
22531
|
+
const names = failed.map((s$1) => s$1.name).join(", ");
|
|
22532
|
+
return `Fix ${n$1} failing ${plural}: ${names}`;
|
|
22533
|
+
}
|
|
22534
|
+
/**
|
|
22535
|
+
* Builds a complete `RemediationContext` from the provided parameters.
|
|
22536
|
+
*
|
|
22537
|
+
* `scenarioResults` is optional — first-iteration retries may not have scenario
|
|
22538
|
+
* data yet. When omitted, `scenarioDiff` defaults to
|
|
22539
|
+
* `"No scenario results available"` and `fixScope` defaults to `""`.
|
|
22540
|
+
*
|
|
22541
|
+
* Stores `satisfactionScoreHistory` as a defensive copy (`[...params.satisfactionScoreHistory]`)
|
|
22542
|
+
* so external mutation of the caller's array does not corrupt the stored history.
|
|
22543
|
+
*/
|
|
22544
|
+
function buildRemediationContext(params) {
|
|
22545
|
+
const scenarioDiff = params.scenarioResults ? formatScenarioDiff(params.scenarioResults) : "No scenario results available";
|
|
22546
|
+
const fixScope = params.scenarioResults ? deriveFixScope(params.scenarioResults) : "";
|
|
22547
|
+
return {
|
|
22548
|
+
previousFailureReason: params.previousFailureReason,
|
|
22549
|
+
scenarioDiff,
|
|
22550
|
+
iterationCount: params.iterationCount,
|
|
22551
|
+
satisfactionScoreHistory: [...params.satisfactionScoreHistory],
|
|
22552
|
+
fixScope
|
|
22553
|
+
};
|
|
22554
|
+
}
|
|
22555
|
+
/**
|
|
22556
|
+
* Injects a `RemediationContext` into an `IGraphContext` under `REMEDIATION_CONTEXT_KEY`.
|
|
22557
|
+
*
|
|
22558
|
+
* Called by the executor's retry loop before dispatching to the retried node —
|
|
22559
|
+
* story 45-8 wires this call into the graph executor.
|
|
22560
|
+
*/
|
|
22561
|
+
function injectRemediationContext(context, remediation) {
|
|
22562
|
+
context.set(REMEDIATION_CONTEXT_KEY, remediation);
|
|
22563
|
+
}
|
|
22142
22564
|
|
|
22143
22565
|
//#endregion
|
|
22144
22566
|
//#region packages/factory/dist/graph/executor.js
|
|
@@ -22179,17 +22601,6 @@ function normalizeOutcomeStatus(raw) {
|
|
|
22179
22601
|
};
|
|
22180
22602
|
}
|
|
22181
22603
|
/**
|
|
22182
|
-
* Compute exponential backoff delay with ±50% jitter.
|
|
22183
|
-
*
|
|
22184
|
-
* @param attempt - Zero-indexed attempt number (0 = first retry, 1 = second, etc.)
|
|
22185
|
-
* @returns Delay in milliseconds, floored at 0 and capped at 60,000ms
|
|
22186
|
-
*/
|
|
22187
|
-
function computeBackoffDelay(attempt) {
|
|
22188
|
-
const rawDelay = Math.min(200 * Math.pow(2, attempt), 6e4);
|
|
22189
|
-
const jitter = rawDelay * .5 * (2 * Math.random() - 1);
|
|
22190
|
-
return Math.max(0, rawDelay + jitter);
|
|
22191
|
-
}
|
|
22192
|
-
/**
|
|
22193
22604
|
* Dispatch a node handler with exponential backoff retry on FAIL outcomes.
|
|
22194
22605
|
*
|
|
22195
22606
|
* Emits `graph:node-retried` before each retry attempt.
|
|
@@ -22248,6 +22659,13 @@ function createGraphExecutor() {
|
|
|
22248
22659
|
const checkpointManager = new CheckpointManager();
|
|
22249
22660
|
const checkpointFilePath = path.join(config.logsRoot, "checkpoint.json");
|
|
22250
22661
|
const controller = createConvergenceController();
|
|
22662
|
+
const sessionManager = new SessionBudgetManager();
|
|
22663
|
+
const pipelineManager = new PipelineBudgetManager();
|
|
22664
|
+
const plateauDetector = createPlateauDetector({
|
|
22665
|
+
...config.plateauWindow !== void 0 ? { window: config.plateauWindow } : {},
|
|
22666
|
+
...config.plateauThreshold !== void 0 ? { threshold: config.plateauThreshold } : {}
|
|
22667
|
+
});
|
|
22668
|
+
let convergenceIteration = 0;
|
|
22251
22669
|
let completedNodes = [];
|
|
22252
22670
|
let nodeRetries = {};
|
|
22253
22671
|
let context = new GraphContext();
|
|
@@ -22287,23 +22705,64 @@ function createGraphExecutor() {
|
|
|
22287
22705
|
}
|
|
22288
22706
|
} else currentNode = graph.startNode();
|
|
22289
22707
|
while (true) {
|
|
22708
|
+
const sessionResult = sessionManager.checkBudget((config.wallClockCapMs ?? 0) / 1e3);
|
|
22709
|
+
if (!sessionResult.allowed) {
|
|
22710
|
+
config.eventBus?.emit("convergence:budget-exhausted", {
|
|
22711
|
+
runId: config.runId,
|
|
22712
|
+
level: "session",
|
|
22713
|
+
reason: sessionResult.reason
|
|
22714
|
+
});
|
|
22715
|
+
return {
|
|
22716
|
+
status: "FAIL",
|
|
22717
|
+
failureReason: `Session budget exceeded: ${sessionResult.reason}`
|
|
22718
|
+
};
|
|
22719
|
+
}
|
|
22720
|
+
const pipelineResult = pipelineManager.checkBudget(config.pipelineBudgetCapUsd ?? 0);
|
|
22721
|
+
if (!pipelineResult.allowed) {
|
|
22722
|
+
config.eventBus?.emit("convergence:budget-exhausted", {
|
|
22723
|
+
runId: config.runId,
|
|
22724
|
+
level: "pipeline",
|
|
22725
|
+
reason: pipelineResult.reason
|
|
22726
|
+
});
|
|
22727
|
+
return {
|
|
22728
|
+
status: "FAIL",
|
|
22729
|
+
failureReason: `Pipeline budget exceeded: ${pipelineResult.reason}`
|
|
22730
|
+
};
|
|
22731
|
+
}
|
|
22290
22732
|
const exitNode = graph.exitNode();
|
|
22291
22733
|
if (currentNode.id === exitNode.id) {
|
|
22292
|
-
const gateResult = controller.
|
|
22734
|
+
const gateResult = controller.checkGoalGates(graph, config.runId, config.eventBus);
|
|
22293
22735
|
if (!gateResult.satisfied) {
|
|
22294
|
-
const failingNodeId = gateResult.
|
|
22736
|
+
const failingNodeId = gateResult.failedGates[0];
|
|
22295
22737
|
const failingGateNode = graph.nodes.get(failingNodeId);
|
|
22296
|
-
const
|
|
22297
|
-
if (
|
|
22298
|
-
const retryNode = graph.nodes.get(retryTarget);
|
|
22299
|
-
if (!retryNode) throw new Error(`Retry target node "${retryTarget}" not found in graph`);
|
|
22300
|
-
currentNode = retryNode;
|
|
22301
|
-
continue;
|
|
22302
|
-
}
|
|
22303
|
-
return {
|
|
22738
|
+
const retryTargetId = failingGateNode ? controller.resolveRetryTarget(failingGateNode, graph) : null;
|
|
22739
|
+
if (!retryTargetId) return {
|
|
22304
22740
|
status: "FAIL",
|
|
22305
22741
|
failureReason: "Goal gate failed: no retry target"
|
|
22306
22742
|
};
|
|
22743
|
+
const retryNode = graph.nodes.get(retryTargetId);
|
|
22744
|
+
if (!retryNode) throw new Error(`Retry target node "${retryTargetId}" not found in graph`);
|
|
22745
|
+
convergenceIteration++;
|
|
22746
|
+
const satisfactionScore = context.getNumber("satisfaction_score", 0);
|
|
22747
|
+
plateauDetector.recordScore(convergenceIteration, satisfactionScore);
|
|
22748
|
+
const plateauResult = checkPlateauAndEmit(plateauDetector, {
|
|
22749
|
+
runId: config.runId,
|
|
22750
|
+
nodeId: retryTargetId,
|
|
22751
|
+
...config.eventBus ? { eventBus: config.eventBus } : {}
|
|
22752
|
+
});
|
|
22753
|
+
if (plateauResult.plateaued) return {
|
|
22754
|
+
status: "FAIL",
|
|
22755
|
+
failureReason: `Convergence plateau detected after ${convergenceIteration} iteration(s): scores plateaued at [${plateauResult.scores.join(", ")}]`
|
|
22756
|
+
};
|
|
22757
|
+
const remediation = buildRemediationContext({
|
|
22758
|
+
previousFailureReason: `Goal gate unsatisfied: ${gateResult.failedGates.join(", ")}`,
|
|
22759
|
+
iterationCount: convergenceIteration,
|
|
22760
|
+
satisfactionScoreHistory: plateauResult.scores
|
|
22761
|
+
});
|
|
22762
|
+
injectRemediationContext(context, remediation);
|
|
22763
|
+
skipCycleCheck = true;
|
|
22764
|
+
currentNode = retryNode;
|
|
22765
|
+
continue;
|
|
22307
22766
|
}
|
|
22308
22767
|
return { status: "SUCCESS" };
|
|
22309
22768
|
}
|
|
@@ -22400,6 +22859,8 @@ function createGraphExecutor() {
|
|
|
22400
22859
|
controller.recordOutcome(nodeToDispatch.id, controllerStatus);
|
|
22401
22860
|
}
|
|
22402
22861
|
if (outcome.contextUpdates) for (const [key, value] of Object.entries(outcome.contextUpdates)) context.set(key, value);
|
|
22862
|
+
const nodeCost = context.getNumber("factory.lastNodeCostUsd", 0);
|
|
22863
|
+
if (nodeCost > 0) pipelineManager.addCost(nodeCost);
|
|
22403
22864
|
if (!skipCompletedPush) completedNodes.push(currentNode.id);
|
|
22404
22865
|
skipCompletedPush = false;
|
|
22405
22866
|
await checkpointManager.save(config.logsRoot, {
|
|
@@ -22414,7 +22875,7 @@ function createGraphExecutor() {
|
|
|
22414
22875
|
checkpointPath: checkpointFilePath
|
|
22415
22876
|
});
|
|
22416
22877
|
if (outcome.status === "FAIL") {
|
|
22417
|
-
const retryTarget =
|
|
22878
|
+
const retryTarget = controller.resolveRetryTarget(currentNode, graph);
|
|
22418
22879
|
if (retryTarget) {
|
|
22419
22880
|
const retryNode = graph.nodes.get(retryTarget);
|
|
22420
22881
|
if (!retryNode) throw new Error(`Retry target node "${retryTarget}" not found in graph`);
|
|
@@ -27810,13 +28271,19 @@ function registerFactoryCommand(program) {
|
|
|
27810
28271
|
const logsRoot = path.join(projectDir, ".substrate", "runs", runId);
|
|
27811
28272
|
const stateManager = new RunStateManager({ runDir: logsRoot });
|
|
27812
28273
|
await stateManager.initRun(dotSource);
|
|
28274
|
+
/** wallClockCapMs: FactoryConfig.wall_clock_cap_seconds × 1000 (story 45-10) */
|
|
28275
|
+
const factoryConfig = await loadFactoryConfig(projectDir, opts.config);
|
|
27813
28276
|
const executor = createGraphExecutor();
|
|
27814
28277
|
await executor.run(graph, {
|
|
27815
28278
|
runId,
|
|
27816
28279
|
logsRoot,
|
|
27817
28280
|
handlerRegistry: createDefaultRegistry(),
|
|
27818
28281
|
eventBus,
|
|
27819
|
-
dotSource
|
|
28282
|
+
dotSource,
|
|
28283
|
+
wallClockCapMs: (factoryConfig.factory?.wall_clock_cap_seconds ?? 0) * 1e3,
|
|
28284
|
+
pipelineBudgetCapUsd: factoryConfig.factory?.budget_cap_usd ?? 0,
|
|
28285
|
+
plateauWindow: factoryConfig.factory?.plateau_window ?? 3,
|
|
28286
|
+
plateauThreshold: factoryConfig.factory?.plateau_threshold ?? .05
|
|
27820
28287
|
});
|
|
27821
28288
|
} catch (err) {
|
|
27822
28289
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -28691,7 +29158,12 @@ async function runRunAction(options) {
|
|
|
28691
29158
|
devStoryOptions: {
|
|
28692
29159
|
deps: workflowDeps,
|
|
28693
29160
|
eventBus: sdlcEventBus,
|
|
28694
|
-
runDevStory
|
|
29161
|
+
runDevStory,
|
|
29162
|
+
buildVerifier: (root) => runBuildVerification({
|
|
29163
|
+
verifyCommand: pack.manifest.verifyCommand,
|
|
29164
|
+
verifyTimeoutMs: pack.manifest.verifyTimeoutMs,
|
|
29165
|
+
projectRoot: root
|
|
29166
|
+
})
|
|
28695
29167
|
},
|
|
28696
29168
|
codeReviewOptions: {
|
|
28697
29169
|
deps: workflowDeps,
|
|
@@ -29293,5 +29765,5 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
29293
29765
|
}
|
|
29294
29766
|
|
|
29295
29767
|
//#endregion
|
|
29296
|
-
export { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict };
|
|
29297
|
-
//# sourceMappingURL=run-
|
|
29768
|
+
export { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, normalizeGraphSummaryToStatus, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict };
|
|
29769
|
+
//# sourceMappingURL=run-CUMPhuVq.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import "./health-DswaC1q5.js";
|
|
2
|
+
import "./logger-KeHncl-f.js";
|
|
3
|
+
import "./helpers-CElYrONe.js";
|
|
4
|
+
import "./dist-CLvAwmT7.js";
|
|
5
|
+
import { normalizeGraphSummaryToStatus, registerRunCommand, runRunAction } from "./run-CUMPhuVq.js";
|
|
6
|
+
import "./routing-CcBOCuC9.js";
|
|
7
|
+
import "./decisions-C0pz9Clx.js";
|
|
8
|
+
|
|
9
|
+
export { runRunAction };
|
package/dist/schema.sql
CHANGED
|
@@ -274,6 +274,11 @@ CREATE TABLE IF NOT EXISTS story_dependencies (
|
|
|
274
274
|
PRIMARY KEY (story_key, depends_on)
|
|
275
275
|
);
|
|
276
276
|
|
|
277
|
+
-- Migration: add created_at to story_dependencies (added in v0.12.0)
|
|
278
|
+
SET @_sd_created_at_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'story_dependencies' AND COLUMN_NAME = 'created_at');
|
|
279
|
+
SET @_sql = IF(@_sd_created_at_exists = 0, 'ALTER TABLE story_dependencies ADD COLUMN created_at DATETIME DEFAULT NULL', 'SELECT 1');
|
|
280
|
+
PREPARE _add_col FROM @_sql; EXECUTE _add_col; DEALLOCATE PREPARE _add_col;
|
|
281
|
+
|
|
277
282
|
-- ---------------------------------------------------------------------------
|
|
278
283
|
-- ready_stories view (Epic 31-1)
|
|
279
284
|
-- ---------------------------------------------------------------------------
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./dist-
|
|
1
|
+
import "./dist-CLvAwmT7.js";
|
|
2
2
|
import "./version-manager-impl-BmOWu8ml.js";
|
|
3
|
-
import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-
|
|
3
|
+
import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-DT0I_-1E.js";
|
|
4
4
|
|
|
5
5
|
export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createVersionManager } from "./dist-
|
|
1
|
+
import { createVersionManager } from "./dist-CLvAwmT7.js";
|
|
2
2
|
import { execSync, spawn } from "child_process";
|
|
3
3
|
import * as readline from "readline";
|
|
4
4
|
|
|
@@ -123,4 +123,4 @@ function registerUpgradeCommand(program) {
|
|
|
123
123
|
|
|
124
124
|
//#endregion
|
|
125
125
|
export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
|
|
126
|
-
//# sourceMappingURL=upgrade-
|
|
126
|
+
//# sourceMappingURL=upgrade-DT0I_-1E.js.map
|
package/package.json
CHANGED
package/dist/run-C3HrjTtt.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import "./health-BR5GD5Ge.js";
|
|
2
|
-
import "./logger-KeHncl-f.js";
|
|
3
|
-
import "./helpers-CElYrONe.js";
|
|
4
|
-
import "./dist-DKG5lyUw.js";
|
|
5
|
-
import { registerRunCommand, runRunAction } from "./run-zWACyS3w.js";
|
|
6
|
-
import "./routing-CcBOCuC9.js";
|
|
7
|
-
import "./decisions-C0pz9Clx.js";
|
|
8
|
-
|
|
9
|
-
export { runRunAction };
|