substrate-ai 0.20.10 → 0.20.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +193 -103
- package/dist/{health-C6Up5GCr.js → health-CxBbduMn.js} +209 -11
- package/dist/{health-C73H5CUZ.js → health-RIYFKE9U.js} +1 -1
- package/dist/index.d.ts +14 -0
- package/dist/{run-CvCQpsy0.js → run-BDQLMeWK.js} +2 -2
- package/dist/{run-BcwaSYTg.js → run-D5VAkItq.js} +166 -27
- package/package.json +1 -1
- package/packs/bmad/prompts/create-story.md +1 -0
|
@@ -3442,21 +3442,52 @@ const RuntimeProbeListSchema = z.array(RuntimeProbeSchema);
|
|
|
3442
3442
|
//#endregion
|
|
3443
3443
|
//#region packages/sdlc/dist/verification/probes/parser.js
|
|
3444
3444
|
const SECTION_HEADING = /^##\s+Runtime\s+Probes\s*$/i;
|
|
3445
|
+
const FENCE_DELIMITER = /^\s*```/;
|
|
3445
3446
|
/**
|
|
3446
3447
|
* Return the raw text of the story's `## Runtime Probes` section (excluding
|
|
3447
3448
|
* the heading line itself), or `undefined` if the section is not present.
|
|
3448
3449
|
*
|
|
3449
3450
|
* The section ends at the next `##` heading or end-of-file. Sub-headings
|
|
3450
3451
|
* (`###`, `####`) remain part of the section body.
|
|
3452
|
+
*
|
|
3453
|
+
* Story 58-4: the scan tracks code-fence depth so a `## Runtime Probes`
|
|
3454
|
+
* heading that appears *inside* an outer ``` block is ignored. Stories that
|
|
3455
|
+
* DOCUMENT probes in prose — regression fixtures, how-to-author docs, the
|
|
3456
|
+
* Epic 58 e2e test spec — contain illustrative `## Runtime Probes` examples
|
|
3457
|
+
* inside outer fences. Without fence-awareness the parser matches those
|
|
3458
|
+
* illustrations as the story's own section, fails to find a terminated
|
|
3459
|
+
* yaml block (the inner fences are typically escaped), and emits a spurious
|
|
3460
|
+
* `runtime-probe-parse-error`. Hit live during the Epic 58 substrate
|
|
3461
|
+
* dispatch on 58-3's artifact.
|
|
3451
3462
|
*/
|
|
3452
3463
|
function extractRuntimeProbesSection(storyContent) {
|
|
3453
3464
|
const lines = storyContent.split(/\r?\n/);
|
|
3454
|
-
|
|
3465
|
+
let inCodeFence = false;
|
|
3466
|
+
let start = -1;
|
|
3467
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
3468
|
+
const line = lines[i] ?? "";
|
|
3469
|
+
if (FENCE_DELIMITER.test(line)) {
|
|
3470
|
+
inCodeFence = !inCodeFence;
|
|
3471
|
+
continue;
|
|
3472
|
+
}
|
|
3473
|
+
if (!inCodeFence && SECTION_HEADING.test(line.trim())) {
|
|
3474
|
+
start = i;
|
|
3475
|
+
break;
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3455
3478
|
if (start === -1) return void 0;
|
|
3456
3479
|
let end = lines.length;
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3480
|
+
inCodeFence = false;
|
|
3481
|
+
for (let i = start + 1; i < lines.length; i += 1) {
|
|
3482
|
+
const line = lines[i] ?? "";
|
|
3483
|
+
if (FENCE_DELIMITER.test(line)) {
|
|
3484
|
+
inCodeFence = !inCodeFence;
|
|
3485
|
+
continue;
|
|
3486
|
+
}
|
|
3487
|
+
if (!inCodeFence && /^##\s+\S/.test(line)) {
|
|
3488
|
+
end = i;
|
|
3489
|
+
break;
|
|
3490
|
+
}
|
|
3460
3491
|
}
|
|
3461
3492
|
return lines.slice(start + 1, end).join("\n");
|
|
3462
3493
|
}
|
|
@@ -3732,6 +3763,113 @@ var RuntimeProbeCheck = class {
|
|
|
3732
3763
|
}
|
|
3733
3764
|
};
|
|
3734
3765
|
|
|
3766
|
+
//#endregion
|
|
3767
|
+
//#region packages/sdlc/dist/verification/source-ac-fidelity-check.js
|
|
3768
|
+
/**
|
|
3769
|
+
* Extract the story's section from the full epic content.
|
|
3770
|
+
*
|
|
3771
|
+
* Uses the same heading pattern as `isImplicitlyCovered` in the monolith:
|
|
3772
|
+
* `### Story <storyKey>:` or `### Story <storyKey> ` or `### Story <storyKey>\n`
|
|
3773
|
+
*
|
|
3774
|
+
* Returns the extracted section text (from the heading match through to the
|
|
3775
|
+
* next `### Story` heading or end of file), or the full content if no
|
|
3776
|
+
* matching heading is found.
|
|
3777
|
+
*/
|
|
3778
|
+
function extractStorySection(epicContent, storyKey) {
|
|
3779
|
+
const escapedKey = storyKey.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3780
|
+
const headingPattern = new RegExp(`^###\\s+Story\\s+${escapedKey}[:\\s]`, "m");
|
|
3781
|
+
const match = headingPattern.exec(epicContent);
|
|
3782
|
+
if (!match) return epicContent;
|
|
3783
|
+
const start = match.index;
|
|
3784
|
+
const nextHeading = /\n### Story /m.exec(epicContent.slice(start + 1));
|
|
3785
|
+
if (nextHeading) return epicContent.slice(start, start + 1 + nextHeading.index);
|
|
3786
|
+
return epicContent.slice(start);
|
|
3787
|
+
}
|
|
3788
|
+
/**
|
|
3789
|
+
* Extract hard clauses from a story section of an epic file.
|
|
3790
|
+
*
|
|
3791
|
+
* Hard clauses:
|
|
3792
|
+
* 1. Lines containing MUST NOT / MUST / SHALL NOT / SHALL as standalone keywords (case-sensitive)
|
|
3793
|
+
* 2. Backtick-wrapped paths with at least one `/` (excludes bare filenames)
|
|
3794
|
+
* 3. The presence of `## Runtime Probes` heading followed by a fenced yaml block
|
|
3795
|
+
* (represented as a single "runtime-probes-section" clause)
|
|
3796
|
+
*/
|
|
3797
|
+
function extractHardClauses(sectionContent) {
|
|
3798
|
+
const clauses = [];
|
|
3799
|
+
const mustPattern = /\b(MUST NOT|MUST|SHALL NOT|SHALL)\b/;
|
|
3800
|
+
const lines = sectionContent.split("\n");
|
|
3801
|
+
for (const line of lines) {
|
|
3802
|
+
const match = mustPattern.exec(line);
|
|
3803
|
+
if (match) {
|
|
3804
|
+
const keyword = match[1];
|
|
3805
|
+
clauses.push({
|
|
3806
|
+
type: keyword,
|
|
3807
|
+
text: line.trim()
|
|
3808
|
+
});
|
|
3809
|
+
}
|
|
3810
|
+
}
|
|
3811
|
+
const pathPattern = /`([a-zA-Z0-9_./-]+\/[a-zA-Z0-9_./-]+)`/g;
|
|
3812
|
+
let pathMatch;
|
|
3813
|
+
while ((pathMatch = pathPattern.exec(sectionContent)) !== null) clauses.push({
|
|
3814
|
+
type: "path",
|
|
3815
|
+
text: `\`${pathMatch[1]}\``
|
|
3816
|
+
});
|
|
3817
|
+
const probesPattern = /^##\s+Runtime Probes[\s\S]*?```yaml/m;
|
|
3818
|
+
if (probesPattern.test(sectionContent)) clauses.push({
|
|
3819
|
+
type: "runtime-probes-section",
|
|
3820
|
+
text: "## Runtime Probes"
|
|
3821
|
+
});
|
|
3822
|
+
return clauses;
|
|
3823
|
+
}
|
|
3824
|
+
var SourceAcFidelityCheck = class {
|
|
3825
|
+
name = "source-ac-fidelity";
|
|
3826
|
+
tier = "A";
|
|
3827
|
+
async run(context) {
|
|
3828
|
+
const start = Date.now();
|
|
3829
|
+
if (!context.sourceEpicContent) {
|
|
3830
|
+
const findings$1 = [{
|
|
3831
|
+
category: "source-ac-source-unavailable",
|
|
3832
|
+
severity: "warn",
|
|
3833
|
+
message: "source epic content unavailable — skipping fidelity check"
|
|
3834
|
+
}];
|
|
3835
|
+
return {
|
|
3836
|
+
status: "pass",
|
|
3837
|
+
details: renderFindings(findings$1),
|
|
3838
|
+
duration_ms: Date.now() - start,
|
|
3839
|
+
findings: findings$1
|
|
3840
|
+
};
|
|
3841
|
+
}
|
|
3842
|
+
const storySection = extractStorySection(context.sourceEpicContent, context.storyKey);
|
|
3843
|
+
const hardClauses = extractHardClauses(storySection);
|
|
3844
|
+
const findings = [];
|
|
3845
|
+
const storyContent = context.storyContent ?? "";
|
|
3846
|
+
for (const clause of hardClauses) if (clause.type === "runtime-probes-section") {
|
|
3847
|
+
if (!storyContent.includes("## Runtime Probes")) {
|
|
3848
|
+
const truncated = clause.text.length > 120 ? clause.text.slice(0, 120) : clause.text;
|
|
3849
|
+
findings.push({
|
|
3850
|
+
category: "source-ac-drift",
|
|
3851
|
+
severity: "error",
|
|
3852
|
+
message: `runtime-probes-section: "${truncated}" present in epics source but absent in story artifact`
|
|
3853
|
+
});
|
|
3854
|
+
}
|
|
3855
|
+
} else if (!storyContent.includes(clause.text)) {
|
|
3856
|
+
const truncated = clause.text.length > 120 ? clause.text.slice(0, 120) : clause.text;
|
|
3857
|
+
findings.push({
|
|
3858
|
+
category: "source-ac-drift",
|
|
3859
|
+
severity: "error",
|
|
3860
|
+
message: `${clause.type}: "${truncated}" present in epics source but absent in story artifact`
|
|
3861
|
+
});
|
|
3862
|
+
}
|
|
3863
|
+
const status = findings.some((f) => f.severity === "error") ? "fail" : "pass";
|
|
3864
|
+
return {
|
|
3865
|
+
status,
|
|
3866
|
+
details: findings.length > 0 ? renderFindings(findings) : `source-ac-fidelity: ${hardClauses.length} hard clause(s) verified — all present`,
|
|
3867
|
+
duration_ms: Date.now() - start,
|
|
3868
|
+
findings
|
|
3869
|
+
};
|
|
3870
|
+
}
|
|
3871
|
+
};
|
|
3872
|
+
|
|
3735
3873
|
//#endregion
|
|
3736
3874
|
//#region packages/sdlc/dist/verification/verification-pipeline.js
|
|
3737
3875
|
/**
|
|
@@ -3839,12 +3977,14 @@ var VerificationPipeline = class {
|
|
|
3839
3977
|
* Create a VerificationPipeline pre-loaded with the canonical check set.
|
|
3840
3978
|
*
|
|
3841
3979
|
* Canonical Tier A check order:
|
|
3842
|
-
* 1. PhantomReviewCheck
|
|
3843
|
-
* 2. TrivialOutputCheck
|
|
3980
|
+
* 1. PhantomReviewCheck — story 51-2 (runs first: unreviewed stories skipped)
|
|
3981
|
+
* 2. TrivialOutputCheck — story 51-3
|
|
3844
3982
|
* 3. AcceptanceCriteriaEvidenceCheck
|
|
3845
|
-
* 4. BuildCheck
|
|
3846
|
-
* 5. RuntimeProbeCheck
|
|
3847
|
-
*
|
|
3983
|
+
* 4. BuildCheck — story 51-4
|
|
3984
|
+
* 5. RuntimeProbeCheck — Epic 55 Phase 2: runtime behavior gate; runs last
|
|
3985
|
+
* in Tier A because probes may depend on built artifacts
|
|
3986
|
+
* 6. SourceAcFidelityCheck — Story 58-2: cross-references rendered story artifact
|
|
3987
|
+
* against the source epic's hard clauses (MUST/SHALL/paths)
|
|
3848
3988
|
*
|
|
3849
3989
|
* @param bus Typed event bus for verification events.
|
|
3850
3990
|
* @param config Optional config (used to forward threshold to TrivialOutputCheck).
|
|
@@ -3855,7 +3995,8 @@ function createDefaultVerificationPipeline(bus, config) {
|
|
|
3855
3995
|
new TrivialOutputCheck(config),
|
|
3856
3996
|
new AcceptanceCriteriaEvidenceCheck(),
|
|
3857
3997
|
new BuildCheck(),
|
|
3858
|
-
new RuntimeProbeCheck()
|
|
3998
|
+
new RuntimeProbeCheck(),
|
|
3999
|
+
new SourceAcFidelityCheck()
|
|
3859
4000
|
];
|
|
3860
4001
|
return new VerificationPipeline(bus, checks);
|
|
3861
4002
|
}
|
|
@@ -4069,6 +4210,12 @@ const RunManifestSchema = z.object({
|
|
|
4069
4210
|
run_id: z.string(),
|
|
4070
4211
|
cli_flags: CliFlagsSchema.transform((v) => v),
|
|
4071
4212
|
story_scope: z.array(z.string()),
|
|
4213
|
+
run_status: z.enum([
|
|
4214
|
+
"running",
|
|
4215
|
+
"completed",
|
|
4216
|
+
"failed",
|
|
4217
|
+
"stopped"
|
|
4218
|
+
]).optional(),
|
|
4072
4219
|
supervisor_pid: z.number().nullable(),
|
|
4073
4220
|
supervisor_session_id: z.string().nullable(),
|
|
4074
4221
|
per_story_state: z.record(z.string(), PerStoryStateSchema),
|
|
@@ -4078,6 +4225,8 @@ const RunManifestSchema = z.object({
|
|
|
4078
4225
|
run_total: 0
|
|
4079
4226
|
}),
|
|
4080
4227
|
pending_proposals: z.array(ProposalSchema),
|
|
4228
|
+
stopped_reason: z.string().optional(),
|
|
4229
|
+
stopped_at: z.string().optional(),
|
|
4081
4230
|
generation: z.number().int().nonnegative(),
|
|
4082
4231
|
created_at: z.string(),
|
|
4083
4232
|
updated_at: z.string()
|
|
@@ -4419,6 +4568,55 @@ var RunManifest = class RunManifest {
|
|
|
4419
4568
|
/**
|
|
4420
4569
|
* Raw implementation — must only be called from within `_enqueue`.
|
|
4421
4570
|
*/
|
|
4571
|
+
async _patchRunStatusImpl(updates) {
|
|
4572
|
+
let existingData;
|
|
4573
|
+
try {
|
|
4574
|
+
const read = await RunManifest.read(this.runId, this.baseDir, this.doltAdapter);
|
|
4575
|
+
const { generation: _gen, updated_at: _ts,...rest } = read;
|
|
4576
|
+
existingData = rest;
|
|
4577
|
+
} catch {
|
|
4578
|
+
const now = new Date().toISOString();
|
|
4579
|
+
existingData = {
|
|
4580
|
+
run_id: this.runId,
|
|
4581
|
+
cli_flags: {},
|
|
4582
|
+
story_scope: [],
|
|
4583
|
+
supervisor_pid: null,
|
|
4584
|
+
supervisor_session_id: null,
|
|
4585
|
+
per_story_state: {},
|
|
4586
|
+
recovery_history: [],
|
|
4587
|
+
cost_accumulation: {
|
|
4588
|
+
per_story: {},
|
|
4589
|
+
run_total: 0
|
|
4590
|
+
},
|
|
4591
|
+
pending_proposals: [],
|
|
4592
|
+
created_at: now
|
|
4593
|
+
};
|
|
4594
|
+
}
|
|
4595
|
+
const merged = { ...existingData };
|
|
4596
|
+
if (updates.run_status !== void 0) merged.run_status = updates.run_status;
|
|
4597
|
+
if (updates.stopped_reason !== void 0) merged.stopped_reason = updates.stopped_reason;
|
|
4598
|
+
if (updates.stopped_at !== void 0) merged.stopped_at = updates.stopped_at;
|
|
4599
|
+
await this._writeImpl(merged);
|
|
4600
|
+
}
|
|
4601
|
+
/**
|
|
4602
|
+
* Atomically update the run-level status fields in the manifest.
|
|
4603
|
+
*
|
|
4604
|
+
* Reads the current manifest (or creates a minimal default if absent),
|
|
4605
|
+
* merges the provided status updates at the top level, and writes the
|
|
4606
|
+
* result atomically via a single `write()` call.
|
|
4607
|
+
*
|
|
4608
|
+
* Enqueues the operation via `_enqueue` so concurrent calls are serialized
|
|
4609
|
+
* (preserves the single-writer guarantee from Epic 57-1).
|
|
4610
|
+
* Non-fatal: callers MUST wrap in `.catch((err) => logger.warn(...))`.
|
|
4611
|
+
*
|
|
4612
|
+
* @param updates - Top-level status fields to merge (run_status, stopped_reason, stopped_at)
|
|
4613
|
+
*/
|
|
4614
|
+
async patchRunStatus(updates) {
|
|
4615
|
+
return this._enqueue(() => this._patchRunStatusImpl(updates));
|
|
4616
|
+
}
|
|
4617
|
+
/**
|
|
4618
|
+
* Raw implementation — must only be called from within `_enqueue`.
|
|
4619
|
+
*/
|
|
4422
4620
|
async _appendRecoveryEntryImpl(entry) {
|
|
4423
4621
|
let existingData;
|
|
4424
4622
|
try {
|
|
@@ -5336,4 +5534,4 @@ function registerHealthCommand(program, _version = "0.0.0", projectRoot = proces
|
|
|
5336
5534
|
|
|
5337
5535
|
//#endregion
|
|
5338
5536
|
export { BMAD_BASELINE_TOKENS_FULL, DEFAULT_STALL_THRESHOLD_SECONDS, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN$1 as STORY_KEY_PATTERN, SUBSTRATE_OWNED_SETTINGS_KEYS, SupervisorLock, VALID_PHASES, WorkGraphRepository, ZERO_FINDING_COUNTS, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter$1 as createDatabaseAdapter, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, createStateStore, detectCycles, extractTargetFilesFromStoryContent, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, isOrchestratorProcessLine, parseDbTimestampAsUtc, registerHealthCommand, renderFindings, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveGraphPath, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, runHealthAction, validateStoryKey };
|
|
5339
|
-
//# sourceMappingURL=health-
|
|
5537
|
+
//# sourceMappingURL=health-CxBbduMn.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-
|
|
1
|
+
import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-CxBbduMn.js";
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
3
|
import "./dist-CqtWS9wF.js";
|
|
4
4
|
import "./decisions-C0pz9Clx.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -2286,6 +2286,20 @@ interface OrchestratorEvents {
|
|
|
2286
2286
|
/** Retry attempt number (always 2 — first retry after initial timeout) */
|
|
2287
2287
|
attempt: number;
|
|
2288
2288
|
};
|
|
2289
|
+
/**
|
|
2290
|
+
* Emitted when an existing story artifact's stored source-AC hash differs
|
|
2291
|
+
* from the current source epic's AC hash, or when the artifact carries no
|
|
2292
|
+
* hash at all (legacy artifact). Causes the orchestrator to re-run
|
|
2293
|
+
* create-story instead of reusing the stale artifact.
|
|
2294
|
+
*/
|
|
2295
|
+
'story:ac-source-drift': {
|
|
2296
|
+
/** Story key whose artifact is stale */
|
|
2297
|
+
storyKey: string;
|
|
2298
|
+
/** Hash stored in the artifact's HTML comment (null if absent — legacy artifact) */
|
|
2299
|
+
storedHash: string | null;
|
|
2300
|
+
/** Hash computed from the current source epic's AC section */
|
|
2301
|
+
currentHash: string;
|
|
2302
|
+
};
|
|
2289
2303
|
}
|
|
2290
2304
|
|
|
2291
2305
|
//#endregion
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "./health-
|
|
1
|
+
import "./health-CxBbduMn.js";
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
3
|
import "./helpers-CElYrONe.js";
|
|
4
4
|
import "./dist-CqtWS9wF.js";
|
|
5
|
-
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-
|
|
5
|
+
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-D5VAkItq.js";
|
|
6
6
|
import "./routing-CcBOCuC9.js";
|
|
7
7
|
import "./decisions-C0pz9Clx.js";
|
|
8
8
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectCycles, extractTargetFilesFromStoryContent, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, renderFindings, resolveGraphPath, resolveMainRepoRoot, validateStoryKey } from "./health-
|
|
1
|
+
import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectCycles, extractTargetFilesFromStoryContent, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, renderFindings, resolveGraphPath, resolveMainRepoRoot, validateStoryKey } from "./health-CxBbduMn.js";
|
|
2
2
|
import { createLogger } from "./logger-KeHncl-f.js";
|
|
3
3
|
import { TypedEventBusImpl, createEventBus, createTuiApp, isTuiCapable, printNonTtyWarning, sleep } from "./helpers-CElYrONe.js";
|
|
4
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, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-CqtWS9wF.js";
|
|
@@ -5676,6 +5676,21 @@ function getTokenCeiling(workflowType, tokenCeilings) {
|
|
|
5676
5676
|
//#region src/modules/compiled-workflows/create-story.ts
|
|
5677
5677
|
const logger$18 = createLogger("compiled-workflows:create-story");
|
|
5678
5678
|
/**
|
|
5679
|
+
* Compute a hex SHA-256 of the normalized source AC section text.
|
|
5680
|
+
*
|
|
5681
|
+
* Normalization (minimal — avoids spurious regen from editor whitespace noise):
|
|
5682
|
+
* 1. Split on `\n`
|
|
5683
|
+
* 2. Strip trailing whitespace from each line (`.trimEnd()`)
|
|
5684
|
+
* 3. Rejoin with `\n`
|
|
5685
|
+
* 4. Trim the whole result (`.trim()`)
|
|
5686
|
+
*
|
|
5687
|
+
* Pure function: no I/O, no side effects. Safe to call from tests with zero setup.
|
|
5688
|
+
*/
|
|
5689
|
+
function hashSourceAcSection(section) {
|
|
5690
|
+
const normalized = section.split("\n").map((line) => line.trimEnd()).join("\n").trim();
|
|
5691
|
+
return createHash("sha256").update(normalized, "utf8").digest("hex");
|
|
5692
|
+
}
|
|
5693
|
+
/**
|
|
5679
5694
|
* Execute the compiled create-story workflow.
|
|
5680
5695
|
*
|
|
5681
5696
|
* Steps:
|
|
@@ -5693,7 +5708,7 @@ const logger$18 = createLogger("compiled-workflows:create-story");
|
|
|
5693
5708
|
* @returns Promise resolving to CreateStoryResult
|
|
5694
5709
|
*/
|
|
5695
5710
|
async function runCreateStory(deps, params) {
|
|
5696
|
-
const { epicId, storyKey, pipelineRunId } = params;
|
|
5711
|
+
const { epicId, storyKey, pipelineRunId, source_ac_hash } = params;
|
|
5697
5712
|
logger$18.debug({
|
|
5698
5713
|
epicId,
|
|
5699
5714
|
storyKey,
|
|
@@ -5764,7 +5779,12 @@ async function runCreateStory(deps, params) {
|
|
|
5764
5779
|
name: "story_template",
|
|
5765
5780
|
content: storyTemplateContent,
|
|
5766
5781
|
priority: "important"
|
|
5767
|
-
}
|
|
5782
|
+
},
|
|
5783
|
+
...source_ac_hash !== void 0 ? [{
|
|
5784
|
+
name: "source_ac_hash",
|
|
5785
|
+
content: source_ac_hash,
|
|
5786
|
+
priority: "required"
|
|
5787
|
+
}] : []
|
|
5768
5788
|
], TOKEN_CEILING);
|
|
5769
5789
|
logger$18.debug({
|
|
5770
5790
|
tokenCount,
|
|
@@ -5911,13 +5931,14 @@ async function getImplementationDecisions(deps, pipelineRunId) {
|
|
|
5911
5931
|
*/
|
|
5912
5932
|
function extractStorySection(shardContent, storyKey) {
|
|
5913
5933
|
if (!shardContent || !storyKey) return null;
|
|
5914
|
-
const
|
|
5915
|
-
const
|
|
5934
|
+
const parts = storyKey.split(/[-._ ]/);
|
|
5935
|
+
const normalized = parts.map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("[-._ ]");
|
|
5936
|
+
const headingPattern = new RegExp(`(?:^#{2,4}\\s+Story\\s+${normalized}\\b|^Story\\s+${normalized}:|^\\*\\*${normalized}\\*\\*|^${normalized}:)`, "mi");
|
|
5916
5937
|
const match$2 = headingPattern.exec(shardContent);
|
|
5917
5938
|
if (!match$2) return null;
|
|
5918
5939
|
const startIdx = match$2.index;
|
|
5919
5940
|
const rest = shardContent.slice(startIdx + match$2[0].length);
|
|
5920
|
-
const nextStoryPattern = new RegExp(`(?:^#{2,4}\\s+Story\\s+[\\d]|^Story\\s+[\\d][\\d-]*:|^\\*\\*[\\d][\\d-]*\\*\\*|^[\\d][\\d-]*:)`, "mi");
|
|
5941
|
+
const nextStoryPattern = new RegExp(`(?:^#{2,4}\\s+Story\\s+[\\d]|^Story\\s+[\\d][\\d.\\-_a-z]*:|^\\*\\*[\\d][\\d.\\-_a-z]*\\*\\*|^[\\d][\\d.\\-_a-z]*:)`, "mi");
|
|
5921
5942
|
const nextMatch = nextStoryPattern.exec(rest);
|
|
5922
5943
|
const endIdx = nextMatch !== null ? startIdx + match$2[0].length + nextMatch.index : shardContent.length;
|
|
5923
5944
|
const section = shardContent.slice(startIdx, endIdx).trim();
|
|
@@ -10429,7 +10450,8 @@ function assembleVerificationContext(opts) {
|
|
|
10429
10450
|
reviewResult: opts.reviewResult,
|
|
10430
10451
|
storyContent: opts.storyContent,
|
|
10431
10452
|
devStoryResult: opts.devStoryResult,
|
|
10432
|
-
outputTokenCount: opts.outputTokenCount
|
|
10453
|
+
outputTokenCount: opts.outputTokenCount,
|
|
10454
|
+
sourceEpicContent: opts.sourceEpicContent
|
|
10433
10455
|
};
|
|
10434
10456
|
}
|
|
10435
10457
|
/**
|
|
@@ -11365,6 +11387,10 @@ function createImplementationOrchestrator(deps) {
|
|
|
11365
11387
|
let _costWarningEmitted = false;
|
|
11366
11388
|
let _budgetExhausted = false;
|
|
11367
11389
|
let _otlpEndpoint;
|
|
11390
|
+
let _shutdownRequested = false;
|
|
11391
|
+
let _inFlightCount = 0;
|
|
11392
|
+
let _drainResolve = null;
|
|
11393
|
+
let _drainPromise = Promise.resolve();
|
|
11368
11394
|
const verificationStore = new VerificationStore();
|
|
11369
11395
|
const verificationPipeline = createDefaultVerificationPipeline(toSdlcEventBus(eventBus));
|
|
11370
11396
|
const _stateStoreCache = new Map();
|
|
@@ -12002,6 +12028,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
12002
12028
|
startedAt: new Date().toISOString()
|
|
12003
12029
|
});
|
|
12004
12030
|
let storyFilePath;
|
|
12031
|
+
let sourceAcHash;
|
|
12005
12032
|
const artifactsDir = projectRoot ? join$1(projectRoot, "_bmad-output", "implementation-artifacts") : void 0;
|
|
12006
12033
|
if (artifactsDir && existsSync(artifactsDir)) try {
|
|
12007
12034
|
const files = readdirSync(artifactsDir);
|
|
@@ -12015,22 +12042,52 @@ function createImplementationOrchestrator(deps) {
|
|
|
12015
12042
|
reason: validation.reason
|
|
12016
12043
|
}, `Existing story file for ${storyKey} is invalid (${validation.reason}) — re-creating`);
|
|
12017
12044
|
else {
|
|
12018
|
-
|
|
12019
|
-
|
|
12020
|
-
|
|
12021
|
-
|
|
12022
|
-
|
|
12023
|
-
|
|
12024
|
-
|
|
12025
|
-
|
|
12026
|
-
|
|
12027
|
-
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
|
|
12045
|
+
let isDrift = false;
|
|
12046
|
+
try {
|
|
12047
|
+
const epicsPath = projectRoot ? findEpicsFile(projectRoot) : void 0;
|
|
12048
|
+
if (epicsPath !== void 0) {
|
|
12049
|
+
const epicContent = readFileSync(epicsPath, "utf-8");
|
|
12050
|
+
const sourceSection = extractStorySection(epicContent, storyKey);
|
|
12051
|
+
if (sourceSection != null) {
|
|
12052
|
+
const currentHash = hashSourceAcSection(sourceSection);
|
|
12053
|
+
sourceAcHash = currentHash;
|
|
12054
|
+
const artifactContent = await readFile$1(candidatePath, "utf-8");
|
|
12055
|
+
const hashMatch = /<!--\s*source-ac-hash:\s*([0-9a-f]{64})\s*-->/.exec(artifactContent);
|
|
12056
|
+
const storedHash = hashMatch?.[1] ?? null;
|
|
12057
|
+
if (storedHash !== currentHash) {
|
|
12058
|
+
isDrift = true;
|
|
12059
|
+
eventBus.emit("story:ac-source-drift", {
|
|
12060
|
+
storyKey,
|
|
12061
|
+
storedHash,
|
|
12062
|
+
currentHash
|
|
12063
|
+
});
|
|
12064
|
+
logger$24.info({
|
|
12065
|
+
storyKey,
|
|
12066
|
+
storedHash,
|
|
12067
|
+
currentHash
|
|
12068
|
+
}, `[orchestrator] story ${storyKey}: source AC hash mismatch, regenerating story artifact`);
|
|
12069
|
+
}
|
|
12070
|
+
}
|
|
12031
12071
|
}
|
|
12032
|
-
}
|
|
12033
|
-
|
|
12072
|
+
} catch {}
|
|
12073
|
+
if (!isDrift) {
|
|
12074
|
+
storyFilePath = candidatePath;
|
|
12075
|
+
logger$24.info({
|
|
12076
|
+
storyKey,
|
|
12077
|
+
storyFilePath
|
|
12078
|
+
}, "Found existing story file — skipping create-story");
|
|
12079
|
+
endPhase(storyKey, "create-story");
|
|
12080
|
+
eventBus.emit("orchestrator:story-phase-complete", {
|
|
12081
|
+
storyKey,
|
|
12082
|
+
phase: "IN_STORY_CREATION",
|
|
12083
|
+
result: {
|
|
12084
|
+
result: "success",
|
|
12085
|
+
story_file: storyFilePath,
|
|
12086
|
+
story_key: storyKey
|
|
12087
|
+
}
|
|
12088
|
+
});
|
|
12089
|
+
await persistState();
|
|
12090
|
+
}
|
|
12034
12091
|
}
|
|
12035
12092
|
}
|
|
12036
12093
|
} catch {}
|
|
@@ -12067,7 +12124,8 @@ function createImplementationOrchestrator(deps) {
|
|
|
12067
12124
|
}, {
|
|
12068
12125
|
epicId: storyKey.split("-")[0] ?? storyKey,
|
|
12069
12126
|
storyKey,
|
|
12070
|
-
pipelineRunId: config.pipelineRunId
|
|
12127
|
+
pipelineRunId: config.pipelineRunId,
|
|
12128
|
+
source_ac_hash: sourceAcHash
|
|
12071
12129
|
});
|
|
12072
12130
|
endPhase(storyKey, "create-story");
|
|
12073
12131
|
eventBus.emit("orchestrator:story-phase-complete", {
|
|
@@ -13258,13 +13316,21 @@ function createImplementationOrchestrator(deps) {
|
|
|
13258
13316
|
error: reviewResult.error,
|
|
13259
13317
|
rawOutput: reviewResult.rawOutput
|
|
13260
13318
|
} : void 0;
|
|
13319
|
+
let sourceEpicContent;
|
|
13320
|
+
const epicsPath1 = findEpicsFile(projectRoot ?? process.cwd());
|
|
13321
|
+
if (epicsPath1) try {
|
|
13322
|
+
const epicFull = readFileSync(epicsPath1, "utf-8");
|
|
13323
|
+
const section = extractStorySection(epicFull, storyKey);
|
|
13324
|
+
if (section) sourceEpicContent = section;
|
|
13325
|
+
} catch {}
|
|
13261
13326
|
const verifContext = assembleVerificationContext({
|
|
13262
13327
|
storyKey,
|
|
13263
13328
|
workingDir: projectRoot ?? process.cwd(),
|
|
13264
13329
|
reviewResult: latestReviewSignals,
|
|
13265
13330
|
storyContent: storyContentForVerification,
|
|
13266
13331
|
devStoryResult: devStorySignals,
|
|
13267
|
-
outputTokenCount: devOutputTokenCount
|
|
13332
|
+
outputTokenCount: devOutputTokenCount,
|
|
13333
|
+
sourceEpicContent
|
|
13268
13334
|
});
|
|
13269
13335
|
const verifSummary = await verificationPipeline.run(verifContext, "A");
|
|
13270
13336
|
verificationStore.set(storyKey, verifSummary);
|
|
@@ -13522,13 +13588,21 @@ function createImplementationOrchestrator(deps) {
|
|
|
13522
13588
|
error: reviewResult.error,
|
|
13523
13589
|
rawOutput: reviewResult.rawOutput
|
|
13524
13590
|
} : void 0;
|
|
13591
|
+
let sourceEpicContent2;
|
|
13592
|
+
const epicsPath2 = findEpicsFile(projectRoot ?? process.cwd());
|
|
13593
|
+
if (epicsPath2) try {
|
|
13594
|
+
const epicFull2 = readFileSync(epicsPath2, "utf-8");
|
|
13595
|
+
const section2 = extractStorySection(epicFull2, storyKey);
|
|
13596
|
+
if (section2) sourceEpicContent2 = section2;
|
|
13597
|
+
} catch {}
|
|
13525
13598
|
const verifContext = assembleVerificationContext({
|
|
13526
13599
|
storyKey,
|
|
13527
13600
|
workingDir: projectRoot ?? process.cwd(),
|
|
13528
13601
|
reviewResult: latestReviewSignals,
|
|
13529
13602
|
storyContent: storyContentForVerification,
|
|
13530
13603
|
devStoryResult: devStorySignals,
|
|
13531
|
-
outputTokenCount: devOutputTokenCount
|
|
13604
|
+
outputTokenCount: devOutputTokenCount,
|
|
13605
|
+
sourceEpicContent: sourceEpicContent2
|
|
13532
13606
|
});
|
|
13533
13607
|
const verifSummary = await verificationPipeline.run(verifContext, "A");
|
|
13534
13608
|
verificationStore.set(storyKey, verifSummary);
|
|
@@ -13880,6 +13954,10 @@ function createImplementationOrchestrator(deps) {
|
|
|
13880
13954
|
async function processConflictGroup(group) {
|
|
13881
13955
|
const completedStoryKeys = [];
|
|
13882
13956
|
for (const storyKey of group) {
|
|
13957
|
+
if (_shutdownRequested) {
|
|
13958
|
+
logger$24.info({ storyKey }, "shutdown requested — skipping dispatch");
|
|
13959
|
+
return;
|
|
13960
|
+
}
|
|
13883
13961
|
if (runManifest !== null && runManifest !== void 0) try {
|
|
13884
13962
|
const manifestData = await runManifest.read();
|
|
13885
13963
|
const ceiling = manifestData.cli_flags.cost_ceiling;
|
|
@@ -13938,11 +14016,15 @@ function createImplementationOrchestrator(deps) {
|
|
|
13938
14016
|
const running = new Set();
|
|
13939
14017
|
function enqueue() {
|
|
13940
14018
|
if (_budgetExhausted) return;
|
|
14019
|
+
if (_shutdownRequested) return;
|
|
13941
14020
|
const group = queue.shift();
|
|
13942
14021
|
if (group === void 0) return;
|
|
14022
|
+
_inFlightCount++;
|
|
13943
14023
|
const p = processConflictGroup(group).finally(() => {
|
|
13944
14024
|
running.delete(p);
|
|
13945
|
-
|
|
14025
|
+
_inFlightCount--;
|
|
14026
|
+
if (_inFlightCount === 0 && _shutdownRequested) _drainResolve?.();
|
|
14027
|
+
while (running.size < maxConcurrency && queue.length > 0 && !_shutdownRequested && !_budgetExhausted) enqueue();
|
|
13946
14028
|
});
|
|
13947
14029
|
running.add(p);
|
|
13948
14030
|
if (running.size > _maxConcurrentActual) _maxConcurrentActual = running.size;
|
|
@@ -13951,6 +14033,47 @@ function createImplementationOrchestrator(deps) {
|
|
|
13951
14033
|
for (let i = 0; i < initial; i++) enqueue();
|
|
13952
14034
|
while (running.size > 0) await Promise.race(running);
|
|
13953
14035
|
}
|
|
14036
|
+
/**
|
|
14037
|
+
* Gracefully shut down the pipeline in response to a POSIX signal.
|
|
14038
|
+
*
|
|
14039
|
+
* 1. Sets the in-memory `_shutdownRequested` flag so the dispatch loop stops
|
|
14040
|
+
* scheduling new stories.
|
|
14041
|
+
* 2. Awaits any in-flight dispatches for up to `config.shutdownGracePeriodMs` ms
|
|
14042
|
+
* (default 5000).
|
|
14043
|
+
* 3. Writes `run_status: 'stopped'` and `stopped_reason` to the run manifest.
|
|
14044
|
+
* 4. Best-effort: updates `pipeline_runs.status = 'stopped'` in Dolt and
|
|
14045
|
+
* transitions active wg_stories to 'cancelled'.
|
|
14046
|
+
* 5. Calls `process.exit(130)` for SIGINT or `process.exit(143)` for SIGTERM.
|
|
14047
|
+
*/
|
|
14048
|
+
async function shutdownGracefully(reason, signal) {
|
|
14049
|
+
if (_shutdownRequested) return;
|
|
14050
|
+
_shutdownRequested = true;
|
|
14051
|
+
logger$24.info({
|
|
14052
|
+
reason,
|
|
14053
|
+
signal
|
|
14054
|
+
}, "Graceful shutdown initiated");
|
|
14055
|
+
const gracePeriod = config.shutdownGracePeriodMs ?? 5e3;
|
|
14056
|
+
if (_inFlightCount === 0) _drainResolve?.();
|
|
14057
|
+
await Promise.race([_drainPromise, new Promise((resolve$6) => setTimeout(resolve$6, gracePeriod))]);
|
|
14058
|
+
if (runManifest !== null && runManifest !== void 0) await runManifest.patchRunStatus({
|
|
14059
|
+
run_status: "stopped",
|
|
14060
|
+
stopped_reason: reason,
|
|
14061
|
+
stopped_at: new Date().toISOString()
|
|
14062
|
+
}).catch((err) => logger$24.warn({ err }, "patchRunStatus failed during shutdown (best-effort)"));
|
|
14063
|
+
if (config.pipelineRunId !== void 0) try {
|
|
14064
|
+
await updatePipelineRun(db, config.pipelineRunId, { status: "stopped" });
|
|
14065
|
+
} catch (err) {
|
|
14066
|
+
logger$24.warn({ err }, "updatePipelineRun(stopped) failed during shutdown (best-effort)");
|
|
14067
|
+
}
|
|
14068
|
+
for (const [storyKey, storyState] of _stories) {
|
|
14069
|
+
const isActive = storyState.phase === "PENDING" || storyState.phase === "IN_STORY_CREATION" || storyState.phase === "IN_TEST_PLANNING" || storyState.phase === "IN_DEV" || storyState.phase === "IN_REVIEW" || storyState.phase === "NEEDS_FIXES" || storyState.phase === "CHECKPOINT";
|
|
14070
|
+
if (isActive) wgRepo.updateStoryStatus(storyKey, "cancelled").catch((err) => logger$24.warn({
|
|
14071
|
+
err,
|
|
14072
|
+
storyKey
|
|
14073
|
+
}, "updateStoryStatus(cancelled) failed during shutdown (best-effort)"));
|
|
14074
|
+
}
|
|
14075
|
+
process.exit(signal === "SIGINT" ? 130 : 143);
|
|
14076
|
+
}
|
|
13954
14077
|
async function run(storyKeys) {
|
|
13955
14078
|
if (_state === "RUNNING" || _state === "PAUSED") {
|
|
13956
14079
|
logger$24.warn({ state: _state }, "run() called while orchestrator is already running or paused — ignoring");
|
|
@@ -13962,6 +14085,20 @@ function createImplementationOrchestrator(deps) {
|
|
|
13962
14085
|
}
|
|
13963
14086
|
_state = "RUNNING";
|
|
13964
14087
|
_startedAt = new Date().toISOString();
|
|
14088
|
+
_shutdownRequested = false;
|
|
14089
|
+
_inFlightCount = 0;
|
|
14090
|
+
_drainResolve = null;
|
|
14091
|
+
_drainPromise = new Promise((resolve$6) => {
|
|
14092
|
+
_drainResolve = resolve$6;
|
|
14093
|
+
});
|
|
14094
|
+
const sigtermHandler = () => {
|
|
14095
|
+
shutdownGracefully("killed_by_user", "SIGTERM");
|
|
14096
|
+
};
|
|
14097
|
+
const sigintHandler = () => {
|
|
14098
|
+
shutdownGracefully("killed_by_user", "SIGINT");
|
|
14099
|
+
};
|
|
14100
|
+
process.on("SIGTERM", sigtermHandler);
|
|
14101
|
+
process.on("SIGINT", sigintHandler);
|
|
13965
14102
|
for (const key of storyKeys) {
|
|
13966
14103
|
const pendingState = {
|
|
13967
14104
|
phase: "PENDING",
|
|
@@ -14246,6 +14383,8 @@ function createImplementationOrchestrator(deps) {
|
|
|
14246
14383
|
await persistState();
|
|
14247
14384
|
return getStatus();
|
|
14248
14385
|
} finally {
|
|
14386
|
+
process.off("SIGTERM", sigtermHandler);
|
|
14387
|
+
process.off("SIGINT", sigintHandler);
|
|
14249
14388
|
if (stateStore !== void 0) await stateStore.close().catch((err) => logger$24.warn({ err }, "StateStore.close() failed (best-effort)"));
|
|
14250
14389
|
if (ingestionServer !== void 0) await ingestionServer.stop().catch((err) => logger$24.warn({ err }, "IngestionServer.stop() failed (best-effort)"));
|
|
14251
14390
|
}
|
|
@@ -43840,4 +43979,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
43840
43979
|
|
|
43841
43980
|
//#endregion
|
|
43842
43981
|
export { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, normalizeGraphSummaryToStatus, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveMaxReviewCycles, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict, wireNdjsonEmitter };
|
|
43843
|
-
//# sourceMappingURL=run-
|
|
43982
|
+
//# sourceMappingURL=run-D5VAkItq.js.map
|