substrate-ai 0.20.130 → 0.20.132
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-D70o7g1c.js +4 -0
- package/dist/cli/index.js +171 -49
- package/dist/{decisions-B4A60aRy.js → decisions-DAuvU4q9.js} +1 -1
- package/dist/{dist-Bc0-6VcX.js → dist-BUDAiEaH.js} +42 -3
- package/dist/{errors-CwQM_6Yk.js → errors-pJaYVCUJ.js} +2 -2
- package/dist/{experimenter-D9yPAcRD.js → experimenter-CpnxTV5m.js} +1 -1
- package/dist/{health-C5qUaNup.js → health-BtNrnj3J.js} +3 -3
- package/dist/{health-AQjZv_aT.js → health-Cb4jPuRd.js} +3 -3
- package/dist/{index-Ce8BVUmL.d.ts → index-CyQhVXLB.d.ts} +11 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -2
- package/dist/{interactive-prompt-y6udulxR.js → interactive-prompt-DKNFNQ7u.js} +2 -2
- package/dist/{manifest-read-D_HmoOcb.js → manifest-read-CKmTZKA5.js} +2 -2
- package/dist/modules/interactive-prompt/index.js +3 -3
- package/dist/{routing-DFwoxEpT.js → routing-CEd36PVz.js} +1 -1
- package/dist/{run-BsPkkWob.js → run-BMx6kY0E.js} +5 -5
- package/dist/{run-jVpLtRRy.js → run-DAb4BgAO.js} +242 -79
- package/dist/src/modules/recovery-engine/index.d.ts +1 -1
- package/dist/{upgrade-BlBDCOfS.js → upgrade-BApZ1sPK.js} +2 -2
- package/dist/{upgrade-OE6hMPMW.js → upgrade-D4Dj7rjQ.js} +2 -2
- package/dist/{version-manager-impl-BRVBwdma.js → version-manager-impl-Bi05jQ9s.js} +1 -1
- package/package.json +1 -1
- package/dist/adapter-registry-B9G8dfn-.js +0 -4
package/dist/cli/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { FileKvStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createDoltOperatorReader, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-
|
|
2
|
+
import { FileKvStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createDoltOperatorReader, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-BtNrnj3J.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, GlobalSettingsSchema, InMemoryDatabaseAdapter, IngestionServer, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProvidersSchema, RoutingRecommender, STORY_METRICS, TelemetryConfigSchema, addTokenUsage, aggregateTokenUsageForRun, checkDoltInstalled, compareRunMetrics, createAmendmentRun, createConfigSystem, createDecision, createPipelineRun, createStderrLogger, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initWorkGraphSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, swallowDebug, tagRunAsBaseline, updatePipelineRun } from "../dist-
|
|
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-
|
|
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, createPipelineRun, createStderrLogger, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initWorkGraphSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, swallowDebug, tagRunAsBaseline, updatePipelineRun } from "../dist-BUDAiEaH.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-DAb4BgAO.js";
|
|
7
7
|
import "../adapter-registry-DIcrxjH8.js";
|
|
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-
|
|
9
|
-
import "../errors-
|
|
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-CKmTZKA5.js";
|
|
9
|
+
import "../errors-pJaYVCUJ.js";
|
|
10
10
|
import "../routing-DFxoKHDt.js";
|
|
11
11
|
import { WorkGraphRepository } from "../work-graph-repository-DZyJv5pV.js";
|
|
12
12
|
import "../decisions-CzSIEeGP.js";
|
|
13
13
|
import "../decision-router-DblHY8se.js";
|
|
14
|
-
import "../interactive-prompt-
|
|
14
|
+
import "../interactive-prompt-DKNFNQ7u.js";
|
|
15
15
|
import "../recovery-engine-BKGBeBnW.js";
|
|
16
16
|
import "../version-manager-impl-qFBiO4Eh.js";
|
|
17
|
-
import { registerUpgradeCommand } from "../upgrade-
|
|
17
|
+
import { registerUpgradeCommand } from "../upgrade-BApZ1sPK.js";
|
|
18
18
|
import { Command } from "commander";
|
|
19
19
|
import { fileURLToPath } from "url";
|
|
20
20
|
import { dirname, join, resolve } from "path";
|
|
@@ -30,7 +30,7 @@ import { randomUUID } from "node:crypto";
|
|
|
30
30
|
import { z } from "zod";
|
|
31
31
|
import * as fs from "node:fs/promises";
|
|
32
32
|
import { lstat, readFile as readFile$1, readdir as readdir$1, readlink, realpath } from "node:fs/promises";
|
|
33
|
-
import {
|
|
33
|
+
import { chmodSync, cpSync, existsSync as existsSync$1, lstatSync, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdir as readdir$2, readdirSync as readdirSync$1, readlinkSync, realpathSync as realpathSync$1, rmSync as rmSync$1, statSync as statSync$1, unlinkSync as unlinkSync$1, writeFileSync as writeFileSync$1 } from "fs";
|
|
34
34
|
import { homedir } from "os";
|
|
35
35
|
import { createRequire } from "node:module";
|
|
36
36
|
import { fileURLToPath as fileURLToPath$1 } from "node:url";
|
|
@@ -516,6 +516,53 @@ const DEFAULT_ROUTING_POLICY = {
|
|
|
516
516
|
]
|
|
517
517
|
};
|
|
518
518
|
|
|
519
|
+
//#endregion
|
|
520
|
+
//#region src/modules/config/derive-routing-policy.ts
|
|
521
|
+
/**
|
|
522
|
+
* Returns a copy of `basePolicy` filtered to the providers enabled in
|
|
523
|
+
* `providers`. Provider preference order is taken from `basePolicy` (the
|
|
524
|
+
* order each provider first appears as default/preferred/fallback), so output
|
|
525
|
+
* is deterministic regardless of the `providers` object key order.
|
|
526
|
+
*
|
|
527
|
+
* Edge case: if no providers are enabled (e.g. the no-selection init fallback
|
|
528
|
+
* where every provider defaults to `enabled: false`), the base policy is
|
|
529
|
+
* returned unchanged — there is nothing to derive from, and an empty policy
|
|
530
|
+
* would be invalid.
|
|
531
|
+
*/
|
|
532
|
+
function deriveRoutingPolicy(basePolicy, providers) {
|
|
533
|
+
const enabled = Object.entries(providers).filter(([, cfg]) => cfg?.enabled === true).map(([key]) => key);
|
|
534
|
+
if (enabled.length === 0) return structuredClone(basePolicy);
|
|
535
|
+
const ranking = [];
|
|
536
|
+
const addRank = (p) => {
|
|
537
|
+
if (!ranking.includes(p)) ranking.push(p);
|
|
538
|
+
};
|
|
539
|
+
addRank(basePolicy.default_provider);
|
|
540
|
+
for (const rule of basePolicy.rules) {
|
|
541
|
+
addRank(rule.preferred_provider);
|
|
542
|
+
rule.fallback_providers.forEach(addRank);
|
|
543
|
+
}
|
|
544
|
+
const rankOf = (p) => {
|
|
545
|
+
const i = ranking.indexOf(p);
|
|
546
|
+
return i === -1 ? Number.MAX_SAFE_INTEGER : i;
|
|
547
|
+
};
|
|
548
|
+
const enabledRanked = [...enabled].sort((a, b) => rankOf(a) - rankOf(b));
|
|
549
|
+
const isEnabled = (p) => enabled.includes(p);
|
|
550
|
+
const defaultProvider = isEnabled(basePolicy.default_provider) ? basePolicy.default_provider : enabledRanked[0];
|
|
551
|
+
const rules = basePolicy.rules.map((rule) => {
|
|
552
|
+
const ordered = [rule.preferred_provider, ...rule.fallback_providers].filter(isEnabled);
|
|
553
|
+
for (const p of enabledRanked) if (!ordered.includes(p)) ordered.push(p);
|
|
554
|
+
return {
|
|
555
|
+
task_type: rule.task_type,
|
|
556
|
+
preferred_provider: ordered[0] ?? rule.preferred_provider,
|
|
557
|
+
fallback_providers: ordered.slice(1)
|
|
558
|
+
};
|
|
559
|
+
});
|
|
560
|
+
return {
|
|
561
|
+
default_provider: defaultProvider,
|
|
562
|
+
rules
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
|
|
519
566
|
//#endregion
|
|
520
567
|
//#region src/modules/config/config-schema.ts
|
|
521
568
|
const RoutingRuleSchema = z.object({
|
|
@@ -562,7 +609,8 @@ const SubstrateConfigSchema = z.object({
|
|
|
562
609
|
telemetry: TelemetryConfigSchema.optional(),
|
|
563
610
|
default_agent: z.string().optional(),
|
|
564
611
|
supervisor_poll_interval_seconds: z.number().int().positive().optional(),
|
|
565
|
-
retry_budget: z.number().int().positive().optional()
|
|
612
|
+
retry_budget: z.number().int().positive().optional(),
|
|
613
|
+
epics_path: z.string().optional()
|
|
566
614
|
}).strict();
|
|
567
615
|
const PartialSubstrateConfigSchema = z.object({
|
|
568
616
|
config_format_version: z.enum(["1"]).optional(),
|
|
@@ -580,9 +628,63 @@ const PartialSubstrateConfigSchema = z.object({
|
|
|
580
628
|
telemetry: TelemetryConfigSchema.partial().optional(),
|
|
581
629
|
default_agent: z.string().optional(),
|
|
582
630
|
supervisor_poll_interval_seconds: z.number().int().positive().optional(),
|
|
583
|
-
retry_budget: z.number().int().positive().optional()
|
|
631
|
+
retry_budget: z.number().int().positive().optional(),
|
|
632
|
+
epics_path: z.string().optional()
|
|
584
633
|
}).strict();
|
|
585
634
|
|
|
635
|
+
//#endregion
|
|
636
|
+
//#region src/cli/commands/substrate-gitignore.ts
|
|
637
|
+
/**
|
|
638
|
+
* Compute the `.gitignore` content substrate should write so that everything
|
|
639
|
+
* under `.substrate/` is ignored EXCEPT the operator-shared `config.yaml`,
|
|
640
|
+
* consistent with the AGENTS.md/CLAUDE.md/GEMINI.md guidance.
|
|
641
|
+
*
|
|
642
|
+
* The previous init writer enumerated individual runtime files, which both
|
|
643
|
+
* (a) diverged from the documented negation pattern and (b) left a pre-existing
|
|
644
|
+
* wholesale `.substrate/` dir-ignore in place. A dir-ignore (`.substrate/` or
|
|
645
|
+
* `.substrate`) makes git skip the directory entirely, so `!.substrate/config.yaml`
|
|
646
|
+
* can NEVER re-include the file — the fix MUST convert it to `.substrate/*`
|
|
647
|
+
* (ignore the contents, not the directory) before the negation can work.
|
|
648
|
+
*
|
|
649
|
+
* Pure + exported for unit testing; init.ts is the only caller.
|
|
650
|
+
*/
|
|
651
|
+
/** Wholesale `.substrate` dir-ignore forms that block `!config.yaml` re-inclusion. */
|
|
652
|
+
const WHOLESALE_SUBSTRATE_IGNORES = new Set([
|
|
653
|
+
".substrate",
|
|
654
|
+
".substrate/",
|
|
655
|
+
"/.substrate",
|
|
656
|
+
"/.substrate/"
|
|
657
|
+
]);
|
|
658
|
+
const STAR = ".substrate/*";
|
|
659
|
+
const CONFIG_NEGATION = "!.substrate/config.yaml";
|
|
660
|
+
const CODEX_PROMPTS = ".codex/prompts/";
|
|
661
|
+
const CODEX_SKILLS = ".codex/skills/";
|
|
662
|
+
/**
|
|
663
|
+
* Returns the updated `.gitignore` content. Idempotent: running it on its own
|
|
664
|
+
* output returns `changed: false`.
|
|
665
|
+
*/
|
|
666
|
+
function computeSubstrateGitignore(existing) {
|
|
667
|
+
const lines = existing.split("\n").map((line) => WHOLESALE_SUBSTRATE_IGNORES.has(line.trim()) ? STAR : line);
|
|
668
|
+
const trimmed = lines.map((l) => l.trim());
|
|
669
|
+
const append = [];
|
|
670
|
+
if (!trimmed.includes(STAR)) append.push(STAR);
|
|
671
|
+
const starIdx = trimmed.lastIndexOf(STAR);
|
|
672
|
+
const negIdx = trimmed.lastIndexOf(CONFIG_NEGATION);
|
|
673
|
+
const negationEffective = negIdx !== -1 && negIdx > starIdx;
|
|
674
|
+
if (!negationEffective) append.push(CONFIG_NEGATION);
|
|
675
|
+
if (!trimmed.includes(CODEX_PROMPTS)) append.push(CODEX_PROMPTS);
|
|
676
|
+
if (!trimmed.includes(CODEX_SKILLS)) append.push(CODEX_SKILLS);
|
|
677
|
+
let content = lines.join("\n");
|
|
678
|
+
if (append.length > 0) {
|
|
679
|
+
const needsNewline = content.length > 0 && !content.endsWith("\n");
|
|
680
|
+
content += (needsNewline ? "\n" : "") + "\n# Substrate state — track only the operator config\n" + append.join("\n") + "\n";
|
|
681
|
+
}
|
|
682
|
+
return {
|
|
683
|
+
content,
|
|
684
|
+
changed: content !== existing
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
|
|
586
688
|
//#endregion
|
|
587
689
|
//#region src/modules/project-profile/detect.ts
|
|
588
690
|
function execFileAsync(cmd, args, opts) {
|
|
@@ -1738,6 +1840,7 @@ function syncCommandsAsPrompts(commandsDir, promptsDir, ownershipPrefixes, nameP
|
|
|
1738
1840
|
*
|
|
1739
1841
|
* Returns the number of skill directories copied.
|
|
1740
1842
|
*/
|
|
1843
|
+
/** Exported for testing. */
|
|
1741
1844
|
function syncSkillsToTarget(srcSkillsDir, destSkillsDir, ownershipPrefixes, namePrefix) {
|
|
1742
1845
|
if (!existsSync$1(srcSkillsDir)) return 0;
|
|
1743
1846
|
mkdirSync$1(destSkillsDir, { recursive: true });
|
|
@@ -1764,12 +1867,20 @@ function syncSkillsToTarget(srcSkillsDir, destSkillsDir, ownershipPrefixes, name
|
|
|
1764
1867
|
for (const entry of sourceEntries) {
|
|
1765
1868
|
const destName = namePrefix && !entry.name.startsWith(namePrefix) ? `${namePrefix}${entry.name}` : entry.name;
|
|
1766
1869
|
const dest = join(destSkillsDir, destName);
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1870
|
+
try {
|
|
1871
|
+
rmSync$1(dest, {
|
|
1872
|
+
recursive: true,
|
|
1873
|
+
force: true
|
|
1874
|
+
});
|
|
1875
|
+
cpSync(join(srcSkillsDir, entry.name), dest, { recursive: true });
|
|
1876
|
+
count++;
|
|
1877
|
+
} catch (err) {
|
|
1878
|
+
logger$18.warn({
|
|
1879
|
+
skill: entry.name,
|
|
1880
|
+
dest,
|
|
1881
|
+
err: err instanceof Error ? err.message : String(err)
|
|
1882
|
+
}, "Skipped skill due to copy error; continuing with the rest");
|
|
1883
|
+
}
|
|
1773
1884
|
}
|
|
1774
1885
|
return count;
|
|
1775
1886
|
}
|
|
@@ -1856,13 +1967,14 @@ const PROVIDER_KEY_ENV = {
|
|
|
1856
1967
|
codex: "OPENAI_API_KEY",
|
|
1857
1968
|
gemini: "GOOGLE_API_KEY"
|
|
1858
1969
|
};
|
|
1970
|
+
/** Exported for testing. */
|
|
1859
1971
|
function buildProviderConfig(adapterId, cliPath, subscriptionRouting) {
|
|
1860
1972
|
const providerKey = ADAPTER_TO_PROVIDER[adapterId] ?? adapterId;
|
|
1861
1973
|
const defaults = PROVIDER_DEFAULTS[providerKey];
|
|
1862
1974
|
if (!defaults) throw new ConfigError(`Unknown provider: ${providerKey}`, { adapterId });
|
|
1863
1975
|
return {
|
|
1864
1976
|
...defaults,
|
|
1865
|
-
enabled:
|
|
1977
|
+
enabled: subscriptionRouting !== "disabled",
|
|
1866
1978
|
cli_path: cliPath,
|
|
1867
1979
|
subscription_routing: subscriptionRouting
|
|
1868
1980
|
};
|
|
@@ -1993,12 +2105,18 @@ async function runInitAction(options) {
|
|
|
1993
2105
|
providers: configProviders,
|
|
1994
2106
|
telemetry: DEFAULT_CONFIG.telemetry
|
|
1995
2107
|
};
|
|
1996
|
-
const routingPolicy =
|
|
2108
|
+
const routingPolicy = deriveRoutingPolicy(DEFAULT_ROUTING_POLICY, configProviders);
|
|
1997
2109
|
await mkdir(substrateDir, { recursive: true });
|
|
1998
2110
|
const configHeader = "# Substrate Configuration\n# Generated by `substrate init`\n# Edit this file to customize your AI agent orchestration settings.\n# API keys must be set as environment variables — never stored here.\n#\n# Provider API key env vars:\n" + Object.entries(PROVIDER_KEY_ENV).map(([p, env]) => `# ${p}: ${env}`).join("\n") + "\n\n";
|
|
1999
|
-
|
|
2111
|
+
const configExists = existsSync$1(configPath);
|
|
2112
|
+
if (configExists && !force) {
|
|
2113
|
+
if (outputFormat !== "json") process.stdout.write(" .substrate/config.yaml already exists — preserving (use --force to overwrite)\n");
|
|
2114
|
+
} else await writeFile(configPath, configHeader + yaml.dump(config), "utf-8");
|
|
2000
2115
|
const routingHeader = "# Substrate Routing Policy\n# Defines how tasks are routed to AI providers.\n# Customize rules to match your workflow and available agents.\n\n";
|
|
2001
|
-
|
|
2116
|
+
const routingExists = existsSync$1(routingPolicyPath);
|
|
2117
|
+
if (routingExists && !force) {
|
|
2118
|
+
if (outputFormat !== "json") process.stdout.write(" .substrate/routing-policy.yaml already exists — preserving (use --force to overwrite)\n");
|
|
2119
|
+
} else await writeFile(routingPolicyPath, routingHeader + yaml.dump(routingPolicy), "utf-8");
|
|
2002
2120
|
const projectProfilePath = join(substrateDir, "project-profile.yaml");
|
|
2003
2121
|
let detectedProfile = null;
|
|
2004
2122
|
let projectProfileWritten = false;
|
|
@@ -2080,27 +2198,12 @@ async function runInitAction(options) {
|
|
|
2080
2198
|
else if (outputFormat !== "json") process.stderr.write("Warning: --install-user-scope requested but HOME/USERPROFILE is not set\n");
|
|
2081
2199
|
}
|
|
2082
2200
|
const gitignorePath = join(projectRoot, ".gitignore");
|
|
2083
|
-
const runtimeEntries = [
|
|
2084
|
-
".substrate/orchestrator.pid",
|
|
2085
|
-
".substrate/current-run-id",
|
|
2086
|
-
".substrate/scenarios/",
|
|
2087
|
-
".substrate/state/",
|
|
2088
|
-
".substrate/runs/",
|
|
2089
|
-
".substrate/notifications/",
|
|
2090
|
-
".substrate/kv-metrics.json",
|
|
2091
|
-
".substrate/latest-heartbeat-per-story-state.json",
|
|
2092
|
-
".substrate/substrate.db",
|
|
2093
|
-
".substrate/substrate.db-journal",
|
|
2094
|
-
".codex/prompts/",
|
|
2095
|
-
".codex/skills/"
|
|
2096
|
-
];
|
|
2097
2201
|
try {
|
|
2098
2202
|
const existing = existsSync$1(gitignorePath) ? readFileSync$1(gitignorePath, "utf-8") : "";
|
|
2099
|
-
const
|
|
2100
|
-
if (
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
logger$18.info({ entries: missing }, "Added substrate runtime files to .gitignore");
|
|
2203
|
+
const { content, changed } = computeSubstrateGitignore(existing);
|
|
2204
|
+
if (changed) {
|
|
2205
|
+
writeFileSync$1(gitignorePath, content);
|
|
2206
|
+
logger$18.info("Updated .gitignore: track only .substrate/config.yaml");
|
|
2104
2207
|
}
|
|
2105
2208
|
} catch (err) {
|
|
2106
2209
|
logger$18.debug({ err }, "Could not update .gitignore (non-fatal)");
|
|
@@ -6890,7 +6993,7 @@ async function runStatusAction(options) {
|
|
|
6890
6993
|
logger$15.debug({ err }, "Work graph query failed, continuing without work graph data");
|
|
6891
6994
|
}
|
|
6892
6995
|
if (run === void 0) {
|
|
6893
|
-
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-
|
|
6996
|
+
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-Cb4jPuRd.js");
|
|
6894
6997
|
const substrateDirPath = join(projectRoot, ".substrate");
|
|
6895
6998
|
const processInfo = inspectProcessTree$1({
|
|
6896
6999
|
projectRoot,
|
|
@@ -7838,7 +7941,7 @@ function defaultSupervisorDeps() {
|
|
|
7838
7941
|
if (cached === null) {
|
|
7839
7942
|
const { AdapterRegistry: AR } = await import(
|
|
7840
7943
|
/* @vite-ignore */
|
|
7841
|
-
"../adapter-registry-
|
|
7944
|
+
"../adapter-registry-D70o7g1c.js"
|
|
7842
7945
|
);
|
|
7843
7946
|
cached = new AR();
|
|
7844
7947
|
await cached.discoverAndRegister();
|
|
@@ -8405,11 +8508,11 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
8405
8508
|
try {
|
|
8406
8509
|
const { createExperimenter } = await import(
|
|
8407
8510
|
/* @vite-ignore */
|
|
8408
|
-
"../experimenter-
|
|
8511
|
+
"../experimenter-CpnxTV5m.js"
|
|
8409
8512
|
);
|
|
8410
8513
|
const { getLatestRun: getLatest } = await import(
|
|
8411
8514
|
/* @vite-ignore */
|
|
8412
|
-
"../decisions-
|
|
8515
|
+
"../decisions-DAuvU4q9.js"
|
|
8413
8516
|
);
|
|
8414
8517
|
const expAdapter = createDatabaseAdapter({
|
|
8415
8518
|
backend: "auto",
|
|
@@ -8419,7 +8522,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
8419
8522
|
await initSchema(expAdapter);
|
|
8420
8523
|
const { runRunAction: runPipeline } = await import(
|
|
8421
8524
|
/* @vite-ignore */
|
|
8422
|
-
"../run-
|
|
8525
|
+
"../run-BMx6kY0E.js"
|
|
8423
8526
|
);
|
|
8424
8527
|
const runStoryFn = async (opts) => {
|
|
8425
8528
|
const exitCode = await runPipeline({
|
|
@@ -8944,7 +9047,7 @@ async function runMetricsAction(options) {
|
|
|
8944
9047
|
const routingConfigPath = join(dbDir, "routing.yml");
|
|
8945
9048
|
let routingConfig = null;
|
|
8946
9049
|
if (existsSync$1(routingConfigPath)) try {
|
|
8947
|
-
const { loadModelRoutingConfig } = await import("../routing-
|
|
9050
|
+
const { loadModelRoutingConfig } = await import("../routing-CEd36PVz.js");
|
|
8948
9051
|
routingConfig = loadModelRoutingConfig(routingConfigPath);
|
|
8949
9052
|
} catch {}
|
|
8950
9053
|
if (routingConfig === null) routingConfig = {
|
|
@@ -11904,7 +12007,11 @@ var EpicParser = class {
|
|
|
11904
12007
|
*/
|
|
11905
12008
|
parseStories(content) {
|
|
11906
12009
|
const headingMatch = STORY_MAP_HEADING_RE.exec(content);
|
|
11907
|
-
if (!headingMatch)
|
|
12010
|
+
if (!headingMatch) {
|
|
12011
|
+
const hasPerStoryHeadings = /^#{2,4}\s+Story\s+\d+[-._]\d+/im.test(content);
|
|
12012
|
+
const hint = hasPerStoryHeadings ? "\n\nThis document already has per-story headings (e.g. `### Story 7-7:` / `#### Story 7.7:`), which `substrate run --stories <key>` consumes directly — ingest-epic is not required to dispatch from it." : "";
|
|
12013
|
+
throw new Error("No story map section found in document. ingest-epic expects a heading containing \"Story Map\" followed by sprint blocks (`**Sprint N — Label:**`) and story lines (`- N-M: Title (P0, Medium)`)." + hint);
|
|
12014
|
+
}
|
|
11908
12015
|
const afterHeading = content.slice(headingMatch.index + headingMatch[0].length);
|
|
11909
12016
|
const stories = [];
|
|
11910
12017
|
let currentSprint = 0;
|
|
@@ -12733,13 +12840,24 @@ function wallClockMs(state) {
|
|
|
12733
12840
|
const end = new Date(state.completed_at).getTime();
|
|
12734
12841
|
return isNaN(start) || isNaN(end) ? void 0 : end - start;
|
|
12735
12842
|
}
|
|
12843
|
+
/**
|
|
12844
|
+
* Compute the run verdict. Must honor the manifest's `run_status`, not only the
|
|
12845
|
+
* per-story counts: a run that failed before dispatching any story has empty
|
|
12846
|
+
* scope (total=0), and a counts-only verdict would vacuously report "ALL PASSED"
|
|
12847
|
+
* for a failed run. Exported for testing.
|
|
12848
|
+
*/
|
|
12849
|
+
function computeReportVerdict(summary, runStatus) {
|
|
12850
|
+
if (summary.escalated > 0 || summary.failed > 0 || runStatus === "failed") return "NEEDS ATTENTION";
|
|
12851
|
+
if (summary.total === 0) return "NO STORIES RUN";
|
|
12852
|
+
return "ALL PASSED";
|
|
12853
|
+
}
|
|
12736
12854
|
function renderHuman(output, manifest) {
|
|
12737
12855
|
const lines = [];
|
|
12738
12856
|
const { runId, summary, stories, escalations, cost, duration, halts } = output;
|
|
12739
12857
|
const durationStr = duration.wall_clock_ms != null ? formatDurationMs(duration.wall_clock_ms) : "unknown";
|
|
12740
12858
|
const costStr = `$${cost.spent.toFixed(4)}`;
|
|
12741
12859
|
const ceilingStr = cost.ceiling != null ? ` / $${cost.ceiling.toFixed(4)} ceiling (${cost.utilization ?? "?"}) ${cost.overCeiling ? "[OVER CEILING]" : ""}` : "";
|
|
12742
|
-
const verdict = summary
|
|
12860
|
+
const verdict = computeReportVerdict(summary, manifest.run_status);
|
|
12743
12861
|
lines.push(`══════════════════════════════════════════════════════════`);
|
|
12744
12862
|
lines.push(` Run: ${runId}`);
|
|
12745
12863
|
lines.push(` Duration: ${durationStr}`);
|
|
@@ -12747,6 +12865,10 @@ function renderHuman(output, manifest) {
|
|
|
12747
12865
|
lines.push(` Verdict: ${verdict}`);
|
|
12748
12866
|
lines.push(`══════════════════════════════════════════════════════════`);
|
|
12749
12867
|
lines.push("");
|
|
12868
|
+
if (manifest.run_status === "failed" && summary.total === 0) {
|
|
12869
|
+
lines.push(" ⚠ Run failed before any story was dispatched (run_status: failed, empty scope). Check the run manifest and prior output for the cause (e.g. worktree/setup error).");
|
|
12870
|
+
lines.push("");
|
|
12871
|
+
}
|
|
12750
12872
|
lines.push(`${summary.verified} verified, ${summary.recovered} recovered, ${summary.escalated} escalated, ${summary.failed} failed of ${summary.total} total`);
|
|
12751
12873
|
lines.push("");
|
|
12752
12874
|
const COL_WIDTHS = [
|
|
@@ -13235,8 +13357,8 @@ async function createProgram() {
|
|
|
13235
13357
|
/** Fire-and-forget startup version check (story 8.3, AC3/AC5) */
|
|
13236
13358
|
function checkForUpdatesInBackground(currentVersion) {
|
|
13237
13359
|
if (process.env.SUBSTRATE_NO_UPDATE_CHECK === "1") return;
|
|
13238
|
-
import("../upgrade-
|
|
13239
|
-
const { createVersionManager } = await import("../version-manager-impl-
|
|
13360
|
+
import("../upgrade-D4Dj7rjQ.js").then(async () => {
|
|
13361
|
+
const { createVersionManager } = await import("../version-manager-impl-Bi05jQ9s.js");
|
|
13240
13362
|
const vm = createVersionManager();
|
|
13241
13363
|
const result = await vm.checkForUpdates();
|
|
13242
13364
|
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-BUDAiEaH.js";
|
|
2
2
|
import "./decisions-CzSIEeGP.js";
|
|
3
3
|
|
|
4
4
|
export { getLatestRun };
|
|
@@ -9716,6 +9716,29 @@ function stripCodeFences$1(raw) {
|
|
|
9716
9716
|
/** Codex default billing modes — subscription via `codex login`, or API key */
|
|
9717
9717
|
const CODEX_BILLING_MODES = ["subscription", "api"];
|
|
9718
9718
|
/**
|
|
9719
|
+
* Signatures emitted by `codex exec` when its sandbox/approval policy prevents
|
|
9720
|
+
* a file write or command in non-interactive mode. The first two are the
|
|
9721
|
+
* "exec can't service an approval" failures; the third is what an org policy
|
|
9722
|
+
* prints when it overrides the requested approval/sandbox configuration.
|
|
9723
|
+
*/
|
|
9724
|
+
const CODEX_SANDBOX_BLOCK_SIGNATURES = [
|
|
9725
|
+
"approval is not supported in exec mode",
|
|
9726
|
+
"command execution approval is not supported",
|
|
9727
|
+
"file change approval is not supported",
|
|
9728
|
+
"disallowed by requirements"
|
|
9729
|
+
];
|
|
9730
|
+
/** Human-readable explanation appended to escalations caused by a Codex write-block. */
|
|
9731
|
+
const CODEX_SANDBOX_BLOCK_HINT = "Likely cause: Codex could not write files. Substrate runs `codex exec --sandbox workspace-write --ask-for-approval never` (normal automation mode — not the org-blocked `--dangerously-bypass-approvals-and-sandbox`). If the run log shows \"disallowed by requirements\", your org policy forbids the `never` approval policy, so Codex cannot write non-interactively on this machine — an org constraint, not substrate. Workaround: dispatch with a provider that can write here (e.g. `--agent claude-code`), or have the Codex policy permit non-interactive workspace writes.";
|
|
9732
|
+
/**
|
|
9733
|
+
* Returns the Codex-write-block hint if `output` contains a sandbox/approval
|
|
9734
|
+
* block signature, else null. Pure + exported for diagnostics and testing.
|
|
9735
|
+
*/
|
|
9736
|
+
function detectCodexSandboxBlock(output) {
|
|
9737
|
+
if (output === void 0 || output === null || output === "") return null;
|
|
9738
|
+
const lower = output.toLowerCase();
|
|
9739
|
+
return CODEX_SANDBOX_BLOCK_SIGNATURES.some((sig) => lower.includes(sig)) ? CODEX_SANDBOX_BLOCK_HINT : null;
|
|
9740
|
+
}
|
|
9741
|
+
/**
|
|
9719
9742
|
* Adapter for the OpenAI Codex CLI agent.
|
|
9720
9743
|
*
|
|
9721
9744
|
* Codex CLI uses stdin for the prompt and outputs JSON when --json flag is used.
|
|
@@ -9761,12 +9784,28 @@ var CodexCLIAdapter = class {
|
|
|
9761
9784
|
* Build spawn command for a coding task.
|
|
9762
9785
|
* Uses: `codex exec` with prompt delivered via stdin.
|
|
9763
9786
|
*
|
|
9787
|
+
* `--sandbox workspace-write --ask-for-approval never` is required so the
|
|
9788
|
+
* non-interactive `codex exec` can actually write files. Without flags, exec
|
|
9789
|
+
* defaults to a read-only sandbox + an approval policy that escalates to the
|
|
9790
|
+
* user — but exec has no one to approve, so file writes fail with
|
|
9791
|
+
* "file change approval is not supported in exec mode" (→ create-story-no-file).
|
|
9792
|
+
* `never` is exactly what Codex's own docs recommend for non-interactive runs,
|
|
9793
|
+
* and this is normal automation mode — NOT the
|
|
9794
|
+
* `--dangerously-bypass-approvals-and-sandbox` flag (which some org policies
|
|
9795
|
+
* forbid). The planning command stays read-only (it must not write).
|
|
9796
|
+
*
|
|
9764
9797
|
* Do NOT use --json: it produces a JSONL event stream that prevents
|
|
9765
9798
|
* extractYamlBlock from finding the structured result block in stdout.
|
|
9766
9799
|
* Raw text output is required (same rationale as Claude adapter).
|
|
9767
9800
|
*/
|
|
9768
9801
|
buildCommand(prompt, options) {
|
|
9769
|
-
const args = [
|
|
9802
|
+
const args = [
|
|
9803
|
+
"exec",
|
|
9804
|
+
"--sandbox",
|
|
9805
|
+
"workspace-write",
|
|
9806
|
+
"--ask-for-approval",
|
|
9807
|
+
"never"
|
|
9808
|
+
];
|
|
9770
9809
|
if (options.additionalFlags && options.additionalFlags.length > 0) args.push(...options.additionalFlags);
|
|
9771
9810
|
const envEntries = {};
|
|
9772
9811
|
if (options.apiKey) envEntries.OPENAI_API_KEY = options.apiKey;
|
|
@@ -11279,5 +11318,5 @@ async function callLLM(params) {
|
|
|
11279
11318
|
}
|
|
11280
11319
|
|
|
11281
11320
|
//#endregion
|
|
11282
|
-
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, InMemoryDatabaseAdapter, IngestionServer, LEARNING_FINDING, 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, classifyVersionGap, compareRunMetrics, createAmendmentRun, createConfigSystem, createDatabaseAdapter as createDatabaseAdapter$1, createDecision, createExperimenter, createPipelineRun, createRequirement, createStderrLogger, 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, initWorkGraphSchema, initializeDolt, listRequirements, listRunMetrics, loadModelRoutingConfig, loadParentRunDecisions, registerArtifact, resolvePromptFile, supersedeDecision, swallowDebug, tagRunAsBaseline, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics };
|
|
11283
|
-
//# sourceMappingURL=dist-
|
|
11321
|
+
export { ADVISORY_NOTES, AdapterRegistry, AdtError, BudgetConfigSchema, CODEX_SANDBOX_BLOCK_HINT, 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, InMemoryDatabaseAdapter, IngestionServer, LEARNING_FINDING, 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, classifyVersionGap, compareRunMetrics, createAmendmentRun, createConfigSystem, createDatabaseAdapter as createDatabaseAdapter$1, createDecision, createExperimenter, createPipelineRun, createRequirement, createStderrLogger, createVersionManager, detectCodexSandboxBlock, detectInterfaceChanges, determineVerdict, getActiveDecisions, getAllCostEntriesFiltered, getArtifactByTypeForRun, getArtifactsByRun, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getModelTier, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initWorkGraphSchema, initializeDolt, listRequirements, listRunMetrics, loadModelRoutingConfig, loadParentRunDecisions, registerArtifact, resolvePromptFile, supersedeDecision, swallowDebug, tagRunAsBaseline, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics };
|
|
11322
|
+
//# sourceMappingURL=dist-BUDAiEaH.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AdtError } from "./dist-
|
|
1
|
+
import { AdtError } from "./dist-BUDAiEaH.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-pJaYVCUJ.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-BUDAiEaH.js";
|
|
2
2
|
|
|
3
3
|
export { createExperimenter };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createLogger } from "./logger-KeHncl-f.js";
|
|
2
|
-
import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-
|
|
3
|
-
import { resolveMainRepoRoot, resolveRunManifest } from "./manifest-read-
|
|
2
|
+
import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-BUDAiEaH.js";
|
|
3
|
+
import { resolveMainRepoRoot, resolveRunManifest } from "./manifest-read-CKmTZKA5.js";
|
|
4
4
|
import { createRequire } from "module";
|
|
5
5
|
import { dirname, join } from "path";
|
|
6
6
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -1000,4 +1000,4 @@ function registerHealthCommand(program, _version = "0.0.0", projectRoot = proces
|
|
|
1000
1000
|
|
|
1001
1001
|
//#endregion
|
|
1002
1002
|
export { BMAD_BASELINE_TOKENS_FULL, DEFAULT_STALL_THRESHOLD_SECONDS, FileKvStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter$1 as createDatabaseAdapter, createDoltOperatorReader, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, isOrchestratorProcessLine, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, runHealthAction, validateStoryKey };
|
|
1003
|
-
//# sourceMappingURL=health-
|
|
1003
|
+
//# sourceMappingURL=health-BtNrnj3J.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
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-BtNrnj3J.js";
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
|
-
import "./dist-
|
|
4
|
-
import "./manifest-read-
|
|
3
|
+
import "./dist-BUDAiEaH.js";
|
|
4
|
+
import "./manifest-read-CKmTZKA5.js";
|
|
5
5
|
import "./work-graph-repository-DZyJv5pV.js";
|
|
6
6
|
import "./decisions-CzSIEeGP.js";
|
|
7
7
|
|
|
@@ -1333,6 +1333,16 @@ declare class CodexCLIAdapter implements WorkerAdapter {
|
|
|
1333
1333
|
* Build spawn command for a coding task.
|
|
1334
1334
|
* Uses: `codex exec` with prompt delivered via stdin.
|
|
1335
1335
|
*
|
|
1336
|
+
* `--sandbox workspace-write --ask-for-approval never` is required so the
|
|
1337
|
+
* non-interactive `codex exec` can actually write files. Without flags, exec
|
|
1338
|
+
* defaults to a read-only sandbox + an approval policy that escalates to the
|
|
1339
|
+
* user — but exec has no one to approve, so file writes fail with
|
|
1340
|
+
* "file change approval is not supported in exec mode" (→ create-story-no-file).
|
|
1341
|
+
* `never` is exactly what Codex's own docs recommend for non-interactive runs,
|
|
1342
|
+
* and this is normal automation mode — NOT the
|
|
1343
|
+
* `--dangerously-bypass-approvals-and-sandbox` flag (which some org policies
|
|
1344
|
+
* forbid). The planning command stays read-only (it must not write).
|
|
1345
|
+
*
|
|
1336
1346
|
* Do NOT use --json: it produces a JSONL event stream that prevents
|
|
1337
1347
|
* extractYamlBlock from finding the structured result block in stdout.
|
|
1338
1348
|
* Raw text output is required (same rationale as Claude adapter).
|
|
@@ -1439,4 +1449,4 @@ interface Recommendation {
|
|
|
1439
1449
|
|
|
1440
1450
|
//#endregion
|
|
1441
1451
|
export { AdapterDiscoveryResult, AdapterRegistry as AdapterRegistry$1, AdtError as AdtError$1, ClaudeCodeAdapter as ClaudeCodeAdapter$1, CodexCLIAdapter as CodexCLIAdapter$1, ConfigError as ConfigError$1, ConfigIncompatibleFormatError as ConfigIncompatibleFormatError$1, CoreEvents, DatabaseAdapter, DiscoveryReport, GeminiCLIAdapter as GeminiCLIAdapter$1, Recommendation, TypedEventBus };
|
|
1442
|
-
//# sourceMappingURL=index-
|
|
1452
|
+
//# sourceMappingURL=index-CyQhVXLB.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AdapterDiscoveryResult, AdapterRegistry$1 as AdapterRegistry, AdtError$1 as AdtError, ClaudeCodeAdapter$1 as ClaudeCodeAdapter, CodexCLIAdapter$1 as CodexCLIAdapter, ConfigError$1 as ConfigError, ConfigIncompatibleFormatError$1 as ConfigIncompatibleFormatError, DiscoveryReport, GeminiCLIAdapter$1 as GeminiCLIAdapter, Recommendation, TypedEventBus } from "./index-
|
|
1
|
+
import { AdapterDiscoveryResult, AdapterRegistry$1 as AdapterRegistry, AdtError$1 as AdtError, ClaudeCodeAdapter$1 as ClaudeCodeAdapter, CodexCLIAdapter$1 as CodexCLIAdapter, ConfigError$1 as ConfigError, ConfigIncompatibleFormatError$1 as ConfigIncompatibleFormatError, DiscoveryReport, GeminiCLIAdapter$1 as GeminiCLIAdapter, Recommendation, TypedEventBus } from "./index-CyQhVXLB.js";
|
|
2
2
|
import pino from "pino";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { Readable, Writable } from "node:stream";
|
|
@@ -1014,6 +1014,7 @@ declare const SubstrateConfigSchema: z.ZodObject<{
|
|
|
1014
1014
|
default_agent: z.ZodOptional<z.ZodString>;
|
|
1015
1015
|
supervisor_poll_interval_seconds: z.ZodOptional<z.ZodNumber>;
|
|
1016
1016
|
retry_budget: z.ZodOptional<z.ZodNumber>;
|
|
1017
|
+
epics_path: z.ZodOptional<z.ZodString>;
|
|
1017
1018
|
}, z.core.$strict>;
|
|
1018
1019
|
type SubstrateConfig = z.infer<typeof SubstrateConfigSchema>;
|
|
1019
1020
|
|
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-BUDAiEaH.js";
|
|
4
4
|
import "./adapter-registry-DIcrxjH8.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-pJaYVCUJ.js";
|
|
6
6
|
|
|
7
7
|
//#region src/core/di.ts
|
|
8
8
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createLogger } from "./logger-KeHncl-f.js";
|
|
2
|
-
import { readCurrentRunId, resolveMainRepoRoot } from "./manifest-read-
|
|
2
|
+
import { readCurrentRunId, resolveMainRepoRoot } from "./manifest-read-CKmTZKA5.js";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
5
5
|
import * as readline from "node:readline";
|
|
@@ -180,4 +180,4 @@ async function runInteractivePrompt(decisionContext) {
|
|
|
180
180
|
|
|
181
181
|
//#endregion
|
|
182
182
|
export { runInteractivePrompt };
|
|
183
|
-
//# sourceMappingURL=interactive-prompt-
|
|
183
|
+
//# sourceMappingURL=interactive-prompt-DKNFNQ7u.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createLogger } from "./logger-KeHncl-f.js";
|
|
2
|
-
import { LEARNING_FINDING, createDecision, getDecisionsByCategory } from "./dist-
|
|
2
|
+
import { LEARNING_FINDING, createDecision, getDecisionsByCategory } from "./dist-BUDAiEaH.js";
|
|
3
3
|
import * as path$1 from "path";
|
|
4
4
|
import { join } from "path";
|
|
5
5
|
import { readFile } from "fs/promises";
|
|
@@ -5851,4 +5851,4 @@ async function resolveRunManifest(dbRoot, runId) {
|
|
|
5851
5851
|
|
|
5852
5852
|
//#endregion
|
|
5853
5853
|
export { FindingsInjector, RunManifest, RuntimeProbeListSchema, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, parseRuntimeProbes, readCurrentRunId, renderFindings, resolveGraphPath, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck, runStaleVerificationRecovery };
|
|
5854
|
-
//# sourceMappingURL=manifest-read-
|
|
5854
|
+
//# sourceMappingURL=manifest-read-CKmTZKA5.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "../../logger-KeHncl-f.js";
|
|
2
|
-
import "../../dist-
|
|
3
|
-
import "../../manifest-read-
|
|
4
|
-
import { runInteractivePrompt } from "../../interactive-prompt-
|
|
2
|
+
import "../../dist-BUDAiEaH.js";
|
|
3
|
+
import "../../manifest-read-CKmTZKA5.js";
|
|
4
|
+
import { runInteractivePrompt } from "../../interactive-prompt-DKNFNQ7u.js";
|
|
5
5
|
|
|
6
6
|
export { runInteractivePrompt };
|
|
@@ -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-BUDAiEaH.js";
|
|
2
2
|
import "./routing-DFxoKHDt.js";
|
|
3
3
|
|
|
4
4
|
export { loadModelRoutingConfig };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import "./health-
|
|
1
|
+
import "./health-BtNrnj3J.js";
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
3
|
import "./helpers-CElYrONe.js";
|
|
4
|
-
import "./dist-
|
|
5
|
-
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-
|
|
6
|
-
import "./manifest-read-
|
|
4
|
+
import "./dist-BUDAiEaH.js";
|
|
5
|
+
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-DAb4BgAO.js";
|
|
6
|
+
import "./manifest-read-CKmTZKA5.js";
|
|
7
7
|
import "./routing-DFxoKHDt.js";
|
|
8
8
|
import "./work-graph-repository-DZyJv5pV.js";
|
|
9
9
|
import "./decisions-CzSIEeGP.js";
|
|
10
10
|
import "./decision-router-DblHY8se.js";
|
|
11
|
-
import "./interactive-prompt-
|
|
11
|
+
import "./interactive-prompt-DKNFNQ7u.js";
|
|
12
12
|
import "./recovery-engine-BKGBeBnW.js";
|
|
13
13
|
|
|
14
14
|
export { runRunAction };
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { BMAD_BASELINE_TOKENS_FULL, FileKvStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, validateStoryKey } from "./health-
|
|
1
|
+
import { BMAD_BASELINE_TOKENS_FULL, FileKvStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, validateStoryKey } from "./health-BtNrnj3J.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, EXPERIMENT_RESULT, 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, classifyVersionGap, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, createStderrLogger, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, swallowDebug, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-
|
|
5
|
-
import { FindingsInjector, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, parseRuntimeProbes, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery } from "./manifest-read-
|
|
4
|
+
import { ADVISORY_NOTES, CODEX_SANDBOX_BLOCK_HINT, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, 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, classifyVersionGap, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, createStderrLogger, detectCodexSandboxBlock, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, swallowDebug, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-BUDAiEaH.js";
|
|
5
|
+
import { FindingsInjector, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, parseRuntimeProbes, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery } from "./manifest-read-CKmTZKA5.js";
|
|
6
6
|
import { WorkGraphRepository, detectCycles } from "./work-graph-repository-DZyJv5pV.js";
|
|
7
7
|
import { deriveExitCode, routeDecision } from "./decision-router-DblHY8se.js";
|
|
8
|
-
import { runInteractivePrompt } from "./interactive-prompt-
|
|
8
|
+
import { runInteractivePrompt } from "./interactive-prompt-DKNFNQ7u.js";
|
|
9
9
|
import { runRecoveryEngine } from "./recovery-engine-BKGBeBnW.js";
|
|
10
10
|
import { basename, dirname, extname, join } from "path";
|
|
11
11
|
import { access, readFile, readdir, stat } from "fs/promises";
|
|
12
12
|
import { EventEmitter } from "node:events";
|
|
13
|
+
import * as yaml$1 from "js-yaml";
|
|
13
14
|
import yaml from "js-yaml";
|
|
14
15
|
import * as actualFS from "node:fs";
|
|
15
16
|
import { accessSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, unwatchFile, watchFile, writeFileSync } from "node:fs";
|
|
@@ -135,23 +136,29 @@ async function verifyGitVersion() {
|
|
|
135
136
|
}
|
|
136
137
|
}
|
|
137
138
|
/**
|
|
138
|
-
*
|
|
139
|
+
* Decide whether a registered worktree from a prior dispatch can be reclaimed
|
|
140
|
+
* for a fresh re-run. Safe only when there is nothing to lose: no uncommitted
|
|
141
|
+
* changes AND no commits on the branch beyond the base branch. A negative
|
|
142
|
+
* `commitsAhead` means the ahead-count could not be determined → not safe.
|
|
139
143
|
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* @param projectRoot - Absolute path to the git repository root
|
|
144
|
-
* @param taskId - Task identifier (used in path derivation)
|
|
145
|
-
* @param branchName - Branch name to create (e.g., "substrate/story-abc123")
|
|
146
|
-
* @param baseBranch - Branch to base the worktree on (e.g., "main")
|
|
147
|
-
* @param copyFiles - v0.20.109: Optional list of files to copy from the
|
|
148
|
-
* project root into the new worktree after creation
|
|
149
|
-
* (e.g., `[".env", ".env.local"]`). Missing files are
|
|
150
|
-
* skipped silently. Useful for gitignored files that
|
|
151
|
-
* build tooling needs but `git worktree add` won't carry.
|
|
152
|
-
* @returns - Object with the worktreePath
|
|
153
|
-
* @throws - Error if git command fails
|
|
144
|
+
* Pure + exported for testing (the git I/O that produces the inputs lives in
|
|
145
|
+
* createWorktree).
|
|
154
146
|
*/
|
|
147
|
+
function decideWorktreeReclaim(hasUncommittedChanges, commitsAhead, baseBranch) {
|
|
148
|
+
if (hasUncommittedChanges) return {
|
|
149
|
+
safe: false,
|
|
150
|
+
reason: "it has uncommitted changes that are NOT on the branch"
|
|
151
|
+
};
|
|
152
|
+
if (commitsAhead > 0) return {
|
|
153
|
+
safe: false,
|
|
154
|
+
reason: `its branch has ${String(commitsAhead)} commit(s) beyond ${baseBranch}`
|
|
155
|
+
};
|
|
156
|
+
if (commitsAhead < 0) return {
|
|
157
|
+
safe: false,
|
|
158
|
+
reason: "its state could not be verified as safe to discard"
|
|
159
|
+
};
|
|
160
|
+
return { safe: true };
|
|
161
|
+
}
|
|
155
162
|
async function createWorktree(projectRoot, taskId, branchName, baseBranch, copyFiles = []) {
|
|
156
163
|
const worktreePath = path$5.join(projectRoot, ".substrate-worktrees", taskId);
|
|
157
164
|
const worktreeExists = await access$1(worktreePath).then(() => true).catch((err) => {
|
|
@@ -170,7 +177,29 @@ async function createWorktree(projectRoot, taskId, branchName, baseBranch, copyF
|
|
|
170
177
|
recursive: true,
|
|
171
178
|
force: true
|
|
172
179
|
});
|
|
173
|
-
else
|
|
180
|
+
else {
|
|
181
|
+
const statusResult = await spawnGit(["status", "--porcelain"], { cwd: worktreePath });
|
|
182
|
+
const hasUncommittedChanges = statusResult.code === 0 && statusResult.stdout.trim().length > 0;
|
|
183
|
+
const aheadResult = await spawnGit([
|
|
184
|
+
"rev-list",
|
|
185
|
+
"--count",
|
|
186
|
+
`${baseBranch}..${branchName}`
|
|
187
|
+
], { cwd: projectRoot });
|
|
188
|
+
const commitsAhead = aheadResult.code === 0 ? Number.parseInt(aheadResult.stdout.trim(), 10) || 0 : -1;
|
|
189
|
+
const decision = decideWorktreeReclaim(hasUncommittedChanges, commitsAhead, baseBranch);
|
|
190
|
+
if (!decision.safe) throw new Error(`Worktree at ${worktreePath} is already registered (branch: ${branchName}) and ${decision.reason}.\nIt was preserved from a prior dispatch for inspection — inspect before removing.\n\nTo remove and re-dispatch:\n substrate worktrees --cleanup ${taskId}\n\nTo remove all substrate worktrees:\n substrate worktrees --cleanup`);
|
|
191
|
+
await spawnGit([
|
|
192
|
+
"worktree",
|
|
193
|
+
"remove",
|
|
194
|
+
"--force",
|
|
195
|
+
worktreePath
|
|
196
|
+
], { cwd: projectRoot });
|
|
197
|
+
await spawnGit([
|
|
198
|
+
"branch",
|
|
199
|
+
"-D",
|
|
200
|
+
branchName
|
|
201
|
+
], { cwd: projectRoot });
|
|
202
|
+
}
|
|
174
203
|
}
|
|
175
204
|
const addResult = await spawnGit([
|
|
176
205
|
"worktree",
|
|
@@ -6484,6 +6513,64 @@ const ProbeAuthorResultSchema = z.object({
|
|
|
6484
6513
|
probes: InlineRuntimeProbeListSchema
|
|
6485
6514
|
});
|
|
6486
6515
|
|
|
6516
|
+
//#endregion
|
|
6517
|
+
//#region src/modules/implementation-orchestrator/epic-paths.ts
|
|
6518
|
+
/** Default planning directories scanned for per-epic/glob files, priority order. */
|
|
6519
|
+
const DEFAULT_PLANNING_DIRS = [
|
|
6520
|
+
"_bmad-output/planning-artifacts",
|
|
6521
|
+
"_bmad-output",
|
|
6522
|
+
"docs/planning"
|
|
6523
|
+
];
|
|
6524
|
+
/** Default consolidated-epics file candidates (relative), priority order. */
|
|
6525
|
+
const DEFAULT_EPICS_FILES = [
|
|
6526
|
+
"_bmad-output/planning-artifacts/epics.md",
|
|
6527
|
+
"_bmad-output/epics.md",
|
|
6528
|
+
"docs/planning/epics.md"
|
|
6529
|
+
];
|
|
6530
|
+
function normalizeOverride(projectRoot, override) {
|
|
6531
|
+
if (override === void 0 || override.trim().length === 0) return void 0;
|
|
6532
|
+
const trimmed = override.trim();
|
|
6533
|
+
return isAbsolute(trimmed) ? trimmed : join$1(projectRoot, trimmed);
|
|
6534
|
+
}
|
|
6535
|
+
/**
|
|
6536
|
+
* Ordered absolute candidate paths for the consolidated epics file. An override
|
|
6537
|
+
* (if any) is highest priority, followed by the built-in defaults.
|
|
6538
|
+
*/
|
|
6539
|
+
function buildEpicsFileCandidates(projectRoot, epicsPathOverride) {
|
|
6540
|
+
const out = [];
|
|
6541
|
+
const abs = normalizeOverride(projectRoot, epicsPathOverride);
|
|
6542
|
+
if (abs !== void 0) out.push(abs);
|
|
6543
|
+
for (const rel of DEFAULT_EPICS_FILES) out.push(join$1(projectRoot, rel));
|
|
6544
|
+
return out;
|
|
6545
|
+
}
|
|
6546
|
+
/**
|
|
6547
|
+
* Ordered absolute planning directories to scan for per-epic/glob files. When an
|
|
6548
|
+
* override file is given, its parent directory is searched first.
|
|
6549
|
+
*/
|
|
6550
|
+
function buildPlanningDirs(projectRoot, epicsPathOverride) {
|
|
6551
|
+
const out = [];
|
|
6552
|
+
const abs = normalizeOverride(projectRoot, epicsPathOverride);
|
|
6553
|
+
if (abs !== void 0) out.push(dirname$1(abs));
|
|
6554
|
+
for (const rel of DEFAULT_PLANNING_DIRS) out.push(join$1(projectRoot, rel));
|
|
6555
|
+
return out;
|
|
6556
|
+
}
|
|
6557
|
+
/**
|
|
6558
|
+
* Best-effort read of `epics_path` from `<projectRoot>/.substrate/config.yaml`.
|
|
6559
|
+
* Returns undefined on any error (missing file, parse failure, wrong type) so
|
|
6560
|
+
* discovery silently falls back to the defaults.
|
|
6561
|
+
*/
|
|
6562
|
+
function resolveEpicsPathOverride(projectRoot) {
|
|
6563
|
+
try {
|
|
6564
|
+
const configPath = join$1(projectRoot, ".substrate", "config.yaml");
|
|
6565
|
+
if (!existsSync(configPath)) return void 0;
|
|
6566
|
+
const parsed = yaml$1.load(readFileSync(configPath, "utf-8"));
|
|
6567
|
+
const value = parsed?.epics_path;
|
|
6568
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
6569
|
+
} catch {
|
|
6570
|
+
return void 0;
|
|
6571
|
+
}
|
|
6572
|
+
}
|
|
6573
|
+
|
|
6487
6574
|
//#endregion
|
|
6488
6575
|
//#region src/modules/compiled-workflows/token-ceiling.ts
|
|
6489
6576
|
/**
|
|
@@ -7214,7 +7301,8 @@ async function getArchConstraints$3(deps) {
|
|
|
7214
7301
|
*/
|
|
7215
7302
|
function readEpicShardFromFile(projectRoot, epicId, storyKey) {
|
|
7216
7303
|
try {
|
|
7217
|
-
const
|
|
7304
|
+
const override = resolveEpicsPathOverride(projectRoot);
|
|
7305
|
+
const candidates = buildEpicsFileCandidates(projectRoot, override);
|
|
7218
7306
|
const epicsPath = candidates.find((p) => existsSync(p));
|
|
7219
7307
|
const epicNum = epicId.replace(/^epic-/i, "");
|
|
7220
7308
|
if (epicsPath) {
|
|
@@ -7232,25 +7320,27 @@ function readEpicShardFromFile(projectRoot, epicId, storyKey) {
|
|
|
7232
7320
|
return content.slice(startIdx, endIdx).trim();
|
|
7233
7321
|
}
|
|
7234
7322
|
}
|
|
7235
|
-
const
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7323
|
+
const perEpicPattern = new RegExp(`^epic-${epicNum}-.*\\.md$`);
|
|
7324
|
+
for (const planningDir of buildPlanningDirs(projectRoot, override)) {
|
|
7325
|
+
if (!existsSync(planningDir)) continue;
|
|
7326
|
+
try {
|
|
7327
|
+
const entries = readdirSync(planningDir, { encoding: "utf-8" });
|
|
7328
|
+
const matches = entries.filter((e) => perEpicPattern.test(e)).sort();
|
|
7329
|
+
if (matches.length > 0) {
|
|
7330
|
+
let chosenIdx = 0;
|
|
7331
|
+
if (storyKey !== void 0 && matches.length > 1) for (let i = 0; i < matches.length; i++) {
|
|
7332
|
+
const candidateContent = readFileSync(join$1(planningDir, matches[i]), "utf-8");
|
|
7333
|
+
if (extractStorySection(candidateContent, storyKey) !== null) {
|
|
7334
|
+
chosenIdx = i;
|
|
7335
|
+
break;
|
|
7336
|
+
}
|
|
7247
7337
|
}
|
|
7338
|
+
const perEpicPath = join$1(planningDir, matches[chosenIdx]);
|
|
7339
|
+
const content = readFileSync(perEpicPath, "utf-8");
|
|
7340
|
+
return content.trim();
|
|
7248
7341
|
}
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
return content.trim();
|
|
7252
|
-
}
|
|
7253
|
-
} catch {}
|
|
7342
|
+
} catch {}
|
|
7343
|
+
}
|
|
7254
7344
|
return "";
|
|
7255
7345
|
} catch (err) {
|
|
7256
7346
|
logger$21.warn({
|
|
@@ -12685,17 +12775,16 @@ function discoverPendingStoryKeys(projectRoot, epicNumber) {
|
|
|
12685
12775
|
* For individual epic files, use findEpicFiles() instead.
|
|
12686
12776
|
*/
|
|
12687
12777
|
function findEpicsFile(projectRoot) {
|
|
12688
|
-
const
|
|
12689
|
-
for (const
|
|
12690
|
-
|
|
12691
|
-
if (existsSync(
|
|
12778
|
+
const override = resolveEpicsPathOverride(projectRoot);
|
|
12779
|
+
for (const fullPath of buildEpicsFileCandidates(projectRoot, override)) if (existsSync(fullPath)) return fullPath;
|
|
12780
|
+
for (const planningDir of buildPlanningDirs(projectRoot, override)) {
|
|
12781
|
+
if (!existsSync(planningDir)) continue;
|
|
12782
|
+
try {
|
|
12783
|
+
const entries = readdirSync(planningDir, { encoding: "utf-8" });
|
|
12784
|
+
const match$2 = entries.filter((e) => /^epics[-.].*\.md$/i.test(e) && !/^epic-\d+/.test(e)).sort();
|
|
12785
|
+
if (match$2.length > 0) return join$1(planningDir, match$2[0]);
|
|
12786
|
+
} catch {}
|
|
12692
12787
|
}
|
|
12693
|
-
const planningDir = join$1(projectRoot, "_bmad-output", "planning-artifacts");
|
|
12694
|
-
if (existsSync(planningDir)) try {
|
|
12695
|
-
const entries = readdirSync(planningDir, { encoding: "utf-8" });
|
|
12696
|
-
const match$2 = entries.filter((e) => /^epics[-.].*\.md$/i.test(e) && !/^epic-\d+/.test(e)).sort();
|
|
12697
|
-
if (match$2.length > 0) return join$1(planningDir, match$2[0]);
|
|
12698
|
-
} catch {}
|
|
12699
12788
|
return void 0;
|
|
12700
12789
|
}
|
|
12701
12790
|
/**
|
|
@@ -12703,14 +12792,15 @@ function findEpicsFile(projectRoot) {
|
|
|
12703
12792
|
* Returns paths sorted alphabetically.
|
|
12704
12793
|
*/
|
|
12705
12794
|
function findEpicFiles(projectRoot) {
|
|
12706
|
-
const
|
|
12707
|
-
|
|
12708
|
-
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12795
|
+
const out = [];
|
|
12796
|
+
for (const planningDir of buildPlanningDirs(projectRoot, resolveEpicsPathOverride(projectRoot))) {
|
|
12797
|
+
if (!existsSync(planningDir)) continue;
|
|
12798
|
+
try {
|
|
12799
|
+
const entries = readdirSync(planningDir, { encoding: "utf-8" });
|
|
12800
|
+
for (const e of entries.filter((x) => /^epic-\d+.*\.md$/.test(x)).sort()) out.push(join$1(planningDir, e));
|
|
12801
|
+
} catch {}
|
|
12713
12802
|
}
|
|
12803
|
+
return out;
|
|
12714
12804
|
}
|
|
12715
12805
|
/**
|
|
12716
12806
|
* Story 61-3: find the epic file relevant to a specific story.
|
|
@@ -12753,14 +12843,15 @@ function findEpicFileForStory(projectRoot, storyKey) {
|
|
|
12753
12843
|
const epicNumMatch = /^(\d+)/.exec(storyKey);
|
|
12754
12844
|
if (!epicNumMatch) return void 0;
|
|
12755
12845
|
const epicNum = epicNumMatch[1];
|
|
12756
|
-
const
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12846
|
+
const perEpicPattern = new RegExp(`^epic-${epicNum}-.*\\.md$`);
|
|
12847
|
+
for (const planningDir of buildPlanningDirs(projectRoot, resolveEpicsPathOverride(projectRoot))) {
|
|
12848
|
+
if (!existsSync(planningDir)) continue;
|
|
12849
|
+
try {
|
|
12850
|
+
const entries = readdirSync(planningDir, { encoding: "utf-8" });
|
|
12851
|
+
const matches = entries.filter((e) => perEpicPattern.test(e)).sort();
|
|
12852
|
+
if (matches.length > 0) return join$1(planningDir, matches[0]);
|
|
12853
|
+
} catch {}
|
|
12854
|
+
}
|
|
12764
12855
|
return void 0;
|
|
12765
12856
|
}
|
|
12766
12857
|
/**
|
|
@@ -14244,11 +14335,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
14244
14335
|
completedAt: new Date().toISOString()
|
|
14245
14336
|
});
|
|
14246
14337
|
await writeStoryMetricsBestEffort(storyKey, "failed", 0);
|
|
14338
|
+
const codexHint = detectCodexSandboxBlock(errMsg);
|
|
14247
14339
|
await emitEscalation({
|
|
14248
14340
|
storyKey,
|
|
14249
14341
|
lastVerdict: "create-story-failed",
|
|
14250
14342
|
reviewCycles: 0,
|
|
14251
|
-
issues: [errMsg]
|
|
14343
|
+
issues: codexHint !== null ? [errMsg, codexHint] : [errMsg]
|
|
14252
14344
|
});
|
|
14253
14345
|
await persistState();
|
|
14254
14346
|
return;
|
|
@@ -14331,11 +14423,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
14331
14423
|
completedAt: new Date().toISOString()
|
|
14332
14424
|
});
|
|
14333
14425
|
await writeStoryMetricsBestEffort(storyKey, "failed", 0);
|
|
14426
|
+
const fraudIssues = deps.agentId === "codex" ? [errMsg, CODEX_SANDBOX_BLOCK_HINT] : [errMsg];
|
|
14334
14427
|
await emitEscalation({
|
|
14335
14428
|
storyKey,
|
|
14336
14429
|
lastVerdict: "create-story-fraud-success",
|
|
14337
14430
|
reviewCycles: 0,
|
|
14338
|
-
issues:
|
|
14431
|
+
issues: fraudIssues
|
|
14339
14432
|
});
|
|
14340
14433
|
await persistState();
|
|
14341
14434
|
return;
|
|
@@ -21476,6 +21569,47 @@ async function runResearchPhase(deps, params) {
|
|
|
21476
21569
|
}
|
|
21477
21570
|
}
|
|
21478
21571
|
|
|
21572
|
+
//#endregion
|
|
21573
|
+
//#region src/modules/config/resolve-default-agent.ts
|
|
21574
|
+
/**
|
|
21575
|
+
* Maps config provider keys to the dispatch agent ids the registry/orchestrator
|
|
21576
|
+
* use. The config keys (`claude`/`codex`/`gemini`) differ from the adapter ids
|
|
21577
|
+
* (`claude-code`/`codex`/`gemini`) only for Claude.
|
|
21578
|
+
*/
|
|
21579
|
+
const PROVIDER_TO_AGENT = {
|
|
21580
|
+
claude: "claude-code",
|
|
21581
|
+
codex: "codex",
|
|
21582
|
+
gemini: "gemini"
|
|
21583
|
+
};
|
|
21584
|
+
/**
|
|
21585
|
+
* Precedence when more than one provider is enabled and no `--agent` is given.
|
|
21586
|
+
* Claude first (substrate's reference provider), then Codex, then Gemini.
|
|
21587
|
+
*/
|
|
21588
|
+
const PROVIDER_PRECEDENCE = [
|
|
21589
|
+
"claude",
|
|
21590
|
+
"codex",
|
|
21591
|
+
"gemini"
|
|
21592
|
+
];
|
|
21593
|
+
/**
|
|
21594
|
+
* Returns the dispatch agent id derived from the enabled providers:
|
|
21595
|
+
* - exactly one enabled → that provider's agent id
|
|
21596
|
+
* - several enabled → the highest-precedence enabled provider
|
|
21597
|
+
* - none enabled → `{ error }` (no agent can be chosen)
|
|
21598
|
+
*
|
|
21599
|
+
* Providers absent from the precedence list (future provider keys) sort after
|
|
21600
|
+
* the known ones but remain selectable.
|
|
21601
|
+
*/
|
|
21602
|
+
function resolveDefaultAgentId(providers) {
|
|
21603
|
+
const enabled = Object.entries(providers).filter(([, cfg]) => cfg?.enabled === true).map(([key]) => key);
|
|
21604
|
+
if (enabled.length === 0) return { error: "No enabled providers in .substrate/config.yaml. Run `substrate init` and enable at least one CLI, or pass --agent <claude-code|codex|gemini>." };
|
|
21605
|
+
const rankOf = (p) => {
|
|
21606
|
+
const i = PROVIDER_PRECEDENCE.indexOf(p);
|
|
21607
|
+
return i === -1 ? Number.MAX_SAFE_INTEGER : i;
|
|
21608
|
+
};
|
|
21609
|
+
const chosen = [...enabled].sort((a, b) => rankOf(a) - rankOf(b))[0];
|
|
21610
|
+
return { agentId: PROVIDER_TO_AGENT[chosen] ?? chosen };
|
|
21611
|
+
}
|
|
21612
|
+
|
|
21479
21613
|
//#endregion
|
|
21480
21614
|
//#region src/modules/telemetry/mesh-reporter.ts
|
|
21481
21615
|
const logger$2 = createLogger("mesh-reporter");
|
|
@@ -44658,10 +44792,10 @@ function createTwinManager(eventBus, options) {
|
|
|
44658
44792
|
} catch {
|
|
44659
44793
|
throw new TwinError("Docker not found — twins require Docker");
|
|
44660
44794
|
}
|
|
44661
|
-
const yaml$
|
|
44795
|
+
const yaml$2 = generateComposeYaml(twins);
|
|
44662
44796
|
const dir = join$1(tmpdir(), randomUUID());
|
|
44663
44797
|
mkdirSync(dir, { recursive: true });
|
|
44664
|
-
writeFileSync(join$1(dir, "docker-compose.yml"), yaml$
|
|
44798
|
+
writeFileSync(join$1(dir, "docker-compose.yml"), yaml$2, "utf-8");
|
|
44665
44799
|
composeDir = dir;
|
|
44666
44800
|
startedTwins = twins;
|
|
44667
44801
|
try {
|
|
@@ -45800,7 +45934,7 @@ function resolveProbeAuthorStateIntegrating(cliFlag) {
|
|
|
45800
45934
|
* substrate run --non-interactive --halt-on none --events --output-format json
|
|
45801
45935
|
*/
|
|
45802
45936
|
async function runRunAction(options) {
|
|
45803
|
-
const { pack: packName, from: startPhase, stopAfter, concept: conceptArg, conceptFile, stories: storiesArg, concurrency, outputFormat, projectRoot, events: eventsFlag, verbose: verboseFlag, tui: tuiFlag, skipUx, research: researchFlag, skipResearch: skipResearchFlag, skipPreflight, skipVerification, epic: epicNumber, dryRun, maxReviewCycles = 2, engine, agent:
|
|
45937
|
+
const { pack: packName, from: startPhase, stopAfter, concept: conceptArg, conceptFile, stories: storiesArg, concurrency, outputFormat, projectRoot, events: eventsFlag, verbose: verboseFlag, tui: tuiFlag, skipUx, research: researchFlag, skipResearch: skipResearchFlag, skipPreflight, skipVerification, epic: epicNumber, dryRun, maxReviewCycles = 2, engine, agent: explicitAgentId, registry: injectedRegistry, haltOn: haltOnOpt, costCeiling, probeAuthor, probeAuthorStateIntegrating: probeAuthorStateIntegratingFlag, nonInteractive, verifyAc, noWorktree } = options;
|
|
45804
45938
|
const haltOn = haltOnOpt;
|
|
45805
45939
|
const VALID_PROBE_AUTHOR_MODES = [
|
|
45806
45940
|
"enabled",
|
|
@@ -45845,7 +45979,8 @@ async function runRunAction(options) {
|
|
|
45845
45979
|
else process.stderr.write(`Error: ${errorMsg}\n`);
|
|
45846
45980
|
return 1;
|
|
45847
45981
|
}
|
|
45848
|
-
|
|
45982
|
+
let agentId = explicitAgentId;
|
|
45983
|
+
let agentResolutionError;
|
|
45849
45984
|
if (startPhase !== void 0 && !VALID_PHASES.includes(startPhase)) {
|
|
45850
45985
|
const errorMsg = `Invalid phase '${startPhase}'. Valid phases: ${VALID_PHASES.join(", ")}`;
|
|
45851
45986
|
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, errorMsg) + "\n");
|
|
@@ -45920,6 +46055,13 @@ async function runRunAction(options) {
|
|
|
45920
46055
|
const configSystem = createConfigSystem({ projectConfigDir: dbDir });
|
|
45921
46056
|
await configSystem.load();
|
|
45922
46057
|
const cfg = configSystem.getConfig();
|
|
46058
|
+
if (agentId == null) {
|
|
46059
|
+
const resolved = resolveDefaultAgentId(cfg.providers);
|
|
46060
|
+
if (resolved.agentId != null) {
|
|
46061
|
+
agentId = resolved.agentId;
|
|
46062
|
+
logger.info({ agentId }, "Resolved default dispatch agent from enabled providers");
|
|
46063
|
+
} else agentResolutionError = resolved.error;
|
|
46064
|
+
}
|
|
45923
46065
|
tokenCeilings = cfg.token_ceilings;
|
|
45924
46066
|
if (cfg.dispatch_timeouts) {
|
|
45925
46067
|
dispatchTimeouts = Object.fromEntries(Object.entries(cfg.dispatch_timeouts).filter(([, v]) => v !== void 0));
|
|
@@ -45941,6 +46083,12 @@ async function runRunAction(options) {
|
|
|
45941
46083
|
} catch {
|
|
45942
46084
|
logger.debug("Config loading skipped — using default token ceilings and telemetry settings");
|
|
45943
46085
|
}
|
|
46086
|
+
if (agentResolutionError !== void 0) {
|
|
46087
|
+
if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, agentResolutionError) + "\n");
|
|
46088
|
+
else process.stderr.write(`Error: ${agentResolutionError}\n`);
|
|
46089
|
+
return 1;
|
|
46090
|
+
}
|
|
46091
|
+
const effectiveMaxReviewCycles = resolveMaxReviewCycles(maxReviewCycles, agentId, injectedRegistry);
|
|
45944
46092
|
let parsedStoryKeys = [];
|
|
45945
46093
|
if (storiesArg !== void 0 && storiesArg !== "") {
|
|
45946
46094
|
parsedStoryKeys = storiesArg.split(",").map((k) => k.trim()).filter((k) => k.length > 0);
|
|
@@ -46117,7 +46265,7 @@ async function runRunAction(options) {
|
|
|
46117
46265
|
})
|
|
46118
46266
|
});
|
|
46119
46267
|
try {
|
|
46120
|
-
const runsDir = join(dbDir, "runs");
|
|
46268
|
+
const runsDir$1 = join(dbDir, "runs");
|
|
46121
46269
|
const cliFlags = {
|
|
46122
46270
|
...parsedStoryKeys.length > 0 ? { stories: parsedStoryKeys } : {},
|
|
46123
46271
|
halt_on: haltOn ?? "critical",
|
|
@@ -46128,7 +46276,7 @@ async function runRunAction(options) {
|
|
|
46128
46276
|
...nonInteractive === true ? { non_interactive: true } : {},
|
|
46129
46277
|
...noWorktree === true ? { no_worktree: true } : {}
|
|
46130
46278
|
};
|
|
46131
|
-
const manifest = RunManifest.open(pipelineRun.id, runsDir);
|
|
46279
|
+
const manifest = RunManifest.open(pipelineRun.id, runsDir$1);
|
|
46132
46280
|
await manifest.patchCLIFlags(cliFlags);
|
|
46133
46281
|
await manifest.update({ run_status: "running" });
|
|
46134
46282
|
} catch (err) {
|
|
@@ -46258,6 +46406,16 @@ async function runRunAction(options) {
|
|
|
46258
46406
|
process.stdout.write(sep$2 + "\n");
|
|
46259
46407
|
for (const s$1 of storiesPreview) for (const p of s$1.phases) process.stdout.write(s$1.storyKey.padEnd(COL.story) + p.phase.padEnd(COL.phase) + p.model.padEnd(COL.model) + String(p.estimatedSymbolCount) + "\n");
|
|
46260
46408
|
}
|
|
46409
|
+
try {
|
|
46410
|
+
await RunManifest.open(pipelineRun.id, join(dbDir, "runs")).update({ run_status: "completed" });
|
|
46411
|
+
} catch (err) {
|
|
46412
|
+
logger.debug({ err }, "Failed to finalize dry-run manifest (non-fatal)");
|
|
46413
|
+
}
|
|
46414
|
+
try {
|
|
46415
|
+
await updatePipelineRun(adapter, pipelineRun.id, { status: "completed" });
|
|
46416
|
+
} catch (err) {
|
|
46417
|
+
logger.debug({ err }, "Failed to finalize dry-run Dolt pipeline_runs (non-fatal)");
|
|
46418
|
+
}
|
|
46261
46419
|
return 0;
|
|
46262
46420
|
}
|
|
46263
46421
|
const dispatcher = createDispatcher({
|
|
@@ -46646,11 +46804,16 @@ async function runRunAction(options) {
|
|
|
46646
46804
|
} catch (metricsErr) {
|
|
46647
46805
|
logger.warn({ err: metricsErr }, "Failed to write run metrics (best-effort)");
|
|
46648
46806
|
}
|
|
46807
|
+
const runsDir = join(dbDir, "runs");
|
|
46808
|
+
const terminalStatus = failedKeys.length > 0 || escalatedKeys.length > 0 ? "failed" : "completed";
|
|
46649
46809
|
try {
|
|
46650
|
-
const runsDir = join(dbDir, "runs");
|
|
46651
|
-
const terminalStatus = failedKeys.length > 0 || escalatedKeys.length > 0 ? "failed" : "completed";
|
|
46652
46810
|
await RunManifest.open(pipelineRun.id, runsDir).update({ run_status: terminalStatus });
|
|
46653
46811
|
} catch {}
|
|
46812
|
+
try {
|
|
46813
|
+
await updatePipelineRun(adapter, pipelineRun.id, { status: terminalStatus });
|
|
46814
|
+
} catch (err) {
|
|
46815
|
+
logger.debug({ err }, "Failed to finalize Dolt pipeline_runs status (non-fatal)");
|
|
46816
|
+
}
|
|
46654
46817
|
if (progressRenderer !== void 0) progressRenderer.render({
|
|
46655
46818
|
type: "pipeline:complete",
|
|
46656
46819
|
ts: new Date().toISOString(),
|
|
@@ -46708,8 +46871,8 @@ async function runRunAction(options) {
|
|
|
46708
46871
|
reason: "non-interactive: stdin prompt suppressed"
|
|
46709
46872
|
});
|
|
46710
46873
|
try {
|
|
46711
|
-
const runsDir = join(dbDir, "runs");
|
|
46712
|
-
const runManifestForHalt = RunManifest.open(pipelineRun.id, runsDir);
|
|
46874
|
+
const runsDir$1 = join(dbDir, "runs");
|
|
46875
|
+
const runManifestForHalt = RunManifest.open(pipelineRun.id, runsDir$1);
|
|
46713
46876
|
await runManifestForHalt.update({ cli_flags: {
|
|
46714
46877
|
halt_on: haltPolicy,
|
|
46715
46878
|
halt_skipped: true,
|
|
@@ -46736,8 +46899,8 @@ async function runRunAction(options) {
|
|
|
46736
46899
|
return derivedCode;
|
|
46737
46900
|
}
|
|
46738
46901
|
if (verifyAc === true) try {
|
|
46739
|
-
const runsDir = join(dbDir, "runs");
|
|
46740
|
-
const runManifestForAc = RunManifest.open(pipelineRun.id, runsDir);
|
|
46902
|
+
const runsDir$1 = join(dbDir, "runs");
|
|
46903
|
+
const runManifestForAc = RunManifest.open(pipelineRun.id, runsDir$1);
|
|
46741
46904
|
const manifestData = await runManifestForAc.read();
|
|
46742
46905
|
const artifactsDir = join(dbRoot, "_bmad-output", "implementation-artifacts");
|
|
46743
46906
|
const acResults = {};
|
|
@@ -47278,7 +47441,7 @@ async function runFullPipeline(options) {
|
|
|
47278
47441
|
*/
|
|
47279
47442
|
async function emitPreDispatchVersionAdvisory(currentVersion) {
|
|
47280
47443
|
if (process.env["SUBSTRATE_NO_UPDATE_CHECK"] === "1") return;
|
|
47281
|
-
const { createVersionManager } = await import("./version-manager-impl-
|
|
47444
|
+
const { createVersionManager } = await import("./version-manager-impl-Bi05jQ9s.js");
|
|
47282
47445
|
const vm = createVersionManager();
|
|
47283
47446
|
const result = await vm.checkForUpdates(true);
|
|
47284
47447
|
const gap = classifyVersionGap(currentVersion, result.latestVersion);
|
|
@@ -47375,4 +47538,4 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
|
|
|
47375
47538
|
|
|
47376
47539
|
//#endregion
|
|
47377
47540
|
export { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR$1 as GLOBSTAR, GitClient, GrammarLoader, Minimatch$1 as Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createGitWorktreeManager, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape$1 as escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, normalizeGraphSummaryToStatus, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runRunAction, runSolutioningPhase, unescape$1 as unescape, validateStopAfterFromConflict, wireNdjsonEmitter };
|
|
47378
|
-
//# sourceMappingURL=run-
|
|
47541
|
+
//# sourceMappingURL=run-DAb4BgAO.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createVersionManager } from "./dist-
|
|
1
|
+
import { createVersionManager } from "./dist-BUDAiEaH.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-BApZ1sPK.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./dist-
|
|
1
|
+
import "./dist-BUDAiEaH.js";
|
|
2
2
|
import "./version-manager-impl-qFBiO4Eh.js";
|
|
3
|
-
import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-
|
|
3
|
+
import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-BApZ1sPK.js";
|
|
4
4
|
|
|
5
5
|
export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
|
package/package.json
CHANGED