@nathapp/nax 0.73.4 → 0.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/nax.js +1254 -529
- package/flows/nax-finish/errors.ts +23 -0
- package/flows/nax-finish/exec.ts +70 -0
- package/flows/nax-finish/nax-finish.flow.ts +330 -0
- package/flows/nax-finish/review-prompts.ts +344 -0
- package/flows/nax-finish/steps/acceptance.ts +53 -0
- package/flows/nax-finish/steps/context.ts +64 -0
- package/flows/nax-finish/steps/escalate.ts +93 -0
- package/flows/nax-finish/steps/forge.ts +44 -0
- package/flows/nax-finish/steps/git.ts +73 -0
- package/flows/nax-finish/steps/index.ts +8 -0
- package/flows/nax-finish/steps/pr.ts +71 -0
- package/flows/nax-finish/steps/quality.ts +93 -0
- package/flows/nax-finish/steps/result.ts +15 -0
- package/flows/nax-finish/types.ts +59 -0
- package/package.json +6 -4
package/dist/nax.js
CHANGED
|
@@ -17787,6 +17787,40 @@ var init_schemas3 = __esm(() => {
|
|
|
17787
17787
|
enabled: exports_external.boolean().default(false),
|
|
17788
17788
|
draft: exports_external.boolean().default(true)
|
|
17789
17789
|
}).optional().default({ enabled: false, draft: true }),
|
|
17790
|
+
finish: exports_external.object({
|
|
17791
|
+
autoFlow: exports_external.object({
|
|
17792
|
+
enabled: exports_external.boolean().default(false),
|
|
17793
|
+
flowPath: exports_external.string().default("flows/nax-finish/nax-finish.flow.ts"),
|
|
17794
|
+
defaultAgent: exports_external.string().nullable().default(null),
|
|
17795
|
+
reviewers: exports_external.object({
|
|
17796
|
+
spec: exports_external.string().nullable().default(null),
|
|
17797
|
+
quality: exports_external.string().nullable().default(null)
|
|
17798
|
+
}).default({ spec: null, quality: null }),
|
|
17799
|
+
escalate: exports_external.object({ telegram: exports_external.boolean().default(true) }).default({ telegram: true }),
|
|
17800
|
+
timeouts: exports_external.object({
|
|
17801
|
+
acceptanceMs: exports_external.number().int().positive().default(600000),
|
|
17802
|
+
gateMs: exports_external.number().int().positive().default(900000),
|
|
17803
|
+
flowMs: exports_external.number().int().positive().default(5400000),
|
|
17804
|
+
stepMs: exports_external.number().int().positive().nullable().default(null)
|
|
17805
|
+
}).default({ acceptanceMs: 600000, gateMs: 900000, flowMs: 5400000, stepMs: null })
|
|
17806
|
+
}).default({
|
|
17807
|
+
enabled: false,
|
|
17808
|
+
flowPath: "flows/nax-finish/nax-finish.flow.ts",
|
|
17809
|
+
defaultAgent: null,
|
|
17810
|
+
reviewers: { spec: null, quality: null },
|
|
17811
|
+
escalate: { telegram: true },
|
|
17812
|
+
timeouts: { acceptanceMs: 600000, gateMs: 900000, flowMs: 5400000, stepMs: null }
|
|
17813
|
+
})
|
|
17814
|
+
}).default({
|
|
17815
|
+
autoFlow: {
|
|
17816
|
+
enabled: false,
|
|
17817
|
+
flowPath: "flows/nax-finish/nax-finish.flow.ts",
|
|
17818
|
+
defaultAgent: null,
|
|
17819
|
+
reviewers: { spec: null, quality: null },
|
|
17820
|
+
escalate: { telegram: true },
|
|
17821
|
+
timeouts: { acceptanceMs: 600000, gateMs: 900000, flowMs: 5400000, stepMs: null }
|
|
17822
|
+
}
|
|
17823
|
+
}),
|
|
17790
17824
|
reporters: ReportersConfigSchema,
|
|
17791
17825
|
profile: exports_external.string().default("default"),
|
|
17792
17826
|
profileChain: exports_external.array(exports_external.string()).default([])
|
|
@@ -19476,7 +19510,7 @@ function reshapeSelector(name, fn) {
|
|
|
19476
19510
|
}
|
|
19477
19511
|
|
|
19478
19512
|
// src/config/selectors.ts
|
|
19479
|
-
var reviewConfigSelector, planConfigSelector, decomposeConfigSelector, rectifyConfigSelector, acceptanceConfigSelector, acceptanceFixConfigSelector, acceptanceGenConfigSelector, tddConfigSelector, debateConfigSelector, routingConfigSelector, verifyConfigSelector, mutationCheckConfigSelector, rectificationGateConfigSelector, agentConfigSelector, agentManagerConfigSelector, interactionConfigSelector, precheckConfigSelector, qualityConfigSelector, autofixConfigSelector, executionGatesConfigSelector, testPatternConfigSelector, contextConfigSelector, contextToolRuntimeConfigSelector, promptLoaderConfigSelector, llmRoutingConfigSelector;
|
|
19513
|
+
var reviewConfigSelector, planConfigSelector, decomposeConfigSelector, rectifyConfigSelector, acceptanceConfigSelector, acceptanceFixConfigSelector, acceptanceGenConfigSelector, tddConfigSelector, debateConfigSelector, routingConfigSelector, verifyConfigSelector, mutationCheckConfigSelector, rectificationGateConfigSelector, agentConfigSelector, agentManagerConfigSelector, interactionConfigSelector, precheckConfigSelector, qualityConfigSelector, autofixConfigSelector, executionGatesConfigSelector, testPatternConfigSelector, contextConfigSelector, contextToolRuntimeConfigSelector, promptLoaderConfigSelector, llmRoutingConfigSelector, finishConfigSelector;
|
|
19480
19514
|
var init_selectors = __esm(() => {
|
|
19481
19515
|
reviewConfigSelector = pickSelector("review", "review", "debate", "models", "execution", "project", "quality", "agent");
|
|
19482
19516
|
planConfigSelector = pickSelector("plan", "plan", "debate", "agent", "project", "routing");
|
|
@@ -19506,6 +19540,7 @@ var init_selectors = __esm(() => {
|
|
|
19506
19540
|
contextToolRuntimeConfigSelector = pickSelector("context-tool-runtime", "context", "execution", "project", "quality");
|
|
19507
19541
|
promptLoaderConfigSelector = pickSelector("prompt-loader", "prompts", "context", "project");
|
|
19508
19542
|
llmRoutingConfigSelector = pickSelector("llm-routing", "routing", "models", "agent", "tdd", "execution", "precheck");
|
|
19543
|
+
finishConfigSelector = pickSelector("finish", "finish", "interaction", "quality");
|
|
19509
19544
|
});
|
|
19510
19545
|
|
|
19511
19546
|
// src/config/loader-runtime.ts
|
|
@@ -19649,7 +19684,8 @@ When a spec is provided, these rules govern acceptance criteria generation:
|
|
|
19649
19684
|
3. **Respect story scope.** Each story's criteria must only cover what the spec says for that story. Do not assign criteria that belong to a different story's scope (wrong feature area, wrong file, wrong dependency chain).
|
|
19650
19685
|
4. **\`suggestedCriteria\` format.** Each element must be a plain behavioral assertion \u2014 an observable output, return value, state change, or error condition that a test can assert. Never include implementation details (imports, internal structure), design suggestions, or vague descriptions.
|
|
19651
19686
|
5. **Enumerate failure-mode tables.** If the spec contains a "Failure handling", "Error handling", "Failure modes", or equivalent table/section enumerating error/exception scenarios, every row MUST produce at least one acceptance criterion in the matching story. Walk the table row by row; do not skip rows because they look minor. A failure-mode row without an AC is treated as a missing AC and will cause rejection.
|
|
19652
|
-
6. **
|
|
19687
|
+
6. **Preserve the spec's out-of-scope statements.** If the spec has an "Out of Scope", "Non-Goals", or "Not in scope" section \u2014 or an inline \`**Out of scope \u2026:**\` lead-in \u2014 copy every item **verbatim** into the top-level \`outOfScope\` string array. This is what the feature deliberately does NOT do; it is the only channel by which a deferred arc reaches the implementer, which never sees the spec. Never drop an item, never merge two into one, and never turn one into an acceptance criterion. Echo an item into a story's \`**Scope** \u2014 Out:\` bullet as well whenever that story sits close enough to the boundary that an implementer might stray across it. Omit \`outOfScope\` only when the spec declares nothing.
|
|
19688
|
+
7. **Resolve internal spec contradictions toward the AC.** If the spec's prose, design table, or interface block contradicts a stated acceptance criterion (e.g. design table says \`lookback or strategy_lookback\` but the AC says \`lookback=None\`), the AC is authoritative. Implement the AC; do NOT echo the contradicting prose into the description.`, DESCRIPTION_QUALITY_RULES = `## Description Quality Rules
|
|
19653
19689
|
|
|
19654
19690
|
When a spec contains a design subsection for a story (e.g. \`### N. <Topic>\` under \`## Design\`), the story description MUST embed that subsection's interface declarations, algorithms, and design notes verbatim.
|
|
19655
19691
|
|
|
@@ -19666,6 +19702,7 @@ When a spec contains a design subsection for a story (e.g. \`### N. <Topic>\` un
|
|
|
19666
19702
|
### Rules
|
|
19667
19703
|
|
|
19668
19704
|
1. Do NOT paraphrase spec design sections \u2014 embed them verbatim.
|
|
19705
|
+
1a. \`**Scope** \u2014 Out:\` states *inter-story* boundaries \u2014 work that belongs to a different story in this PRD. Feature-level exclusions (what the whole feature defers) belong in the top-level \`outOfScope\` array, not here. List an item in both places when this story sits close enough to a feature-level boundary that an implementer might stray across it.
|
|
19669
19706
|
2. A one-sentence description is almost always too short for implementation stories that have spec design content.
|
|
19670
19707
|
3. The implementer receives only this description \u2014 no access to the spec. Design decisions lost here are permanently invisible to the implementer.
|
|
19671
19708
|
4. **Self-check before emitting.** After drafting each description, re-read it against the story's \`acceptanceCriteria\`. If any sentence in the description contradicts an AC (e.g. description says behaviour X, AC says behaviour not-X), the description is wrong \u2014 rewrite the offending sentence to match the AC, or delete it. The AC is authoritative. Embedding contradicting spec prose verbatim still counts as a contradiction; resolve it.
|
|
@@ -19784,6 +19821,7 @@ __export(exports_config, {
|
|
|
19784
19821
|
globalConfigPath: () => globalConfigPath,
|
|
19785
19822
|
globalConfigDir: () => globalConfigDir,
|
|
19786
19823
|
getAcQualityRules: () => getAcQualityRules,
|
|
19824
|
+
finishConfigSelector: () => finishConfigSelector,
|
|
19787
19825
|
findProjectDir: () => findProjectDir,
|
|
19788
19826
|
executionGatesConfigSelector: () => executionGatesConfigSelector,
|
|
19789
19827
|
deepMergeConfig: () => deepMergeConfig,
|
|
@@ -28368,6 +28406,247 @@ var init_static_rules = __esm(() => {
|
|
|
28368
28406
|
LEGACY_CANDIDATE_FILES = ["CLAUDE.md", ".cursorrules", "AGENTS.md"];
|
|
28369
28407
|
});
|
|
28370
28408
|
|
|
28409
|
+
// src/prd/out-of-scope.ts
|
|
28410
|
+
function stripEmphasis(text) {
|
|
28411
|
+
return text.replace(/\*\*/g, "").replace(/[*`_]/g, "");
|
|
28412
|
+
}
|
|
28413
|
+
function outOfScopeHeadingLevel(line, nextLine) {
|
|
28414
|
+
const atx = stripEmphasis(line).match(OUT_OF_SCOPE_HEADING);
|
|
28415
|
+
if (atx)
|
|
28416
|
+
return atx[1].length;
|
|
28417
|
+
if (nextLine !== undefined && SETEXT_UNDERLINE.test(nextLine)) {
|
|
28418
|
+
const title = stripEmphasis(line).trim().replace(/:$/, "");
|
|
28419
|
+
if (OUT_OF_SCOPE_TITLE.test(title))
|
|
28420
|
+
return nextLine.trim().startsWith("=") ? 1 : 2;
|
|
28421
|
+
}
|
|
28422
|
+
return null;
|
|
28423
|
+
}
|
|
28424
|
+
function isSetextUnderline(lines, index) {
|
|
28425
|
+
if (!SETEXT_UNDERLINE.test(lines[index]))
|
|
28426
|
+
return false;
|
|
28427
|
+
const prev = lines[index - 1];
|
|
28428
|
+
return prev !== undefined && prev.trim().length > 0 && !ANY_HEADING.test(prev);
|
|
28429
|
+
}
|
|
28430
|
+
function canonical(text) {
|
|
28431
|
+
return text.replace(/`/g, "").replace(/\s+/g, " ").trim().toLowerCase();
|
|
28432
|
+
}
|
|
28433
|
+
function stripBullet(line) {
|
|
28434
|
+
return line.replace(LIST_ITEM_START, "").trim();
|
|
28435
|
+
}
|
|
28436
|
+
function sectionLines(lines, startIndex, level) {
|
|
28437
|
+
const collected = [];
|
|
28438
|
+
let inFence = false;
|
|
28439
|
+
for (let i = startIndex + 1;i < lines.length; i++) {
|
|
28440
|
+
const line = lines[i];
|
|
28441
|
+
if (FENCE.test(line)) {
|
|
28442
|
+
inFence = !inFence;
|
|
28443
|
+
continue;
|
|
28444
|
+
}
|
|
28445
|
+
if (inFence)
|
|
28446
|
+
continue;
|
|
28447
|
+
const heading = line.match(ANY_HEADING);
|
|
28448
|
+
if (heading && (heading[1].length <= level || level === 1))
|
|
28449
|
+
break;
|
|
28450
|
+
if (heading) {
|
|
28451
|
+
collected.push("");
|
|
28452
|
+
continue;
|
|
28453
|
+
}
|
|
28454
|
+
if (isSetextUnderline(lines, i)) {
|
|
28455
|
+
const setextLevel = line.trim().startsWith("=") ? 1 : 2;
|
|
28456
|
+
if (setextLevel <= level) {
|
|
28457
|
+
collected.pop();
|
|
28458
|
+
break;
|
|
28459
|
+
}
|
|
28460
|
+
collected.pop();
|
|
28461
|
+
continue;
|
|
28462
|
+
}
|
|
28463
|
+
collected.push(line);
|
|
28464
|
+
}
|
|
28465
|
+
return collected;
|
|
28466
|
+
}
|
|
28467
|
+
function itemsFromSection(body) {
|
|
28468
|
+
const items = [];
|
|
28469
|
+
let current = [];
|
|
28470
|
+
const flush = () => {
|
|
28471
|
+
const text = current.join(" ").replace(INLINE_MARKER, "").replace(/\s+/g, " ").trim();
|
|
28472
|
+
if (text)
|
|
28473
|
+
items.push(text);
|
|
28474
|
+
current = [];
|
|
28475
|
+
};
|
|
28476
|
+
const hasBullets = body.some((line) => LIST_ITEM_START.test(line));
|
|
28477
|
+
for (const [index, line] of body.entries()) {
|
|
28478
|
+
if (line.trim().length === 0) {
|
|
28479
|
+
flush();
|
|
28480
|
+
continue;
|
|
28481
|
+
}
|
|
28482
|
+
if (TABLE_ROW.test(line) && TABLE_SEPARATOR.test(body[index + 1] ?? ""))
|
|
28483
|
+
continue;
|
|
28484
|
+
if (TABLE_SEPARATOR.test(line))
|
|
28485
|
+
continue;
|
|
28486
|
+
if (TABLE_ROW.test(line)) {
|
|
28487
|
+
flush();
|
|
28488
|
+
const cells = line.trim().replace(/^\||\|$/g, "").split("|").map((c) => c.trim()).filter((c) => c.length > 0);
|
|
28489
|
+
if (cells.length > 0)
|
|
28490
|
+
current.push(cells.join(" \u2014 "));
|
|
28491
|
+
flush();
|
|
28492
|
+
continue;
|
|
28493
|
+
}
|
|
28494
|
+
if (hasBullets && LIST_ITEM_START.test(line)) {
|
|
28495
|
+
flush();
|
|
28496
|
+
current.push(stripBullet(line));
|
|
28497
|
+
continue;
|
|
28498
|
+
}
|
|
28499
|
+
current.push(line.trim());
|
|
28500
|
+
}
|
|
28501
|
+
flush();
|
|
28502
|
+
return items;
|
|
28503
|
+
}
|
|
28504
|
+
function fencedLineIndices(lines) {
|
|
28505
|
+
const fenced = new Set;
|
|
28506
|
+
let inFence = false;
|
|
28507
|
+
for (const [i, line] of lines.entries()) {
|
|
28508
|
+
if (FENCE.test(line)) {
|
|
28509
|
+
fenced.add(i);
|
|
28510
|
+
inFence = !inFence;
|
|
28511
|
+
continue;
|
|
28512
|
+
}
|
|
28513
|
+
if (inFence)
|
|
28514
|
+
fenced.add(i);
|
|
28515
|
+
}
|
|
28516
|
+
return fenced;
|
|
28517
|
+
}
|
|
28518
|
+
function itemsFromInlineMarkers(lines, fenced, boundary) {
|
|
28519
|
+
const items = [];
|
|
28520
|
+
for (let i = 0;i < boundary; i++) {
|
|
28521
|
+
if (fenced.has(i) || !INLINE_MARKER.test(lines[i]))
|
|
28522
|
+
continue;
|
|
28523
|
+
const remainder = lines[i].replace(INLINE_MARKER, "").trim();
|
|
28524
|
+
let j = i + 1;
|
|
28525
|
+
if (remainder.length === 0) {
|
|
28526
|
+
const body = [];
|
|
28527
|
+
while (j < lines.length && !fenced.has(j) && lines[j].trim().length > 0 && !ANY_HEADING.test(lines[j])) {
|
|
28528
|
+
body.push(lines[j]);
|
|
28529
|
+
j += 1;
|
|
28530
|
+
}
|
|
28531
|
+
items.push(...itemsFromSection(body));
|
|
28532
|
+
i = j - 1;
|
|
28533
|
+
continue;
|
|
28534
|
+
}
|
|
28535
|
+
const parts = [remainder];
|
|
28536
|
+
while (j < lines.length && !fenced.has(j) && lines[j].trim().length > 0 && !ANY_HEADING.test(lines[j]) && !LIST_ITEM_START.test(lines[j])) {
|
|
28537
|
+
parts.push(lines[j].trim());
|
|
28538
|
+
j += 1;
|
|
28539
|
+
}
|
|
28540
|
+
const text = parts.join(" ").replace(/\s+/g, " ").trim();
|
|
28541
|
+
if (text)
|
|
28542
|
+
items.push(text);
|
|
28543
|
+
i = j - 1;
|
|
28544
|
+
}
|
|
28545
|
+
return items;
|
|
28546
|
+
}
|
|
28547
|
+
function isListLeadIn(item) {
|
|
28548
|
+
return item.trimEnd().endsWith(":");
|
|
28549
|
+
}
|
|
28550
|
+
function dedupeAndCap(items) {
|
|
28551
|
+
const seen = new Set;
|
|
28552
|
+
const out = [];
|
|
28553
|
+
for (const item of items) {
|
|
28554
|
+
const key = canonical(item);
|
|
28555
|
+
if (EMPTY_SENTINELS.has(key) || isListLeadIn(item))
|
|
28556
|
+
continue;
|
|
28557
|
+
if (key.length === 0 || seen.has(key))
|
|
28558
|
+
continue;
|
|
28559
|
+
seen.add(key);
|
|
28560
|
+
out.push(item);
|
|
28561
|
+
if (out.length >= MAX_OUT_OF_SCOPE_ITEMS)
|
|
28562
|
+
break;
|
|
28563
|
+
}
|
|
28564
|
+
return out;
|
|
28565
|
+
}
|
|
28566
|
+
function storyScopeBoundary(lines) {
|
|
28567
|
+
const index = lines.findIndex((line) => STORY_SECTION_HEADING.test(stripEmphasis(line)));
|
|
28568
|
+
return index === -1 ? lines.length : index;
|
|
28569
|
+
}
|
|
28570
|
+
function normalizeOutOfScopeList(raw) {
|
|
28571
|
+
if (!Array.isArray(raw))
|
|
28572
|
+
return;
|
|
28573
|
+
const strings = raw.filter((item) => typeof item === "string" && item.trim().length > 0);
|
|
28574
|
+
const items = dedupeAndCap(strings.map((item) => item.trim()));
|
|
28575
|
+
return items.length > 0 ? items : undefined;
|
|
28576
|
+
}
|
|
28577
|
+
function extractSpecOutOfScope(specContent) {
|
|
28578
|
+
if (!specContent.trim())
|
|
28579
|
+
return [];
|
|
28580
|
+
const lines = specContent.split(`
|
|
28581
|
+
`);
|
|
28582
|
+
const fenced = fencedLineIndices(lines);
|
|
28583
|
+
const boundary = storyScopeBoundary(lines);
|
|
28584
|
+
const items = [];
|
|
28585
|
+
for (let i = 0;i < lines.length; i++) {
|
|
28586
|
+
if (fenced.has(i))
|
|
28587
|
+
continue;
|
|
28588
|
+
const level = outOfScopeHeadingLevel(lines[i], lines[i + 1]);
|
|
28589
|
+
if (level === null)
|
|
28590
|
+
continue;
|
|
28591
|
+
if (level > 2 && i > boundary)
|
|
28592
|
+
continue;
|
|
28593
|
+
const bodyStart = SETEXT_UNDERLINE.test(lines[i + 1] ?? "") ? i + 1 : i;
|
|
28594
|
+
items.push(...itemsFromSection(sectionLines(lines, bodyStart, level)));
|
|
28595
|
+
}
|
|
28596
|
+
items.push(...itemsFromInlineMarkers(lines, fenced, boundary));
|
|
28597
|
+
return dedupeAndCap(items);
|
|
28598
|
+
}
|
|
28599
|
+
function findMissingOutOfScope(specContent, prd) {
|
|
28600
|
+
const declared = extractSpecOutOfScope(specContent);
|
|
28601
|
+
if (declared.length === 0)
|
|
28602
|
+
return [];
|
|
28603
|
+
const present = (prd.outOfScope ?? []).map(canonical);
|
|
28604
|
+
return declared.filter((item) => !present.some((entry) => entry.includes(canonical(item))));
|
|
28605
|
+
}
|
|
28606
|
+
function applyOutOfScopeFallback(prd, specContent) {
|
|
28607
|
+
const missing = findMissingOutOfScope(specContent, prd);
|
|
28608
|
+
if (missing.length === 0)
|
|
28609
|
+
return prd;
|
|
28610
|
+
return { ...prd, outOfScope: dedupeAndCap([...missing, ...prd.outOfScope ?? []]) };
|
|
28611
|
+
}
|
|
28612
|
+
function propagateOutOfScopeToStories(prd) {
|
|
28613
|
+
const featureLevel = prd.outOfScope ?? [];
|
|
28614
|
+
if (featureLevel.length === 0)
|
|
28615
|
+
return prd;
|
|
28616
|
+
const userStories = prd.userStories.map((story) => ({
|
|
28617
|
+
...story,
|
|
28618
|
+
outOfScope: dedupeAndCap([...featureLevel, ...story.outOfScope ?? []])
|
|
28619
|
+
}));
|
|
28620
|
+
return { ...prd, userStories };
|
|
28621
|
+
}
|
|
28622
|
+
function stripPropagatedOutOfScope(prd) {
|
|
28623
|
+
const featureLevel = new Set((prd.outOfScope ?? []).map(canonical));
|
|
28624
|
+
if (featureLevel.size === 0)
|
|
28625
|
+
return prd;
|
|
28626
|
+
if (!prd.userStories.some((story) => (story.outOfScope ?? []).length > 0))
|
|
28627
|
+
return prd;
|
|
28628
|
+
const userStories = prd.userStories.map((story) => {
|
|
28629
|
+
const specific = (story.outOfScope ?? []).filter((item) => !featureLevel.has(canonical(item)));
|
|
28630
|
+
const { outOfScope: _dropped, ...rest } = story;
|
|
28631
|
+
return specific.length > 0 ? { ...rest, outOfScope: specific } : rest;
|
|
28632
|
+
});
|
|
28633
|
+
return { ...prd, userStories };
|
|
28634
|
+
}
|
|
28635
|
+
var MAX_OUT_OF_SCOPE_ITEMS = 25, OUT_OF_SCOPE_TITLE, OUT_OF_SCOPE_HEADING, ANY_HEADING, FENCE, TABLE_SEPARATOR, TABLE_ROW, STORY_SECTION_HEADING, SETEXT_UNDERLINE, INLINE_MARKER, LIST_ITEM_START, EMPTY_SENTINELS;
|
|
28636
|
+
var init_out_of_scope = __esm(() => {
|
|
28637
|
+
OUT_OF_SCOPE_TITLE = /^(?:out[\s-]?of[\s-]?scope|non[\s-]?goals?|not[\s-]in[\s-]scope)\b/i;
|
|
28638
|
+
OUT_OF_SCOPE_HEADING = /^(#{1,6})\s*(?:out[\s-]?of[\s-]?scope|non[\s-]?goals?|not[\s-]in[\s-]scope)\b/i;
|
|
28639
|
+
ANY_HEADING = /^(#{1,6})\s/;
|
|
28640
|
+
FENCE = /^\s*(?:```|~~~)/;
|
|
28641
|
+
TABLE_SEPARATOR = /^\s*\|?[\s:|-]+\|[\s:|-]*$/;
|
|
28642
|
+
TABLE_ROW = /^\s*\|.*\|\s*$/;
|
|
28643
|
+
STORY_SECTION_HEADING = /^#{1,3}\s*(?:stories|acceptance\s+criteria|user\s+stories)\b/i;
|
|
28644
|
+
SETEXT_UNDERLINE = /^\s*(?:=+|-+)\s*$/;
|
|
28645
|
+
INLINE_MARKER = /^\s*(?:[-*]\s*)?\*\*\s*(?:out[\s-]?of[\s-]?scope|non[\s-]?goals?)[^*]*\*\*\s*:?\s*/i;
|
|
28646
|
+
LIST_ITEM_START = /^\s*(?:[-*+\u2022\u2023\u25E6\u2043\u2219]|\d+\.)\s+/;
|
|
28647
|
+
EMPTY_SENTINELS = new Set(["none", "none.", "n/a", "na", "nothing", "nothing.", "tbd", "-"]);
|
|
28648
|
+
});
|
|
28649
|
+
|
|
28371
28650
|
// src/prd/types.ts
|
|
28372
28651
|
function getContextFiles(story) {
|
|
28373
28652
|
const legacyFiles = story.relevantFiles;
|
|
@@ -28425,7 +28704,7 @@ function normalizeWs(text) {
|
|
|
28425
28704
|
function stripBackticks(text) {
|
|
28426
28705
|
return text.replace(/`/g, "");
|
|
28427
28706
|
}
|
|
28428
|
-
function
|
|
28707
|
+
function canonical2(text) {
|
|
28429
28708
|
return normalizeWs(stripBackticks(text));
|
|
28430
28709
|
}
|
|
28431
28710
|
function leadingTagGroup(line) {
|
|
@@ -28440,7 +28719,7 @@ function isContinuation(line) {
|
|
|
28440
28719
|
return false;
|
|
28441
28720
|
if (HEADING.test(line))
|
|
28442
28721
|
return false;
|
|
28443
|
-
if (
|
|
28722
|
+
if (LIST_ITEM_START2.test(line))
|
|
28444
28723
|
return false;
|
|
28445
28724
|
return true;
|
|
28446
28725
|
}
|
|
@@ -28466,13 +28745,13 @@ function extractVerbatimAcs(specContent) {
|
|
|
28466
28745
|
return blocks;
|
|
28467
28746
|
}
|
|
28468
28747
|
function prdAcPayloads(prd) {
|
|
28469
|
-
return (prd.userStories ?? []).flatMap((story) => (story.acceptanceCriteria ?? []).map(
|
|
28748
|
+
return (prd.userStories ?? []).flatMap((story) => (story.acceptanceCriteria ?? []).map(canonical2));
|
|
28470
28749
|
}
|
|
28471
28750
|
function findMissingVerbatimAcs(specContent, prd) {
|
|
28472
28751
|
const prdAcs = prdAcPayloads(prd);
|
|
28473
28752
|
const missing = [];
|
|
28474
28753
|
for (const block of extractVerbatimAcs(specContent)) {
|
|
28475
|
-
const payload =
|
|
28754
|
+
const payload = canonical2(stripTagPrefix(block));
|
|
28476
28755
|
if (payload.length === 0)
|
|
28477
28756
|
continue;
|
|
28478
28757
|
if (!prdAcs.some((ac) => ac.includes(payload)))
|
|
@@ -28480,10 +28759,10 @@ function findMissingVerbatimAcs(specContent, prd) {
|
|
|
28480
28759
|
}
|
|
28481
28760
|
return missing;
|
|
28482
28761
|
}
|
|
28483
|
-
var LEADING_TAG_GROUP,
|
|
28762
|
+
var LEADING_TAG_GROUP, LIST_ITEM_START2, HEADING;
|
|
28484
28763
|
var init_verbatim_fidelity = __esm(() => {
|
|
28485
28764
|
LEADING_TAG_GROUP = /^\s*(?:[-*]|\d+\.)?\s*((?:\[[a-z][a-z-]*\]\s*)+)/i;
|
|
28486
|
-
|
|
28765
|
+
LIST_ITEM_START2 = /^\s*(?:[-*]|\d+\.)\s/;
|
|
28487
28766
|
HEADING = /^\s*#/;
|
|
28488
28767
|
});
|
|
28489
28768
|
|
|
@@ -28699,6 +28978,7 @@ function validateStory(raw, index, allIds) {
|
|
|
28699
28978
|
suggestedCriteria = coerced;
|
|
28700
28979
|
}
|
|
28701
28980
|
}
|
|
28981
|
+
const storyOutOfScope = normalizeOutOfScopeList(s.outOfScope);
|
|
28702
28982
|
const routing = typeof s.routing === "object" && s.routing !== null ? s.routing : {};
|
|
28703
28983
|
const rawComplexity = routing.complexity ?? s.complexity;
|
|
28704
28984
|
if (rawComplexity === undefined || rawComplexity === null) {
|
|
@@ -28839,6 +29119,7 @@ function validateStory(raw, index, allIds) {
|
|
|
28839
29119
|
...contextFiles.length > 0 ? { contextFiles } : {},
|
|
28840
29120
|
...expectedFiles.length > 0 ? { expectedFiles } : {},
|
|
28841
29121
|
...suggestedCriteria !== undefined ? { suggestedCriteria } : {},
|
|
29122
|
+
...storyOutOfScope !== undefined ? { outOfScope: storyOutOfScope } : {},
|
|
28842
29123
|
...verifiedBy !== undefined ? { verifiedBy } : {},
|
|
28843
29124
|
...intent !== undefined ? { intent } : {}
|
|
28844
29125
|
};
|
|
@@ -28893,6 +29174,7 @@ function validatePlanOutput(raw, feature, branch) {
|
|
|
28893
29174
|
}
|
|
28894
29175
|
const userStories = rawStories.map((story, index) => validateStory(story, index, allIds));
|
|
28895
29176
|
const now = new Date().toISOString();
|
|
29177
|
+
const featureOutOfScope = normalizeOutOfScopeList(obj.outOfScope);
|
|
28896
29178
|
return {
|
|
28897
29179
|
project: typeof obj.project === "string" && obj.project !== "" ? obj.project : feature,
|
|
28898
29180
|
feature,
|
|
@@ -28900,13 +29182,15 @@ function validatePlanOutput(raw, feature, branch) {
|
|
|
28900
29182
|
createdAt: typeof obj.createdAt === "string" ? obj.createdAt : now,
|
|
28901
29183
|
updatedAt: now,
|
|
28902
29184
|
userStories,
|
|
28903
|
-
...typeof obj.analysis === "string" && obj.analysis.trim() !== "" ? { analysis: obj.analysis.trim() } : {}
|
|
29185
|
+
...typeof obj.analysis === "string" && obj.analysis.trim() !== "" ? { analysis: obj.analysis.trim() } : {},
|
|
29186
|
+
...featureOutOfScope !== undefined ? { outOfScope: featureOutOfScope } : {}
|
|
28904
29187
|
};
|
|
28905
29188
|
}
|
|
28906
29189
|
var VALID_COMPLEXITY, STORY_ID_NO_SEPARATOR;
|
|
28907
29190
|
var init_schema2 = __esm(() => {
|
|
28908
29191
|
init_test_strategy();
|
|
28909
29192
|
init_errors();
|
|
29193
|
+
init_out_of_scope();
|
|
28910
29194
|
VALID_COMPLEXITY = ["simple", "medium", "complex", "expert"];
|
|
28911
29195
|
STORY_ID_NO_SEPARATOR = /^([A-Za-z]+)(\d+)$/;
|
|
28912
29196
|
});
|
|
@@ -28916,10 +29200,13 @@ var exports_prd = {};
|
|
|
28916
29200
|
__export(exports_prd, {
|
|
28917
29201
|
validatePlanOutput: () => validatePlanOutput,
|
|
28918
29202
|
validateInjectedStory: () => validateInjectedStory,
|
|
29203
|
+
stripPropagatedOutOfScope: () => stripPropagatedOutOfScope,
|
|
28919
29204
|
setStoryPriority: () => setStoryPriority,
|
|
28920
29205
|
savePRD: () => savePRD,
|
|
28921
29206
|
resetStoryToPending: () => resetStoryToPending,
|
|
28922
29207
|
resetFailedStoriesToPending: () => resetFailedStoriesToPending,
|
|
29208
|
+
propagateOutOfScopeToStories: () => propagateOutOfScopeToStories,
|
|
29209
|
+
normalizeOutOfScopeList: () => normalizeOutOfScopeList,
|
|
28923
29210
|
markStorySkipped: () => markStorySkipped,
|
|
28924
29211
|
markStoryPaused: () => markStoryPaused,
|
|
28925
29212
|
markStoryPassed: () => markStoryPassed,
|
|
@@ -28935,10 +29222,14 @@ __export(exports_prd, {
|
|
|
28935
29222
|
generateHumanHaltSummary: () => generateHumanHaltSummary,
|
|
28936
29223
|
findSpecDriftViolations: () => findSpecDriftViolations,
|
|
28937
29224
|
findMissingVerbatimAcs: () => findMissingVerbatimAcs,
|
|
29225
|
+
findMissingOutOfScope: () => findMissingOutOfScope,
|
|
28938
29226
|
extractVerbatimAcs: () => extractVerbatimAcs,
|
|
29227
|
+
extractSpecOutOfScope: () => extractSpecOutOfScope,
|
|
28939
29228
|
deriveNextStoryId: () => deriveNextStoryId,
|
|
28940
29229
|
countStories: () => countStories,
|
|
28941
|
-
|
|
29230
|
+
applyOutOfScopeFallback: () => applyOutOfScopeFallback,
|
|
29231
|
+
PRD_MAX_FILE_SIZE: () => PRD_MAX_FILE_SIZE,
|
|
29232
|
+
MAX_OUT_OF_SCOPE_ITEMS: () => MAX_OUT_OF_SCOPE_ITEMS
|
|
28942
29233
|
});
|
|
28943
29234
|
import { existsSync as existsSync4, statSync } from "fs";
|
|
28944
29235
|
async function loadPRD(path) {
|
|
@@ -28971,11 +29262,11 @@ async function loadPRD(path) {
|
|
|
28971
29262
|
}
|
|
28972
29263
|
story.storyPoints = story.storyPoints ?? 1;
|
|
28973
29264
|
}
|
|
28974
|
-
return prd;
|
|
29265
|
+
return propagateOutOfScopeToStories(prd);
|
|
28975
29266
|
}
|
|
28976
29267
|
async function savePRD(prd, path) {
|
|
28977
29268
|
prd.updatedAt = new Date().toISOString();
|
|
28978
|
-
await saveJsonFile(path, prd, "prd");
|
|
29269
|
+
await saveJsonFile(path, stripPropagatedOutOfScope(prd), "prd");
|
|
28979
29270
|
}
|
|
28980
29271
|
function hasSatisfiedDependencies(story, storyIds, completedIds) {
|
|
28981
29272
|
return story.dependencies.every((dep) => !storyIds.has(dep) || completedIds.has(dep));
|
|
@@ -29129,8 +29420,10 @@ var PRD_MAX_FILE_SIZE;
|
|
|
29129
29420
|
var init_prd = __esm(() => {
|
|
29130
29421
|
init_errors();
|
|
29131
29422
|
init_json_file();
|
|
29423
|
+
init_out_of_scope();
|
|
29132
29424
|
init_verbatim_fidelity();
|
|
29133
29425
|
init_spec_drift();
|
|
29426
|
+
init_out_of_scope();
|
|
29134
29427
|
init_inject();
|
|
29135
29428
|
init_schema2();
|
|
29136
29429
|
PRD_MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
@@ -31204,7 +31497,49 @@ var init_role_task = __esm(() => {
|
|
|
31204
31497
|
init_test_runners();
|
|
31205
31498
|
});
|
|
31206
31499
|
|
|
31500
|
+
// src/prompts/sections/out-of-scope.ts
|
|
31501
|
+
function buildOutOfScopeLines(items) {
|
|
31502
|
+
if (!items || items.length === 0)
|
|
31503
|
+
return [];
|
|
31504
|
+
return [
|
|
31505
|
+
"",
|
|
31506
|
+
"**Out of Scope \u2014 do NOT implement these:**",
|
|
31507
|
+
...items.map((item) => `- ${item}`),
|
|
31508
|
+
"",
|
|
31509
|
+
"Treat the list above as a hard boundary. If satisfying an acceptance criterion appears to require",
|
|
31510
|
+
"one of these, implement only what the criterion states and note the tension in your final message \u2014",
|
|
31511
|
+
"do not expand into the excluded work."
|
|
31512
|
+
];
|
|
31513
|
+
}
|
|
31514
|
+
function buildReviewOutOfScopeBlock(items, opts = {}) {
|
|
31515
|
+
if (!items || items.length === 0)
|
|
31516
|
+
return "";
|
|
31517
|
+
const header = [
|
|
31518
|
+
"",
|
|
31519
|
+
"**Out of Scope (feature-level \u2014 NOT acceptance criteria):**",
|
|
31520
|
+
...items.map((item, i) => `${i + 1}. ${item}`),
|
|
31521
|
+
"",
|
|
31522
|
+
"These state what the feature deliberately does not do. They are not acceptance criteria:",
|
|
31523
|
+
"never cite one as `acQuote`/`acIndex`, and never treat the absence of this work as a defect."
|
|
31524
|
+
];
|
|
31525
|
+
if (!opts.citable) {
|
|
31526
|
+
return [...header, "Report nothing against this list; it is context so you do not demand excluded work."].join(`
|
|
31527
|
+
`);
|
|
31528
|
+
}
|
|
31529
|
+
return [
|
|
31530
|
+
...header,
|
|
31531
|
+
'To report work that crossed one of these boundaries, set `category` to `"out-of-scope"`, quote the',
|
|
31532
|
+
"entry verbatim in `scopeQuote`, and set `scopeIndex` to its number above. Emit these as",
|
|
31533
|
+
'`severity: "warning"` \u2014 never `"error"`. Set `scopeQuote`/`scopeIndex` ONLY on an `"out-of-scope"`',
|
|
31534
|
+
"finding; on any other finding they are ignored."
|
|
31535
|
+
].join(`
|
|
31536
|
+
`);
|
|
31537
|
+
}
|
|
31538
|
+
|
|
31207
31539
|
// src/prompts/sections/story.ts
|
|
31540
|
+
function outOfScopeLines(story) {
|
|
31541
|
+
return buildOutOfScopeLines(story.outOfScope);
|
|
31542
|
+
}
|
|
31208
31543
|
function buildBatchStorySection(stories) {
|
|
31209
31544
|
const storyBlocks = stories.map((story, i) => {
|
|
31210
31545
|
const criteria = story.acceptanceCriteria.map((c, j) => `${j + 1}. ${c}`).join(`
|
|
@@ -31215,7 +31550,8 @@ function buildBatchStorySection(stories) {
|
|
|
31215
31550
|
story.description,
|
|
31216
31551
|
"",
|
|
31217
31552
|
"**Acceptance Criteria:**",
|
|
31218
|
-
criteria
|
|
31553
|
+
criteria,
|
|
31554
|
+
...outOfScopeLines(story)
|
|
31219
31555
|
].join(`
|
|
31220
31556
|
`);
|
|
31221
31557
|
});
|
|
@@ -31255,6 +31591,7 @@ function buildStoryReminderSection(story) {
|
|
|
31255
31591
|
"",
|
|
31256
31592
|
"**Acceptance Criteria:**",
|
|
31257
31593
|
criteria,
|
|
31594
|
+
...outOfScopeLines(story),
|
|
31258
31595
|
"",
|
|
31259
31596
|
"<!-- END USER-SUPPLIED DATA -->"
|
|
31260
31597
|
].join(`
|
|
@@ -31277,11 +31614,13 @@ function buildStorySection(story) {
|
|
|
31277
31614
|
"",
|
|
31278
31615
|
"**Acceptance Criteria:**",
|
|
31279
31616
|
criteria,
|
|
31617
|
+
...outOfScopeLines(story),
|
|
31280
31618
|
"",
|
|
31281
31619
|
"<!-- END USER-SUPPLIED DATA -->"
|
|
31282
31620
|
].join(`
|
|
31283
31621
|
`);
|
|
31284
31622
|
}
|
|
31623
|
+
var init_story = () => {};
|
|
31285
31624
|
|
|
31286
31625
|
// src/prompts/sections/verdict.ts
|
|
31287
31626
|
function buildVerdictSection(story) {
|
|
@@ -31528,6 +31867,7 @@ When the story is ambiguous, pick an interpretation, proceed, and document the c
|
|
|
31528
31867
|
var init_sections2 = __esm(() => {
|
|
31529
31868
|
init_hermetic();
|
|
31530
31869
|
init_role_task();
|
|
31870
|
+
init_story();
|
|
31531
31871
|
init_acceptance();
|
|
31532
31872
|
});
|
|
31533
31873
|
|
|
@@ -32292,6 +32632,7 @@ Notes:
|
|
|
32292
32632
|
- \`inspectedFiles\` must list the relative paths you actually opened while reviewing. A \`passed:true\` verdict with an empty or absent \`inspectedFiles\` is invalid \u2014 walk each AC against the real files before passing.
|
|
32293
32633
|
If all ACs are correctly implemented after inspecting the code, respond with { "passed": true, "inspectedFiles": ["..."], "findings": [] }.`, ReviewPromptBuilder;
|
|
32294
32634
|
var init_review_builder = __esm(() => {
|
|
32635
|
+
init_sections2();
|
|
32295
32636
|
SEMANTIC_ROLE = "You are a semantic code reviewer with access to the repository files. " + "Your job is to walk each acceptance criterion (AC) and judge whether the production code fulfills it \u2014 fully, partially, or not at all. " + "Test coverage gaps and convention/lint issues are out of scope \u2014 adversarial review and lint/typecheck handle those.";
|
|
32296
32637
|
ReviewPromptBuilder = class ReviewPromptBuilder {
|
|
32297
32638
|
buildSemanticReviewPrompt(story, semanticConfig, options) {
|
|
@@ -32317,7 +32658,7 @@ ${semanticConfig.rules.map((r, i) => `${i + 1}. ${r}`).join(`
|
|
|
32317
32658
|
${story.description}
|
|
32318
32659
|
|
|
32319
32660
|
### Acceptance Criteria
|
|
32320
|
-
${acList}
|
|
32661
|
+
${acList}${buildReviewOutOfScopeBlock(story.outOfScope)}
|
|
32321
32662
|
${customRulesBlock}${priorIterationsBlock}
|
|
32322
32663
|
${SEMANTIC_INSTRUCTIONS}
|
|
32323
32664
|
${SEMANTIC_OUTPUT_SCHEMA}
|
|
@@ -32557,13 +32898,15 @@ Respond with ONLY a JSON object \u2014 no preamble, no explanation outside the J
|
|
|
32557
32898
|
"findings": [
|
|
32558
32899
|
{
|
|
32559
32900
|
"severity": "error" | "warning" | "info" | "unverifiable",
|
|
32560
|
-
"category": "input" | "error-path" | "abandonment" | "test-gap" | "convention" | "assumption",
|
|
32901
|
+
"category": "input" | "error-path" | "abandonment" | "test-gap" | "convention" | "assumption" | "out-of-scope",
|
|
32561
32902
|
"file": "relative/path/to/file.ts",
|
|
32562
32903
|
"line": 42,
|
|
32563
32904
|
"issue": "Precise description of the weakness",
|
|
32564
32905
|
"suggestion": "Concrete fix or mitigation",
|
|
32565
32906
|
"acQuote": "<verbatim substring of one AC bullet constraining this locus \u2014 required for 'error'>",
|
|
32566
32907
|
"acIndex": 2,
|
|
32908
|
+
"scopeQuote": "<out-of-scope findings ONLY: verbatim substring of one Out of Scope entry>",
|
|
32909
|
+
"scopeIndex": 1,
|
|
32567
32910
|
"verifiedBy": {
|
|
32568
32911
|
"command": "command used to inspect the current codebase",
|
|
32569
32912
|
"file": "relative/path/to/file.ts",
|
|
@@ -32609,10 +32952,19 @@ Worked example:
|
|
|
32609
32952
|
**Exception \u2014 the trap does NOT apply to \`category:"test-gap"\` findings.** A fake/placeholder/missing test is the *absence* of verification for an AC's behaviour; it cannot name a symbol that is present in the (worthless) test file, because the defect is precisely that the symbol-under-test is never exercised. A \`test-gap\` finding is grounded by the AC whose behaviour goes unverified \u2014 cite that AC's \`acIndex\` and a verbatim \`acQuote\` substring from it, and keep severity \`"error"\`. The symbol-naming requirement is waived for this category.
|
|
32610
32953
|
|
|
32611
32954
|
**Scope constraints are not Acceptance Criteria:**
|
|
32612
|
-
|
|
32955
|
+
Scope boundaries reach you two ways: the story description may contain a "Scope" section with "In:" and "Out:" bullets (inter-story boundaries), and the story may carry a numbered **Out of Scope** list (feature-level exclusions the spec declared). Neither is an AC.
|
|
32956
|
+
|
|
32957
|
+
A finding about code that crossed one of these boundaries must NOT cite an AC \u2014 \`acQuote\`/\`acIndex\` are for acceptance criteria only, and scope text is not in the numbered AC list. Instead:
|
|
32958
|
+
- Set \`category\` to \`"out-of-scope"\`.
|
|
32959
|
+
- When the boundary comes from the numbered **Out of Scope** list, set \`scopeQuote\` to a verbatim substring of that entry and \`scopeIndex\` to its 1-based number. A \`scopeQuote\` that is not a verbatim substring of the entry you indexed is discarded.
|
|
32960
|
+
- When the boundary is only a description "Out:" bullet, quote it in \`issue\` and leave \`scopeQuote\`/\`scopeIndex\` unset.
|
|
32961
|
+
- Emit scope-violation findings as \`"warning"\` \u2014 never \`"error"\`. Reporting the boundary is the goal; it does not block the story.
|
|
32962
|
+
|
|
32963
|
+
Never use \`acIndex: 0\`; \`acIndex\` is 1-based (first AC bullet = 1). The same applies to \`scopeIndex\`.
|
|
32613
32964
|
|
|
32614
32965
|
If you cannot find an AC that names the **specific symbol** in your finding, downgrade to \`"info"\` or \`"warning"\`. A finding dropped by the validator is worse than one correctly classified as advisory.`, AdversarialReviewPromptBuilder;
|
|
32615
32966
|
var init_adversarial_review_builder = __esm(() => {
|
|
32967
|
+
init_sections2();
|
|
32616
32968
|
AdversarialReviewPromptBuilder = class AdversarialReviewPromptBuilder {
|
|
32617
32969
|
buildAdversarialReviewPrompt(story, config2, options) {
|
|
32618
32970
|
const {
|
|
@@ -32636,7 +32988,7 @@ var init_adversarial_review_builder = __esm(() => {
|
|
|
32636
32988
|
|
|
32637
32989
|
**Acceptance Criteria:**
|
|
32638
32990
|
${story.acceptanceCriteria.map((ac, i) => `${i + 1}. ${ac}`).join(`
|
|
32639
|
-
`)}
|
|
32991
|
+
`)}${buildReviewOutOfScopeBlock(story.outOfScope, { citable: true })}
|
|
32640
32992
|
|
|
32641
32993
|
`;
|
|
32642
32994
|
const customRulesBlock = config2.rules.length > 0 ? `## Project-Specific Adversarial Rules
|
|
@@ -33190,7 +33542,49 @@ function filterByAcGroundingMinimal(findings, acceptanceCriteria) {
|
|
|
33190
33542
|
}
|
|
33191
33543
|
return { accepted, dropped };
|
|
33192
33544
|
}
|
|
33193
|
-
|
|
33545
|
+
function claimsScopeViolation(finding) {
|
|
33546
|
+
return finding.category === "out-of-scope";
|
|
33547
|
+
}
|
|
33548
|
+
function validateScopeQuote(finding, outOfScope) {
|
|
33549
|
+
if (!claimsScopeViolation(finding))
|
|
33550
|
+
return { valid: true };
|
|
33551
|
+
const { scopeQuote, scopeIndex } = finding;
|
|
33552
|
+
if (scopeQuote === undefined)
|
|
33553
|
+
return { valid: true };
|
|
33554
|
+
if (typeof scopeQuote !== "string" || scopeQuote.trim().length < MIN_SCOPE_QUOTE_LENGTH) {
|
|
33555
|
+
return { valid: false, code: "missing_scope_quote" };
|
|
33556
|
+
}
|
|
33557
|
+
if (outOfScope.length === 0) {
|
|
33558
|
+
return { valid: false, code: "no_out_of_scope_declared" };
|
|
33559
|
+
}
|
|
33560
|
+
if (typeof scopeIndex !== "number" || scopeIndex < 1 || scopeIndex > outOfScope.length) {
|
|
33561
|
+
return { valid: false, code: "scope_index_out_of_range" };
|
|
33562
|
+
}
|
|
33563
|
+
const entry = normalizeWs2(stripMarkdownInline(outOfScope[scopeIndex - 1]));
|
|
33564
|
+
const quote = normalizeWs2(stripMarkdownInline(scopeQuote));
|
|
33565
|
+
if (!entry.toLowerCase().includes(quote.toLowerCase())) {
|
|
33566
|
+
return { valid: false, code: "scope_quote_not_substring" };
|
|
33567
|
+
}
|
|
33568
|
+
return { valid: true };
|
|
33569
|
+
}
|
|
33570
|
+
function filterByScopeQuote(findings, outOfScope) {
|
|
33571
|
+
const accepted = [];
|
|
33572
|
+
const dropped = [];
|
|
33573
|
+
for (const finding of findings) {
|
|
33574
|
+
if (!claimsScopeViolation(finding)) {
|
|
33575
|
+
accepted.push(finding.scopeQuote === undefined && finding.scopeIndex === undefined ? finding : { ...finding, scopeQuote: undefined, scopeIndex: undefined });
|
|
33576
|
+
continue;
|
|
33577
|
+
}
|
|
33578
|
+
const result = validateScopeQuote(finding, outOfScope);
|
|
33579
|
+
if (result.valid) {
|
|
33580
|
+
accepted.push(finding);
|
|
33581
|
+
} else {
|
|
33582
|
+
dropped.push({ finding, code: result.code });
|
|
33583
|
+
}
|
|
33584
|
+
}
|
|
33585
|
+
return { accepted, dropped };
|
|
33586
|
+
}
|
|
33587
|
+
var BLOCKING_SEVERITIES, MIN_SCOPE_QUOTE_LENGTH = 3;
|
|
33194
33588
|
var init_ac_quote_validator = __esm(() => {
|
|
33195
33589
|
BLOCKING_SEVERITIES = new Set(["error", "critical"]);
|
|
33196
33590
|
});
|
|
@@ -33393,6 +33787,17 @@ function warnOnDroppedVerbatimAcs(prd, specContent, featureName) {
|
|
|
33393
33787
|
getSafeLogger()?.warn("plan", "[verbatim] spec acceptance criteria dropped from PRD \u2014 run spec-review --prd before executing", { featureName, missingCount: missing.length, missing });
|
|
33394
33788
|
}
|
|
33395
33789
|
}
|
|
33790
|
+
function backfillOutOfScope(prd, specContent, featureName) {
|
|
33791
|
+
const missing = findMissingOutOfScope(specContent, prd);
|
|
33792
|
+
if (missing.length === 0)
|
|
33793
|
+
return prd;
|
|
33794
|
+
getSafeLogger()?.warn("plan", "Spec out-of-scope statements dropped from PRD \u2014 backfilled verbatim from the spec", {
|
|
33795
|
+
featureName,
|
|
33796
|
+
missingCount: missing.length,
|
|
33797
|
+
missing
|
|
33798
|
+
});
|
|
33799
|
+
return applyOutOfScopeFallback(prd, specContent);
|
|
33800
|
+
}
|
|
33396
33801
|
function warnOnSpecDrift(prd, featureName) {
|
|
33397
33802
|
const violations = findSpecDriftViolations(prd);
|
|
33398
33803
|
if (violations.length > 0) {
|
|
@@ -33461,7 +33866,7 @@ ${outputFormat}`, overridable: false }
|
|
|
33461
33866
|
if (!parsed.userStories || parsed.userStories.length === 0)
|
|
33462
33867
|
return null;
|
|
33463
33868
|
warnOnDroppedVerbatimAcs(parsed, input.specContent, input.featureName);
|
|
33464
|
-
return parsed;
|
|
33869
|
+
return backfillOutOfScope(parsed, input.specContent, input.featureName);
|
|
33465
33870
|
},
|
|
33466
33871
|
recover: async (input, ctx) => {
|
|
33467
33872
|
const content = await ctx.readFile(input.outputPath);
|
|
@@ -33659,6 +34064,32 @@ function verbatimSelfHealStep(builder) {
|
|
|
33659
34064
|
}
|
|
33660
34065
|
});
|
|
33661
34066
|
}
|
|
34067
|
+
async function readMissingOutOfScope(input) {
|
|
34068
|
+
const content = await _planRefineDeps.readFile(input.outputPath);
|
|
34069
|
+
if (!content)
|
|
34070
|
+
return [];
|
|
34071
|
+
try {
|
|
34072
|
+
const prd = validatePlanOutput(content, input.featureName, input.branchName);
|
|
34073
|
+
return findMissingOutOfScope(input.specContent, prd);
|
|
34074
|
+
} catch (err) {
|
|
34075
|
+
getSafeLogger()?.debug("plan", "Skipped out-of-scope self-heal \u2014 draft PRD not yet parseable", {
|
|
34076
|
+
featureName: input.featureName,
|
|
34077
|
+
error: errorMessage(err)
|
|
34078
|
+
});
|
|
34079
|
+
return [];
|
|
34080
|
+
}
|
|
34081
|
+
}
|
|
34082
|
+
function outOfScopeSelfHealStep(builder) {
|
|
34083
|
+
return makeSelfHealStep({
|
|
34084
|
+
detect: (input) => readMissingOutOfScope(input),
|
|
34085
|
+
buildRepair: (missing, input) => builder.buildOutOfScopeRepair(missing, input.outputPath),
|
|
34086
|
+
log: {
|
|
34087
|
+
kind: "plan",
|
|
34088
|
+
message: "Refine dropped spec out-of-scope statements \u2014 issuing one repair turn",
|
|
34089
|
+
meta: (input, missing) => ({ featureName: input.featureName, missingCount: missing.length })
|
|
34090
|
+
}
|
|
34091
|
+
});
|
|
34092
|
+
}
|
|
33662
34093
|
function specDriftSelfHealStep(builder) {
|
|
33663
34094
|
return makeSelfHealStep({
|
|
33664
34095
|
detect: (input) => readSpecDriftViolations(input),
|
|
@@ -33765,6 +34196,7 @@ ${outputFormat}`,
|
|
|
33765
34196
|
};
|
|
33766
34197
|
const steps = [
|
|
33767
34198
|
verbatimSelfHealStep(builder),
|
|
34199
|
+
outOfScopeSelfHealStep(builder),
|
|
33768
34200
|
...specGuard ? [specDriftSelfHealStep(builder)] : []
|
|
33769
34201
|
];
|
|
33770
34202
|
return runSelfHealChain(ctx, seed, steps);
|
|
@@ -33778,7 +34210,8 @@ ${outputFormat}`,
|
|
|
33778
34210
|
if (ctx.config.plan.specGuard) {
|
|
33779
34211
|
warnOnSpecDrift(validated, input.featureName);
|
|
33780
34212
|
}
|
|
33781
|
-
|
|
34213
|
+
const scoped = backfillOutOfScope(validated, input.specContent, input.featureName);
|
|
34214
|
+
return await normalizeCreatedContextFiles(scoped, input.workdir, ctx.fileExists);
|
|
33782
34215
|
},
|
|
33783
34216
|
recover: async (input, ctx) => {
|
|
33784
34217
|
const content = await ctx.readFile(input.outputPath);
|
|
@@ -35201,6 +35634,8 @@ var init_ac_structural_counterfactual = __esm(() => {
|
|
|
35201
35634
|
|
|
35202
35635
|
// src/review/category-fix-target.ts
|
|
35203
35636
|
function categoryToFixTarget(category) {
|
|
35637
|
+
if (category === "out-of-scope")
|
|
35638
|
+
return "source";
|
|
35204
35639
|
return category != null && BLOCKING_CATEGORIES.has(category) ? "source" : "test";
|
|
35205
35640
|
}
|
|
35206
35641
|
var init_category_fix_target = __esm(() => {
|
|
@@ -35239,6 +35674,10 @@ function toAdversarialReviewFindings(findings) {
|
|
|
35239
35674
|
metaExtras.acIndex = f.acIndex;
|
|
35240
35675
|
if (f.verifiedBy)
|
|
35241
35676
|
metaExtras.verifiedBy = f.verifiedBy;
|
|
35677
|
+
if (f.scopeQuote)
|
|
35678
|
+
metaExtras.scopeQuote = f.scopeQuote;
|
|
35679
|
+
if (f.scopeIndex != null)
|
|
35680
|
+
metaExtras.scopeIndex = f.scopeIndex;
|
|
35242
35681
|
return {
|
|
35243
35682
|
source: "adversarial-review",
|
|
35244
35683
|
severity: normalizeSeverity(f.severity),
|
|
@@ -35479,9 +35918,9 @@ function parseRequoteResponse(output) {
|
|
|
35479
35918
|
const parsed = tryParseLLMJson(output);
|
|
35480
35919
|
if (!isRecord(parsed))
|
|
35481
35920
|
return null;
|
|
35482
|
-
const
|
|
35483
|
-
if (
|
|
35484
|
-
return
|
|
35921
|
+
const canonical3 = extractCanonical(parsed);
|
|
35922
|
+
if (canonical3)
|
|
35923
|
+
return canonical3;
|
|
35485
35924
|
const findings = parsed.findings;
|
|
35486
35925
|
if (!Array.isArray(findings) || findings.length !== 1)
|
|
35487
35926
|
return null;
|
|
@@ -36195,7 +36634,28 @@ var init_adversarial_review = __esm(() => {
|
|
|
36195
36634
|
storyId: input.story.id,
|
|
36196
36635
|
blockingThreshold: threshold
|
|
36197
36636
|
});
|
|
36198
|
-
const { accepted, dropped } =
|
|
36637
|
+
const { accepted: scopeGrounded, dropped: scopeDropped } = filterByScopeQuote(substantiated, input.story.outOfScope ?? []);
|
|
36638
|
+
for (const entry of scopeDropped) {
|
|
36639
|
+
getSafeLogger()?.info("review", "Adversarial scope finding dropped (ungrounded scopeQuote)", {
|
|
36640
|
+
storyId: input.story.id,
|
|
36641
|
+
event: "review.adversarial.scope_quote_dropped",
|
|
36642
|
+
file: entry.finding.file,
|
|
36643
|
+
code: entry.code
|
|
36644
|
+
});
|
|
36645
|
+
}
|
|
36646
|
+
for (const finding of scopeGrounded) {
|
|
36647
|
+
if (finding.category !== "out-of-scope" && finding.scopeQuote === undefined)
|
|
36648
|
+
continue;
|
|
36649
|
+
getSafeLogger()?.info("review", "Adversarial scope finding accepted (advisory)", {
|
|
36650
|
+
storyId: input.story.id,
|
|
36651
|
+
event: "review.adversarial.scope_finding_accepted",
|
|
36652
|
+
file: finding.file,
|
|
36653
|
+
severity: finding.severity,
|
|
36654
|
+
grounded: finding.scopeQuote !== undefined,
|
|
36655
|
+
declaredExclusions: (input.story.outOfScope ?? []).length
|
|
36656
|
+
});
|
|
36657
|
+
}
|
|
36658
|
+
const { accepted, dropped } = filterByAcQuote(scopeGrounded, input.story.acceptanceCriteria);
|
|
36199
36659
|
const recurrenceCfg = input.adversarialConfig.recurrenceDemotion ?? { enabled: true, maxBlockingRounds: 2 };
|
|
36200
36660
|
const patterns = input.resolvedTestPatterns?.regex ?? [];
|
|
36201
36661
|
const testFileMatch = (file3) => patterns.some((re) => re.test(file3));
|
|
@@ -41815,7 +42275,7 @@ var package_default;
|
|
|
41815
42275
|
var init_package = __esm(() => {
|
|
41816
42276
|
package_default = {
|
|
41817
42277
|
name: "@nathapp/nax",
|
|
41818
|
-
version: "0.
|
|
42278
|
+
version: "0.74.0",
|
|
41819
42279
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
41820
42280
|
type: "module",
|
|
41821
42281
|
bin: {
|
|
@@ -41826,9 +42286,9 @@ var init_package = __esm(() => {
|
|
|
41826
42286
|
dev: "bun run bin/nax.ts",
|
|
41827
42287
|
build: 'bun build bin/nax.ts --outdir dist --target bun --define "GIT_COMMIT=\\"$(git rev-parse --short HEAD)\\""',
|
|
41828
42288
|
typecheck: "bun x tsc --noEmit && bun x tsc --noEmit -p tsconfig.contracts.json",
|
|
41829
|
-
lint: "bun x biome check src/ bin/ && bun run check:no-real-global-nax && bun run check:alias-internals && bun run check:deep-relatives && bun run check:nax-error && bun run check:logger-storyid && bun run check:log-format-layering && bun run check:file-sizes",
|
|
41830
|
-
"lint:json": "bun x biome check src/ bin/ --reporter json && bun run check:nax-error 1>&2 && bun run check:logger-storyid 1>&2",
|
|
41831
|
-
"lint:fix": "bun x biome check --write src/ bin/",
|
|
42289
|
+
lint: "bun x biome check src/ bin/ flows/ && bun run check:no-real-global-nax && bun run check:alias-internals && bun run check:deep-relatives && bun run check:nax-error && bun run check:logger-storyid && bun run check:log-format-layering && bun run check:file-sizes",
|
|
42290
|
+
"lint:json": "bun x biome check src/ bin/ flows/ --reporter json && bun run check:nax-error 1>&2 && bun run check:logger-storyid 1>&2",
|
|
42291
|
+
"lint:fix": "bun x biome check --write src/ bin/ flows/",
|
|
41832
42292
|
"check:no-real-global-nax": "bun run scripts/check-no-real-global-nax.ts",
|
|
41833
42293
|
"check:alias-internals": "bun run scripts/check-alias-internals.ts",
|
|
41834
42294
|
"check:deep-relatives": "bun run scripts/check-deep-relatives.ts",
|
|
@@ -41865,6 +42325,7 @@ var init_package = __esm(() => {
|
|
|
41865
42325
|
},
|
|
41866
42326
|
dependencies: {
|
|
41867
42327
|
"@types/react": "^19.2.14",
|
|
42328
|
+
acpx: "^0.12.1",
|
|
41868
42329
|
chalk: "^5.6.2",
|
|
41869
42330
|
commander: "^13.1.0",
|
|
41870
42331
|
ink: "^6.7.0",
|
|
@@ -41890,6 +42351,7 @@ var init_package = __esm(() => {
|
|
|
41890
42351
|
],
|
|
41891
42352
|
files: [
|
|
41892
42353
|
"dist/",
|
|
42354
|
+
"flows/",
|
|
41893
42355
|
"README.md",
|
|
41894
42356
|
"CHANGELOG.md"
|
|
41895
42357
|
],
|
|
@@ -41916,8 +42378,8 @@ var init_version = __esm(() => {
|
|
|
41916
42378
|
NAX_VERSION = package_default.version;
|
|
41917
42379
|
NAX_COMMIT = (() => {
|
|
41918
42380
|
try {
|
|
41919
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
41920
|
-
return "
|
|
42381
|
+
if (/^[0-9a-f]{6,10}$/.test("91bb7306"))
|
|
42382
|
+
return "91bb7306";
|
|
41921
42383
|
} catch {}
|
|
41922
42384
|
try {
|
|
41923
42385
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -45067,6 +45529,9 @@ Re-check routing.complexity and routing.testStrategy against the current codebas
|
|
|
45067
45529
|
#### regression-coverage
|
|
45068
45530
|
If a story changes existing behavior, extracts a shared helper, extends an existing function signature, or replaces a warning/stub path with real behavior, ensure there is at least one acceptance criterion protecting backward compatibility or proving the old placeholder behavior is gone.
|
|
45069
45531
|
|
|
45532
|
+
#### out-of-scope-preservation
|
|
45533
|
+
If the spec has an "Out of Scope", "Non-Goals", or "Not in scope" section \u2014 or an inline \`**Out of scope \u2026:**\` lead-in \u2014 enumerate every item it states and confirm each appears in the top-level \`outOfScope\` array. Restore any that are missing, verbatim. Never convert one into an acceptance criterion, and never delete one because it looks obvious. Where a story sits close to one of these boundaries, echo the item into that story's \`**Scope** \u2014 Out:\` bullet too.
|
|
45534
|
+
|
|
45070
45535
|
#### scope-consistency
|
|
45071
45536
|
Check each story's title, description, scope, contextFiles, and acceptance criteria for internal consistency. If the story says a file or command is in scope anywhere else, do not list it as out of scope. If the title or acceptance criteria clearly include CLI, output, tests, or helper extraction work, the Scope section must reflect that accurately.${specGuardItems}
|
|
45072
45537
|
|
|
@@ -45105,6 +45570,24 @@ For each one:
|
|
|
45105
45570
|
- Preserve every backtick-quoted command, file path, regex, and count exactly as written in the spec. Do not paraphrase, retag, split, or move them into a description.
|
|
45106
45571
|
- Do not remove or weaken any acceptance criteria that are already correct.
|
|
45107
45572
|
|
|
45573
|
+
Write the corrected PRD to this file path: ${outputFilePath}
|
|
45574
|
+
Do not output the PRD in chat. After writing the file, reply with a brief text confirmation only.`;
|
|
45575
|
+
}
|
|
45576
|
+
buildOutOfScopeRepair(missing, outputFilePath) {
|
|
45577
|
+
const list = missing.map((item) => `- ${item}`).join(`
|
|
45578
|
+
`);
|
|
45579
|
+
return `Your revised PRD dropped feature-level exclusions the spec declared out of scope. These are the only channel by which a deferred arc reaches the implementer \u2014 the implementer never sees the spec, so a dropped exclusion means nothing stops it from building work this feature deliberately defers.
|
|
45580
|
+
|
|
45581
|
+
The following out-of-scope statements are missing from the top-level \`outOfScope\` array:
|
|
45582
|
+
|
|
45583
|
+
${list}
|
|
45584
|
+
|
|
45585
|
+
For each one:
|
|
45586
|
+
- Add it to the top-level \`outOfScope\` array, preserving the spec's wording. You may append a short clarifier, but never drop or merge an item.
|
|
45587
|
+
- Never convert an out-of-scope statement into an acceptance criterion \u2014 it describes work NOT to do.
|
|
45588
|
+
- Where a story sits close enough to the boundary that an implementer might stray across it, also echo the item into that story's \`**Scope** \u2014 Out:\` bullet.
|
|
45589
|
+
- Do not remove or weaken anything already correct.
|
|
45590
|
+
|
|
45108
45591
|
Write the corrected PRD to this file path: ${outputFilePath}
|
|
45109
45592
|
Do not output the PRD in chat. After writing the file, reply with a brief text confirmation only.`;
|
|
45110
45593
|
}
|
|
@@ -45185,6 +45668,7 @@ Generate a JSON object with this exact structure (no markdown, no explanation \u
|
|
|
45185
45668
|
"branchName": "string \u2014 git branch (e.g. feat/my-feature)",
|
|
45186
45669
|
"createdAt": "ISO 8601 timestamp",
|
|
45187
45670
|
"updatedAt": "ISO 8601 timestamp",
|
|
45671
|
+
${OUT_OF_SCOPE_SCHEMA_FIELD}
|
|
45188
45672
|
"userStories": [
|
|
45189
45673
|
{
|
|
45190
45674
|
"id": "string \u2014 e.g. US-001",
|
|
@@ -45193,6 +45677,7 @@ Generate a JSON object with this exact structure (no markdown, no explanation \u
|
|
|
45193
45677
|
"acceptanceCriteria": ["string \u2014 behavioral, testable criteria. Format: 'When [X], then [Y]'. One assertion per AC. Never include quality gates."],${suggestedCriteriaField}
|
|
45194
45678
|
"contextFiles": ["string \u2014 EXISTING source files the agent should read (max 5, relative paths)"],
|
|
45195
45679
|
${EXPECTED_FILES_SCHEMA_FIELD}
|
|
45680
|
+
${STORY_OUT_OF_SCOPE_SCHEMA_FIELD}
|
|
45196
45681
|
"tags": ["string \u2014 routing tags, e.g. feature, security, api"],
|
|
45197
45682
|
"dependencies": ["string \u2014 story IDs this story depends on"],${workdirField}
|
|
45198
45683
|
"status": "pending",
|
|
@@ -45284,6 +45769,7 @@ Produce a JSON object with this exact structure. Field names are mandatory \u201
|
|
|
45284
45769
|
"project": "string \u2014 project name",
|
|
45285
45770
|
"feature": "string \u2014 feature name (copy from above)",
|
|
45286
45771
|
"branchName": "string \u2014 git branch name",
|
|
45772
|
+
${OUT_OF_SCOPE_SCHEMA_FIELD}
|
|
45287
45773
|
"userStories": [
|
|
45288
45774
|
{
|
|
45289
45775
|
"id": "string \u2014 e.g. US-001",
|
|
@@ -45292,6 +45778,7 @@ Produce a JSON object with this exact structure. Field names are mandatory \u201
|
|
|
45292
45778
|
"acceptanceCriteria": ["string \u2014 behavioral criterion, format: 'When [X], then [Y]'. One assertion per item."],${suggestedCriteriaField}
|
|
45293
45779
|
"contextFiles": ["string \u2014 EXISTING relative paths the implementer should read (max 5)"],
|
|
45294
45780
|
${EXPECTED_FILES_SCHEMA_FIELD}
|
|
45781
|
+
${STORY_OUT_OF_SCOPE_SCHEMA_FIELD}
|
|
45295
45782
|
"tags": ["string"],
|
|
45296
45783
|
"dependencies": ["string \u2014 story IDs this story depends on"],${workdirField}
|
|
45297
45784
|
"routing": {
|
|
@@ -45335,7 +45822,7 @@ ${rows.join(`
|
|
|
45335
45822
|
}
|
|
45336
45823
|
var CONTEXT_VS_EXPECTED_FILES_RULE = `**\`contextFiles\` rule \u2014 files readable when this story runs.** List paths that already exist in the repo today, PLUS any file an UPSTREAM dependency story creates (it does not exist now but will exist by the time this story runs, because dependencies execute first). The pipeline verifies every \`contextFiles\` entry against the filesystem; a path that exists neither on disk nor in an upstream dependency's outputs is treated as a missing-context warning.
|
|
45337
45824
|
|
|
45338
|
-
**\`expectedFiles\` rule \u2014 files THIS story CREATES.** List every NEW file this story authors (relative paths). A file this story creates belongs here, NEVER in \`contextFiles\` \u2014 these are the story's outputs, not files to read first. A file created by an upstream dependency and only read/modified here belongs in \`contextFiles\`, NOT here (this story does not author it). A single path may appear in \`contextFiles\` (an existing sibling to mirror) AND \`expectedFiles\` (the new file itself), but the same path must never be in both.`, EXPECTED_FILES_SCHEMA_FIELD = `"expectedFiles": ["string \u2014 NEW files this story creates (relative paths, omit if none)"],`;
|
|
45825
|
+
**\`expectedFiles\` rule \u2014 files THIS story CREATES.** List every NEW file this story authors (relative paths). A file this story creates belongs here, NEVER in \`contextFiles\` \u2014 these are the story's outputs, not files to read first. A file created by an upstream dependency and only read/modified here belongs in \`contextFiles\`, NOT here (this story does not author it). A single path may appear in \`contextFiles\` (an existing sibling to mirror) AND \`expectedFiles\` (the new file itself), but the same path must never be in both.`, EXPECTED_FILES_SCHEMA_FIELD = `"expectedFiles": ["string \u2014 NEW files this story creates (relative paths, omit if none)"],`, OUT_OF_SCOPE_SCHEMA_FIELD = `"outOfScope": ["string \u2014 verbatim from the spec's Out of Scope / Non-Goals section: what this feature deliberately does NOT do. Omit if the spec declares none."],`, STORY_OUT_OF_SCOPE_SCHEMA_FIELD = `"outOfScope": ["string \u2014 optional, exclusions specific to THIS story beyond the feature-level list. Omit if none."],`;
|
|
45339
45826
|
var init_plan_builder = __esm(() => {
|
|
45340
45827
|
init_config();
|
|
45341
45828
|
init_one_shot_builder();
|
|
@@ -45775,6 +46262,7 @@ var init_prompts = __esm(() => {
|
|
|
45775
46262
|
init_tdd_builder();
|
|
45776
46263
|
init_tdd_builder();
|
|
45777
46264
|
init_debate_builder();
|
|
46265
|
+
init_sections2();
|
|
45778
46266
|
init_review_builder();
|
|
45779
46267
|
init_adversarial_review_builder();
|
|
45780
46268
|
init_acceptance_builder();
|
|
@@ -57896,15 +58384,26 @@ function recordOscillations(store, storyId, delta) {
|
|
|
57896
58384
|
function getOscillations(store, storyId) {
|
|
57897
58385
|
return store.get(storyId) ?? 0;
|
|
57898
58386
|
}
|
|
58387
|
+
function sourceSet(findings) {
|
|
58388
|
+
return new Set((Array.isArray(findings) ? findings : []).map((f) => f.source));
|
|
58389
|
+
}
|
|
57899
58390
|
function countOscillationOutcomes(iterations) {
|
|
58391
|
+
const resolvedSources = new Set;
|
|
57900
58392
|
let count = 0;
|
|
57901
58393
|
for (const iteration of iterations) {
|
|
57902
|
-
|
|
57903
|
-
|
|
58394
|
+
const beforeSources = sourceSet(iteration.findingsBefore);
|
|
58395
|
+
const afterSources = sourceSet(iteration.findingsAfter);
|
|
58396
|
+
for (const source of afterSources) {
|
|
58397
|
+
if (resolvedSources.has(source))
|
|
58398
|
+
count += 1;
|
|
58399
|
+
}
|
|
58400
|
+
for (const source of beforeSources) {
|
|
58401
|
+
if (!afterSources.has(source))
|
|
58402
|
+
resolvedSources.add(source);
|
|
58403
|
+
}
|
|
57904
58404
|
}
|
|
57905
58405
|
return count;
|
|
57906
58406
|
}
|
|
57907
|
-
var OSCILLATION_OUTCOME = "regressed-different-source";
|
|
57908
58407
|
|
|
57909
58408
|
// src/execution/checkpoint/resume-plan.ts
|
|
57910
58409
|
function buildResumePlan(cp, current) {
|
|
@@ -63473,6 +63972,218 @@ var init_curator = __esm(() => {
|
|
|
63473
63972
|
};
|
|
63474
63973
|
});
|
|
63475
63974
|
|
|
63975
|
+
// src/plugins/builtin/nax-finish/config.ts
|
|
63976
|
+
function selectFinish(config2) {
|
|
63977
|
+
if (!config2 || typeof config2 !== "object")
|
|
63978
|
+
return;
|
|
63979
|
+
return finishConfigSelector.select(config2)?.finish;
|
|
63980
|
+
}
|
|
63981
|
+
function getFinishAutoFlowConfig(ctx) {
|
|
63982
|
+
const autoFlow = selectFinish(ctx.config)?.autoFlow;
|
|
63983
|
+
if (!autoFlow)
|
|
63984
|
+
return DEFAULT_FINISH_AUTO_FLOW_CONFIG;
|
|
63985
|
+
const defaults = DEFAULT_FINISH_AUTO_FLOW_CONFIG;
|
|
63986
|
+
return {
|
|
63987
|
+
enabled: autoFlow.enabled === true,
|
|
63988
|
+
flowPath: autoFlow.flowPath ?? defaults.flowPath,
|
|
63989
|
+
defaultAgent: autoFlow.defaultAgent ?? null,
|
|
63990
|
+
reviewers: {
|
|
63991
|
+
spec: autoFlow.reviewers?.spec ?? null,
|
|
63992
|
+
quality: autoFlow.reviewers?.quality ?? null
|
|
63993
|
+
},
|
|
63994
|
+
escalate: { telegram: autoFlow.escalate?.telegram !== false },
|
|
63995
|
+
timeouts: {
|
|
63996
|
+
acceptanceMs: autoFlow.timeouts?.acceptanceMs ?? defaults.timeouts.acceptanceMs,
|
|
63997
|
+
gateMs: autoFlow.timeouts?.gateMs ?? defaults.timeouts.gateMs,
|
|
63998
|
+
flowMs: autoFlow.timeouts?.flowMs ?? defaults.timeouts.flowMs,
|
|
63999
|
+
stepMs: autoFlow.timeouts?.stepMs ?? defaults.timeouts.stepMs
|
|
64000
|
+
}
|
|
64001
|
+
};
|
|
64002
|
+
}
|
|
64003
|
+
function telegramCreds(config2) {
|
|
64004
|
+
const interaction = config2?.interaction;
|
|
64005
|
+
const tg = interaction?.plugin === "telegram" ? interaction.config ?? {} : {};
|
|
64006
|
+
const token = tg.botToken ?? process.env.NAX_TELEGRAM_TOKEN ?? process.env.TELEGRAM_BOT_TOKEN ?? null;
|
|
64007
|
+
const chatId = tg.chatId ?? process.env.NAX_TELEGRAM_CHAT_ID ?? null;
|
|
64008
|
+
return token && chatId ? { token, chatId } : null;
|
|
64009
|
+
}
|
|
64010
|
+
var DEFAULT_FINISH_AUTO_FLOW_CONFIG;
|
|
64011
|
+
var init_config2 = __esm(() => {
|
|
64012
|
+
init_config();
|
|
64013
|
+
DEFAULT_FINISH_AUTO_FLOW_CONFIG = {
|
|
64014
|
+
enabled: false,
|
|
64015
|
+
flowPath: "flows/nax-finish/nax-finish.flow.ts",
|
|
64016
|
+
defaultAgent: null,
|
|
64017
|
+
reviewers: { spec: null, quality: null },
|
|
64018
|
+
escalate: { telegram: true },
|
|
64019
|
+
timeouts: { acceptanceMs: 600000, gateMs: 900000, flowMs: 5400000, stepMs: null }
|
|
64020
|
+
};
|
|
64021
|
+
});
|
|
64022
|
+
|
|
64023
|
+
// src/plugins/builtin/nax-finish/telegram.ts
|
|
64024
|
+
async function sendTelegramNotify(cfg, text) {
|
|
64025
|
+
const res = await _telegramDeps.fetch(`https://api.telegram.org/bot${cfg.token}/sendMessage`, {
|
|
64026
|
+
method: "POST",
|
|
64027
|
+
headers: { "content-type": "application/json" },
|
|
64028
|
+
body: JSON.stringify({ chat_id: cfg.chatId, text, parse_mode: "Markdown" })
|
|
64029
|
+
});
|
|
64030
|
+
return res.ok;
|
|
64031
|
+
}
|
|
64032
|
+
var _telegramDeps;
|
|
64033
|
+
var init_telegram2 = __esm(() => {
|
|
64034
|
+
_telegramDeps = { fetch: (...a) => fetch(...a) };
|
|
64035
|
+
});
|
|
64036
|
+
|
|
64037
|
+
// src/plugins/builtin/nax-finish/index.ts
|
|
64038
|
+
import * as path21 from "path";
|
|
64039
|
+
async function defaultRun2(cmd, opts) {
|
|
64040
|
+
const proc = Bun.spawn(cmd, { cwd: opts.cwd, env: opts.env, stdout: "pipe", stderr: "pipe" });
|
|
64041
|
+
let timedOut = false;
|
|
64042
|
+
const timer = opts.timeoutMs && opts.timeoutMs > 0 ? setTimeout(() => {
|
|
64043
|
+
timedOut = true;
|
|
64044
|
+
proc.kill();
|
|
64045
|
+
}, opts.timeoutMs) : undefined;
|
|
64046
|
+
try {
|
|
64047
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
64048
|
+
proc.exited,
|
|
64049
|
+
new Response(proc.stdout).text(),
|
|
64050
|
+
new Response(proc.stderr).text()
|
|
64051
|
+
]);
|
|
64052
|
+
return timedOut ? {
|
|
64053
|
+
exitCode: exitCode === 0 ? 124 : exitCode,
|
|
64054
|
+
stdout,
|
|
64055
|
+
stderr: `${stderr}
|
|
64056
|
+
[nax-finish] flow killed after ${opts.timeoutMs}ms timeout`
|
|
64057
|
+
} : { exitCode, stdout, stderr };
|
|
64058
|
+
} finally {
|
|
64059
|
+
if (timer)
|
|
64060
|
+
clearTimeout(timer);
|
|
64061
|
+
}
|
|
64062
|
+
}
|
|
64063
|
+
async function defaultReadResult(workdir) {
|
|
64064
|
+
const f = Bun.file(path21.join(workdir, ".nax", "nax-finish-result.json"));
|
|
64065
|
+
if (!await f.exists())
|
|
64066
|
+
return null;
|
|
64067
|
+
return JSON.parse(await f.text());
|
|
64068
|
+
}
|
|
64069
|
+
function isFeatureBranch(b) {
|
|
64070
|
+
return b !== "main" && b !== "master" && b.length > 0;
|
|
64071
|
+
}
|
|
64072
|
+
async function resolveFlowPath(workdir, flowPath, deps = _naxFinishDeps) {
|
|
64073
|
+
if (path21.isAbsolute(flowPath)) {
|
|
64074
|
+
return await deps.exists(flowPath) ? flowPath : null;
|
|
64075
|
+
}
|
|
64076
|
+
const candidates = [];
|
|
64077
|
+
let dir = deps.moduleDir;
|
|
64078
|
+
for (let i = 0;i < PACKAGE_ROOT_SEARCH_DEPTH; i += 1) {
|
|
64079
|
+
dir = path21.dirname(dir);
|
|
64080
|
+
if (await deps.exists(path21.join(dir, "package.json")))
|
|
64081
|
+
candidates.push(path21.resolve(dir, flowPath));
|
|
64082
|
+
}
|
|
64083
|
+
candidates.push(path21.resolve(workdir, flowPath));
|
|
64084
|
+
for (const candidate of candidates) {
|
|
64085
|
+
if (await deps.exists(candidate))
|
|
64086
|
+
return candidate;
|
|
64087
|
+
}
|
|
64088
|
+
return null;
|
|
64089
|
+
}
|
|
64090
|
+
function buildFlowArgv(flowPath, inputJson, defaultAgent, stepMs) {
|
|
64091
|
+
const stepTimeout = stepMs && stepMs > 0 ? ["--timeout", String(Math.ceil(stepMs / 1000))] : [];
|
|
64092
|
+
return [
|
|
64093
|
+
"acpx",
|
|
64094
|
+
"--approve-all",
|
|
64095
|
+
...stepTimeout,
|
|
64096
|
+
"flow",
|
|
64097
|
+
"run",
|
|
64098
|
+
flowPath,
|
|
64099
|
+
"--input-json",
|
|
64100
|
+
inputJson,
|
|
64101
|
+
...defaultAgent ? ["--default-agent", defaultAgent] : []
|
|
64102
|
+
];
|
|
64103
|
+
}
|
|
64104
|
+
function buildFlowEnv(cfg) {
|
|
64105
|
+
const env2 = { ...process.env };
|
|
64106
|
+
if (cfg.reviewers.spec)
|
|
64107
|
+
env2.NAX_FINISH_SPEC_PROFILE = cfg.reviewers.spec;
|
|
64108
|
+
if (cfg.reviewers.quality)
|
|
64109
|
+
env2.NAX_FINISH_QUALITY_PROFILE = cfg.reviewers.quality;
|
|
64110
|
+
return env2;
|
|
64111
|
+
}
|
|
64112
|
+
var PLUGIN_NAME4 = "nax-finish", PLUGIN_VERSION4 = "0.1.0", PACKAGE_ROOT_SEARCH_DEPTH = 6, _naxFinishDeps, naxFinishAction, naxFinishPlugin;
|
|
64113
|
+
var init_nax_finish = __esm(() => {
|
|
64114
|
+
init_config2();
|
|
64115
|
+
init_telegram2();
|
|
64116
|
+
_naxFinishDeps = {
|
|
64117
|
+
run: defaultRun2,
|
|
64118
|
+
readResult: defaultReadResult,
|
|
64119
|
+
exists: (p) => Bun.file(p).exists(),
|
|
64120
|
+
moduleDir: import.meta.dir,
|
|
64121
|
+
notify: sendTelegramNotify
|
|
64122
|
+
};
|
|
64123
|
+
naxFinishAction = {
|
|
64124
|
+
name: PLUGIN_NAME4,
|
|
64125
|
+
description: "Autonomously finishes a feature (acceptance -> review -> gates -> PR) via an acpx flow after a successful run",
|
|
64126
|
+
async shouldRun(ctx) {
|
|
64127
|
+
const cfg = getFinishAutoFlowConfig(ctx);
|
|
64128
|
+
if (!cfg.enabled)
|
|
64129
|
+
return false;
|
|
64130
|
+
const s = ctx.storySummary;
|
|
64131
|
+
if (s.completed === 0 || s.failed > 0 || s.paused > 0)
|
|
64132
|
+
return false;
|
|
64133
|
+
return isFeatureBranch(ctx.branch);
|
|
64134
|
+
},
|
|
64135
|
+
async execute(ctx) {
|
|
64136
|
+
try {
|
|
64137
|
+
const cfg = getFinishAutoFlowConfig(ctx);
|
|
64138
|
+
const flowPath = await resolveFlowPath(ctx.workdir, cfg.flowPath);
|
|
64139
|
+
if (!flowPath) {
|
|
64140
|
+
return {
|
|
64141
|
+
success: false,
|
|
64142
|
+
message: `nax-finish: flow module "${cfg.flowPath}" not found in the nax install or ${ctx.workdir}`
|
|
64143
|
+
};
|
|
64144
|
+
}
|
|
64145
|
+
const creds = telegramCreds(ctx.config);
|
|
64146
|
+
const escalateTelegram = cfg.escalate.telegram && creds !== null;
|
|
64147
|
+
const input = {
|
|
64148
|
+
feature: ctx.feature,
|
|
64149
|
+
workdir: ctx.workdir,
|
|
64150
|
+
branch: ctx.branch,
|
|
64151
|
+
prdPath: ctx.prdPath,
|
|
64152
|
+
escalateTelegram,
|
|
64153
|
+
timeouts: { acceptanceMs: cfg.timeouts.acceptanceMs, gateMs: cfg.timeouts.gateMs }
|
|
64154
|
+
};
|
|
64155
|
+
const cmd = buildFlowArgv(flowPath, JSON.stringify(input), cfg.defaultAgent, cfg.timeouts.stepMs);
|
|
64156
|
+
const res = await _naxFinishDeps.run(cmd, {
|
|
64157
|
+
cwd: ctx.workdir,
|
|
64158
|
+
env: buildFlowEnv(cfg),
|
|
64159
|
+
timeoutMs: cfg.timeouts.flowMs
|
|
64160
|
+
});
|
|
64161
|
+
const result = await _naxFinishDeps.readResult(ctx.workdir);
|
|
64162
|
+
if (!result) {
|
|
64163
|
+
return { success: res.exitCode === 0, message: `nax-finish flow exited ${res.exitCode} (no result file)` };
|
|
64164
|
+
}
|
|
64165
|
+
if (result.status === "escalated" && escalateTelegram && creds) {
|
|
64166
|
+
await _naxFinishDeps.notify(creds, `nax-finish escalated *${result.feature}*: ${result.escalationReason ?? ""}`);
|
|
64167
|
+
}
|
|
64168
|
+
return { success: true, message: `nax-finish: ${result.status}`, url: result.url };
|
|
64169
|
+
} catch (err) {
|
|
64170
|
+
ctx.logger.warn("nax-finish execute failed", { error: String(err) });
|
|
64171
|
+
return { success: false, message: `nax-finish failed: ${String(err)}` };
|
|
64172
|
+
}
|
|
64173
|
+
}
|
|
64174
|
+
};
|
|
64175
|
+
naxFinishPlugin = {
|
|
64176
|
+
name: PLUGIN_NAME4,
|
|
64177
|
+
version: PLUGIN_VERSION4,
|
|
64178
|
+
provides: ["post-run-action"],
|
|
64179
|
+
async setup(_config, _logger) {},
|
|
64180
|
+
async teardown() {},
|
|
64181
|
+
extensions: {
|
|
64182
|
+
postRunAction: naxFinishAction
|
|
64183
|
+
}
|
|
64184
|
+
};
|
|
64185
|
+
});
|
|
64186
|
+
|
|
63476
64187
|
// src/plugins/builtin/reporter-shared/interpolate.ts
|
|
63477
64188
|
function interpolateHeaders(headers, env2 = process.env) {
|
|
63478
64189
|
const resolved = {};
|
|
@@ -64075,14 +64786,14 @@ var init_validator = __esm(() => {
|
|
|
64075
64786
|
|
|
64076
64787
|
// src/plugins/loader.ts
|
|
64077
64788
|
import * as fs from "fs/promises";
|
|
64078
|
-
import * as
|
|
64789
|
+
import * as path22 from "path";
|
|
64079
64790
|
function getSafeLogger6() {
|
|
64080
64791
|
return getSafeLogger();
|
|
64081
64792
|
}
|
|
64082
64793
|
function extractPluginName(pluginPath) {
|
|
64083
|
-
const basename12 =
|
|
64794
|
+
const basename12 = path22.basename(pluginPath);
|
|
64084
64795
|
if (basename12 === "index.ts" || basename12 === "index.js" || basename12 === "index.mjs") {
|
|
64085
|
-
return
|
|
64796
|
+
return path22.basename(path22.dirname(pluginPath));
|
|
64086
64797
|
}
|
|
64087
64798
|
return basename12.replace(/\.(ts|js|mjs)$/, "");
|
|
64088
64799
|
}
|
|
@@ -64118,6 +64829,17 @@ async function loadPlugins(globalDir, projectDir, configPlugins, projectRoot, di
|
|
|
64118
64829
|
} else {
|
|
64119
64830
|
logger?.info("plugins", `Skipping disabled plugin: '${autoPrPlugin.name}' (built-in)`);
|
|
64120
64831
|
}
|
|
64832
|
+
if (!disabledSet.has(naxFinishPlugin.name)) {
|
|
64833
|
+
if (naxFinishPlugin.setup) {
|
|
64834
|
+
const pluginLogger = createPluginLogger(naxFinishPlugin.name);
|
|
64835
|
+
await naxFinishPlugin.setup({}, pluginLogger);
|
|
64836
|
+
}
|
|
64837
|
+
const action = naxFinishPlugin.extensions.postRunAction;
|
|
64838
|
+
if (action)
|
|
64839
|
+
builtinPostRunActions.push(action);
|
|
64840
|
+
} else {
|
|
64841
|
+
logger?.info("plugins", `Skipping disabled plugin: '${naxFinishPlugin.name}' (built-in)`);
|
|
64842
|
+
}
|
|
64121
64843
|
if (!disabledSet.has(autoRoutePlugin.name)) {
|
|
64122
64844
|
if (autoRoutePlugin.setup) {
|
|
64123
64845
|
const pluginLogger = createPluginLogger(autoRoutePlugin.name);
|
|
@@ -64219,7 +64941,7 @@ async function discoverPlugins(dir, isTestFileFn) {
|
|
|
64219
64941
|
try {
|
|
64220
64942
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
64221
64943
|
for (const entry of entries) {
|
|
64222
|
-
const fullPath =
|
|
64944
|
+
const fullPath = path22.join(dir, entry.name);
|
|
64223
64945
|
if (entry.isFile()) {
|
|
64224
64946
|
if (isPluginFile(entry.name, isTestFileFn)) {
|
|
64225
64947
|
discovered.push({ path: fullPath });
|
|
@@ -64227,7 +64949,7 @@ async function discoverPlugins(dir, isTestFileFn) {
|
|
|
64227
64949
|
} else if (entry.isDirectory()) {
|
|
64228
64950
|
const indexPaths = ["index.ts", "index.js", "index.mjs"];
|
|
64229
64951
|
for (const indexFile of indexPaths) {
|
|
64230
|
-
const indexPath =
|
|
64952
|
+
const indexPath = path22.join(fullPath, indexFile);
|
|
64231
64953
|
try {
|
|
64232
64954
|
await fs.access(indexPath);
|
|
64233
64955
|
discovered.push({ path: indexPath });
|
|
@@ -64252,13 +64974,13 @@ function isPluginFile(filename, isTestFileFn) {
|
|
|
64252
64974
|
return !FALLBACK_TEST_FILE_RE.test(filename);
|
|
64253
64975
|
}
|
|
64254
64976
|
function resolveModulePath(modulePath, projectRoot) {
|
|
64255
|
-
if (
|
|
64977
|
+
if (path22.isAbsolute(modulePath) || !modulePath.startsWith("./") && !modulePath.startsWith("../")) {
|
|
64256
64978
|
return modulePath;
|
|
64257
64979
|
}
|
|
64258
64980
|
if (projectRoot) {
|
|
64259
|
-
return
|
|
64981
|
+
return path22.resolve(projectRoot, modulePath);
|
|
64260
64982
|
}
|
|
64261
|
-
return
|
|
64983
|
+
return path22.resolve(modulePath);
|
|
64262
64984
|
}
|
|
64263
64985
|
async function loadAndValidatePlugin(initialModulePath, config2, allowedRoots = [], originalPath) {
|
|
64264
64986
|
let attemptedPath = initialModulePath;
|
|
@@ -64320,6 +65042,7 @@ var init_loader4 = __esm(() => {
|
|
|
64320
65042
|
init_auto_pr();
|
|
64321
65043
|
init_auto_route();
|
|
64322
65044
|
init_curator();
|
|
65045
|
+
init_nax_finish();
|
|
64323
65046
|
init_otel_reporter();
|
|
64324
65047
|
init_webhook_reporter();
|
|
64325
65048
|
init_plugin_logger();
|
|
@@ -64376,7 +65099,7 @@ var init_writer = __esm(() => {
|
|
|
64376
65099
|
});
|
|
64377
65100
|
|
|
64378
65101
|
// src/execution/checkpoint/reader.ts
|
|
64379
|
-
import { join as
|
|
65102
|
+
import { join as join82 } from "path";
|
|
64380
65103
|
function isValidRecord(value) {
|
|
64381
65104
|
if (!value || typeof value !== "object")
|
|
64382
65105
|
return false;
|
|
@@ -64409,7 +65132,7 @@ async function defaultRead(filePath) {
|
|
|
64409
65132
|
return file3.text();
|
|
64410
65133
|
}
|
|
64411
65134
|
async function loadCheckpoints(featureDir, options = { _deps: { read: defaultRead } }) {
|
|
64412
|
-
const filePath =
|
|
65135
|
+
const filePath = join82(featureDir, "checkpoint.jsonl");
|
|
64413
65136
|
const deps = options._deps ?? { read: defaultRead };
|
|
64414
65137
|
let content;
|
|
64415
65138
|
try {
|
|
@@ -64479,7 +65202,7 @@ var init_reader = __esm(() => {
|
|
|
64479
65202
|
});
|
|
64480
65203
|
|
|
64481
65204
|
// src/execution/checkpoint/resume-cli.ts
|
|
64482
|
-
import { join as
|
|
65205
|
+
import { join as join83 } from "path";
|
|
64483
65206
|
function applyResumeModeDeps(featureDir, mode = "auto") {
|
|
64484
65207
|
if (mode === "fresh" || mode === "no-resume") {
|
|
64485
65208
|
_storyOrchestratorDeps.loadCheckpoints = async (_fd) => new Map;
|
|
@@ -64489,7 +65212,7 @@ function applyResumeModeDeps(featureDir, mode = "auto") {
|
|
|
64489
65212
|
_storyOrchestratorDeps.loadCheckpoints = async (_fd) => loadCheckpoints(target);
|
|
64490
65213
|
}
|
|
64491
65214
|
function applyRecordGreenDeps(featureDir, runId) {
|
|
64492
|
-
const writer = createCheckpointWriter(
|
|
65215
|
+
const writer = createCheckpointWriter(join83(featureDir, "checkpoint.jsonl"), runId);
|
|
64493
65216
|
_storyOrchestratorDeps.recordGreen = (storyId, phase, tree) => writer.recordGreen(storyId, phase, tree);
|
|
64494
65217
|
}
|
|
64495
65218
|
var init_resume_cli = __esm(() => {
|
|
@@ -64519,11 +65242,11 @@ var init_checkpoint = __esm(() => {
|
|
|
64519
65242
|
});
|
|
64520
65243
|
|
|
64521
65244
|
// src/hooks/runner.ts
|
|
64522
|
-
import { join as
|
|
65245
|
+
import { join as join84 } from "path";
|
|
64523
65246
|
function createDrainDeadline2(deadlineMs) {
|
|
64524
65247
|
let timeoutId;
|
|
64525
|
-
const promise2 = new Promise((
|
|
64526
|
-
timeoutId = setTimeout(() =>
|
|
65248
|
+
const promise2 = new Promise((resolve17) => {
|
|
65249
|
+
timeoutId = setTimeout(() => resolve17(""), deadlineMs);
|
|
64527
65250
|
});
|
|
64528
65251
|
return {
|
|
64529
65252
|
promise: promise2,
|
|
@@ -64538,14 +65261,14 @@ async function loadHooksConfig(projectDir, globalDir) {
|
|
|
64538
65261
|
let globalHooks = { hooks: {} };
|
|
64539
65262
|
let projectHooks = { hooks: {} };
|
|
64540
65263
|
let skipGlobal = false;
|
|
64541
|
-
const projectPath =
|
|
65264
|
+
const projectPath = join84(projectDir, "hooks.json");
|
|
64542
65265
|
const projectData = await loadJsonFile(projectPath, "hooks");
|
|
64543
65266
|
if (projectData) {
|
|
64544
65267
|
projectHooks = projectData;
|
|
64545
65268
|
skipGlobal = projectData.skipGlobal ?? false;
|
|
64546
65269
|
}
|
|
64547
65270
|
if (!skipGlobal && globalDir) {
|
|
64548
|
-
const globalPath =
|
|
65271
|
+
const globalPath = join84(globalDir, "hooks.json");
|
|
64549
65272
|
const globalData = await loadJsonFile(globalPath, "hooks");
|
|
64550
65273
|
if (globalData) {
|
|
64551
65274
|
globalHooks = globalData;
|
|
@@ -65053,7 +65776,7 @@ var init_crash_recovery = __esm(() => {
|
|
|
65053
65776
|
});
|
|
65054
65777
|
|
|
65055
65778
|
// src/acceptance/import-resolution.ts
|
|
65056
|
-
import { resolve as
|
|
65779
|
+
import { resolve as resolve17, sep as sep5 } from "path";
|
|
65057
65780
|
function languageFromExtension(testFilePath) {
|
|
65058
65781
|
if (!testFilePath)
|
|
65059
65782
|
return;
|
|
@@ -65075,8 +65798,8 @@ async function resolveLanguage(opts) {
|
|
|
65075
65798
|
return "typescript";
|
|
65076
65799
|
}
|
|
65077
65800
|
async function readCapped(relPath, packageDir) {
|
|
65078
|
-
const resolvedPackageDir =
|
|
65079
|
-
const fullPath =
|
|
65801
|
+
const resolvedPackageDir = resolve17(packageDir);
|
|
65802
|
+
const fullPath = resolve17(resolvedPackageDir, relPath);
|
|
65080
65803
|
if (fullPath !== resolvedPackageDir && !fullPath.startsWith(resolvedPackageDir + sep5)) {
|
|
65081
65804
|
return null;
|
|
65082
65805
|
}
|
|
@@ -65258,7 +65981,7 @@ var init_fix_diagnosis = __esm(() => {
|
|
|
65258
65981
|
});
|
|
65259
65982
|
|
|
65260
65983
|
// src/execution/lifecycle/acceptance-helpers.ts
|
|
65261
|
-
import
|
|
65984
|
+
import path24 from "path";
|
|
65262
65985
|
function isStubTestFile(content) {
|
|
65263
65986
|
return isStubTestContent(content);
|
|
65264
65987
|
}
|
|
@@ -65277,7 +66000,7 @@ function isTestLevelFailure(failedACs, totalACs, semanticVerdicts) {
|
|
|
65277
66000
|
async function loadSpecContent(featureDir) {
|
|
65278
66001
|
if (!featureDir)
|
|
65279
66002
|
return "";
|
|
65280
|
-
const specPath =
|
|
66003
|
+
const specPath = path24.join(featureDir, "spec.md");
|
|
65281
66004
|
const specFile = Bun.file(specPath);
|
|
65282
66005
|
return await specFile.exists() ? await specFile.text() : "";
|
|
65283
66006
|
}
|
|
@@ -65297,7 +66020,7 @@ async function loadAcceptanceTestContent2(featureDir, testPaths, configuredTestP
|
|
|
65297
66020
|
}
|
|
65298
66021
|
if (!configuredTestPath)
|
|
65299
66022
|
return [];
|
|
65300
|
-
const resolvedPath =
|
|
66023
|
+
const resolvedPath = path24.join(featureDir, configuredTestPath);
|
|
65301
66024
|
const testFile = Bun.file(resolvedPath);
|
|
65302
66025
|
const content = await testFile.exists() ? await testFile.text() : "";
|
|
65303
66026
|
return [{ content, path: resolvedPath }];
|
|
@@ -65314,7 +66037,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
|
|
|
65314
66037
|
const { unlink: unlink3 } = await import("fs/promises");
|
|
65315
66038
|
await unlink3(testPath);
|
|
65316
66039
|
if (acceptanceContext.featureDir) {
|
|
65317
|
-
const metaPath =
|
|
66040
|
+
const metaPath = path24.join(acceptanceContext.featureDir, "acceptance-meta.json");
|
|
65318
66041
|
try {
|
|
65319
66042
|
await unlink3(metaPath);
|
|
65320
66043
|
} catch {}
|
|
@@ -65328,7 +66051,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
|
|
|
65328
66051
|
const changedFilesRaw = diffOutput.split(`
|
|
65329
66052
|
`).map((f) => f.trim()).filter((f) => f.length > 0);
|
|
65330
66053
|
const repoRoot = acceptanceContext.projectDir ?? workdir;
|
|
65331
|
-
const packageDir = acceptanceContext.story.workdir && acceptanceContext.projectDir ?
|
|
66054
|
+
const packageDir = acceptanceContext.story.workdir && acceptanceContext.projectDir ? path24.join(acceptanceContext.projectDir, acceptanceContext.story.workdir) : undefined;
|
|
65332
66055
|
const ignoreMatchers = acceptanceContext.naxIgnoreIndex?.getMatchers(packageDir) ?? await resolveNaxIgnorePatterns(repoRoot, packageDir);
|
|
65333
66056
|
const changedFiles = filterNaxInternalPaths(changedFilesRaw, ignoreMatchers);
|
|
65334
66057
|
const MAX_BYTES = 51200;
|
|
@@ -65337,7 +66060,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
|
|
|
65337
66060
|
for (const file3 of changedFiles) {
|
|
65338
66061
|
if (totalBytes >= MAX_BYTES)
|
|
65339
66062
|
break;
|
|
65340
|
-
const filePath =
|
|
66063
|
+
const filePath = path24.join(workdir, file3);
|
|
65341
66064
|
try {
|
|
65342
66065
|
const fileContent = await _regenerateDeps.readFile(filePath);
|
|
65343
66066
|
const remaining = MAX_BYTES - totalBytes;
|
|
@@ -65775,15 +66498,15 @@ var init_acceptance_loop = __esm(() => {
|
|
|
65775
66498
|
|
|
65776
66499
|
// src/session/scratch-purge.ts
|
|
65777
66500
|
import { mkdir as mkdir12, rename, rm } from "fs/promises";
|
|
65778
|
-
import { dirname as
|
|
66501
|
+
import { dirname as dirname14, join as join85 } from "path";
|
|
65779
66502
|
async function purgeStaleScratch(projectDir, featureName, retentionDays, archiveInsteadOfDelete = false) {
|
|
65780
|
-
const sessionsDir =
|
|
66503
|
+
const sessionsDir = join85(projectDir, ".nax", "features", featureName, "sessions");
|
|
65781
66504
|
const sessionIds = await _scratchPurgeDeps.listSessionDirs(sessionsDir);
|
|
65782
66505
|
const cutoffMs = _scratchPurgeDeps.now() - retentionDays * 86400000;
|
|
65783
66506
|
let purged = 0;
|
|
65784
66507
|
for (const sessionId of sessionIds) {
|
|
65785
|
-
const sessionDir =
|
|
65786
|
-
const descriptorPath =
|
|
66508
|
+
const sessionDir = join85(sessionsDir, sessionId);
|
|
66509
|
+
const descriptorPath = join85(sessionDir, "descriptor.json");
|
|
65787
66510
|
if (!await _scratchPurgeDeps.fileExists(descriptorPath))
|
|
65788
66511
|
continue;
|
|
65789
66512
|
let lastActivityAt;
|
|
@@ -65799,7 +66522,7 @@ async function purgeStaleScratch(projectDir, featureName, retentionDays, archive
|
|
|
65799
66522
|
if (new Date(lastActivityAt).getTime() >= cutoffMs)
|
|
65800
66523
|
continue;
|
|
65801
66524
|
if (archiveInsteadOfDelete) {
|
|
65802
|
-
const archiveDest =
|
|
66525
|
+
const archiveDest = join85(projectDir, ".nax", "features", featureName, "_archive", "sessions", sessionId);
|
|
65803
66526
|
await _scratchPurgeDeps.move(sessionDir, archiveDest);
|
|
65804
66527
|
} else {
|
|
65805
66528
|
await _scratchPurgeDeps.remove(sessionDir);
|
|
@@ -65822,11 +66545,11 @@ var init_scratch_purge = __esm(() => {
|
|
|
65822
66545
|
return [];
|
|
65823
66546
|
}
|
|
65824
66547
|
},
|
|
65825
|
-
fileExists: (
|
|
65826
|
-
readFile: (
|
|
65827
|
-
remove: (
|
|
66548
|
+
fileExists: (path25) => Bun.file(path25).exists(),
|
|
66549
|
+
readFile: (path25) => Bun.file(path25).text(),
|
|
66550
|
+
remove: (path25) => rm(path25, { recursive: true, force: true }),
|
|
65828
66551
|
move: async (src, dest) => {
|
|
65829
|
-
await mkdir12(
|
|
66552
|
+
await mkdir12(dirname14(dest), { recursive: true });
|
|
65830
66553
|
await rename(src, dest);
|
|
65831
66554
|
},
|
|
65832
66555
|
now: () => Date.now()
|
|
@@ -66670,7 +67393,7 @@ var init_headless_formatter = __esm(() => {
|
|
|
66670
67393
|
});
|
|
66671
67394
|
|
|
66672
67395
|
// src/execution/runner-completion.ts
|
|
66673
|
-
import
|
|
67396
|
+
import path25 from "path";
|
|
66674
67397
|
async function runCompletionPhase(options) {
|
|
66675
67398
|
const logger = getSafeLogger();
|
|
66676
67399
|
logger?.debug("execution", "Completion phase started", {
|
|
@@ -66690,11 +67413,11 @@ async function runCompletionPhase(options) {
|
|
|
66690
67413
|
options.statusWriter.setPostRunPhase("acceptance", { status: "running" });
|
|
66691
67414
|
pipelineEventBus.emit({ type: "postrun:phase:started", phase: "acceptance" });
|
|
66692
67415
|
const acceptanceTestPaths = options.featureDir ? await Promise.all((await groupStoriesByPackage(options.prd, options.workdir, options.feature, options.config.acceptance.testPath, options.config.project?.language)).map(async (g) => {
|
|
66693
|
-
const relativeWorkdir =
|
|
67416
|
+
const relativeWorkdir = path25.relative(options.workdir, g.packageDir);
|
|
66694
67417
|
let groupConfig = options.config;
|
|
66695
67418
|
if (relativeWorkdir && relativeWorkdir !== ".") {
|
|
66696
67419
|
try {
|
|
66697
|
-
groupConfig = await _runnerCompletionDeps.loadConfigForWorkdir(
|
|
67420
|
+
groupConfig = await _runnerCompletionDeps.loadConfigForWorkdir(path25.join(options.workdir, ".nax", "config.json"), relativeWorkdir);
|
|
66698
67421
|
} catch (error48) {
|
|
66699
67422
|
logger?.warn("execution", "Falling back to root config for package acceptance settings", {
|
|
66700
67423
|
packageDir: g.packageDir,
|
|
@@ -66924,7 +67647,7 @@ function precomputeBatchPlan(stories, maxBatchSize = DEFAULT_MAX_BATCH_SIZE) {
|
|
|
66924
67647
|
var DEFAULT_MAX_BATCH_SIZE = 4;
|
|
66925
67648
|
|
|
66926
67649
|
// src/execution/ensure-package-dirs.ts
|
|
66927
|
-
import
|
|
67650
|
+
import path26 from "path";
|
|
66928
67651
|
async function ensureStoryPackageDirs(prd, workdir, deps = _ensurePackageDirsDeps) {
|
|
66929
67652
|
const logger = getSafeLogger();
|
|
66930
67653
|
const relToStoryId = new Map;
|
|
@@ -66937,8 +67660,8 @@ async function ensureStoryPackageDirs(prd, workdir, deps = _ensurePackageDirsDep
|
|
|
66937
67660
|
}
|
|
66938
67661
|
const created = [];
|
|
66939
67662
|
for (const [rel, storyId] of relToStoryId) {
|
|
66940
|
-
const abs =
|
|
66941
|
-
const rootWithSep = workdir.endsWith(
|
|
67663
|
+
const abs = path26.resolve(workdir, rel);
|
|
67664
|
+
const rootWithSep = workdir.endsWith(path26.sep) ? workdir : workdir + path26.sep;
|
|
66942
67665
|
if (abs !== workdir && !abs.startsWith(rootWithSep)) {
|
|
66943
67666
|
logger?.warn("execution", "Skipping story workdir outside repo root", {
|
|
66944
67667
|
storyId,
|
|
@@ -66980,12 +67703,12 @@ var init_ensure_package_dirs = __esm(() => {
|
|
|
66980
67703
|
|
|
66981
67704
|
// src/pipeline/subscribers/events-writer.ts
|
|
66982
67705
|
import { appendFile as appendFile5, mkdir as mkdir13 } from "fs/promises";
|
|
66983
|
-
import { basename as basename15, join as
|
|
67706
|
+
import { basename as basename15, join as join86 } from "path";
|
|
66984
67707
|
function wireEventsWriter(bus, feature, runId, workdir) {
|
|
66985
67708
|
const logger = getSafeLogger();
|
|
66986
67709
|
const project = basename15(workdir);
|
|
66987
|
-
const eventsDir =
|
|
66988
|
-
const eventsFile =
|
|
67710
|
+
const eventsDir = join86(getEventsRootDir(), project);
|
|
67711
|
+
const eventsFile = join86(eventsDir, "events.jsonl");
|
|
66989
67712
|
let dirReady = false;
|
|
66990
67713
|
const write = (line) => {
|
|
66991
67714
|
return (async () => {
|
|
@@ -67166,12 +67889,12 @@ var init_interaction2 = __esm(() => {
|
|
|
67166
67889
|
|
|
67167
67890
|
// src/pipeline/subscribers/registry.ts
|
|
67168
67891
|
import { mkdir as mkdir14, writeFile as writeFile2 } from "fs/promises";
|
|
67169
|
-
import { basename as basename16, join as
|
|
67892
|
+
import { basename as basename16, join as join87 } from "path";
|
|
67170
67893
|
function wireRegistry(bus, feature, runId, workdir, outputDir) {
|
|
67171
67894
|
const logger = getSafeLogger();
|
|
67172
67895
|
const project = basename16(workdir);
|
|
67173
|
-
const runDir =
|
|
67174
|
-
const metaFile =
|
|
67896
|
+
const runDir = join87(getRunsDir(), `${project}-${feature}-${runId}`);
|
|
67897
|
+
const metaFile = join87(runDir, "meta.json");
|
|
67175
67898
|
const unsub = bus.on("run:started", (_ev) => {
|
|
67176
67899
|
return (async () => {
|
|
67177
67900
|
try {
|
|
@@ -67181,8 +67904,8 @@ function wireRegistry(bus, feature, runId, workdir, outputDir) {
|
|
|
67181
67904
|
project,
|
|
67182
67905
|
feature,
|
|
67183
67906
|
workdir,
|
|
67184
|
-
statusPath:
|
|
67185
|
-
eventsDir:
|
|
67907
|
+
statusPath: join87(outputDir, "features", feature, "status.json"),
|
|
67908
|
+
eventsDir: join87(outputDir, "features", feature, "runs"),
|
|
67186
67909
|
registeredAt: new Date().toISOString()
|
|
67187
67910
|
};
|
|
67188
67911
|
await writeFile2(metaFile, JSON.stringify(meta3, null, 2));
|
|
@@ -67428,7 +68151,7 @@ var init_types10 = __esm(() => {
|
|
|
67428
68151
|
|
|
67429
68152
|
// src/worktree/dependencies.ts
|
|
67430
68153
|
import { existsSync as existsSync33 } from "fs";
|
|
67431
|
-
import { join as
|
|
68154
|
+
import { join as join88 } from "path";
|
|
67432
68155
|
async function prepareWorktreeDependencies(options) {
|
|
67433
68156
|
const mode = options.config.execution.worktreeDependencies.mode;
|
|
67434
68157
|
const resolvedCwd = resolveDependencyCwd(options);
|
|
@@ -67442,7 +68165,7 @@ async function prepareWorktreeDependencies(options) {
|
|
|
67442
68165
|
}
|
|
67443
68166
|
}
|
|
67444
68167
|
function resolveDependencyCwd(options) {
|
|
67445
|
-
return options.storyWorkdir ?
|
|
68168
|
+
return options.storyWorkdir ? join88(options.worktreeRoot, options.storyWorkdir) : options.worktreeRoot;
|
|
67446
68169
|
}
|
|
67447
68170
|
function resolveInheritedDependencies(options, resolvedCwd) {
|
|
67448
68171
|
if (hasDependencyManifests(options.worktreeRoot, resolvedCwd)) {
|
|
@@ -67452,7 +68175,7 @@ function resolveInheritedDependencies(options, resolvedCwd) {
|
|
|
67452
68175
|
}
|
|
67453
68176
|
function hasDependencyManifests(worktreeRoot, resolvedCwd) {
|
|
67454
68177
|
const directories = resolvedCwd === worktreeRoot ? [worktreeRoot] : [worktreeRoot, resolvedCwd];
|
|
67455
|
-
return directories.some((directory) => PHASE_ONE_INHERIT_UNSUPPORTED_FILES.some((filename) => _worktreeDependencyDeps.existsSync(
|
|
68178
|
+
return directories.some((directory) => PHASE_ONE_INHERIT_UNSUPPORTED_FILES.some((filename) => _worktreeDependencyDeps.existsSync(join88(directory, filename))));
|
|
67456
68179
|
}
|
|
67457
68180
|
async function provisionDependencies(config2, worktreeRoot, resolvedCwd) {
|
|
67458
68181
|
const setupCommand2 = config2.execution.worktreeDependencies.setupCommand;
|
|
@@ -67516,13 +68239,13 @@ __export(exports_manager, {
|
|
|
67516
68239
|
});
|
|
67517
68240
|
import { existsSync as existsSync34, symlinkSync } from "fs";
|
|
67518
68241
|
import { mkdir as mkdir15 } from "fs/promises";
|
|
67519
|
-
import { join as
|
|
68242
|
+
import { join as join89 } from "path";
|
|
67520
68243
|
|
|
67521
68244
|
class WorktreeManager {
|
|
67522
68245
|
async ensureGitExcludes(projectRoot) {
|
|
67523
68246
|
const logger = getSafeLogger();
|
|
67524
|
-
const infoDir =
|
|
67525
|
-
const excludePath =
|
|
68247
|
+
const infoDir = join89(projectRoot, ".git", "info");
|
|
68248
|
+
const excludePath = join89(infoDir, "exclude");
|
|
67526
68249
|
try {
|
|
67527
68250
|
await mkdir15(infoDir, { recursive: true });
|
|
67528
68251
|
let existing = "";
|
|
@@ -67549,7 +68272,7 @@ ${missing.join(`
|
|
|
67549
68272
|
}
|
|
67550
68273
|
async create(projectRoot, storyId) {
|
|
67551
68274
|
validateStoryId(storyId);
|
|
67552
|
-
const worktreePath =
|
|
68275
|
+
const worktreePath = join89(projectRoot, ".nax-wt", storyId);
|
|
67553
68276
|
const branchName = `nax/${storyId}`;
|
|
67554
68277
|
try {
|
|
67555
68278
|
const pruneProc = _managerDeps.spawn(["git", "worktree", "prune"], {
|
|
@@ -67610,9 +68333,9 @@ ${missing.join(`
|
|
|
67610
68333
|
projectRoot
|
|
67611
68334
|
});
|
|
67612
68335
|
}
|
|
67613
|
-
const envSource =
|
|
68336
|
+
const envSource = join89(projectRoot, ".env");
|
|
67614
68337
|
if (existsSync34(envSource)) {
|
|
67615
|
-
const envTarget =
|
|
68338
|
+
const envTarget = join89(worktreePath, ".env");
|
|
67616
68339
|
try {
|
|
67617
68340
|
symlinkSync(envSource, envTarget, "file");
|
|
67618
68341
|
} catch (error48) {
|
|
@@ -67628,7 +68351,7 @@ ${missing.join(`
|
|
|
67628
68351
|
}
|
|
67629
68352
|
async remove(projectRoot, storyId) {
|
|
67630
68353
|
validateStoryId(storyId);
|
|
67631
|
-
const worktreePath =
|
|
68354
|
+
const worktreePath = join89(projectRoot, ".nax-wt", storyId);
|
|
67632
68355
|
const branchName = `nax/${storyId}`;
|
|
67633
68356
|
try {
|
|
67634
68357
|
const proc = _managerDeps.spawn(["git", "worktree", "remove", worktreePath, "--force"], {
|
|
@@ -68097,9 +68820,9 @@ var _quoteIntegrityDeps, CONTEXT_LINES = 3;
|
|
|
68097
68820
|
var init_quote_integrity = __esm(() => {
|
|
68098
68821
|
init_logger2();
|
|
68099
68822
|
_quoteIntegrityDeps = {
|
|
68100
|
-
readFile: async (
|
|
68823
|
+
readFile: async (path27) => {
|
|
68101
68824
|
try {
|
|
68102
|
-
return await Bun.file(
|
|
68825
|
+
return await Bun.file(path27).text();
|
|
68103
68826
|
} catch {
|
|
68104
68827
|
return null;
|
|
68105
68828
|
}
|
|
@@ -68388,7 +69111,7 @@ var exports_merge_conflict_rectify = {};
|
|
|
68388
69111
|
__export(exports_merge_conflict_rectify, {
|
|
68389
69112
|
rectifyConflictedStory: () => rectifyConflictedStory
|
|
68390
69113
|
});
|
|
68391
|
-
import
|
|
69114
|
+
import path27 from "path";
|
|
68392
69115
|
async function closeStaleAcpSession(worktreePath, sessionName) {
|
|
68393
69116
|
const logger = getSafeLogger();
|
|
68394
69117
|
try {
|
|
@@ -68415,7 +69138,7 @@ async function rectifyConflictedStory(options) {
|
|
|
68415
69138
|
await worktreeManager.remove(workdir, storyId);
|
|
68416
69139
|
} catch {}
|
|
68417
69140
|
await worktreeManager.create(workdir, storyId);
|
|
68418
|
-
const worktreePath =
|
|
69141
|
+
const worktreePath = path27.join(workdir, ".nax-wt", storyId);
|
|
68419
69142
|
const { formatSessionName: formatSessionName2 } = await Promise.resolve().then(() => (init_naming(), exports_naming));
|
|
68420
69143
|
const staleSessionName = formatSessionName2({
|
|
68421
69144
|
workdir: worktreePath,
|
|
@@ -68480,10 +69203,10 @@ var init_merge_conflict_rectify = __esm(() => {
|
|
|
68480
69203
|
});
|
|
68481
69204
|
|
|
68482
69205
|
// src/execution/pipeline-result-handler.ts
|
|
68483
|
-
import { join as
|
|
69206
|
+
import { join as join90 } from "path";
|
|
68484
69207
|
async function removeWorktreeDirectory(projectRoot, storyId) {
|
|
68485
69208
|
const logger = getSafeLogger();
|
|
68486
|
-
const worktreePath =
|
|
69209
|
+
const worktreePath = join90(projectRoot, ".nax-wt", storyId);
|
|
68487
69210
|
try {
|
|
68488
69211
|
const proc = _resultHandlerDeps.spawn(["git", "worktree", "remove", worktreePath, "--force"], {
|
|
68489
69212
|
cwd: projectRoot,
|
|
@@ -68700,7 +69423,7 @@ var init_pipeline_result_handler = __esm(() => {
|
|
|
68700
69423
|
|
|
68701
69424
|
// src/execution/iteration-runner.ts
|
|
68702
69425
|
import { existsSync as existsSync35 } from "fs";
|
|
68703
|
-
import { join as
|
|
69426
|
+
import { join as join91 } from "path";
|
|
68704
69427
|
async function runIteration(ctx, prd, selection, iterations, totalCost2, allStoryMetrics) {
|
|
68705
69428
|
const { story, storiesToExecute, routing, isBatchExecution } = selection;
|
|
68706
69429
|
if (ctx.dryRun) {
|
|
@@ -68725,7 +69448,7 @@ async function runIteration(ctx, prd, selection, iterations, totalCost2, allStor
|
|
|
68725
69448
|
const storyStartTime = Date.now();
|
|
68726
69449
|
let effectiveWorkdir = ctx.workdir;
|
|
68727
69450
|
if (ctx.config.execution.storyIsolation === "worktree") {
|
|
68728
|
-
const worktreePath =
|
|
69451
|
+
const worktreePath = join91(ctx.workdir, ".nax-wt", story.id);
|
|
68729
69452
|
const worktreeExists = _iterationRunnerDeps.existsSync(worktreePath);
|
|
68730
69453
|
if (!worktreeExists) {
|
|
68731
69454
|
await _iterationRunnerDeps.worktreeManager.ensureGitExcludes(ctx.workdir);
|
|
@@ -68745,7 +69468,7 @@ async function runIteration(ctx, prd, selection, iterations, totalCost2, allStor
|
|
|
68745
69468
|
}
|
|
68746
69469
|
const accumulatedAttemptCost = (story.priorFailures || []).reduce((sum, f) => sum + (f.cost || 0), 0);
|
|
68747
69470
|
const profileOverride = profileOverrideFromConfig(ctx.config);
|
|
68748
|
-
const effectiveConfig = story.workdir ? await _iterationRunnerDeps.loadConfigForWorkdir(
|
|
69471
|
+
const effectiveConfig = story.workdir ? await _iterationRunnerDeps.loadConfigForWorkdir(join91(ctx.workdir, ".nax", "config.json"), story.workdir, profileOverride) : ctx.config;
|
|
68749
69472
|
let dependencyContext;
|
|
68750
69473
|
if (ctx.config.execution.storyIsolation === "worktree") {
|
|
68751
69474
|
try {
|
|
@@ -68772,7 +69495,7 @@ async function runIteration(ctx, prd, selection, iterations, totalCost2, allStor
|
|
|
68772
69495
|
};
|
|
68773
69496
|
}
|
|
68774
69497
|
}
|
|
68775
|
-
const resolvedWorkdir = dependencyContext?.cwd ? dependencyContext.cwd : ctx.config.execution.storyIsolation === "worktree" ? story.workdir ?
|
|
69498
|
+
const resolvedWorkdir = dependencyContext?.cwd ? dependencyContext.cwd : ctx.config.execution.storyIsolation === "worktree" ? story.workdir ? join91(effectiveWorkdir, story.workdir) : effectiveWorkdir : story.workdir ? join91(ctx.workdir, story.workdir) : ctx.workdir;
|
|
68776
69499
|
const pipelineContext = {
|
|
68777
69500
|
config: effectiveConfig,
|
|
68778
69501
|
rootConfig: ctx.config,
|
|
@@ -68975,7 +69698,7 @@ __export(exports_parallel_worker, {
|
|
|
68975
69698
|
buildWorktreePipelineContext: () => buildWorktreePipelineContext,
|
|
68976
69699
|
_parallelWorkerDeps: () => _parallelWorkerDeps
|
|
68977
69700
|
});
|
|
68978
|
-
import { join as
|
|
69701
|
+
import { join as join92 } from "path";
|
|
68979
69702
|
function buildWorktreePipelineContext(base, _story) {
|
|
68980
69703
|
return { ...base, prd: structuredClone(base.prd) };
|
|
68981
69704
|
}
|
|
@@ -68998,7 +69721,7 @@ async function executeStoryInWorktree(story, worktreePath, dependencyContext, co
|
|
|
68998
69721
|
story,
|
|
68999
69722
|
stories: [story],
|
|
69000
69723
|
projectDir: context.projectDir,
|
|
69001
|
-
workdir: dependencyContext.cwd ?? (story.workdir ?
|
|
69724
|
+
workdir: dependencyContext.cwd ?? (story.workdir ? join92(worktreePath, story.workdir) : worktreePath),
|
|
69002
69725
|
worktreeDependencyContext: dependencyContext,
|
|
69003
69726
|
routing,
|
|
69004
69727
|
storyGitRef: storyGitRef ?? undefined
|
|
@@ -69099,7 +69822,7 @@ __export(exports_parallel_batch, {
|
|
|
69099
69822
|
runParallelBatch: () => runParallelBatch,
|
|
69100
69823
|
_parallelBatchDeps: () => _parallelBatchDeps
|
|
69101
69824
|
});
|
|
69102
|
-
import
|
|
69825
|
+
import path28 from "path";
|
|
69103
69826
|
async function runParallelBatch(options) {
|
|
69104
69827
|
const { stories, ctx, prd } = options;
|
|
69105
69828
|
const { workdir, config: config2, maxConcurrency, pipelineContext, eventEmitter, agentGetFn, hooks, pluginRegistry } = ctx;
|
|
@@ -69118,9 +69841,9 @@ async function runParallelBatch(options) {
|
|
|
69118
69841
|
});
|
|
69119
69842
|
throw error48;
|
|
69120
69843
|
}
|
|
69121
|
-
worktreePaths.set(story.id,
|
|
69844
|
+
worktreePaths.set(story.id, path28.join(workdir, ".nax-wt", story.id));
|
|
69122
69845
|
}
|
|
69123
|
-
const rootConfigPath =
|
|
69846
|
+
const rootConfigPath = path28.join(workdir, ".nax", "config.json");
|
|
69124
69847
|
const profileOverride = profileOverrideFromConfig(config2);
|
|
69125
69848
|
const storyEffectiveConfigs = new Map;
|
|
69126
69849
|
const configResults = await Promise.allSettled(stories.filter((story) => story.workdir).map(async (story) => {
|
|
@@ -69958,7 +70681,7 @@ var init_runner_execution = __esm(() => {
|
|
|
69958
70681
|
|
|
69959
70682
|
// src/execution/status-file.ts
|
|
69960
70683
|
import { rename as rename2, unlink as unlink3 } from "fs/promises";
|
|
69961
|
-
import { resolve as
|
|
70684
|
+
import { resolve as resolve18 } from "path";
|
|
69962
70685
|
function countProgress(prd) {
|
|
69963
70686
|
const stories = prd.userStories;
|
|
69964
70687
|
const passed = stories.filter((s) => s.status === "passed").length;
|
|
@@ -70003,7 +70726,7 @@ function buildStatusSnapshot(state) {
|
|
|
70003
70726
|
return snapshot;
|
|
70004
70727
|
}
|
|
70005
70728
|
async function writeStatusFile(filePath, status) {
|
|
70006
|
-
const resolvedPath =
|
|
70729
|
+
const resolvedPath = resolve18(filePath);
|
|
70007
70730
|
if (filePath.includes("../") || filePath.includes("..\\")) {
|
|
70008
70731
|
throw new Error("Invalid status file path: path traversal detected");
|
|
70009
70732
|
}
|
|
@@ -70017,7 +70740,7 @@ async function writeStatusFile(filePath, status) {
|
|
|
70017
70740
|
var init_status_file = () => {};
|
|
70018
70741
|
|
|
70019
70742
|
// src/execution/status-writer.ts
|
|
70020
|
-
import { join as
|
|
70743
|
+
import { join as join93 } from "path";
|
|
70021
70744
|
|
|
70022
70745
|
class StatusWriter {
|
|
70023
70746
|
statusFile;
|
|
@@ -70136,7 +70859,7 @@ class StatusWriter {
|
|
|
70136
70859
|
if (!this._prd)
|
|
70137
70860
|
return;
|
|
70138
70861
|
const safeLogger = getSafeLogger();
|
|
70139
|
-
const featureStatusPath =
|
|
70862
|
+
const featureStatusPath = join93(featureDir, "status.json");
|
|
70140
70863
|
const write = async () => {
|
|
70141
70864
|
try {
|
|
70142
70865
|
const base = this.getSnapshot(totalCost2, iterations);
|
|
@@ -70169,7 +70892,7 @@ __export(exports_migrate, {
|
|
|
70169
70892
|
});
|
|
70170
70893
|
import { existsSync as existsSync36 } from "fs";
|
|
70171
70894
|
import { mkdir as mkdir16, readdir as readdir5, rename as rename3 } from "fs/promises";
|
|
70172
|
-
import
|
|
70895
|
+
import path29 from "path";
|
|
70173
70896
|
async function detectGeneratedContent(naxDir) {
|
|
70174
70897
|
if (!existsSync36(naxDir))
|
|
70175
70898
|
return [];
|
|
@@ -70182,17 +70905,17 @@ async function detectGeneratedContent(naxDir) {
|
|
|
70182
70905
|
}
|
|
70183
70906
|
for (const entry of entries) {
|
|
70184
70907
|
if (GENERATED_NAMES.has(entry)) {
|
|
70185
|
-
candidates.push({ name: entry, srcPath:
|
|
70908
|
+
candidates.push({ name: entry, srcPath: path29.join(naxDir, entry) });
|
|
70186
70909
|
}
|
|
70187
70910
|
}
|
|
70188
|
-
const featuresDir =
|
|
70911
|
+
const featuresDir = path29.join(naxDir, "features");
|
|
70189
70912
|
if (existsSync36(featuresDir)) {
|
|
70190
70913
|
let featureDirs = [];
|
|
70191
70914
|
try {
|
|
70192
70915
|
featureDirs = await readdir5(featuresDir);
|
|
70193
70916
|
} catch {}
|
|
70194
70917
|
for (const fid of featureDirs) {
|
|
70195
|
-
const featureDir =
|
|
70918
|
+
const featureDir = path29.join(featuresDir, fid);
|
|
70196
70919
|
let subEntries = [];
|
|
70197
70920
|
try {
|
|
70198
70921
|
subEntries = await readdir5(featureDir);
|
|
@@ -70202,12 +70925,12 @@ async function detectGeneratedContent(naxDir) {
|
|
|
70202
70925
|
for (const sub of subEntries) {
|
|
70203
70926
|
if (GENERATED_FEATURE_SUBNAMES.has(sub)) {
|
|
70204
70927
|
candidates.push({
|
|
70205
|
-
name:
|
|
70206
|
-
srcPath:
|
|
70928
|
+
name: path29.join("features", fid, sub),
|
|
70929
|
+
srcPath: path29.join(featureDir, sub)
|
|
70207
70930
|
});
|
|
70208
70931
|
}
|
|
70209
70932
|
if (sub === "stories") {
|
|
70210
|
-
const storiesDir =
|
|
70933
|
+
const storiesDir = path29.join(featureDir, "stories");
|
|
70211
70934
|
let storyDirs = [];
|
|
70212
70935
|
try {
|
|
70213
70936
|
storyDirs = await readdir5(storiesDir);
|
|
@@ -70215,7 +70938,7 @@ async function detectGeneratedContent(naxDir) {
|
|
|
70215
70938
|
continue;
|
|
70216
70939
|
}
|
|
70217
70940
|
for (const sid of storyDirs) {
|
|
70218
|
-
const storyDir =
|
|
70941
|
+
const storyDir = path29.join(storiesDir, sid);
|
|
70219
70942
|
let storyEntries = [];
|
|
70220
70943
|
try {
|
|
70221
70944
|
storyEntries = await readdir5(storyDir);
|
|
@@ -70225,8 +70948,8 @@ async function detectGeneratedContent(naxDir) {
|
|
|
70225
70948
|
for (const se of storyEntries) {
|
|
70226
70949
|
if (se.startsWith("context-manifest-") && se.endsWith(".json")) {
|
|
70227
70950
|
candidates.push({
|
|
70228
|
-
name:
|
|
70229
|
-
srcPath:
|
|
70951
|
+
name: path29.join("features", fid, "stories", sid, se),
|
|
70952
|
+
srcPath: path29.join(storyDir, se)
|
|
70230
70953
|
});
|
|
70231
70954
|
}
|
|
70232
70955
|
}
|
|
@@ -70247,15 +70970,15 @@ async function migrateCommand(options) {
|
|
|
70247
70970
|
name: options.reclaim
|
|
70248
70971
|
});
|
|
70249
70972
|
}
|
|
70250
|
-
const src =
|
|
70973
|
+
const src = path29.join(globalConfigDir(), options.reclaim);
|
|
70251
70974
|
if (!existsSync36(src)) {
|
|
70252
70975
|
throw new NaxError(`Nothing to reclaim: ~/.nax/${options.reclaim} does not exist`, "MIGRATE_RECLAIM_NOT_FOUND", {
|
|
70253
70976
|
stage: "migrate",
|
|
70254
70977
|
name: options.reclaim
|
|
70255
70978
|
});
|
|
70256
70979
|
}
|
|
70257
|
-
const archiveBase =
|
|
70258
|
-
const archiveDest =
|
|
70980
|
+
const archiveBase = path29.join(globalConfigDir(), "_archive");
|
|
70981
|
+
const archiveDest = path29.join(archiveBase, `${options.reclaim}-${Date.now()}`);
|
|
70259
70982
|
await mkdir16(archiveBase, { recursive: true });
|
|
70260
70983
|
await rename3(src, archiveDest);
|
|
70261
70984
|
logger.info("migrate", `Reclaimed: archived to ${archiveDest}`, { storyId: "_migrate" });
|
|
@@ -70292,8 +71015,8 @@ async function migrateCommand(options) {
|
|
|
70292
71015
|
logger.info("migrate", `Merged: identity for "${options.merge}" updated`, { storyId: "_migrate" });
|
|
70293
71016
|
return;
|
|
70294
71017
|
}
|
|
70295
|
-
const naxDir =
|
|
70296
|
-
const configPath =
|
|
71018
|
+
const naxDir = path29.join(options.workdir, ".nax");
|
|
71019
|
+
const configPath = path29.join(naxDir, "config.json");
|
|
70297
71020
|
if (!existsSync36(configPath)) {
|
|
70298
71021
|
throw new NaxError("No .nax/config.json found \u2014 run nax init first", "MIGRATE_NO_CONFIG", {
|
|
70299
71022
|
stage: "migrate",
|
|
@@ -70309,7 +71032,7 @@ async function migrateCommand(options) {
|
|
|
70309
71032
|
cause: e
|
|
70310
71033
|
});
|
|
70311
71034
|
}
|
|
70312
|
-
const projectKey = config2.name?.trim() ||
|
|
71035
|
+
const projectKey = config2.name?.trim() || path29.basename(options.workdir);
|
|
70313
71036
|
const destBase = projectOutputDir(projectKey, config2.outputDir);
|
|
70314
71037
|
const candidates = await detectGeneratedContent(naxDir);
|
|
70315
71038
|
if (candidates.length === 0) {
|
|
@@ -70318,7 +71041,7 @@ async function migrateCommand(options) {
|
|
|
70318
71041
|
}
|
|
70319
71042
|
if (options.dryRun) {
|
|
70320
71043
|
for (const c of candidates) {
|
|
70321
|
-
logger.info("migrate", `[dry-run] Would move: ${c.srcPath} -> ${
|
|
71044
|
+
logger.info("migrate", `[dry-run] Would move: ${c.srcPath} -> ${path29.join(destBase, c.name)}`, {
|
|
70322
71045
|
storyId: "_migrate"
|
|
70323
71046
|
});
|
|
70324
71047
|
}
|
|
@@ -70327,8 +71050,8 @@ async function migrateCommand(options) {
|
|
|
70327
71050
|
await mkdir16(destBase, { recursive: true });
|
|
70328
71051
|
let moved = 0;
|
|
70329
71052
|
for (const candidate of candidates) {
|
|
70330
|
-
const dest =
|
|
70331
|
-
await mkdir16(
|
|
71053
|
+
const dest = path29.join(destBase, candidate.name);
|
|
71054
|
+
await mkdir16(path29.dirname(dest), { recursive: true });
|
|
70332
71055
|
if (existsSync36(dest)) {
|
|
70333
71056
|
throw new NaxError(`Migration conflict: destination already exists.
|
|
70334
71057
|
Source: ${candidate.srcPath}
|
|
@@ -70358,7 +71081,7 @@ async function migrateCommand(options) {
|
|
|
70358
71081
|
moved++;
|
|
70359
71082
|
logger.info("migrate", `Moved: ${candidate.name}`, { storyId: "_migrate" });
|
|
70360
71083
|
}
|
|
70361
|
-
await Bun.write(
|
|
71084
|
+
await Bun.write(path29.join(destBase, ".migrated-from"), JSON.stringify({ from: options.workdir, migratedAt: new Date().toISOString() }, null, 2));
|
|
70362
71085
|
logger.info("migrate", `Migration complete: ${moved} entries moved`, {
|
|
70363
71086
|
storyId: "_migrate",
|
|
70364
71087
|
destBase
|
|
@@ -70475,7 +71198,7 @@ __export(exports_precheck_runner, {
|
|
|
70475
71198
|
runPrecheckValidation: () => runPrecheckValidation
|
|
70476
71199
|
});
|
|
70477
71200
|
import { mkdirSync as mkdirSync7 } from "fs";
|
|
70478
|
-
import
|
|
71201
|
+
import path30 from "path";
|
|
70479
71202
|
async function runPrecheckValidation(ctx) {
|
|
70480
71203
|
const logger = getSafeLogger();
|
|
70481
71204
|
if (process.env.NAX_PRECHECK !== "1") {
|
|
@@ -70490,7 +71213,7 @@ async function runPrecheckValidation(ctx) {
|
|
|
70490
71213
|
silent: true
|
|
70491
71214
|
});
|
|
70492
71215
|
if (ctx.logFilePath) {
|
|
70493
|
-
mkdirSync7(
|
|
71216
|
+
mkdirSync7(path30.dirname(ctx.logFilePath), { recursive: true });
|
|
70494
71217
|
const precheckLog = {
|
|
70495
71218
|
type: "precheck",
|
|
70496
71219
|
timestamp: new Date().toISOString(),
|
|
@@ -70580,7 +71303,7 @@ __export(exports_run_initialization, {
|
|
|
70580
71303
|
initializeRun: () => initializeRun,
|
|
70581
71304
|
_reconcileDeps: () => _reconcileDeps
|
|
70582
71305
|
});
|
|
70583
|
-
import { join as
|
|
71306
|
+
import { join as join94 } from "path";
|
|
70584
71307
|
async function reconcileState(prd, prdPath, workdir, config2) {
|
|
70585
71308
|
const logger = getSafeLogger();
|
|
70586
71309
|
let reconciledCount = 0;
|
|
@@ -70597,7 +71320,7 @@ async function reconcileState(prd, prdPath, workdir, config2) {
|
|
|
70597
71320
|
});
|
|
70598
71321
|
continue;
|
|
70599
71322
|
}
|
|
70600
|
-
const effectiveWorkdir = story.workdir ?
|
|
71323
|
+
const effectiveWorkdir = story.workdir ? join94(workdir, story.workdir) : workdir;
|
|
70601
71324
|
try {
|
|
70602
71325
|
const reviewResult = await _reconcileDeps.runReview(config2.review, effectiveWorkdir, config2.execution);
|
|
70603
71326
|
if (!reviewResult.success) {
|
|
@@ -70803,7 +71526,7 @@ __export(exports_run_setup, {
|
|
|
70803
71526
|
setupRun: () => setupRun,
|
|
70804
71527
|
_runSetupDeps: () => _runSetupDeps
|
|
70805
71528
|
});
|
|
70806
|
-
import
|
|
71529
|
+
import path31 from "path";
|
|
70807
71530
|
function warnProfileMismatch(prd, config2, logger) {
|
|
70808
71531
|
const profiles = config2.routing?.agents?.profiles ?? [];
|
|
70809
71532
|
const profileIds = new Set(profiles.map((p) => p.id));
|
|
@@ -70924,7 +71647,7 @@ async function setupRun(options) {
|
|
|
70924
71647
|
statusWriter.setPrd(prd);
|
|
70925
71648
|
{
|
|
70926
71649
|
const { detectGeneratedContent: detectGeneratedContent2, migrateCommand: migrateCommand2 } = await Promise.resolve().then(() => (init_migrate(), exports_migrate));
|
|
70927
|
-
const naxDir =
|
|
71650
|
+
const naxDir = path31.join(workdir, ".nax");
|
|
70928
71651
|
const candidates = await detectGeneratedContent2(naxDir).catch(() => []);
|
|
70929
71652
|
if (candidates.length > 0) {
|
|
70930
71653
|
logger?.info("setup", "Found generated content under .nax/ \u2014 migrating to output dir", {
|
|
@@ -70951,7 +71674,7 @@ async function setupRun(options) {
|
|
|
70951
71674
|
remoteUrl = new TextDecoder().decode(gitResult.stdout).trim() || null;
|
|
70952
71675
|
}
|
|
70953
71676
|
} catch {}
|
|
70954
|
-
const projectKey = config2.name?.trim() ||
|
|
71677
|
+
const projectKey = config2.name?.trim() || path31.basename(workdir);
|
|
70955
71678
|
await claimProjectIdentity2(projectKey, workdir, remoteUrl).catch((err) => {
|
|
70956
71679
|
if (err instanceof NaxError && err.code === "RUN_NAME_COLLISION") {
|
|
70957
71680
|
throw err;
|
|
@@ -71006,8 +71729,8 @@ async function setupRun(options) {
|
|
|
71006
71729
|
explicit: Object.fromEntries(explicitFields.map((f) => [f, existingProjectConfig[f]])),
|
|
71007
71730
|
detected: Object.fromEntries(autodetectedFields.map((f) => [f, detectedProfile[f]]))
|
|
71008
71731
|
});
|
|
71009
|
-
const globalPluginsDir =
|
|
71010
|
-
const projectPluginsDir =
|
|
71732
|
+
const globalPluginsDir = path31.join(globalConfigDir(), "plugins");
|
|
71733
|
+
const projectPluginsDir = path31.join(workdir, ".nax", "plugins");
|
|
71011
71734
|
const configPlugins = config2.plugins || [];
|
|
71012
71735
|
const resolvedPatterns = await resolveTestFilePatterns(config2, workdir);
|
|
71013
71736
|
const isTestFileFn = (filename) => resolvedPatterns.regex.some((re) => re.test(filename));
|
|
@@ -71941,14 +72664,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
71941
72664
|
prevActScopeDepth !== actScopeDepth - 1 && console.error("You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. ");
|
|
71942
72665
|
actScopeDepth = prevActScopeDepth;
|
|
71943
72666
|
}
|
|
71944
|
-
function recursivelyFlushAsyncActWork(returnValue,
|
|
72667
|
+
function recursivelyFlushAsyncActWork(returnValue, resolve19, reject) {
|
|
71945
72668
|
var queue = ReactSharedInternals.actQueue;
|
|
71946
72669
|
if (queue !== null)
|
|
71947
72670
|
if (queue.length !== 0)
|
|
71948
72671
|
try {
|
|
71949
72672
|
flushActQueue(queue);
|
|
71950
72673
|
enqueueTask(function() {
|
|
71951
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
72674
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve19, reject);
|
|
71952
72675
|
});
|
|
71953
72676
|
return;
|
|
71954
72677
|
} catch (error48) {
|
|
@@ -71956,7 +72679,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
71956
72679
|
}
|
|
71957
72680
|
else
|
|
71958
72681
|
ReactSharedInternals.actQueue = null;
|
|
71959
|
-
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) :
|
|
72682
|
+
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve19(returnValue);
|
|
71960
72683
|
}
|
|
71961
72684
|
function flushActQueue(queue) {
|
|
71962
72685
|
if (!isFlushing) {
|
|
@@ -72132,14 +72855,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
72132
72855
|
didAwaitActCall || didWarnNoAwaitAct || (didWarnNoAwaitAct = true, console.error("You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);"));
|
|
72133
72856
|
});
|
|
72134
72857
|
return {
|
|
72135
|
-
then: function(
|
|
72858
|
+
then: function(resolve19, reject) {
|
|
72136
72859
|
didAwaitActCall = true;
|
|
72137
72860
|
thenable.then(function(returnValue) {
|
|
72138
72861
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
72139
72862
|
if (prevActScopeDepth === 0) {
|
|
72140
72863
|
try {
|
|
72141
72864
|
flushActQueue(queue), enqueueTask(function() {
|
|
72142
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
72865
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve19, reject);
|
|
72143
72866
|
});
|
|
72144
72867
|
} catch (error$0) {
|
|
72145
72868
|
ReactSharedInternals.thrownErrors.push(error$0);
|
|
@@ -72150,7 +72873,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
72150
72873
|
reject(_thrownError);
|
|
72151
72874
|
}
|
|
72152
72875
|
} else
|
|
72153
|
-
|
|
72876
|
+
resolve19(returnValue);
|
|
72154
72877
|
}, function(error48) {
|
|
72155
72878
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
72156
72879
|
0 < ReactSharedInternals.thrownErrors.length ? (error48 = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(error48)) : reject(error48);
|
|
@@ -72166,11 +72889,11 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
72166
72889
|
if (0 < ReactSharedInternals.thrownErrors.length)
|
|
72167
72890
|
throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
|
|
72168
72891
|
return {
|
|
72169
|
-
then: function(
|
|
72892
|
+
then: function(resolve19, reject) {
|
|
72170
72893
|
didAwaitActCall = true;
|
|
72171
72894
|
prevActScopeDepth === 0 ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
|
|
72172
|
-
return recursivelyFlushAsyncActWork(returnValue$jscomp$0,
|
|
72173
|
-
})) :
|
|
72895
|
+
return recursivelyFlushAsyncActWork(returnValue$jscomp$0, resolve19, reject);
|
|
72896
|
+
})) : resolve19(returnValue$jscomp$0);
|
|
72174
72897
|
}
|
|
72175
72898
|
};
|
|
72176
72899
|
};
|
|
@@ -72870,11 +73593,11 @@ var require_react_reconciler_development = __commonJS((exports, module) => {
|
|
|
72870
73593
|
fiber = fiber.next, id--;
|
|
72871
73594
|
return fiber;
|
|
72872
73595
|
}
|
|
72873
|
-
function copyWithSetImpl(obj,
|
|
72874
|
-
if (index >=
|
|
73596
|
+
function copyWithSetImpl(obj, path32, index, value) {
|
|
73597
|
+
if (index >= path32.length)
|
|
72875
73598
|
return value;
|
|
72876
|
-
var key =
|
|
72877
|
-
updated[key] = copyWithSetImpl(obj[key],
|
|
73599
|
+
var key = path32[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
|
|
73600
|
+
updated[key] = copyWithSetImpl(obj[key], path32, index + 1, value);
|
|
72878
73601
|
return updated;
|
|
72879
73602
|
}
|
|
72880
73603
|
function copyWithRename(obj, oldPath, newPath) {
|
|
@@ -72894,11 +73617,11 @@ var require_react_reconciler_development = __commonJS((exports, module) => {
|
|
|
72894
73617
|
index + 1 === oldPath.length ? (updated[newPath[index]] = updated[oldKey], isArrayImpl(updated) ? updated.splice(oldKey, 1) : delete updated[oldKey]) : updated[oldKey] = copyWithRenameImpl(obj[oldKey], oldPath, newPath, index + 1);
|
|
72895
73618
|
return updated;
|
|
72896
73619
|
}
|
|
72897
|
-
function copyWithDeleteImpl(obj,
|
|
72898
|
-
var key =
|
|
72899
|
-
if (index + 1 ===
|
|
73620
|
+
function copyWithDeleteImpl(obj, path32, index) {
|
|
73621
|
+
var key = path32[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
|
|
73622
|
+
if (index + 1 === path32.length)
|
|
72900
73623
|
return isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], updated;
|
|
72901
|
-
updated[key] = copyWithDeleteImpl(obj[key],
|
|
73624
|
+
updated[key] = copyWithDeleteImpl(obj[key], path32, index + 1);
|
|
72902
73625
|
return updated;
|
|
72903
73626
|
}
|
|
72904
73627
|
function shouldSuspendImpl() {
|
|
@@ -75012,8 +75735,8 @@ It can also happen if the client has a browser extension installed which messes
|
|
|
75012
75735
|
currentEntangledActionThenable = {
|
|
75013
75736
|
status: "pending",
|
|
75014
75737
|
value: undefined,
|
|
75015
|
-
then: function(
|
|
75016
|
-
entangledListeners.push(
|
|
75738
|
+
then: function(resolve19) {
|
|
75739
|
+
entangledListeners.push(resolve19);
|
|
75017
75740
|
}
|
|
75018
75741
|
};
|
|
75019
75742
|
}
|
|
@@ -75037,8 +75760,8 @@ It can also happen if the client has a browser extension installed which messes
|
|
|
75037
75760
|
status: "pending",
|
|
75038
75761
|
value: null,
|
|
75039
75762
|
reason: null,
|
|
75040
|
-
then: function(
|
|
75041
|
-
listeners.push(
|
|
75763
|
+
then: function(resolve19) {
|
|
75764
|
+
listeners.push(resolve19);
|
|
75042
75765
|
}
|
|
75043
75766
|
};
|
|
75044
75767
|
thenable.then(function() {
|
|
@@ -82921,29 +83644,29 @@ Check the top-level render call using <` + componentName2 + ">.");
|
|
|
82921
83644
|
var didWarnAboutNestedUpdates = false;
|
|
82922
83645
|
var didWarnAboutFindNodeInStrictMode = {};
|
|
82923
83646
|
var overrideHookState = null, overrideHookStateDeletePath = null, overrideHookStateRenamePath = null, overrideProps = null, overridePropsDeletePath = null, overridePropsRenamePath = null, scheduleUpdate = null, scheduleRetry = null, setErrorHandler = null, setSuspenseHandler = null;
|
|
82924
|
-
overrideHookState = function(fiber, id,
|
|
83647
|
+
overrideHookState = function(fiber, id, path32, value) {
|
|
82925
83648
|
id = findHook(fiber, id);
|
|
82926
|
-
id !== null && (
|
|
83649
|
+
id !== null && (path32 = copyWithSetImpl(id.memoizedState, path32, 0, value), id.memoizedState = path32, id.baseState = path32, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path32 = enqueueConcurrentRenderForLane(fiber, 2), path32 !== null && scheduleUpdateOnFiber(path32, fiber, 2));
|
|
82927
83650
|
};
|
|
82928
|
-
overrideHookStateDeletePath = function(fiber, id,
|
|
83651
|
+
overrideHookStateDeletePath = function(fiber, id, path32) {
|
|
82929
83652
|
id = findHook(fiber, id);
|
|
82930
|
-
id !== null && (
|
|
83653
|
+
id !== null && (path32 = copyWithDeleteImpl(id.memoizedState, path32, 0), id.memoizedState = path32, id.baseState = path32, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path32 = enqueueConcurrentRenderForLane(fiber, 2), path32 !== null && scheduleUpdateOnFiber(path32, fiber, 2));
|
|
82931
83654
|
};
|
|
82932
83655
|
overrideHookStateRenamePath = function(fiber, id, oldPath, newPath) {
|
|
82933
83656
|
id = findHook(fiber, id);
|
|
82934
83657
|
id !== null && (oldPath = copyWithRename(id.memoizedState, oldPath, newPath), id.memoizedState = oldPath, id.baseState = oldPath, fiber.memoizedProps = assign2({}, fiber.memoizedProps), oldPath = enqueueConcurrentRenderForLane(fiber, 2), oldPath !== null && scheduleUpdateOnFiber(oldPath, fiber, 2));
|
|
82935
83658
|
};
|
|
82936
|
-
overrideProps = function(fiber,
|
|
82937
|
-
fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps,
|
|
83659
|
+
overrideProps = function(fiber, path32, value) {
|
|
83660
|
+
fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path32, 0, value);
|
|
82938
83661
|
fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
|
|
82939
|
-
|
|
82940
|
-
|
|
83662
|
+
path32 = enqueueConcurrentRenderForLane(fiber, 2);
|
|
83663
|
+
path32 !== null && scheduleUpdateOnFiber(path32, fiber, 2);
|
|
82941
83664
|
};
|
|
82942
|
-
overridePropsDeletePath = function(fiber,
|
|
82943
|
-
fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps,
|
|
83665
|
+
overridePropsDeletePath = function(fiber, path32) {
|
|
83666
|
+
fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path32, 0);
|
|
82944
83667
|
fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
|
|
82945
|
-
|
|
82946
|
-
|
|
83668
|
+
path32 = enqueueConcurrentRenderForLane(fiber, 2);
|
|
83669
|
+
path32 !== null && scheduleUpdateOnFiber(path32, fiber, 2);
|
|
82947
83670
|
};
|
|
82948
83671
|
overridePropsRenamePath = function(fiber, oldPath, newPath) {
|
|
82949
83672
|
fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
|
|
@@ -86998,8 +87721,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
86998
87721
|
}
|
|
86999
87722
|
return false;
|
|
87000
87723
|
}
|
|
87001
|
-
function utils_getInObject(object2,
|
|
87002
|
-
return
|
|
87724
|
+
function utils_getInObject(object2, path32) {
|
|
87725
|
+
return path32.reduce(function(reduced, attr2) {
|
|
87003
87726
|
if (reduced) {
|
|
87004
87727
|
if (utils_hasOwnProperty.call(reduced, attr2)) {
|
|
87005
87728
|
return reduced[attr2];
|
|
@@ -87011,11 +87734,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87011
87734
|
return null;
|
|
87012
87735
|
}, object2);
|
|
87013
87736
|
}
|
|
87014
|
-
function deletePathInObject(object2,
|
|
87015
|
-
var length =
|
|
87016
|
-
var last2 =
|
|
87737
|
+
function deletePathInObject(object2, path32) {
|
|
87738
|
+
var length = path32.length;
|
|
87739
|
+
var last2 = path32[length - 1];
|
|
87017
87740
|
if (object2 != null) {
|
|
87018
|
-
var parent = utils_getInObject(object2,
|
|
87741
|
+
var parent = utils_getInObject(object2, path32.slice(0, length - 1));
|
|
87019
87742
|
if (parent) {
|
|
87020
87743
|
if (src_isArray(parent)) {
|
|
87021
87744
|
parent.splice(last2, 1);
|
|
@@ -87041,11 +87764,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87041
87764
|
}
|
|
87042
87765
|
}
|
|
87043
87766
|
}
|
|
87044
|
-
function utils_setInObject(object2,
|
|
87045
|
-
var length =
|
|
87046
|
-
var last2 =
|
|
87767
|
+
function utils_setInObject(object2, path32, value) {
|
|
87768
|
+
var length = path32.length;
|
|
87769
|
+
var last2 = path32[length - 1];
|
|
87047
87770
|
if (object2 != null) {
|
|
87048
|
-
var parent = utils_getInObject(object2,
|
|
87771
|
+
var parent = utils_getInObject(object2, path32.slice(0, length - 1));
|
|
87049
87772
|
if (parent) {
|
|
87050
87773
|
parent[last2] = value;
|
|
87051
87774
|
}
|
|
@@ -87576,8 +88299,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87576
88299
|
unserializable: Symbol("unserializable")
|
|
87577
88300
|
};
|
|
87578
88301
|
var LEVEL_THRESHOLD = 2;
|
|
87579
|
-
function createDehydrated(type, inspectable, data, cleaned,
|
|
87580
|
-
cleaned.push(
|
|
88302
|
+
function createDehydrated(type, inspectable, data, cleaned, path32) {
|
|
88303
|
+
cleaned.push(path32);
|
|
87581
88304
|
var dehydrated = {
|
|
87582
88305
|
inspectable,
|
|
87583
88306
|
type,
|
|
@@ -87595,13 +88318,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87595
88318
|
}
|
|
87596
88319
|
return dehydrated;
|
|
87597
88320
|
}
|
|
87598
|
-
function dehydrate(data, cleaned, unserializable,
|
|
88321
|
+
function dehydrate(data, cleaned, unserializable, path32, isPathAllowed) {
|
|
87599
88322
|
var level = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
|
|
87600
88323
|
var type = getDataType(data);
|
|
87601
88324
|
var isPathAllowedCheck;
|
|
87602
88325
|
switch (type) {
|
|
87603
88326
|
case "html_element":
|
|
87604
|
-
cleaned.push(
|
|
88327
|
+
cleaned.push(path32);
|
|
87605
88328
|
return {
|
|
87606
88329
|
inspectable: false,
|
|
87607
88330
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87610,7 +88333,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87610
88333
|
type
|
|
87611
88334
|
};
|
|
87612
88335
|
case "function":
|
|
87613
|
-
cleaned.push(
|
|
88336
|
+
cleaned.push(path32);
|
|
87614
88337
|
return {
|
|
87615
88338
|
inspectable: false,
|
|
87616
88339
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87619,14 +88342,14 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87619
88342
|
type
|
|
87620
88343
|
};
|
|
87621
88344
|
case "string":
|
|
87622
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88345
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87623
88346
|
if (isPathAllowedCheck) {
|
|
87624
88347
|
return data;
|
|
87625
88348
|
} else {
|
|
87626
88349
|
return data.length <= 500 ? data : data.slice(0, 500) + "...";
|
|
87627
88350
|
}
|
|
87628
88351
|
case "bigint":
|
|
87629
|
-
cleaned.push(
|
|
88352
|
+
cleaned.push(path32);
|
|
87630
88353
|
return {
|
|
87631
88354
|
inspectable: false,
|
|
87632
88355
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87635,7 +88358,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87635
88358
|
type
|
|
87636
88359
|
};
|
|
87637
88360
|
case "symbol":
|
|
87638
|
-
cleaned.push(
|
|
88361
|
+
cleaned.push(path32);
|
|
87639
88362
|
return {
|
|
87640
88363
|
inspectable: false,
|
|
87641
88364
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87644,9 +88367,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87644
88367
|
type
|
|
87645
88368
|
};
|
|
87646
88369
|
case "react_element": {
|
|
87647
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88370
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87648
88371
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87649
|
-
cleaned.push(
|
|
88372
|
+
cleaned.push(path32);
|
|
87650
88373
|
return {
|
|
87651
88374
|
inspectable: true,
|
|
87652
88375
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87663,19 +88386,19 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87663
88386
|
preview_long: formatDataForPreview(data, true),
|
|
87664
88387
|
name: getDisplayNameForReactElement(data) || "Unknown"
|
|
87665
88388
|
};
|
|
87666
|
-
unserializableValue.key = dehydrate(data.key, cleaned, unserializable,
|
|
88389
|
+
unserializableValue.key = dehydrate(data.key, cleaned, unserializable, path32.concat(["key"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87667
88390
|
if (data.$$typeof === REACT_LEGACY_ELEMENT_TYPE) {
|
|
87668
|
-
unserializableValue.ref = dehydrate(data.ref, cleaned, unserializable,
|
|
88391
|
+
unserializableValue.ref = dehydrate(data.ref, cleaned, unserializable, path32.concat(["ref"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87669
88392
|
}
|
|
87670
|
-
unserializableValue.props = dehydrate(data.props, cleaned, unserializable,
|
|
87671
|
-
unserializable.push(
|
|
88393
|
+
unserializableValue.props = dehydrate(data.props, cleaned, unserializable, path32.concat(["props"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
88394
|
+
unserializable.push(path32);
|
|
87672
88395
|
return unserializableValue;
|
|
87673
88396
|
}
|
|
87674
88397
|
case "react_lazy": {
|
|
87675
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88398
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87676
88399
|
var payload = data._payload;
|
|
87677
88400
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87678
|
-
cleaned.push(
|
|
88401
|
+
cleaned.push(path32);
|
|
87679
88402
|
var inspectable = payload !== null && hydration_typeof(payload) === "object" && (payload._status === 1 || payload._status === 2 || payload.status === "fulfilled" || payload.status === "rejected");
|
|
87680
88403
|
return {
|
|
87681
88404
|
inspectable,
|
|
@@ -87692,13 +88415,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87692
88415
|
preview_long: formatDataForPreview(data, true),
|
|
87693
88416
|
name: "lazy()"
|
|
87694
88417
|
};
|
|
87695
|
-
_unserializableValue._payload = dehydrate(payload, cleaned, unserializable,
|
|
87696
|
-
unserializable.push(
|
|
88418
|
+
_unserializableValue._payload = dehydrate(payload, cleaned, unserializable, path32.concat(["_payload"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
88419
|
+
unserializable.push(path32);
|
|
87697
88420
|
return _unserializableValue;
|
|
87698
88421
|
}
|
|
87699
88422
|
case "array_buffer":
|
|
87700
88423
|
case "data_view":
|
|
87701
|
-
cleaned.push(
|
|
88424
|
+
cleaned.push(path32);
|
|
87702
88425
|
return {
|
|
87703
88426
|
inspectable: false,
|
|
87704
88427
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87708,21 +88431,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87708
88431
|
type
|
|
87709
88432
|
};
|
|
87710
88433
|
case "array":
|
|
87711
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88434
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87712
88435
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87713
|
-
return createDehydrated(type, true, data, cleaned,
|
|
88436
|
+
return createDehydrated(type, true, data, cleaned, path32);
|
|
87714
88437
|
}
|
|
87715
88438
|
var arr = [];
|
|
87716
88439
|
for (var i = 0;i < data.length; i++) {
|
|
87717
|
-
arr[i] = dehydrateKey(data, i, cleaned, unserializable,
|
|
88440
|
+
arr[i] = dehydrateKey(data, i, cleaned, unserializable, path32.concat([i]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87718
88441
|
}
|
|
87719
88442
|
return arr;
|
|
87720
88443
|
case "html_all_collection":
|
|
87721
88444
|
case "typed_array":
|
|
87722
88445
|
case "iterator":
|
|
87723
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88446
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87724
88447
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87725
|
-
return createDehydrated(type, true, data, cleaned,
|
|
88448
|
+
return createDehydrated(type, true, data, cleaned, path32);
|
|
87726
88449
|
} else {
|
|
87727
88450
|
var _unserializableValue2 = {
|
|
87728
88451
|
unserializable: true,
|
|
@@ -87734,13 +88457,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87734
88457
|
name: typeof data.constructor !== "function" || typeof data.constructor.name !== "string" || data.constructor.name === "Object" ? "" : data.constructor.name
|
|
87735
88458
|
};
|
|
87736
88459
|
Array.from(data).forEach(function(item, i2) {
|
|
87737
|
-
return _unserializableValue2[i2] = dehydrate(item, cleaned, unserializable,
|
|
88460
|
+
return _unserializableValue2[i2] = dehydrate(item, cleaned, unserializable, path32.concat([i2]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87738
88461
|
});
|
|
87739
|
-
unserializable.push(
|
|
88462
|
+
unserializable.push(path32);
|
|
87740
88463
|
return _unserializableValue2;
|
|
87741
88464
|
}
|
|
87742
88465
|
case "opaque_iterator":
|
|
87743
|
-
cleaned.push(
|
|
88466
|
+
cleaned.push(path32);
|
|
87744
88467
|
return {
|
|
87745
88468
|
inspectable: false,
|
|
87746
88469
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87749,7 +88472,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87749
88472
|
type
|
|
87750
88473
|
};
|
|
87751
88474
|
case "date":
|
|
87752
|
-
cleaned.push(
|
|
88475
|
+
cleaned.push(path32);
|
|
87753
88476
|
return {
|
|
87754
88477
|
inspectable: false,
|
|
87755
88478
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87758,7 +88481,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87758
88481
|
type
|
|
87759
88482
|
};
|
|
87760
88483
|
case "regexp":
|
|
87761
|
-
cleaned.push(
|
|
88484
|
+
cleaned.push(path32);
|
|
87762
88485
|
return {
|
|
87763
88486
|
inspectable: false,
|
|
87764
88487
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87767,9 +88490,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87767
88490
|
type
|
|
87768
88491
|
};
|
|
87769
88492
|
case "thenable":
|
|
87770
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88493
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87771
88494
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87772
|
-
cleaned.push(
|
|
88495
|
+
cleaned.push(path32);
|
|
87773
88496
|
return {
|
|
87774
88497
|
inspectable: data.status === "fulfilled" || data.status === "rejected",
|
|
87775
88498
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87790,8 +88513,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87790
88513
|
preview_long: formatDataForPreview(data, true),
|
|
87791
88514
|
name: "fulfilled Thenable"
|
|
87792
88515
|
};
|
|
87793
|
-
_unserializableValue3.value = dehydrate(data.value, cleaned, unserializable,
|
|
87794
|
-
unserializable.push(
|
|
88516
|
+
_unserializableValue3.value = dehydrate(data.value, cleaned, unserializable, path32.concat(["value"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
88517
|
+
unserializable.push(path32);
|
|
87795
88518
|
return _unserializableValue3;
|
|
87796
88519
|
}
|
|
87797
88520
|
case "rejected": {
|
|
@@ -87802,12 +88525,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87802
88525
|
preview_long: formatDataForPreview(data, true),
|
|
87803
88526
|
name: "rejected Thenable"
|
|
87804
88527
|
};
|
|
87805
|
-
_unserializableValue4.reason = dehydrate(data.reason, cleaned, unserializable,
|
|
87806
|
-
unserializable.push(
|
|
88528
|
+
_unserializableValue4.reason = dehydrate(data.reason, cleaned, unserializable, path32.concat(["reason"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
88529
|
+
unserializable.push(path32);
|
|
87807
88530
|
return _unserializableValue4;
|
|
87808
88531
|
}
|
|
87809
88532
|
default:
|
|
87810
|
-
cleaned.push(
|
|
88533
|
+
cleaned.push(path32);
|
|
87811
88534
|
return {
|
|
87812
88535
|
inspectable: false,
|
|
87813
88536
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87817,21 +88540,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87817
88540
|
};
|
|
87818
88541
|
}
|
|
87819
88542
|
case "object":
|
|
87820
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88543
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87821
88544
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87822
|
-
return createDehydrated(type, true, data, cleaned,
|
|
88545
|
+
return createDehydrated(type, true, data, cleaned, path32);
|
|
87823
88546
|
} else {
|
|
87824
88547
|
var object2 = {};
|
|
87825
88548
|
getAllEnumerableKeys(data).forEach(function(key) {
|
|
87826
88549
|
var name = key.toString();
|
|
87827
|
-
object2[name] = dehydrateKey(data, key, cleaned, unserializable,
|
|
88550
|
+
object2[name] = dehydrateKey(data, key, cleaned, unserializable, path32.concat([name]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87828
88551
|
});
|
|
87829
88552
|
return object2;
|
|
87830
88553
|
}
|
|
87831
88554
|
case "class_instance": {
|
|
87832
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88555
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87833
88556
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87834
|
-
return createDehydrated(type, true, data, cleaned,
|
|
88557
|
+
return createDehydrated(type, true, data, cleaned, path32);
|
|
87835
88558
|
}
|
|
87836
88559
|
var value = {
|
|
87837
88560
|
unserializable: true,
|
|
@@ -87843,15 +88566,15 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87843
88566
|
};
|
|
87844
88567
|
getAllEnumerableKeys(data).forEach(function(key) {
|
|
87845
88568
|
var keyAsString = key.toString();
|
|
87846
|
-
value[keyAsString] = dehydrate(data[key], cleaned, unserializable,
|
|
88569
|
+
value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path32.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87847
88570
|
});
|
|
87848
|
-
unserializable.push(
|
|
88571
|
+
unserializable.push(path32);
|
|
87849
88572
|
return value;
|
|
87850
88573
|
}
|
|
87851
88574
|
case "error": {
|
|
87852
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88575
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87853
88576
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87854
|
-
return createDehydrated(type, true, data, cleaned,
|
|
88577
|
+
return createDehydrated(type, true, data, cleaned, path32);
|
|
87855
88578
|
}
|
|
87856
88579
|
var _value = {
|
|
87857
88580
|
unserializable: true,
|
|
@@ -87861,22 +88584,22 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87861
88584
|
preview_long: formatDataForPreview(data, true),
|
|
87862
88585
|
name: data.name
|
|
87863
88586
|
};
|
|
87864
|
-
_value.message = dehydrate(data.message, cleaned, unserializable,
|
|
87865
|
-
_value.stack = dehydrate(data.stack, cleaned, unserializable,
|
|
88587
|
+
_value.message = dehydrate(data.message, cleaned, unserializable, path32.concat(["message"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
88588
|
+
_value.stack = dehydrate(data.stack, cleaned, unserializable, path32.concat(["stack"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87866
88589
|
if ("cause" in data) {
|
|
87867
|
-
_value.cause = dehydrate(data.cause, cleaned, unserializable,
|
|
88590
|
+
_value.cause = dehydrate(data.cause, cleaned, unserializable, path32.concat(["cause"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87868
88591
|
}
|
|
87869
88592
|
getAllEnumerableKeys(data).forEach(function(key) {
|
|
87870
88593
|
var keyAsString = key.toString();
|
|
87871
|
-
_value[keyAsString] = dehydrate(data[key], cleaned, unserializable,
|
|
88594
|
+
_value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path32.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87872
88595
|
});
|
|
87873
|
-
unserializable.push(
|
|
88596
|
+
unserializable.push(path32);
|
|
87874
88597
|
return _value;
|
|
87875
88598
|
}
|
|
87876
88599
|
case "infinity":
|
|
87877
88600
|
case "nan":
|
|
87878
88601
|
case "undefined":
|
|
87879
|
-
cleaned.push(
|
|
88602
|
+
cleaned.push(path32);
|
|
87880
88603
|
return {
|
|
87881
88604
|
type
|
|
87882
88605
|
};
|
|
@@ -87884,10 +88607,10 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87884
88607
|
return data;
|
|
87885
88608
|
}
|
|
87886
88609
|
}
|
|
87887
|
-
function dehydrateKey(parent, key, cleaned, unserializable,
|
|
88610
|
+
function dehydrateKey(parent, key, cleaned, unserializable, path32, isPathAllowed) {
|
|
87888
88611
|
var level = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0;
|
|
87889
88612
|
try {
|
|
87890
|
-
return dehydrate(parent[key], cleaned, unserializable,
|
|
88613
|
+
return dehydrate(parent[key], cleaned, unserializable, path32, isPathAllowed, level);
|
|
87891
88614
|
} catch (error48) {
|
|
87892
88615
|
var preview = "";
|
|
87893
88616
|
if (hydration_typeof(error48) === "object" && error48 !== null && typeof error48.stack === "string") {
|
|
@@ -87895,7 +88618,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87895
88618
|
} else if (typeof error48 === "string") {
|
|
87896
88619
|
preview = error48;
|
|
87897
88620
|
}
|
|
87898
|
-
cleaned.push(
|
|
88621
|
+
cleaned.push(path32);
|
|
87899
88622
|
return {
|
|
87900
88623
|
inspectable: false,
|
|
87901
88624
|
preview_short: "[Exception]",
|
|
@@ -87905,8 +88628,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87905
88628
|
};
|
|
87906
88629
|
}
|
|
87907
88630
|
}
|
|
87908
|
-
function fillInPath(object2, data,
|
|
87909
|
-
var target = getInObject(object2,
|
|
88631
|
+
function fillInPath(object2, data, path32, value) {
|
|
88632
|
+
var target = getInObject(object2, path32);
|
|
87910
88633
|
if (target != null) {
|
|
87911
88634
|
if (!target[meta3.unserializable]) {
|
|
87912
88635
|
delete target[meta3.inspectable];
|
|
@@ -87921,9 +88644,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87921
88644
|
}
|
|
87922
88645
|
if (value !== null && data.unserializable.length > 0) {
|
|
87923
88646
|
var unserializablePath = data.unserializable[0];
|
|
87924
|
-
var isMatch2 = unserializablePath.length ===
|
|
87925
|
-
for (var i = 0;i <
|
|
87926
|
-
if (
|
|
88647
|
+
var isMatch2 = unserializablePath.length === path32.length;
|
|
88648
|
+
for (var i = 0;i < path32.length; i++) {
|
|
88649
|
+
if (path32[i] !== unserializablePath[i]) {
|
|
87927
88650
|
isMatch2 = false;
|
|
87928
88651
|
break;
|
|
87929
88652
|
}
|
|
@@ -87932,13 +88655,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87932
88655
|
upgradeUnserializable(value, value);
|
|
87933
88656
|
}
|
|
87934
88657
|
}
|
|
87935
|
-
setInObject(object2,
|
|
88658
|
+
setInObject(object2, path32, value);
|
|
87936
88659
|
}
|
|
87937
88660
|
function hydrate(object2, cleaned, unserializable) {
|
|
87938
|
-
cleaned.forEach(function(
|
|
87939
|
-
var length =
|
|
87940
|
-
var last2 =
|
|
87941
|
-
var parent = getInObject(object2,
|
|
88661
|
+
cleaned.forEach(function(path32) {
|
|
88662
|
+
var length = path32.length;
|
|
88663
|
+
var last2 = path32[length - 1];
|
|
88664
|
+
var parent = getInObject(object2, path32.slice(0, length - 1));
|
|
87942
88665
|
if (!parent || !parent.hasOwnProperty(last2)) {
|
|
87943
88666
|
return;
|
|
87944
88667
|
}
|
|
@@ -87964,10 +88687,10 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87964
88687
|
parent[last2] = replaced;
|
|
87965
88688
|
}
|
|
87966
88689
|
});
|
|
87967
|
-
unserializable.forEach(function(
|
|
87968
|
-
var length =
|
|
87969
|
-
var last2 =
|
|
87970
|
-
var parent = getInObject(object2,
|
|
88690
|
+
unserializable.forEach(function(path32) {
|
|
88691
|
+
var length = path32.length;
|
|
88692
|
+
var last2 = path32[length - 1];
|
|
88693
|
+
var parent = getInObject(object2, path32.slice(0, length - 1));
|
|
87971
88694
|
if (!parent || !parent.hasOwnProperty(last2)) {
|
|
87972
88695
|
return;
|
|
87973
88696
|
}
|
|
@@ -88088,11 +88811,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
88088
88811
|
return gte2(version2, FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER);
|
|
88089
88812
|
}
|
|
88090
88813
|
function cleanForBridge(data, isPathAllowed) {
|
|
88091
|
-
var
|
|
88814
|
+
var path32 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
88092
88815
|
if (data !== null) {
|
|
88093
88816
|
var cleanedPaths = [];
|
|
88094
88817
|
var unserializablePaths = [];
|
|
88095
|
-
var cleanedData = dehydrate(data, cleanedPaths, unserializablePaths,
|
|
88818
|
+
var cleanedData = dehydrate(data, cleanedPaths, unserializablePaths, path32, isPathAllowed);
|
|
88096
88819
|
return {
|
|
88097
88820
|
data: cleanedData,
|
|
88098
88821
|
cleaned: cleanedPaths,
|
|
@@ -88102,18 +88825,18 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
88102
88825
|
return null;
|
|
88103
88826
|
}
|
|
88104
88827
|
}
|
|
88105
|
-
function copyWithDelete(obj,
|
|
88828
|
+
function copyWithDelete(obj, path32) {
|
|
88106
88829
|
var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
88107
|
-
var key =
|
|
88830
|
+
var key = path32[index];
|
|
88108
88831
|
var updated = shared_isArray(obj) ? obj.slice() : utils_objectSpread({}, obj);
|
|
88109
|
-
if (index + 1 ===
|
|
88832
|
+
if (index + 1 === path32.length) {
|
|
88110
88833
|
if (shared_isArray(updated)) {
|
|
88111
88834
|
updated.splice(key, 1);
|
|
88112
88835
|
} else {
|
|
88113
88836
|
delete updated[key];
|
|
88114
88837
|
}
|
|
88115
88838
|
} else {
|
|
88116
|
-
updated[key] = copyWithDelete(obj[key],
|
|
88839
|
+
updated[key] = copyWithDelete(obj[key], path32, index + 1);
|
|
88117
88840
|
}
|
|
88118
88841
|
return updated;
|
|
88119
88842
|
}
|
|
@@ -88134,14 +88857,14 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
88134
88857
|
}
|
|
88135
88858
|
return updated;
|
|
88136
88859
|
}
|
|
88137
|
-
function copyWithSet(obj,
|
|
88860
|
+
function copyWithSet(obj, path32, value) {
|
|
88138
88861
|
var index = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
|
|
88139
|
-
if (index >=
|
|
88862
|
+
if (index >= path32.length) {
|
|
88140
88863
|
return value;
|
|
88141
88864
|
}
|
|
88142
|
-
var key =
|
|
88865
|
+
var key = path32[index];
|
|
88143
88866
|
var updated = shared_isArray(obj) ? obj.slice() : utils_objectSpread({}, obj);
|
|
88144
|
-
updated[key] = copyWithSet(obj[key],
|
|
88867
|
+
updated[key] = copyWithSet(obj[key], path32, value, index + 1);
|
|
88145
88868
|
return updated;
|
|
88146
88869
|
}
|
|
88147
88870
|
function getEffectDurations(root) {
|
|
@@ -89469,12 +90192,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89469
90192
|
}
|
|
89470
90193
|
});
|
|
89471
90194
|
bridge_defineProperty(_this, "overrideValueAtPath", function(_ref) {
|
|
89472
|
-
var { id, path:
|
|
90195
|
+
var { id, path: path32, rendererID, type, value } = _ref;
|
|
89473
90196
|
switch (type) {
|
|
89474
90197
|
case "context":
|
|
89475
90198
|
_this.send("overrideContext", {
|
|
89476
90199
|
id,
|
|
89477
|
-
path:
|
|
90200
|
+
path: path32,
|
|
89478
90201
|
rendererID,
|
|
89479
90202
|
wasForwarded: true,
|
|
89480
90203
|
value
|
|
@@ -89483,7 +90206,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89483
90206
|
case "hooks":
|
|
89484
90207
|
_this.send("overrideHookState", {
|
|
89485
90208
|
id,
|
|
89486
|
-
path:
|
|
90209
|
+
path: path32,
|
|
89487
90210
|
rendererID,
|
|
89488
90211
|
wasForwarded: true,
|
|
89489
90212
|
value
|
|
@@ -89492,7 +90215,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89492
90215
|
case "props":
|
|
89493
90216
|
_this.send("overrideProps", {
|
|
89494
90217
|
id,
|
|
89495
|
-
path:
|
|
90218
|
+
path: path32,
|
|
89496
90219
|
rendererID,
|
|
89497
90220
|
wasForwarded: true,
|
|
89498
90221
|
value
|
|
@@ -89501,7 +90224,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89501
90224
|
case "state":
|
|
89502
90225
|
_this.send("overrideState", {
|
|
89503
90226
|
id,
|
|
89504
|
-
path:
|
|
90227
|
+
path: path32,
|
|
89505
90228
|
rendererID,
|
|
89506
90229
|
wasForwarded: true,
|
|
89507
90230
|
value
|
|
@@ -89835,12 +90558,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89835
90558
|
}
|
|
89836
90559
|
});
|
|
89837
90560
|
agent_defineProperty(_this, "copyElementPath", function(_ref5) {
|
|
89838
|
-
var { id, path:
|
|
90561
|
+
var { id, path: path32, rendererID } = _ref5;
|
|
89839
90562
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
89840
90563
|
if (renderer == null) {
|
|
89841
90564
|
console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
|
|
89842
90565
|
} else {
|
|
89843
|
-
var value = renderer.getSerializedElementValueByPath(id,
|
|
90566
|
+
var value = renderer.getSerializedElementValueByPath(id, path32);
|
|
89844
90567
|
if (value != null) {
|
|
89845
90568
|
_this._bridge.send("saveToClipboard", value);
|
|
89846
90569
|
} else {
|
|
@@ -89849,12 +90572,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89849
90572
|
}
|
|
89850
90573
|
});
|
|
89851
90574
|
agent_defineProperty(_this, "deletePath", function(_ref6) {
|
|
89852
|
-
var { hookID, id, path:
|
|
90575
|
+
var { hookID, id, path: path32, rendererID, type } = _ref6;
|
|
89853
90576
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
89854
90577
|
if (renderer == null) {
|
|
89855
90578
|
console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
|
|
89856
90579
|
} else {
|
|
89857
|
-
renderer.deletePath(type, id, hookID,
|
|
90580
|
+
renderer.deletePath(type, id, hookID, path32);
|
|
89858
90581
|
}
|
|
89859
90582
|
});
|
|
89860
90583
|
agent_defineProperty(_this, "getBackendVersion", function() {
|
|
@@ -89891,12 +90614,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89891
90614
|
}
|
|
89892
90615
|
});
|
|
89893
90616
|
agent_defineProperty(_this, "inspectElement", function(_ref9) {
|
|
89894
|
-
var { forceFullData, id, path:
|
|
90617
|
+
var { forceFullData, id, path: path32, rendererID, requestID } = _ref9;
|
|
89895
90618
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
89896
90619
|
if (renderer == null) {
|
|
89897
90620
|
console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
|
|
89898
90621
|
} else {
|
|
89899
|
-
_this._bridge.send("inspectedElement", renderer.inspectElement(requestID, id,
|
|
90622
|
+
_this._bridge.send("inspectedElement", renderer.inspectElement(requestID, id, path32, forceFullData));
|
|
89900
90623
|
if (_this._persistedSelectionMatch === null || _this._persistedSelectionMatch.id !== id) {
|
|
89901
90624
|
_this._persistedSelection = null;
|
|
89902
90625
|
_this._persistedSelectionMatch = null;
|
|
@@ -89930,15 +90653,15 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89930
90653
|
}
|
|
89931
90654
|
for (var rendererID in _this._rendererInterfaces) {
|
|
89932
90655
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
89933
|
-
var
|
|
90656
|
+
var path32 = null;
|
|
89934
90657
|
if (suspendedByPathIndex !== null && rendererPath !== null) {
|
|
89935
90658
|
var suspendedByPathRendererIndex = suspendedByPathIndex - suspendedByOffset;
|
|
89936
90659
|
var rendererHasRequestedSuspendedByPath = renderer.getElementAttributeByPath(id, ["suspendedBy", suspendedByPathRendererIndex]) !== undefined;
|
|
89937
90660
|
if (rendererHasRequestedSuspendedByPath) {
|
|
89938
|
-
|
|
90661
|
+
path32 = ["suspendedBy", suspendedByPathRendererIndex].concat(rendererPath);
|
|
89939
90662
|
}
|
|
89940
90663
|
}
|
|
89941
|
-
var inspectedRootsPayload = renderer.inspectElement(requestID, id,
|
|
90664
|
+
var inspectedRootsPayload = renderer.inspectElement(requestID, id, path32, forceFullData);
|
|
89942
90665
|
switch (inspectedRootsPayload.type) {
|
|
89943
90666
|
case "hydrated-path":
|
|
89944
90667
|
inspectedRootsPayload.path[1] += suspendedByOffset;
|
|
@@ -90032,20 +90755,20 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90032
90755
|
}
|
|
90033
90756
|
});
|
|
90034
90757
|
agent_defineProperty(_this, "overrideValueAtPath", function(_ref15) {
|
|
90035
|
-
var { hookID, id, path:
|
|
90758
|
+
var { hookID, id, path: path32, rendererID, type, value } = _ref15;
|
|
90036
90759
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
90037
90760
|
if (renderer == null) {
|
|
90038
90761
|
console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
|
|
90039
90762
|
} else {
|
|
90040
|
-
renderer.overrideValueAtPath(type, id, hookID,
|
|
90763
|
+
renderer.overrideValueAtPath(type, id, hookID, path32, value);
|
|
90041
90764
|
}
|
|
90042
90765
|
});
|
|
90043
90766
|
agent_defineProperty(_this, "overrideContext", function(_ref16) {
|
|
90044
|
-
var { id, path:
|
|
90767
|
+
var { id, path: path32, rendererID, wasForwarded, value } = _ref16;
|
|
90045
90768
|
if (!wasForwarded) {
|
|
90046
90769
|
_this.overrideValueAtPath({
|
|
90047
90770
|
id,
|
|
90048
|
-
path:
|
|
90771
|
+
path: path32,
|
|
90049
90772
|
rendererID,
|
|
90050
90773
|
type: "context",
|
|
90051
90774
|
value
|
|
@@ -90053,11 +90776,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90053
90776
|
}
|
|
90054
90777
|
});
|
|
90055
90778
|
agent_defineProperty(_this, "overrideHookState", function(_ref17) {
|
|
90056
|
-
var { id, hookID, path:
|
|
90779
|
+
var { id, hookID, path: path32, rendererID, wasForwarded, value } = _ref17;
|
|
90057
90780
|
if (!wasForwarded) {
|
|
90058
90781
|
_this.overrideValueAtPath({
|
|
90059
90782
|
id,
|
|
90060
|
-
path:
|
|
90783
|
+
path: path32,
|
|
90061
90784
|
rendererID,
|
|
90062
90785
|
type: "hooks",
|
|
90063
90786
|
value
|
|
@@ -90065,11 +90788,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90065
90788
|
}
|
|
90066
90789
|
});
|
|
90067
90790
|
agent_defineProperty(_this, "overrideProps", function(_ref18) {
|
|
90068
|
-
var { id, path:
|
|
90791
|
+
var { id, path: path32, rendererID, wasForwarded, value } = _ref18;
|
|
90069
90792
|
if (!wasForwarded) {
|
|
90070
90793
|
_this.overrideValueAtPath({
|
|
90071
90794
|
id,
|
|
90072
|
-
path:
|
|
90795
|
+
path: path32,
|
|
90073
90796
|
rendererID,
|
|
90074
90797
|
type: "props",
|
|
90075
90798
|
value
|
|
@@ -90077,11 +90800,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90077
90800
|
}
|
|
90078
90801
|
});
|
|
90079
90802
|
agent_defineProperty(_this, "overrideState", function(_ref19) {
|
|
90080
|
-
var { id, path:
|
|
90803
|
+
var { id, path: path32, rendererID, wasForwarded, value } = _ref19;
|
|
90081
90804
|
if (!wasForwarded) {
|
|
90082
90805
|
_this.overrideValueAtPath({
|
|
90083
90806
|
id,
|
|
90084
|
-
path:
|
|
90807
|
+
path: path32,
|
|
90085
90808
|
rendererID,
|
|
90086
90809
|
type: "state",
|
|
90087
90810
|
value
|
|
@@ -90148,12 +90871,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90148
90871
|
_this._bridge.send("stopInspectingHost", selected);
|
|
90149
90872
|
});
|
|
90150
90873
|
agent_defineProperty(_this, "storeAsGlobal", function(_ref23) {
|
|
90151
|
-
var { count, id, path:
|
|
90874
|
+
var { count, id, path: path32, rendererID } = _ref23;
|
|
90152
90875
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
90153
90876
|
if (renderer == null) {
|
|
90154
90877
|
console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
|
|
90155
90878
|
} else {
|
|
90156
|
-
renderer.storeAsGlobal(id,
|
|
90879
|
+
renderer.storeAsGlobal(id, path32, count);
|
|
90157
90880
|
}
|
|
90158
90881
|
});
|
|
90159
90882
|
agent_defineProperty(_this, "updateHookSettings", function(settings) {
|
|
@@ -90170,12 +90893,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90170
90893
|
var rendererID = +rendererIDString;
|
|
90171
90894
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
90172
90895
|
if (_this._lastSelectedRendererID === rendererID) {
|
|
90173
|
-
var
|
|
90174
|
-
if (
|
|
90175
|
-
renderer.setTrackedPath(
|
|
90896
|
+
var path32 = renderer.getPathForElement(_this._lastSelectedElementID);
|
|
90897
|
+
if (path32 !== null) {
|
|
90898
|
+
renderer.setTrackedPath(path32);
|
|
90176
90899
|
_this._persistedSelection = {
|
|
90177
90900
|
rendererID,
|
|
90178
|
-
path:
|
|
90901
|
+
path: path32
|
|
90179
90902
|
};
|
|
90180
90903
|
}
|
|
90181
90904
|
}
|
|
@@ -90250,11 +90973,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90250
90973
|
var rendererID = _this._lastSelectedRendererID;
|
|
90251
90974
|
var id = _this._lastSelectedElementID;
|
|
90252
90975
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
90253
|
-
var
|
|
90254
|
-
if (
|
|
90976
|
+
var path32 = renderer != null ? renderer.getPathForElement(id) : null;
|
|
90977
|
+
if (path32 !== null) {
|
|
90255
90978
|
storage_sessionStorageSetItem(SESSION_STORAGE_LAST_SELECTION_KEY, JSON.stringify({
|
|
90256
90979
|
rendererID,
|
|
90257
|
-
path:
|
|
90980
|
+
path: path32
|
|
90258
90981
|
}));
|
|
90259
90982
|
} else {
|
|
90260
90983
|
storage_sessionStorageRemoveItem(SESSION_STORAGE_LAST_SELECTION_KEY);
|
|
@@ -90977,7 +91700,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90977
91700
|
hasElementWithId: function hasElementWithId() {
|
|
90978
91701
|
return false;
|
|
90979
91702
|
},
|
|
90980
|
-
inspectElement: function inspectElement(requestID, id,
|
|
91703
|
+
inspectElement: function inspectElement(requestID, id, path32) {
|
|
90981
91704
|
return {
|
|
90982
91705
|
id,
|
|
90983
91706
|
responseID: requestID,
|
|
@@ -96247,9 +96970,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
96247
96970
|
}
|
|
96248
96971
|
return null;
|
|
96249
96972
|
}
|
|
96250
|
-
function getElementAttributeByPath(id,
|
|
96973
|
+
function getElementAttributeByPath(id, path32) {
|
|
96251
96974
|
if (isMostRecentlyInspectedElement(id)) {
|
|
96252
|
-
return utils_getInObject(mostRecentlyInspectedElement,
|
|
96975
|
+
return utils_getInObject(mostRecentlyInspectedElement, path32);
|
|
96253
96976
|
}
|
|
96254
96977
|
return;
|
|
96255
96978
|
}
|
|
@@ -96952,9 +97675,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
96952
97675
|
function isMostRecentlyInspectedElementCurrent(id) {
|
|
96953
97676
|
return isMostRecentlyInspectedElement(id) && !hasElementUpdatedSinceLastInspected;
|
|
96954
97677
|
}
|
|
96955
|
-
function mergeInspectedPaths(
|
|
97678
|
+
function mergeInspectedPaths(path32) {
|
|
96956
97679
|
var current = currentlyInspectedPaths;
|
|
96957
|
-
|
|
97680
|
+
path32.forEach(function(key) {
|
|
96958
97681
|
if (!current[key]) {
|
|
96959
97682
|
current[key] = {};
|
|
96960
97683
|
}
|
|
@@ -96962,21 +97685,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
96962
97685
|
});
|
|
96963
97686
|
}
|
|
96964
97687
|
function createIsPathAllowed(key, secondaryCategory) {
|
|
96965
|
-
return function isPathAllowed(
|
|
97688
|
+
return function isPathAllowed(path32) {
|
|
96966
97689
|
switch (secondaryCategory) {
|
|
96967
97690
|
case "hooks":
|
|
96968
|
-
if (
|
|
97691
|
+
if (path32.length === 1) {
|
|
96969
97692
|
return true;
|
|
96970
97693
|
}
|
|
96971
|
-
if (
|
|
97694
|
+
if (path32[path32.length - 2] === "hookSource" && path32[path32.length - 1] === "fileName") {
|
|
96972
97695
|
return true;
|
|
96973
97696
|
}
|
|
96974
|
-
if (
|
|
97697
|
+
if (path32[path32.length - 1] === "subHooks" || path32[path32.length - 2] === "subHooks") {
|
|
96975
97698
|
return true;
|
|
96976
97699
|
}
|
|
96977
97700
|
break;
|
|
96978
97701
|
case "suspendedBy":
|
|
96979
|
-
if (
|
|
97702
|
+
if (path32.length < 5) {
|
|
96980
97703
|
return true;
|
|
96981
97704
|
}
|
|
96982
97705
|
break;
|
|
@@ -96987,8 +97710,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
96987
97710
|
if (!current) {
|
|
96988
97711
|
return false;
|
|
96989
97712
|
}
|
|
96990
|
-
for (var i = 0;i <
|
|
96991
|
-
current = current[
|
|
97713
|
+
for (var i = 0;i < path32.length; i++) {
|
|
97714
|
+
current = current[path32[i]];
|
|
96992
97715
|
if (!current) {
|
|
96993
97716
|
return false;
|
|
96994
97717
|
}
|
|
@@ -97042,38 +97765,38 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
97042
97765
|
break;
|
|
97043
97766
|
}
|
|
97044
97767
|
}
|
|
97045
|
-
function storeAsGlobal(id,
|
|
97768
|
+
function storeAsGlobal(id, path32, count) {
|
|
97046
97769
|
if (isMostRecentlyInspectedElement(id)) {
|
|
97047
|
-
var value = utils_getInObject(mostRecentlyInspectedElement,
|
|
97770
|
+
var value = utils_getInObject(mostRecentlyInspectedElement, path32);
|
|
97048
97771
|
var key = "$reactTemp".concat(count);
|
|
97049
97772
|
window[key] = value;
|
|
97050
97773
|
console.log(key);
|
|
97051
97774
|
console.log(value);
|
|
97052
97775
|
}
|
|
97053
97776
|
}
|
|
97054
|
-
function getSerializedElementValueByPath(id,
|
|
97777
|
+
function getSerializedElementValueByPath(id, path32) {
|
|
97055
97778
|
if (isMostRecentlyInspectedElement(id)) {
|
|
97056
|
-
var valueToCopy = utils_getInObject(mostRecentlyInspectedElement,
|
|
97779
|
+
var valueToCopy = utils_getInObject(mostRecentlyInspectedElement, path32);
|
|
97057
97780
|
return serializeToString(valueToCopy);
|
|
97058
97781
|
}
|
|
97059
97782
|
}
|
|
97060
|
-
function inspectElement(requestID, id,
|
|
97061
|
-
if (
|
|
97062
|
-
mergeInspectedPaths(
|
|
97783
|
+
function inspectElement(requestID, id, path32, forceFullData) {
|
|
97784
|
+
if (path32 !== null) {
|
|
97785
|
+
mergeInspectedPaths(path32);
|
|
97063
97786
|
}
|
|
97064
97787
|
if (isMostRecentlyInspectedElement(id) && !forceFullData) {
|
|
97065
97788
|
if (!hasElementUpdatedSinceLastInspected) {
|
|
97066
|
-
if (
|
|
97789
|
+
if (path32 !== null) {
|
|
97067
97790
|
var secondaryCategory = null;
|
|
97068
|
-
if (
|
|
97069
|
-
secondaryCategory =
|
|
97791
|
+
if (path32[0] === "hooks" || path32[0] === "suspendedBy") {
|
|
97792
|
+
secondaryCategory = path32[0];
|
|
97070
97793
|
}
|
|
97071
97794
|
return {
|
|
97072
97795
|
id,
|
|
97073
97796
|
responseID: requestID,
|
|
97074
97797
|
type: "hydrated-path",
|
|
97075
|
-
path:
|
|
97076
|
-
value: cleanForBridge(utils_getInObject(mostRecentlyInspectedElement,
|
|
97798
|
+
path: path32,
|
|
97799
|
+
value: cleanForBridge(utils_getInObject(mostRecentlyInspectedElement, path32), createIsPathAllowed(null, secondaryCategory), path32)
|
|
97077
97800
|
};
|
|
97078
97801
|
} else {
|
|
97079
97802
|
return {
|
|
@@ -97269,7 +97992,7 @@ The error thrown in the component is:
|
|
|
97269
97992
|
console.groupEnd();
|
|
97270
97993
|
}
|
|
97271
97994
|
}
|
|
97272
|
-
function deletePath(type, id, hookID,
|
|
97995
|
+
function deletePath(type, id, hookID, path32) {
|
|
97273
97996
|
var devtoolsInstance = idToDevToolsInstanceMap.get(id);
|
|
97274
97997
|
if (devtoolsInstance === undefined) {
|
|
97275
97998
|
console.warn('Could not find DevToolsInstance with id "'.concat(id, '"'));
|
|
@@ -97283,11 +98006,11 @@ The error thrown in the component is:
|
|
|
97283
98006
|
var instance2 = fiber.stateNode;
|
|
97284
98007
|
switch (type) {
|
|
97285
98008
|
case "context":
|
|
97286
|
-
|
|
98009
|
+
path32 = path32.slice(1);
|
|
97287
98010
|
switch (fiber.tag) {
|
|
97288
98011
|
case ClassComponent:
|
|
97289
|
-
if (
|
|
97290
|
-
deletePathInObject(instance2.context,
|
|
98012
|
+
if (path32.length === 0) {} else {
|
|
98013
|
+
deletePathInObject(instance2.context, path32);
|
|
97291
98014
|
}
|
|
97292
98015
|
instance2.forceUpdate();
|
|
97293
98016
|
break;
|
|
@@ -97297,21 +98020,21 @@ The error thrown in the component is:
|
|
|
97297
98020
|
break;
|
|
97298
98021
|
case "hooks":
|
|
97299
98022
|
if (typeof overrideHookStateDeletePath === "function") {
|
|
97300
|
-
overrideHookStateDeletePath(fiber, hookID,
|
|
98023
|
+
overrideHookStateDeletePath(fiber, hookID, path32);
|
|
97301
98024
|
}
|
|
97302
98025
|
break;
|
|
97303
98026
|
case "props":
|
|
97304
98027
|
if (instance2 === null) {
|
|
97305
98028
|
if (typeof overridePropsDeletePath === "function") {
|
|
97306
|
-
overridePropsDeletePath(fiber,
|
|
98029
|
+
overridePropsDeletePath(fiber, path32);
|
|
97307
98030
|
}
|
|
97308
98031
|
} else {
|
|
97309
|
-
fiber.pendingProps = copyWithDelete(instance2.props,
|
|
98032
|
+
fiber.pendingProps = copyWithDelete(instance2.props, path32);
|
|
97310
98033
|
instance2.forceUpdate();
|
|
97311
98034
|
}
|
|
97312
98035
|
break;
|
|
97313
98036
|
case "state":
|
|
97314
|
-
deletePathInObject(instance2.state,
|
|
98037
|
+
deletePathInObject(instance2.state, path32);
|
|
97315
98038
|
instance2.forceUpdate();
|
|
97316
98039
|
break;
|
|
97317
98040
|
}
|
|
@@ -97366,7 +98089,7 @@ The error thrown in the component is:
|
|
|
97366
98089
|
}
|
|
97367
98090
|
}
|
|
97368
98091
|
}
|
|
97369
|
-
function overrideValueAtPath(type, id, hookID,
|
|
98092
|
+
function overrideValueAtPath(type, id, hookID, path32, value) {
|
|
97370
98093
|
var devtoolsInstance = idToDevToolsInstanceMap.get(id);
|
|
97371
98094
|
if (devtoolsInstance === undefined) {
|
|
97372
98095
|
console.warn('Could not find DevToolsInstance with id "'.concat(id, '"'));
|
|
@@ -97380,13 +98103,13 @@ The error thrown in the component is:
|
|
|
97380
98103
|
var instance2 = fiber.stateNode;
|
|
97381
98104
|
switch (type) {
|
|
97382
98105
|
case "context":
|
|
97383
|
-
|
|
98106
|
+
path32 = path32.slice(1);
|
|
97384
98107
|
switch (fiber.tag) {
|
|
97385
98108
|
case ClassComponent:
|
|
97386
|
-
if (
|
|
98109
|
+
if (path32.length === 0) {
|
|
97387
98110
|
instance2.context = value;
|
|
97388
98111
|
} else {
|
|
97389
|
-
utils_setInObject(instance2.context,
|
|
98112
|
+
utils_setInObject(instance2.context, path32, value);
|
|
97390
98113
|
}
|
|
97391
98114
|
instance2.forceUpdate();
|
|
97392
98115
|
break;
|
|
@@ -97396,18 +98119,18 @@ The error thrown in the component is:
|
|
|
97396
98119
|
break;
|
|
97397
98120
|
case "hooks":
|
|
97398
98121
|
if (typeof overrideHookState === "function") {
|
|
97399
|
-
overrideHookState(fiber, hookID,
|
|
98122
|
+
overrideHookState(fiber, hookID, path32, value);
|
|
97400
98123
|
}
|
|
97401
98124
|
break;
|
|
97402
98125
|
case "props":
|
|
97403
98126
|
switch (fiber.tag) {
|
|
97404
98127
|
case ClassComponent:
|
|
97405
|
-
fiber.pendingProps = copyWithSet(instance2.props,
|
|
98128
|
+
fiber.pendingProps = copyWithSet(instance2.props, path32, value);
|
|
97406
98129
|
instance2.forceUpdate();
|
|
97407
98130
|
break;
|
|
97408
98131
|
default:
|
|
97409
98132
|
if (typeof overrideProps === "function") {
|
|
97410
|
-
overrideProps(fiber,
|
|
98133
|
+
overrideProps(fiber, path32, value);
|
|
97411
98134
|
}
|
|
97412
98135
|
break;
|
|
97413
98136
|
}
|
|
@@ -97415,7 +98138,7 @@ The error thrown in the component is:
|
|
|
97415
98138
|
case "state":
|
|
97416
98139
|
switch (fiber.tag) {
|
|
97417
98140
|
case ClassComponent:
|
|
97418
|
-
utils_setInObject(instance2.state,
|
|
98141
|
+
utils_setInObject(instance2.state, path32, value);
|
|
97419
98142
|
instance2.forceUpdate();
|
|
97420
98143
|
break;
|
|
97421
98144
|
}
|
|
@@ -97701,14 +98424,14 @@ The error thrown in the component is:
|
|
|
97701
98424
|
var trackedPathMatchInstance = null;
|
|
97702
98425
|
var trackedPathMatchDepth = -1;
|
|
97703
98426
|
var mightBeOnTrackedPath = false;
|
|
97704
|
-
function setTrackedPath(
|
|
97705
|
-
if (
|
|
98427
|
+
function setTrackedPath(path32) {
|
|
98428
|
+
if (path32 === null) {
|
|
97706
98429
|
trackedPathMatchFiber = null;
|
|
97707
98430
|
trackedPathMatchInstance = null;
|
|
97708
98431
|
trackedPathMatchDepth = -1;
|
|
97709
98432
|
mightBeOnTrackedPath = false;
|
|
97710
98433
|
}
|
|
97711
|
-
trackedPath =
|
|
98434
|
+
trackedPath = path32;
|
|
97712
98435
|
}
|
|
97713
98436
|
function updateTrackedPathStateBeforeMount(fiber, fiberInstance) {
|
|
97714
98437
|
if (trackedPath === null || !mightBeOnTrackedPath) {
|
|
@@ -98472,9 +99195,9 @@ The error thrown in the component is:
|
|
|
98472
99195
|
}
|
|
98473
99196
|
var currentlyInspectedElementID = null;
|
|
98474
99197
|
var currentlyInspectedPaths = {};
|
|
98475
|
-
function mergeInspectedPaths(
|
|
99198
|
+
function mergeInspectedPaths(path32) {
|
|
98476
99199
|
var current = currentlyInspectedPaths;
|
|
98477
|
-
|
|
99200
|
+
path32.forEach(function(key) {
|
|
98478
99201
|
if (!current[key]) {
|
|
98479
99202
|
current[key] = {};
|
|
98480
99203
|
}
|
|
@@ -98482,13 +99205,13 @@ The error thrown in the component is:
|
|
|
98482
99205
|
});
|
|
98483
99206
|
}
|
|
98484
99207
|
function createIsPathAllowed(key) {
|
|
98485
|
-
return function isPathAllowed(
|
|
99208
|
+
return function isPathAllowed(path32) {
|
|
98486
99209
|
var current = currentlyInspectedPaths[key];
|
|
98487
99210
|
if (!current) {
|
|
98488
99211
|
return false;
|
|
98489
99212
|
}
|
|
98490
|
-
for (var i = 0;i <
|
|
98491
|
-
current = current[
|
|
99213
|
+
for (var i = 0;i < path32.length; i++) {
|
|
99214
|
+
current = current[path32[i]];
|
|
98492
99215
|
if (!current) {
|
|
98493
99216
|
return false;
|
|
98494
99217
|
}
|
|
@@ -98538,24 +99261,24 @@ The error thrown in the component is:
|
|
|
98538
99261
|
break;
|
|
98539
99262
|
}
|
|
98540
99263
|
}
|
|
98541
|
-
function storeAsGlobal(id,
|
|
99264
|
+
function storeAsGlobal(id, path32, count) {
|
|
98542
99265
|
var inspectedElement = inspectElementRaw(id);
|
|
98543
99266
|
if (inspectedElement !== null) {
|
|
98544
|
-
var value = utils_getInObject(inspectedElement,
|
|
99267
|
+
var value = utils_getInObject(inspectedElement, path32);
|
|
98545
99268
|
var key = "$reactTemp".concat(count);
|
|
98546
99269
|
window[key] = value;
|
|
98547
99270
|
console.log(key);
|
|
98548
99271
|
console.log(value);
|
|
98549
99272
|
}
|
|
98550
99273
|
}
|
|
98551
|
-
function getSerializedElementValueByPath(id,
|
|
99274
|
+
function getSerializedElementValueByPath(id, path32) {
|
|
98552
99275
|
var inspectedElement = inspectElementRaw(id);
|
|
98553
99276
|
if (inspectedElement !== null) {
|
|
98554
|
-
var valueToCopy = utils_getInObject(inspectedElement,
|
|
99277
|
+
var valueToCopy = utils_getInObject(inspectedElement, path32);
|
|
98555
99278
|
return serializeToString(valueToCopy);
|
|
98556
99279
|
}
|
|
98557
99280
|
}
|
|
98558
|
-
function inspectElement(requestID, id,
|
|
99281
|
+
function inspectElement(requestID, id, path32, forceFullData) {
|
|
98559
99282
|
if (forceFullData || currentlyInspectedElementID !== id) {
|
|
98560
99283
|
currentlyInspectedElementID = id;
|
|
98561
99284
|
currentlyInspectedPaths = {};
|
|
@@ -98568,8 +99291,8 @@ The error thrown in the component is:
|
|
|
98568
99291
|
type: "not-found"
|
|
98569
99292
|
};
|
|
98570
99293
|
}
|
|
98571
|
-
if (
|
|
98572
|
-
mergeInspectedPaths(
|
|
99294
|
+
if (path32 !== null) {
|
|
99295
|
+
mergeInspectedPaths(path32);
|
|
98573
99296
|
}
|
|
98574
99297
|
updateSelectedElement(id);
|
|
98575
99298
|
inspectedElement.context = cleanForBridge(inspectedElement.context, createIsPathAllowed("context"));
|
|
@@ -98772,10 +99495,10 @@ The error thrown in the component is:
|
|
|
98772
99495
|
console.groupEnd();
|
|
98773
99496
|
}
|
|
98774
99497
|
}
|
|
98775
|
-
function getElementAttributeByPath(id,
|
|
99498
|
+
function getElementAttributeByPath(id, path32) {
|
|
98776
99499
|
var inspectedElement = inspectElementRaw(id);
|
|
98777
99500
|
if (inspectedElement !== null) {
|
|
98778
|
-
return utils_getInObject(inspectedElement,
|
|
99501
|
+
return utils_getInObject(inspectedElement, path32);
|
|
98779
99502
|
}
|
|
98780
99503
|
return;
|
|
98781
99504
|
}
|
|
@@ -98792,14 +99515,14 @@ The error thrown in the component is:
|
|
|
98792
99515
|
}
|
|
98793
99516
|
return element.type;
|
|
98794
99517
|
}
|
|
98795
|
-
function deletePath(type, id, hookID,
|
|
99518
|
+
function deletePath(type, id, hookID, path32) {
|
|
98796
99519
|
var internalInstance = idToInternalInstanceMap.get(id);
|
|
98797
99520
|
if (internalInstance != null) {
|
|
98798
99521
|
var publicInstance = internalInstance._instance;
|
|
98799
99522
|
if (publicInstance != null) {
|
|
98800
99523
|
switch (type) {
|
|
98801
99524
|
case "context":
|
|
98802
|
-
deletePathInObject(publicInstance.context,
|
|
99525
|
+
deletePathInObject(publicInstance.context, path32);
|
|
98803
99526
|
forceUpdate(publicInstance);
|
|
98804
99527
|
break;
|
|
98805
99528
|
case "hooks":
|
|
@@ -98807,12 +99530,12 @@ The error thrown in the component is:
|
|
|
98807
99530
|
case "props":
|
|
98808
99531
|
var element = internalInstance._currentElement;
|
|
98809
99532
|
internalInstance._currentElement = legacy_renderer_objectSpread(legacy_renderer_objectSpread({}, element), {}, {
|
|
98810
|
-
props: copyWithDelete(element.props,
|
|
99533
|
+
props: copyWithDelete(element.props, path32)
|
|
98811
99534
|
});
|
|
98812
99535
|
forceUpdate(publicInstance);
|
|
98813
99536
|
break;
|
|
98814
99537
|
case "state":
|
|
98815
|
-
deletePathInObject(publicInstance.state,
|
|
99538
|
+
deletePathInObject(publicInstance.state, path32);
|
|
98816
99539
|
forceUpdate(publicInstance);
|
|
98817
99540
|
break;
|
|
98818
99541
|
}
|
|
@@ -98846,14 +99569,14 @@ The error thrown in the component is:
|
|
|
98846
99569
|
}
|
|
98847
99570
|
}
|
|
98848
99571
|
}
|
|
98849
|
-
function overrideValueAtPath(type, id, hookID,
|
|
99572
|
+
function overrideValueAtPath(type, id, hookID, path32, value) {
|
|
98850
99573
|
var internalInstance = idToInternalInstanceMap.get(id);
|
|
98851
99574
|
if (internalInstance != null) {
|
|
98852
99575
|
var publicInstance = internalInstance._instance;
|
|
98853
99576
|
if (publicInstance != null) {
|
|
98854
99577
|
switch (type) {
|
|
98855
99578
|
case "context":
|
|
98856
|
-
utils_setInObject(publicInstance.context,
|
|
99579
|
+
utils_setInObject(publicInstance.context, path32, value);
|
|
98857
99580
|
forceUpdate(publicInstance);
|
|
98858
99581
|
break;
|
|
98859
99582
|
case "hooks":
|
|
@@ -98861,12 +99584,12 @@ The error thrown in the component is:
|
|
|
98861
99584
|
case "props":
|
|
98862
99585
|
var element = internalInstance._currentElement;
|
|
98863
99586
|
internalInstance._currentElement = legacy_renderer_objectSpread(legacy_renderer_objectSpread({}, element), {}, {
|
|
98864
|
-
props: copyWithSet(element.props,
|
|
99587
|
+
props: copyWithSet(element.props, path32, value)
|
|
98865
99588
|
});
|
|
98866
99589
|
forceUpdate(publicInstance);
|
|
98867
99590
|
break;
|
|
98868
99591
|
case "state":
|
|
98869
|
-
utils_setInObject(publicInstance.state,
|
|
99592
|
+
utils_setInObject(publicInstance.state, path32, value);
|
|
98870
99593
|
forceUpdate(publicInstance);
|
|
98871
99594
|
break;
|
|
98872
99595
|
}
|
|
@@ -98907,7 +99630,7 @@ The error thrown in the component is:
|
|
|
98907
99630
|
return [];
|
|
98908
99631
|
}
|
|
98909
99632
|
function setTraceUpdatesEnabled(enabled) {}
|
|
98910
|
-
function setTrackedPath(
|
|
99633
|
+
function setTrackedPath(path32) {}
|
|
98911
99634
|
function getOwnersList(id) {
|
|
98912
99635
|
return null;
|
|
98913
99636
|
}
|
|
@@ -100937,9 +101660,9 @@ var init_ranking = __esm(() => {
|
|
|
100937
101660
|
});
|
|
100938
101661
|
|
|
100939
101662
|
// src/bakeoff/coordinator.ts
|
|
100940
|
-
import { join as
|
|
101663
|
+
import { join as join99 } from "path";
|
|
100941
101664
|
async function persistBakeoffResult(result2, outputDir) {
|
|
100942
|
-
const filePath =
|
|
101665
|
+
const filePath = join99(outputDir, "bakeoff.json");
|
|
100943
101666
|
await Bun.write(filePath, JSON.stringify(result2, null, 2));
|
|
100944
101667
|
}
|
|
100945
101668
|
async function runBakeoff(options, deps = {}) {
|
|
@@ -101127,7 +101850,7 @@ __export(exports_curator, {
|
|
|
101127
101850
|
});
|
|
101128
101851
|
import { readdirSync as readdirSync9 } from "fs";
|
|
101129
101852
|
import { unlink as unlink4 } from "fs/promises";
|
|
101130
|
-
import { basename as basename18, join as
|
|
101853
|
+
import { basename as basename18, join as join100 } from "path";
|
|
101131
101854
|
function getProjectKey(config2, projectDir) {
|
|
101132
101855
|
return config2.name?.trim() || basename18(projectDir);
|
|
101133
101856
|
}
|
|
@@ -101210,7 +101933,7 @@ async function curatorStatus(options) {
|
|
|
101210
101933
|
const config2 = await _curatorCmdDeps.loadConfig(resolved.projectDir);
|
|
101211
101934
|
const projectKey = getProjectKey(config2, resolved.projectDir);
|
|
101212
101935
|
const outputDir = _curatorCmdDeps.projectOutputDir(projectKey, config2.outputDir);
|
|
101213
|
-
const runsDir =
|
|
101936
|
+
const runsDir = join100(outputDir, "runs");
|
|
101214
101937
|
const runIds = listRunIds(runsDir);
|
|
101215
101938
|
let runId;
|
|
101216
101939
|
if (options.run) {
|
|
@@ -101227,8 +101950,8 @@ async function curatorStatus(options) {
|
|
|
101227
101950
|
runId = runIds[runIds.length - 1];
|
|
101228
101951
|
}
|
|
101229
101952
|
console.log(`Run: ${runId}`);
|
|
101230
|
-
const runDir =
|
|
101231
|
-
const observationsPath =
|
|
101953
|
+
const runDir = join100(runsDir, runId);
|
|
101954
|
+
const observationsPath = join100(runDir, "observations.jsonl");
|
|
101232
101955
|
const observations = await parseObservations(observationsPath);
|
|
101233
101956
|
const counts = new Map;
|
|
101234
101957
|
for (const obs of observations) {
|
|
@@ -101238,7 +101961,7 @@ async function curatorStatus(options) {
|
|
|
101238
101961
|
for (const [kind, count] of counts.entries()) {
|
|
101239
101962
|
console.log(` ${kind}: ${count}`);
|
|
101240
101963
|
}
|
|
101241
|
-
const proposalsPath =
|
|
101964
|
+
const proposalsPath = join100(runDir, "curator-proposals.md");
|
|
101242
101965
|
const proposalText = await _curatorCmdDeps.readFile(proposalsPath).catch(() => null);
|
|
101243
101966
|
if (proposalText !== null) {
|
|
101244
101967
|
console.log("");
|
|
@@ -101252,8 +101975,8 @@ async function curatorCommit(options) {
|
|
|
101252
101975
|
const config2 = await _curatorCmdDeps.loadConfig(resolved.projectDir);
|
|
101253
101976
|
const projectKey = getProjectKey(config2, resolved.projectDir);
|
|
101254
101977
|
const outputDir = _curatorCmdDeps.projectOutputDir(projectKey, config2.outputDir);
|
|
101255
|
-
const runDir =
|
|
101256
|
-
const proposalsPath =
|
|
101978
|
+
const runDir = join100(outputDir, "runs", options.runId);
|
|
101979
|
+
const proposalsPath = join100(runDir, "curator-proposals.md");
|
|
101257
101980
|
const proposalText = await _curatorCmdDeps.readFile(proposalsPath).catch(() => null);
|
|
101258
101981
|
if (proposalText === null) {
|
|
101259
101982
|
console.log(`curator-proposals.md not found for run ${options.runId}.`);
|
|
@@ -101269,7 +101992,7 @@ async function curatorCommit(options) {
|
|
|
101269
101992
|
const dropFileState = new Map;
|
|
101270
101993
|
const skippedDrops = new Set;
|
|
101271
101994
|
for (const drop2 of drops) {
|
|
101272
|
-
const targetPath =
|
|
101995
|
+
const targetPath = join100(resolved.projectDir, drop2.canonicalFile);
|
|
101273
101996
|
if (!dropFileState.has(targetPath)) {
|
|
101274
101997
|
const fileExists2 = await Bun.file(targetPath).exists();
|
|
101275
101998
|
const existing = fileExists2 ? await _curatorCmdDeps.readFile(targetPath).catch(() => "") : "";
|
|
@@ -101303,7 +102026,7 @@ async function curatorCommit(options) {
|
|
|
101303
102026
|
if (skippedDrops.has(drop2)) {
|
|
101304
102027
|
continue;
|
|
101305
102028
|
}
|
|
101306
|
-
const targetPath =
|
|
102029
|
+
const targetPath = join100(resolved.projectDir, drop2.canonicalFile);
|
|
101307
102030
|
const existing = await _curatorCmdDeps.readFile(targetPath).catch(() => "");
|
|
101308
102031
|
const filtered = filterDropContent(existing, drop2.description);
|
|
101309
102032
|
await _curatorCmdDeps.writeFile(targetPath, filtered);
|
|
@@ -101312,7 +102035,7 @@ async function curatorCommit(options) {
|
|
|
101312
102035
|
}
|
|
101313
102036
|
const adds = proposals.filter((p) => p.action === "add" || p.action === "advisory");
|
|
101314
102037
|
for (const add2 of adds) {
|
|
101315
|
-
const targetPath =
|
|
102038
|
+
const targetPath = join100(resolved.projectDir, add2.canonicalFile);
|
|
101316
102039
|
const content = buildAddContent(add2);
|
|
101317
102040
|
await _curatorCmdDeps.appendFile(targetPath, content);
|
|
101318
102041
|
modifiedFiles.add(targetPath);
|
|
@@ -101349,7 +102072,7 @@ async function curatorDryrun(options) {
|
|
|
101349
102072
|
const config2 = await _curatorCmdDeps.loadConfig(resolved.projectDir);
|
|
101350
102073
|
const projectKey = getProjectKey(config2, resolved.projectDir);
|
|
101351
102074
|
const outputDir = _curatorCmdDeps.projectOutputDir(projectKey, config2.outputDir);
|
|
101352
|
-
const runsDir =
|
|
102075
|
+
const runsDir = join100(outputDir, "runs");
|
|
101353
102076
|
const runIds = listRunIds(runsDir);
|
|
101354
102077
|
if (runIds.length === 0) {
|
|
101355
102078
|
console.log("No runs found.");
|
|
@@ -101360,7 +102083,7 @@ async function curatorDryrun(options) {
|
|
|
101360
102083
|
console.log(`Run ${options.run} not found in ${runsDir}.`);
|
|
101361
102084
|
return;
|
|
101362
102085
|
}
|
|
101363
|
-
const observationsPath =
|
|
102086
|
+
const observationsPath = join100(runsDir, runId, "observations.jsonl");
|
|
101364
102087
|
const observations = await parseObservations(observationsPath);
|
|
101365
102088
|
const thresholds = getThresholds(config2);
|
|
101366
102089
|
const proposals = runHeuristics(observations, thresholds);
|
|
@@ -101401,12 +102124,12 @@ async function curatorGc(options) {
|
|
|
101401
102124
|
await _curatorCmdDeps.writeFile(rollupPath, newContent);
|
|
101402
102125
|
const projectKey = getProjectKey(config2, resolved.projectDir);
|
|
101403
102126
|
const outputDir = _curatorCmdDeps.projectOutputDir(projectKey, config2.outputDir);
|
|
101404
|
-
const perRunsDir =
|
|
102127
|
+
const perRunsDir = join100(outputDir, "runs");
|
|
101405
102128
|
for (const runId of uniqueRunIds) {
|
|
101406
102129
|
if (!keepSet.has(runId)) {
|
|
101407
|
-
const runDir =
|
|
101408
|
-
await _curatorCmdDeps.removeFile(
|
|
101409
|
-
await _curatorCmdDeps.removeFile(
|
|
102130
|
+
const runDir = join100(perRunsDir, runId);
|
|
102131
|
+
await _curatorCmdDeps.removeFile(join100(runDir, "observations.jsonl"));
|
|
102132
|
+
await _curatorCmdDeps.removeFile(join100(runDir, "curator-proposals.md"));
|
|
101410
102133
|
}
|
|
101411
102134
|
}
|
|
101412
102135
|
console.log(`[gc] Pruned rollup to ${keep} most recent runs (was ${uniqueRunIds.length}).`);
|
|
@@ -101451,7 +102174,7 @@ var init_curator2 = __esm(() => {
|
|
|
101451
102174
|
init_source();
|
|
101452
102175
|
import { existsSync as existsSync39, mkdirSync as mkdirSync8 } from "fs";
|
|
101453
102176
|
import { homedir as homedir3 } from "os";
|
|
101454
|
-
import { basename as basename19, join as
|
|
102177
|
+
import { basename as basename19, join as join101 } from "path";
|
|
101455
102178
|
|
|
101456
102179
|
// node_modules/commander/esm.mjs
|
|
101457
102180
|
var import__ = __toESM(require_commander(), 1);
|
|
@@ -101716,7 +102439,8 @@ class DebatePlanStrategy {
|
|
|
101716
102439
|
if (debateResult.outcome !== "failed" && debateResult.output) {
|
|
101717
102440
|
const prd2 = validatePlanOutput(debateResult.output, ctx.options.feature, ctx.branchName);
|
|
101718
102441
|
warnOnDroppedVerbatimAcs(prd2, ctx.specContent, ctx.options.feature);
|
|
101719
|
-
const
|
|
102442
|
+
const scoped2 = backfillOutOfScope(prd2, ctx.specContent, ctx.options.feature);
|
|
102443
|
+
const withProject2 = { ...scoped2, project: ctx.projectName };
|
|
101720
102444
|
return _debatePlanDeps.writeOrRecoverPrd(ctx, withProject2);
|
|
101721
102445
|
}
|
|
101722
102446
|
const prd = await callOp({
|
|
@@ -101814,7 +102538,8 @@ class PipelinePlanStrategy {
|
|
|
101814
102538
|
if (verdict.outcome !== "passed") {
|
|
101815
102539
|
throw new NaxError(verdict.specDeltasPath ? `Plan pipeline failed; see ${verdict.specDeltasPath}` : "Plan pipeline failed with no spec-deltas path", "PLAN_CRITIC_BLOCKED", { stage: "plan", specDeltasPath: verdict.specDeltasPath });
|
|
101816
102540
|
}
|
|
101817
|
-
const
|
|
102541
|
+
const scoped2 = backfillOutOfScope(verdict.prd, ctx.specContent, ctx.options.feature);
|
|
102542
|
+
const prdToWrite = finalizePrdRouting({ ...scoped2, project: ctx.projectName }, ctx.config.routing?.agents, ctx.profileName);
|
|
101818
102543
|
await ctx.deps.writeFile(ctx.outputPath, JSON.stringify(prdToWrite, null, 2));
|
|
101819
102544
|
return ctx.outputPath;
|
|
101820
102545
|
} finally {
|
|
@@ -102216,10 +102941,10 @@ init_setup_write();
|
|
|
102216
102941
|
// src/cli/plugins.ts
|
|
102217
102942
|
init_paths();
|
|
102218
102943
|
init_loader4();
|
|
102219
|
-
import * as
|
|
102944
|
+
import * as path23 from "path";
|
|
102220
102945
|
async function pluginsListCommand(config2, workdir, overrideGlobalPluginsDir) {
|
|
102221
|
-
const globalPluginsDir = overrideGlobalPluginsDir ??
|
|
102222
|
-
const projectPluginsDir =
|
|
102946
|
+
const globalPluginsDir = overrideGlobalPluginsDir ?? path23.join(globalConfigDir(), "plugins");
|
|
102947
|
+
const projectPluginsDir = path23.join(workdir, ".nax", "plugins");
|
|
102223
102948
|
const configPlugins = config2.plugins || [];
|
|
102224
102949
|
const registry3 = await loadPlugins(globalPluginsDir, projectPluginsDir, configPlugins, workdir, config2.disabledPlugins);
|
|
102225
102950
|
const plugins = registry3.plugins;
|
|
@@ -102269,10 +102994,10 @@ function formatSource(type, sourcePath) {
|
|
|
102269
102994
|
return `built-in (${sourcePath})`;
|
|
102270
102995
|
}
|
|
102271
102996
|
if (type === "global") {
|
|
102272
|
-
return `global (${
|
|
102997
|
+
return `global (${path23.basename(sourcePath)})`;
|
|
102273
102998
|
}
|
|
102274
102999
|
if (type === "project") {
|
|
102275
|
-
return `project (${
|
|
103000
|
+
return `project (${path23.basename(sourcePath)})`;
|
|
102276
103001
|
}
|
|
102277
103002
|
return `config (${sourcePath})`;
|
|
102278
103003
|
}
|
|
@@ -102287,7 +103012,7 @@ init_source();
|
|
|
102287
103012
|
init_loader();
|
|
102288
103013
|
init_generator2();
|
|
102289
103014
|
import { existsSync as existsSync24 } from "fs";
|
|
102290
|
-
import { join as
|
|
103015
|
+
import { join as join68 } from "path";
|
|
102291
103016
|
var VALID_AGENTS = ["claude", "codex", "opencode", "cursor", "windsurf", "aider", "gemini"];
|
|
102292
103017
|
async function generateCommand(options) {
|
|
102293
103018
|
const workdir = options.dir ?? process.cwd();
|
|
@@ -102330,7 +103055,7 @@ async function generateCommand(options) {
|
|
|
102330
103055
|
return;
|
|
102331
103056
|
}
|
|
102332
103057
|
if (options.package) {
|
|
102333
|
-
const packageDir =
|
|
103058
|
+
const packageDir = join68(workdir, options.package);
|
|
102334
103059
|
if (dryRun) {
|
|
102335
103060
|
console.log(source_default.yellow("\u26A0 Dry run \u2014 no files will be written"));
|
|
102336
103061
|
}
|
|
@@ -102350,8 +103075,8 @@ async function generateCommand(options) {
|
|
|
102350
103075
|
process.exit(1);
|
|
102351
103076
|
return;
|
|
102352
103077
|
}
|
|
102353
|
-
const contextPath = options.context ?
|
|
102354
|
-
const outputDir = options.output ?
|
|
103078
|
+
const contextPath = options.context ? join68(workdir, options.context) : join68(workdir, ".nax/context.md");
|
|
103079
|
+
const outputDir = options.output ? join68(workdir, options.output) : workdir;
|
|
102355
103080
|
const autoInject = !options.noAutoInject;
|
|
102356
103081
|
if (!existsSync24(contextPath)) {
|
|
102357
103082
|
console.error(source_default.red(`\u2717 Context file not found: ${contextPath}`));
|
|
@@ -102457,7 +103182,7 @@ async function generateCommand(options) {
|
|
|
102457
103182
|
// src/cli/config-display.ts
|
|
102458
103183
|
init_loader();
|
|
102459
103184
|
import { existsSync as existsSync26 } from "fs";
|
|
102460
|
-
import { join as
|
|
103185
|
+
import { join as join70 } from "path";
|
|
102461
103186
|
|
|
102462
103187
|
// src/cli/config-descriptions.ts
|
|
102463
103188
|
var FIELD_DESCRIPTIONS = {
|
|
@@ -102665,10 +103390,10 @@ function deepDiffConfigs(global2, project, currentPath = []) {
|
|
|
102665
103390
|
for (const key of Object.keys(project)) {
|
|
102666
103391
|
const projectValue = project[key];
|
|
102667
103392
|
const globalValue = global2[key];
|
|
102668
|
-
const
|
|
102669
|
-
const pathStr =
|
|
103393
|
+
const path24 = [...currentPath, key];
|
|
103394
|
+
const pathStr = path24.join(".");
|
|
102670
103395
|
if (projectValue !== null && typeof projectValue === "object" && !Array.isArray(projectValue) && globalValue !== null && typeof globalValue === "object" && !Array.isArray(globalValue)) {
|
|
102671
|
-
const nestedDiffs = deepDiffConfigs(globalValue, projectValue,
|
|
103396
|
+
const nestedDiffs = deepDiffConfigs(globalValue, projectValue, path24);
|
|
102672
103397
|
diffs.push(...nestedDiffs);
|
|
102673
103398
|
} else {
|
|
102674
103399
|
if (!deepEqual(projectValue, globalValue)) {
|
|
@@ -102710,12 +103435,12 @@ function deepEqual(a, b) {
|
|
|
102710
103435
|
init_defaults();
|
|
102711
103436
|
init_loader();
|
|
102712
103437
|
import { existsSync as existsSync25 } from "fs";
|
|
102713
|
-
import { join as
|
|
102714
|
-
async function loadConfigFile(
|
|
102715
|
-
if (!existsSync25(
|
|
103438
|
+
import { join as join69 } from "path";
|
|
103439
|
+
async function loadConfigFile(path24) {
|
|
103440
|
+
if (!existsSync25(path24))
|
|
102716
103441
|
return null;
|
|
102717
103442
|
try {
|
|
102718
|
-
return await Bun.file(
|
|
103443
|
+
return await Bun.file(path24).json();
|
|
102719
103444
|
} catch {
|
|
102720
103445
|
return null;
|
|
102721
103446
|
}
|
|
@@ -102732,7 +103457,7 @@ async function loadProjectConfig() {
|
|
|
102732
103457
|
const projectDir = findProjectDir();
|
|
102733
103458
|
if (!projectDir)
|
|
102734
103459
|
return null;
|
|
102735
|
-
const projectPath =
|
|
103460
|
+
const projectPath = join69(projectDir, "config.json");
|
|
102736
103461
|
return await loadConfigFile(projectPath);
|
|
102737
103462
|
}
|
|
102738
103463
|
|
|
@@ -102762,10 +103487,10 @@ async function configCommand(config2, options = {}) {
|
|
|
102762
103487
|
console.log(`${"Field".padEnd(40)}${"Project Value".padEnd(20)}Global Value`);
|
|
102763
103488
|
console.log("\u2500".repeat(80));
|
|
102764
103489
|
for (const diff2 of diffs) {
|
|
102765
|
-
const
|
|
103490
|
+
const path24 = diff2.path.padEnd(40);
|
|
102766
103491
|
const projectVal = formatValueForTable(diff2.projectValue);
|
|
102767
103492
|
const globalVal = formatValueForTable(diff2.globalValue);
|
|
102768
|
-
console.log(`${
|
|
103493
|
+
console.log(`${path24}${projectVal.padEnd(20)}${globalVal}`);
|
|
102769
103494
|
const description = FIELD_DESCRIPTIONS[diff2.path];
|
|
102770
103495
|
if (description) {
|
|
102771
103496
|
console.log(`${"".padEnd(40)}\u21B3 ${description}`);
|
|
@@ -102792,32 +103517,32 @@ async function configCommand(config2, options = {}) {
|
|
|
102792
103517
|
function determineConfigSources() {
|
|
102793
103518
|
const globalPath = globalConfigPath();
|
|
102794
103519
|
const projectDir = findProjectDir();
|
|
102795
|
-
const projectPath = projectDir ?
|
|
103520
|
+
const projectPath = projectDir ? join70(projectDir, "config.json") : null;
|
|
102796
103521
|
return {
|
|
102797
103522
|
global: fileExists(globalPath) ? globalPath : null,
|
|
102798
103523
|
project: projectPath && fileExists(projectPath) ? projectPath : null
|
|
102799
103524
|
};
|
|
102800
103525
|
}
|
|
102801
|
-
function fileExists(
|
|
102802
|
-
return existsSync26(
|
|
103526
|
+
function fileExists(path24) {
|
|
103527
|
+
return existsSync26(path24);
|
|
102803
103528
|
}
|
|
102804
|
-
function displayConfigWithDescriptions(obj,
|
|
103529
|
+
function displayConfigWithDescriptions(obj, path24, sources, indent = 0) {
|
|
102805
103530
|
const indentStr = " ".repeat(indent);
|
|
102806
|
-
const pathStr =
|
|
103531
|
+
const pathStr = path24.join(".");
|
|
102807
103532
|
if (obj === null || obj === undefined || typeof obj !== "object" || Array.isArray(obj)) {
|
|
102808
103533
|
const description = FIELD_DESCRIPTIONS[pathStr];
|
|
102809
103534
|
const value = formatValue(obj);
|
|
102810
103535
|
if (description) {
|
|
102811
103536
|
console.log(`${indentStr}# ${description}`);
|
|
102812
103537
|
}
|
|
102813
|
-
const key =
|
|
103538
|
+
const key = path24[path24.length - 1] || "";
|
|
102814
103539
|
console.log(`${indentStr}${key}: ${value}`);
|
|
102815
103540
|
console.log();
|
|
102816
103541
|
return;
|
|
102817
103542
|
}
|
|
102818
103543
|
const entries = Object.entries(obj);
|
|
102819
103544
|
const objAsRecord = obj;
|
|
102820
|
-
const isPromptsSection =
|
|
103545
|
+
const isPromptsSection = path24.join(".") === "prompts";
|
|
102821
103546
|
if (isPromptsSection && !objAsRecord.overrides) {
|
|
102822
103547
|
const description = FIELD_DESCRIPTIONS["prompts.overrides"];
|
|
102823
103548
|
if (description) {
|
|
@@ -102840,7 +103565,7 @@ function displayConfigWithDescriptions(obj, path23, sources, indent = 0) {
|
|
|
102840
103565
|
}
|
|
102841
103566
|
for (let i = 0;i < entries.length; i++) {
|
|
102842
103567
|
const [key, value] = entries[i];
|
|
102843
|
-
const currentPath = [...
|
|
103568
|
+
const currentPath = [...path24, key];
|
|
102844
103569
|
const currentPathStr = currentPath.join(".");
|
|
102845
103570
|
const description = FIELD_DESCRIPTIONS[currentPathStr];
|
|
102846
103571
|
if (description) {
|
|
@@ -102941,15 +103666,15 @@ init_paths();
|
|
|
102941
103666
|
init_profile();
|
|
102942
103667
|
import { mkdirSync as mkdirSync5 } from "fs";
|
|
102943
103668
|
import { readdirSync as readdirSync5 } from "fs";
|
|
102944
|
-
import { join as
|
|
103669
|
+
import { join as join71 } from "path";
|
|
102945
103670
|
var _profileCLIDeps = {
|
|
102946
103671
|
env: process.env
|
|
102947
103672
|
};
|
|
102948
103673
|
var SENSITIVE_KEY_PATTERN = /key|token|secret|password|credential/i;
|
|
102949
103674
|
var VAR_PATTERN = /\$[A-Za-z_][A-Za-z0-9_]*/;
|
|
102950
103675
|
async function profileListCommand(startDir) {
|
|
102951
|
-
const globalProfilesDir =
|
|
102952
|
-
const projectProfilesDir =
|
|
103676
|
+
const globalProfilesDir = join71(globalConfigDir(), "profiles");
|
|
103677
|
+
const projectProfilesDir = join71(projectConfigDir(startDir), "profiles");
|
|
102953
103678
|
const globalProfiles = scanProfileDir(globalProfilesDir);
|
|
102954
103679
|
const projectProfiles = scanProfileDir(projectProfilesDir);
|
|
102955
103680
|
const activeProfile = await resolveProfileName({}, _profileCLIDeps.env, startDir);
|
|
@@ -103008,7 +103733,7 @@ function maskProfileValues(obj) {
|
|
|
103008
103733
|
return result;
|
|
103009
103734
|
}
|
|
103010
103735
|
async function profileUseCommand(profileName, startDir) {
|
|
103011
|
-
const configPath =
|
|
103736
|
+
const configPath = join71(projectConfigDir(startDir), "config.json");
|
|
103012
103737
|
const configFile = Bun.file(configPath);
|
|
103013
103738
|
let existing = {};
|
|
103014
103739
|
if (await configFile.exists()) {
|
|
@@ -103027,8 +103752,8 @@ async function profileCurrentCommand(startDir) {
|
|
|
103027
103752
|
return resolveProfileName({}, _profileCLIDeps.env, startDir);
|
|
103028
103753
|
}
|
|
103029
103754
|
async function profileCreateCommand(profileName, startDir) {
|
|
103030
|
-
const profilesDir =
|
|
103031
|
-
const profilePath =
|
|
103755
|
+
const profilesDir = join71(projectConfigDir(startDir), "profiles");
|
|
103756
|
+
const profilePath = join71(profilesDir, `${profileName}.json`);
|
|
103032
103757
|
const profileFile = Bun.file(profilePath);
|
|
103033
103758
|
if (await profileFile.exists()) {
|
|
103034
103759
|
throw new Error(`Profile "${profileName}" already exists at ${profilePath}`);
|
|
@@ -103150,22 +103875,22 @@ async function contextInspectCommand(options) {
|
|
|
103150
103875
|
init_canonical_loader();
|
|
103151
103876
|
init_errors();
|
|
103152
103877
|
import { mkdir as mkdir11 } from "fs/promises";
|
|
103153
|
-
import { basename as basename13, join as
|
|
103878
|
+
import { basename as basename13, join as join72 } from "path";
|
|
103154
103879
|
var _rulesCLIDeps = {
|
|
103155
|
-
readFile: async (
|
|
103156
|
-
writeFile: async (
|
|
103157
|
-
await Bun.write(
|
|
103880
|
+
readFile: async (path24) => Bun.file(path24).text(),
|
|
103881
|
+
writeFile: async (path24, content) => {
|
|
103882
|
+
await Bun.write(path24, content);
|
|
103158
103883
|
},
|
|
103159
|
-
fileExists: async (
|
|
103884
|
+
fileExists: async (path24) => Bun.file(path24).exists(),
|
|
103160
103885
|
globInDir: (dir) => {
|
|
103161
103886
|
try {
|
|
103162
|
-
return [...new Bun.Glob("*.md").scanSync({ cwd: dir })].sort().map((f) =>
|
|
103887
|
+
return [...new Bun.Glob("*.md").scanSync({ cwd: dir })].sort().map((f) => join72(dir, f));
|
|
103163
103888
|
} catch {
|
|
103164
103889
|
return [];
|
|
103165
103890
|
}
|
|
103166
103891
|
},
|
|
103167
|
-
mkdir: async (
|
|
103168
|
-
await mkdir11(
|
|
103892
|
+
mkdir: async (path24) => {
|
|
103893
|
+
await mkdir11(path24, { recursive: true });
|
|
103169
103894
|
},
|
|
103170
103895
|
globCanonicalRuleFiles: (workdir) => {
|
|
103171
103896
|
try {
|
|
@@ -103208,7 +103933,7 @@ ${r.content}`).join(`
|
|
|
103208
103933
|
`);
|
|
103209
103934
|
const shimContent = `${header + body}
|
|
103210
103935
|
`;
|
|
103211
|
-
const shimPath =
|
|
103936
|
+
const shimPath = join72(workdir, shimFileName);
|
|
103212
103937
|
if (options.dryRun) {
|
|
103213
103938
|
console.log(`[dry-run] Would write ${shimPath} (${shimContent.length} bytes)`);
|
|
103214
103939
|
return;
|
|
@@ -103237,14 +103962,14 @@ function neutralizeContent(content) {
|
|
|
103237
103962
|
}
|
|
103238
103963
|
async function collectMigrationSources(workdir) {
|
|
103239
103964
|
const sources = [];
|
|
103240
|
-
const claudeMdPath =
|
|
103965
|
+
const claudeMdPath = join72(workdir, "CLAUDE.md");
|
|
103241
103966
|
if (await _rulesCLIDeps.fileExists(claudeMdPath)) {
|
|
103242
103967
|
const content = await _rulesCLIDeps.readFile(claudeMdPath);
|
|
103243
103968
|
if (content.trim()) {
|
|
103244
103969
|
sources.push({ sourcePath: claudeMdPath, targetFileName: "project-conventions.md", content });
|
|
103245
103970
|
}
|
|
103246
103971
|
}
|
|
103247
|
-
const rulesDir =
|
|
103972
|
+
const rulesDir = join72(workdir, ".claude", "rules");
|
|
103248
103973
|
const ruleFiles = _rulesCLIDeps.globInDir(rulesDir);
|
|
103249
103974
|
for (const filePath of ruleFiles) {
|
|
103250
103975
|
try {
|
|
@@ -103264,7 +103989,7 @@ async function rulesMigrateCommand(options) {
|
|
|
103264
103989
|
console.log("[WARN] No source files found (checked CLAUDE.md and .claude/rules/*.md). Nothing to migrate.");
|
|
103265
103990
|
return;
|
|
103266
103991
|
}
|
|
103267
|
-
const targetDir =
|
|
103992
|
+
const targetDir = join72(workdir, CANONICAL_RULES_DIR);
|
|
103268
103993
|
if (!options.dryRun) {
|
|
103269
103994
|
try {
|
|
103270
103995
|
await _rulesCLIDeps.mkdir(targetDir);
|
|
@@ -103275,7 +104000,7 @@ async function rulesMigrateCommand(options) {
|
|
|
103275
104000
|
let written = 0;
|
|
103276
104001
|
let skipped = 0;
|
|
103277
104002
|
for (const { sourcePath, targetFileName, content } of sources) {
|
|
103278
|
-
const targetPath =
|
|
104003
|
+
const targetPath = join72(targetDir, targetFileName);
|
|
103279
104004
|
if (!force && !options.dryRun && await _rulesCLIDeps.fileExists(targetPath)) {
|
|
103280
104005
|
console.log(`[skip] ${targetFileName} already exists (use --force to overwrite)`);
|
|
103281
104006
|
skipped++;
|
|
@@ -103314,7 +104039,7 @@ function collectCanonicalRuleRoots(workdir) {
|
|
|
103314
104039
|
const packageRel = normalized.slice(0, idx);
|
|
103315
104040
|
if (!packageRel)
|
|
103316
104041
|
continue;
|
|
103317
|
-
roots.add(
|
|
104042
|
+
roots.add(join72(workdir, packageRel));
|
|
103318
104043
|
}
|
|
103319
104044
|
return [...roots].sort();
|
|
103320
104045
|
}
|
|
@@ -103338,8 +104063,8 @@ async function resolveRunProfileOverride(opts) {
|
|
|
103338
104063
|
return cliChain;
|
|
103339
104064
|
if (opts.envProfile)
|
|
103340
104065
|
return;
|
|
103341
|
-
const readJson = opts._readJson ?? (async (
|
|
103342
|
-
const file3 = Bun.file(
|
|
104066
|
+
const readJson = opts._readJson ?? (async (path24) => {
|
|
104067
|
+
const file3 = Bun.file(path24);
|
|
103343
104068
|
if (!await file3.exists())
|
|
103344
104069
|
return;
|
|
103345
104070
|
return file3.json();
|
|
@@ -103362,7 +104087,7 @@ async function resolveRunProfileOverride(opts) {
|
|
|
103362
104087
|
// src/cli/features-resolve.ts
|
|
103363
104088
|
init_config();
|
|
103364
104089
|
import { existsSync as existsSync28, readdirSync as readdirSync6 } from "fs";
|
|
103365
|
-
import { join as
|
|
104090
|
+
import { join as join74, relative as relative16 } from "path";
|
|
103366
104091
|
|
|
103367
104092
|
// src/cli/features-acceptance.ts
|
|
103368
104093
|
init_acceptance2();
|
|
@@ -103370,7 +104095,7 @@ init_config();
|
|
|
103370
104095
|
init_logger2();
|
|
103371
104096
|
init_prd();
|
|
103372
104097
|
import { existsSync as existsSync27 } from "fs";
|
|
103373
|
-
import { join as
|
|
104098
|
+
import { join as join73, relative as relative15 } from "path";
|
|
103374
104099
|
async function resolveFeatureAcceptance(featureName, workdir) {
|
|
103375
104100
|
let enabled = true;
|
|
103376
104101
|
try {
|
|
@@ -103378,13 +104103,13 @@ async function resolveFeatureAcceptance(featureName, workdir) {
|
|
|
103378
104103
|
if (!naxDir) {
|
|
103379
104104
|
return { status: "no-prd", enabled, groups: [] };
|
|
103380
104105
|
}
|
|
103381
|
-
const repoRoot =
|
|
104106
|
+
const repoRoot = join73(naxDir, "..");
|
|
103382
104107
|
const config2 = await loadConfig(workdir);
|
|
103383
104108
|
enabled = config2.acceptance?.enabled ?? true;
|
|
103384
104109
|
if (!enabled) {
|
|
103385
104110
|
return { status: "disabled", enabled: false, groups: [] };
|
|
103386
104111
|
}
|
|
103387
|
-
const prdPath =
|
|
104112
|
+
const prdPath = join73(naxDir, "features", featureName, "prd.json");
|
|
103388
104113
|
if (!existsSync27(prdPath)) {
|
|
103389
104114
|
return { status: "no-prd", enabled, groups: [] };
|
|
103390
104115
|
}
|
|
@@ -103427,10 +104152,10 @@ async function isNonEmptyFile(absolutePath) {
|
|
|
103427
104152
|
}
|
|
103428
104153
|
async function searchSpecSource(naxDir, repoRoot, name) {
|
|
103429
104154
|
const candidates = [
|
|
103430
|
-
{ abs:
|
|
103431
|
-
{ abs:
|
|
104155
|
+
{ abs: join74(naxDir, "features", name, "spec.md"), kind: "markdown" },
|
|
104156
|
+
{ abs: join74(naxDir, "specs", `${name}.md`), kind: "markdown" }
|
|
103432
104157
|
];
|
|
103433
|
-
const docsSpecExact =
|
|
104158
|
+
const docsSpecExact = join74(repoRoot, "docs", "specs", `SPEC-${name}.md`);
|
|
103434
104159
|
candidates.push({ abs: docsSpecExact, kind: "markdown" });
|
|
103435
104160
|
const checked = candidates.map((c) => relative16(repoRoot, c.abs));
|
|
103436
104161
|
for (const { abs, kind } of candidates.slice(0, 2)) {
|
|
@@ -103444,11 +104169,11 @@ async function searchSpecSource(naxDir, repoRoot, name) {
|
|
|
103444
104169
|
if (await isNonEmptyFile(docsSpecExact)) {
|
|
103445
104170
|
return { source: { kind: "markdown", path: relative16(repoRoot, docsSpecExact) }, checked };
|
|
103446
104171
|
}
|
|
103447
|
-
const docsSpecsDir =
|
|
104172
|
+
const docsSpecsDir = join74(repoRoot, "docs", "specs");
|
|
103448
104173
|
if (existsSync28(docsSpecsDir)) {
|
|
103449
104174
|
const glob = new Bun.Glob(`*${name}*.md`);
|
|
103450
104175
|
for (const match of glob.scanSync({ cwd: docsSpecsDir, absolute: false })) {
|
|
103451
|
-
const abs =
|
|
104176
|
+
const abs = join74(docsSpecsDir, match);
|
|
103452
104177
|
if (await isNonEmptyFile(abs)) {
|
|
103453
104178
|
const relPath = relative16(repoRoot, abs);
|
|
103454
104179
|
if (!checked.includes(relPath))
|
|
@@ -103457,7 +104182,7 @@ async function searchSpecSource(naxDir, repoRoot, name) {
|
|
|
103457
104182
|
}
|
|
103458
104183
|
}
|
|
103459
104184
|
}
|
|
103460
|
-
const prdAbs =
|
|
104185
|
+
const prdAbs = join74(naxDir, "features", name, "prd.json");
|
|
103461
104186
|
const prdRel = relative16(repoRoot, prdAbs);
|
|
103462
104187
|
if (!checked.includes(prdRel))
|
|
103463
104188
|
checked.push(prdRel);
|
|
@@ -103467,14 +104192,14 @@ async function searchSpecSource(naxDir, repoRoot, name) {
|
|
|
103467
104192
|
return { source: null, checked };
|
|
103468
104193
|
}
|
|
103469
104194
|
function discoverCandidates(naxDir) {
|
|
103470
|
-
const featuresDir =
|
|
104195
|
+
const featuresDir = join74(naxDir, "features");
|
|
103471
104196
|
if (!existsSync28(featuresDir))
|
|
103472
104197
|
return [];
|
|
103473
104198
|
return readdirSync6(featuresDir, { withFileTypes: true }).filter((e) => {
|
|
103474
104199
|
if (!e.isDirectory())
|
|
103475
104200
|
return false;
|
|
103476
|
-
const dir =
|
|
103477
|
-
return existsSync28(
|
|
104201
|
+
const dir = join74(featuresDir, e.name);
|
|
104202
|
+
return existsSync28(join74(dir, "prd.json")) || existsSync28(join74(dir, "spec.md"));
|
|
103478
104203
|
}).map((e) => e.name).sort();
|
|
103479
104204
|
}
|
|
103480
104205
|
async function resolveFeatureSpec(name, workdir) {
|
|
@@ -103485,9 +104210,9 @@ async function resolveFeatureSpec(name, workdir) {
|
|
|
103485
104210
|
message: `not a nax repo: no .nax/config.json found from ${workdir}`
|
|
103486
104211
|
};
|
|
103487
104212
|
}
|
|
103488
|
-
const repoRoot =
|
|
104213
|
+
const repoRoot = join74(naxDir, "..");
|
|
103489
104214
|
if (name !== undefined && (name.startsWith("./") || name.startsWith("/") || name.endsWith(".md"))) {
|
|
103490
|
-
const abs = name.startsWith("/") ? name :
|
|
104215
|
+
const abs = name.startsWith("/") ? name : join74(workdir, name);
|
|
103491
104216
|
if (!existsSync28(abs)) {
|
|
103492
104217
|
return {
|
|
103493
104218
|
status: "missing",
|
|
@@ -103526,7 +104251,7 @@ async function resolveFeatureSpec(name, workdir) {
|
|
|
103526
104251
|
message: `resolved spec: ${source2.path}`
|
|
103527
104252
|
};
|
|
103528
104253
|
}
|
|
103529
|
-
const featureDir =
|
|
104254
|
+
const featureDir = join74(naxDir, "features", name);
|
|
103530
104255
|
if (existsSync28(featureDir)) {
|
|
103531
104256
|
return {
|
|
103532
104257
|
status: "missing",
|
|
@@ -103588,14 +104313,14 @@ init_runtime();
|
|
|
103588
104313
|
init_json_file();
|
|
103589
104314
|
init_routing();
|
|
103590
104315
|
import { mkdirSync as mkdirSync6 } from "fs";
|
|
103591
|
-
import { basename as basename14, join as
|
|
104316
|
+
import { basename as basename14, join as join75 } from "path";
|
|
103592
104317
|
var _routingCalibrateDeps = {
|
|
103593
104318
|
loadRunMetrics: (outputDir) => loadRunMetrics(outputDir),
|
|
103594
104319
|
readConfig: (workdir) => loadConfig(workdir),
|
|
103595
104320
|
writeConfig: async (workdir, config2) => {
|
|
103596
104321
|
const dir = projectInputDir(workdir);
|
|
103597
104322
|
mkdirSync6(dir, { recursive: true });
|
|
103598
|
-
const filePath =
|
|
104323
|
+
const filePath = join75(dir, "config.json");
|
|
103599
104324
|
await saveJsonFile(filePath, config2, "routing-calibrate");
|
|
103600
104325
|
},
|
|
103601
104326
|
stdout: (msg) => {
|
|
@@ -103722,7 +104447,7 @@ init_logger2();
|
|
|
103722
104447
|
init_detect2();
|
|
103723
104448
|
init_workspace();
|
|
103724
104449
|
init_common();
|
|
103725
|
-
import { join as
|
|
104450
|
+
import { join as join76 } from "path";
|
|
103726
104451
|
function resolveEffective(detected, configPatterns) {
|
|
103727
104452
|
if (configPatterns !== undefined)
|
|
103728
104453
|
return "config";
|
|
@@ -103730,14 +104455,14 @@ function resolveEffective(detected, configPatterns) {
|
|
|
103730
104455
|
return "detected";
|
|
103731
104456
|
return "none";
|
|
103732
104457
|
}
|
|
103733
|
-
async function loadRawConfig(
|
|
103734
|
-
const f = Bun.file(
|
|
104458
|
+
async function loadRawConfig(path24) {
|
|
104459
|
+
const f = Bun.file(path24);
|
|
103735
104460
|
if (!await f.exists())
|
|
103736
104461
|
return {};
|
|
103737
104462
|
return JSON.parse(await f.text());
|
|
103738
104463
|
}
|
|
103739
|
-
async function writeRawConfig(
|
|
103740
|
-
await Bun.write(
|
|
104464
|
+
async function writeRawConfig(path24, data) {
|
|
104465
|
+
await Bun.write(path24, `${JSON.stringify(data, null, 2)}
|
|
103741
104466
|
`);
|
|
103742
104467
|
}
|
|
103743
104468
|
function deepSet(obj, keyPath, value) {
|
|
@@ -103807,7 +104532,7 @@ async function detectCommand(options) {
|
|
|
103807
104532
|
const rootDetected = detectionMap[""] ?? { patterns: [], confidence: "empty", sources: [] };
|
|
103808
104533
|
const pkgEntries = await Promise.all(packageDirs.map(async (dir) => {
|
|
103809
104534
|
const det = detectionMap[dir] ?? { patterns: [], confidence: "empty", sources: [] };
|
|
103810
|
-
const pkgConfigPath =
|
|
104535
|
+
const pkgConfigPath = join76(workdir, ".nax", "mono", dir, "config.json");
|
|
103811
104536
|
const pkgRaw = await loadRawConfig(pkgConfigPath);
|
|
103812
104537
|
const pkgPatterns = deepGet(pkgRaw, TEST_PATTERNS_KEY);
|
|
103813
104538
|
const effective = Array.isArray(pkgPatterns) ? pkgPatterns : undefined;
|
|
@@ -103861,13 +104586,13 @@ async function detectCommand(options) {
|
|
|
103861
104586
|
if (rootDetected.confidence === "empty") {
|
|
103862
104587
|
console.log(source_default.yellow(" root: skipped (empty detection)"));
|
|
103863
104588
|
} else {
|
|
103864
|
-
const rootConfigPath =
|
|
104589
|
+
const rootConfigPath = join76(workdir, ".nax", "config.json");
|
|
103865
104590
|
try {
|
|
103866
104591
|
const status = await applyToConfig(rootConfigPath, rootDetected.patterns, options.force ?? false);
|
|
103867
104592
|
if (status === "skipped") {
|
|
103868
104593
|
console.log(source_default.dim(" root: skipped (testFilePatterns already set; use --force to overwrite)"));
|
|
103869
104594
|
} else {
|
|
103870
|
-
console.log(source_default.green(` root: ${status} \u2192 ${
|
|
104595
|
+
console.log(source_default.green(` root: ${status} \u2192 ${join76(".nax", "config.json")}`));
|
|
103871
104596
|
}
|
|
103872
104597
|
} catch (err) {
|
|
103873
104598
|
console.error(source_default.red(` root: write failed \u2014 ${err.message}`));
|
|
@@ -103880,13 +104605,13 @@ async function detectCommand(options) {
|
|
|
103880
104605
|
console.log(source_default.dim(` ${dir}: skipped (empty detection)`));
|
|
103881
104606
|
continue;
|
|
103882
104607
|
}
|
|
103883
|
-
const pkgConfigPath =
|
|
104608
|
+
const pkgConfigPath = join76(workdir, ".nax", "mono", dir, "config.json");
|
|
103884
104609
|
try {
|
|
103885
104610
|
const status = await applyToConfig(pkgConfigPath, det.patterns, options.force ?? false);
|
|
103886
104611
|
if (status === "skipped") {
|
|
103887
104612
|
console.log(source_default.dim(` ${dir}: skipped (already set)`));
|
|
103888
104613
|
} else {
|
|
103889
|
-
console.log(source_default.green(` ${dir}: ${status} \u2192 ${
|
|
104614
|
+
console.log(source_default.green(` ${dir}: ${status} \u2192 ${join76(".nax", "mono", dir, "config.json")}`));
|
|
103890
104615
|
}
|
|
103891
104616
|
} catch (err) {
|
|
103892
104617
|
console.error(source_default.red(` ${dir}: write failed \u2014 ${err.message}`));
|
|
@@ -103904,19 +104629,19 @@ async function detectCommand(options) {
|
|
|
103904
104629
|
// src/commands/logs.ts
|
|
103905
104630
|
init_common();
|
|
103906
104631
|
import { existsSync as existsSync30 } from "fs";
|
|
103907
|
-
import { join as
|
|
104632
|
+
import { join as join79 } from "path";
|
|
103908
104633
|
|
|
103909
104634
|
// src/commands/logs-formatter.ts
|
|
103910
104635
|
init_source();
|
|
103911
104636
|
init_formatter();
|
|
103912
104637
|
import { readdirSync as readdirSync8 } from "fs";
|
|
103913
|
-
import { join as
|
|
104638
|
+
import { join as join78 } from "path";
|
|
103914
104639
|
|
|
103915
104640
|
// src/commands/logs-reader.ts
|
|
103916
104641
|
init_paths3();
|
|
103917
104642
|
import { existsSync as existsSync29, readdirSync as readdirSync7 } from "fs";
|
|
103918
104643
|
import { readdir as readdir3 } from "fs/promises";
|
|
103919
|
-
import { join as
|
|
104644
|
+
import { join as join77 } from "path";
|
|
103920
104645
|
var _logsReaderDeps = {
|
|
103921
104646
|
getRunsDir
|
|
103922
104647
|
};
|
|
@@ -103930,7 +104655,7 @@ async function resolveRunFileFromRegistry(runId) {
|
|
|
103930
104655
|
}
|
|
103931
104656
|
let matched = null;
|
|
103932
104657
|
for (const entry of entries) {
|
|
103933
|
-
const metaPath =
|
|
104658
|
+
const metaPath = join77(runsDir, entry, "meta.json");
|
|
103934
104659
|
try {
|
|
103935
104660
|
const meta3 = await Bun.file(metaPath).json();
|
|
103936
104661
|
if (meta3.runId === runId || meta3.runId.startsWith(runId)) {
|
|
@@ -103952,14 +104677,14 @@ async function resolveRunFileFromRegistry(runId) {
|
|
|
103952
104677
|
return null;
|
|
103953
104678
|
}
|
|
103954
104679
|
const specificFile = files.find((f) => f === `${matched.runId}.jsonl`);
|
|
103955
|
-
return
|
|
104680
|
+
return join77(matched.eventsDir, specificFile ?? files[0]);
|
|
103956
104681
|
}
|
|
103957
104682
|
async function selectRunFile(runsDir) {
|
|
103958
104683
|
const files = readdirSync7(runsDir).filter((f) => f.endsWith(".jsonl") && f !== "latest.jsonl").sort().reverse();
|
|
103959
104684
|
if (files.length === 0) {
|
|
103960
104685
|
return null;
|
|
103961
104686
|
}
|
|
103962
|
-
return
|
|
104687
|
+
return join77(runsDir, files[0]);
|
|
103963
104688
|
}
|
|
103964
104689
|
async function extractRunSummary(filePath) {
|
|
103965
104690
|
const file3 = Bun.file(filePath);
|
|
@@ -104045,7 +104770,7 @@ Runs:
|
|
|
104045
104770
|
console.log(source_default.gray(" Timestamp Stories Duration Cost Status"));
|
|
104046
104771
|
console.log(source_default.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
104047
104772
|
for (const file3 of files) {
|
|
104048
|
-
const filePath =
|
|
104773
|
+
const filePath = join78(runsDir, file3);
|
|
104049
104774
|
const summary = await extractRunSummary(filePath);
|
|
104050
104775
|
const timestamp = file3.replace(".jsonl", "");
|
|
104051
104776
|
const stories = summary ? `${summary.passed}/${summary.total}` : "?/?";
|
|
@@ -104159,7 +104884,7 @@ async function logsCommand(options) {
|
|
|
104159
104884
|
return;
|
|
104160
104885
|
}
|
|
104161
104886
|
const resolved = resolveProject2({ dir: options.dir });
|
|
104162
|
-
const naxDir =
|
|
104887
|
+
const naxDir = join79(resolved.projectDir, ".nax");
|
|
104163
104888
|
const configPath = resolved.configPath;
|
|
104164
104889
|
const configFile = Bun.file(configPath);
|
|
104165
104890
|
const config2 = await configFile.json();
|
|
@@ -104167,8 +104892,8 @@ async function logsCommand(options) {
|
|
|
104167
104892
|
if (!featureName) {
|
|
104168
104893
|
throw new Error("No feature specified in config.json");
|
|
104169
104894
|
}
|
|
104170
|
-
const featureDir =
|
|
104171
|
-
const runsDir =
|
|
104895
|
+
const featureDir = join79(naxDir, "features", featureName);
|
|
104896
|
+
const runsDir = join79(featureDir, "runs");
|
|
104172
104897
|
if (!existsSync30(runsDir)) {
|
|
104173
104898
|
throw new Error(`No runs directory found for feature: ${featureName}`);
|
|
104174
104899
|
}
|
|
@@ -104194,7 +104919,7 @@ init_prd();
|
|
|
104194
104919
|
init_precheck();
|
|
104195
104920
|
init_common();
|
|
104196
104921
|
import { existsSync as existsSync31 } from "fs";
|
|
104197
|
-
import { join as
|
|
104922
|
+
import { join as join80 } from "path";
|
|
104198
104923
|
async function precheckCommand(options) {
|
|
104199
104924
|
const resolved = resolveProject2({
|
|
104200
104925
|
dir: options.dir,
|
|
@@ -104216,9 +104941,9 @@ async function precheckCommand(options) {
|
|
|
104216
104941
|
process.exit(1);
|
|
104217
104942
|
}
|
|
104218
104943
|
}
|
|
104219
|
-
const naxDir =
|
|
104220
|
-
const featureDir =
|
|
104221
|
-
const prdPath =
|
|
104944
|
+
const naxDir = join80(resolved.projectDir, ".nax");
|
|
104945
|
+
const featureDir = join80(naxDir, "features", featureName);
|
|
104946
|
+
const prdPath = join80(featureDir, "prd.json");
|
|
104222
104947
|
if (!existsSync31(featureDir)) {
|
|
104223
104948
|
console.error(source_default.red(`Feature not found: ${featureName}`));
|
|
104224
104949
|
process.exit(1);
|
|
@@ -104240,13 +104965,13 @@ async function precheckCommand(options) {
|
|
|
104240
104965
|
// src/commands/replay.ts
|
|
104241
104966
|
init_errors();
|
|
104242
104967
|
import { existsSync as existsSync32 } from "fs";
|
|
104243
|
-
import { dirname as
|
|
104968
|
+
import { dirname as dirname13 } from "path";
|
|
104244
104969
|
|
|
104245
104970
|
// src/replay/discovery.ts
|
|
104246
104971
|
init_errors();
|
|
104247
104972
|
init_paths3();
|
|
104248
104973
|
import { readdir as readdir4 } from "fs/promises";
|
|
104249
|
-
import { join as
|
|
104974
|
+
import { join as join81 } from "path";
|
|
104250
104975
|
var _discoveryDeps = {
|
|
104251
104976
|
getRunsDir
|
|
104252
104977
|
};
|
|
@@ -104260,7 +104985,7 @@ async function loadMetas(runsDir) {
|
|
|
104260
104985
|
const metas = [];
|
|
104261
104986
|
for (const entry of entries) {
|
|
104262
104987
|
try {
|
|
104263
|
-
const meta3 = await Bun.file(
|
|
104988
|
+
const meta3 = await Bun.file(join81(runsDir, entry, "meta.json")).json();
|
|
104264
104989
|
metas.push(meta3);
|
|
104265
104990
|
} catch {}
|
|
104266
104991
|
}
|
|
@@ -104277,7 +105002,7 @@ async function discoverRun(query, depsArg = _discoveryDeps) {
|
|
|
104277
105002
|
throw new NaxError("No runs registered", "RUN_NOT_FOUND", { runsDir });
|
|
104278
105003
|
}
|
|
104279
105004
|
const latest = metas.reduce((acc, m) => m.runId > acc.runId ? m : acc);
|
|
104280
|
-
return { meta: latest, jsonlPath:
|
|
105005
|
+
return { meta: latest, jsonlPath: join81(latest.eventsDir, `${latest.runId}.jsonl`) };
|
|
104281
105006
|
}
|
|
104282
105007
|
const matched = metas.filter((m) => matches(m, query));
|
|
104283
105008
|
if (matched.length === 0) {
|
|
@@ -104294,7 +105019,7 @@ async function discoverRun(query, depsArg = _discoveryDeps) {
|
|
|
104294
105019
|
});
|
|
104295
105020
|
}
|
|
104296
105021
|
const meta3 = matched[0];
|
|
104297
|
-
return { meta: meta3, jsonlPath:
|
|
105022
|
+
return { meta: meta3, jsonlPath: join81(meta3.eventsDir, `${meta3.runId}.jsonl`) };
|
|
104298
105023
|
}
|
|
104299
105024
|
|
|
104300
105025
|
// src/replay/json.ts
|
|
@@ -104525,10 +105250,10 @@ function renderReport(timeline, options = {}) {
|
|
|
104525
105250
|
}
|
|
104526
105251
|
|
|
104527
105252
|
// src/commands/replay.ts
|
|
104528
|
-
async function readJsonlLenient(
|
|
104529
|
-
if (!existsSync32(
|
|
105253
|
+
async function readJsonlLenient(path24) {
|
|
105254
|
+
if (!existsSync32(path24))
|
|
104530
105255
|
return [];
|
|
104531
|
-
const content = await Bun.file(
|
|
105256
|
+
const content = await Bun.file(path24).text();
|
|
104532
105257
|
const lines = content.split(`
|
|
104533
105258
|
`);
|
|
104534
105259
|
const entries = [];
|
|
@@ -104542,18 +105267,18 @@ async function readJsonlLenient(path23) {
|
|
|
104542
105267
|
}
|
|
104543
105268
|
return entries;
|
|
104544
105269
|
}
|
|
104545
|
-
async function readJsonOrUndefined(
|
|
104546
|
-
if (!existsSync32(
|
|
105270
|
+
async function readJsonOrUndefined(path24) {
|
|
105271
|
+
if (!existsSync32(path24))
|
|
104547
105272
|
return;
|
|
104548
105273
|
try {
|
|
104549
|
-
return await Bun.file(
|
|
105274
|
+
return await Bun.file(path24).json();
|
|
104550
105275
|
} catch {
|
|
104551
105276
|
return;
|
|
104552
105277
|
}
|
|
104553
105278
|
}
|
|
104554
105279
|
async function readMetricsFromProject(meta3) {
|
|
104555
105280
|
const { loadRunMetrics: loadRunMetrics2 } = await Promise.resolve().then(() => (init_tracker(), exports_tracker));
|
|
104556
|
-
const outputDir =
|
|
105281
|
+
const outputDir = dirname13(dirname13(dirname13(meta3.eventsDir)));
|
|
104557
105282
|
const all = await loadRunMetrics2(outputDir);
|
|
104558
105283
|
return all.find((m) => m.runId === meta3.runId);
|
|
104559
105284
|
}
|
|
@@ -104632,11 +105357,11 @@ init_errors();
|
|
|
104632
105357
|
init_checkpoint();
|
|
104633
105358
|
init_runtime();
|
|
104634
105359
|
import { existsSync as existsSync37 } from "fs";
|
|
104635
|
-
import { basename as basename17, join as
|
|
105360
|
+
import { basename as basename17, join as join95 } from "path";
|
|
104636
105361
|
async function defaultCheckpointExists(featureDir) {
|
|
104637
105362
|
if (!featureDir || !existsSync37(featureDir))
|
|
104638
105363
|
return false;
|
|
104639
|
-
return existsSync37(
|
|
105364
|
+
return existsSync37(join95(featureDir, "checkpoint.jsonl"));
|
|
104640
105365
|
}
|
|
104641
105366
|
async function defaultLoadCheckpoints(featureDir) {
|
|
104642
105367
|
return loadCheckpoints(featureDir);
|
|
@@ -104696,12 +105421,12 @@ function registerResumeCommand(program2) {
|
|
|
104696
105421
|
`);
|
|
104697
105422
|
process.exit(1);
|
|
104698
105423
|
}
|
|
104699
|
-
const featureDir =
|
|
105424
|
+
const featureDir = join95(naxDir, "features", cmdOpts.feature);
|
|
104700
105425
|
const deps = {
|
|
104701
105426
|
..._resumeCmdDeps,
|
|
104702
105427
|
runInvocation: async (feature, opts) => {
|
|
104703
105428
|
const config2 = await loadConfig2(naxDir ?? undefined);
|
|
104704
|
-
const prdPath =
|
|
105429
|
+
const prdPath = join95(opts.featureDir ?? "", "prd.json");
|
|
104705
105430
|
if (!existsSync38(prdPath)) {
|
|
104706
105431
|
process.stderr.write(`Feature "${feature}" not found or missing prd.json
|
|
104707
105432
|
`);
|
|
@@ -104713,7 +105438,7 @@ function registerResumeCommand(program2) {
|
|
|
104713
105438
|
applyResumeModeDeps2(opts.featureDir ?? "", "auto");
|
|
104714
105439
|
const projectKey = config2.name?.trim() || basename17(cmdOpts.dir);
|
|
104715
105440
|
const outputDir = projectOutputDir(projectKey, config2.outputDir);
|
|
104716
|
-
const statusFilePath =
|
|
105441
|
+
const statusFilePath = join95(outputDir, "status.json");
|
|
104717
105442
|
const result = await run2({
|
|
104718
105443
|
prdPath,
|
|
104719
105444
|
workdir: cmdOpts.dir,
|
|
@@ -104748,7 +105473,7 @@ function registerResumeCommand(program2) {
|
|
|
104748
105473
|
init_source();
|
|
104749
105474
|
init_paths3();
|
|
104750
105475
|
import { readdir as readdir6 } from "fs/promises";
|
|
104751
|
-
import { join as
|
|
105476
|
+
import { join as join96 } from "path";
|
|
104752
105477
|
var DEFAULT_LIMIT = 20;
|
|
104753
105478
|
var _runsCmdDeps = {
|
|
104754
105479
|
getRunsDir
|
|
@@ -104805,7 +105530,7 @@ async function runsCommand(options = {}) {
|
|
|
104805
105530
|
}
|
|
104806
105531
|
const rows = [];
|
|
104807
105532
|
for (const entry of entries) {
|
|
104808
|
-
const metaPath =
|
|
105533
|
+
const metaPath = join96(runsDir, entry, "meta.json");
|
|
104809
105534
|
let meta3;
|
|
104810
105535
|
try {
|
|
104811
105536
|
meta3 = await Bun.file(metaPath).json();
|
|
@@ -104882,7 +105607,7 @@ async function runsCommand(options = {}) {
|
|
|
104882
105607
|
|
|
104883
105608
|
// src/commands/unlock.ts
|
|
104884
105609
|
init_source();
|
|
104885
|
-
import { join as
|
|
105610
|
+
import { join as join97 } from "path";
|
|
104886
105611
|
function isProcessAlive2(pid) {
|
|
104887
105612
|
try {
|
|
104888
105613
|
process.kill(pid, 0);
|
|
@@ -104897,7 +105622,7 @@ function formatLockAge(ageMs) {
|
|
|
104897
105622
|
}
|
|
104898
105623
|
async function unlockCommand(options) {
|
|
104899
105624
|
const workdir = options.dir ?? process.cwd();
|
|
104900
|
-
const lockPath =
|
|
105625
|
+
const lockPath = join97(workdir, "nax.lock");
|
|
104901
105626
|
const lockFile = Bun.file(lockPath);
|
|
104902
105627
|
const exists = await lockFile.exists();
|
|
104903
105628
|
if (!exists) {
|
|
@@ -109842,8 +110567,8 @@ function Text({ color, backgroundColor, dimColor = false, bold = false, italic =
|
|
|
109842
110567
|
}
|
|
109843
110568
|
|
|
109844
110569
|
// node_modules/ink/build/components/ErrorOverview.js
|
|
109845
|
-
var cleanupPath = (
|
|
109846
|
-
return
|
|
110570
|
+
var cleanupPath = (path32) => {
|
|
110571
|
+
return path32?.replace(`file://${cwd()}/`, "");
|
|
109847
110572
|
};
|
|
109848
110573
|
var stackUtils = new import_stack_utils.default({
|
|
109849
110574
|
cwd: cwd(),
|
|
@@ -110547,8 +111272,8 @@ class Ink {
|
|
|
110547
111272
|
}
|
|
110548
111273
|
}
|
|
110549
111274
|
async waitUntilExit() {
|
|
110550
|
-
this.exitPromise ||= new Promise((
|
|
110551
|
-
this.resolveExitPromise =
|
|
111275
|
+
this.exitPromise ||= new Promise((resolve19, reject2) => {
|
|
111276
|
+
this.resolveExitPromise = resolve19;
|
|
110552
111277
|
this.rejectExitPromise = reject2;
|
|
110553
111278
|
});
|
|
110554
111279
|
if (!this.beforeExitHandler) {
|
|
@@ -112802,7 +113527,7 @@ async function promptForConfirmation(question) {
|
|
|
112802
113527
|
if (!process.stdin.isTTY) {
|
|
112803
113528
|
return true;
|
|
112804
113529
|
}
|
|
112805
|
-
return new Promise((
|
|
113530
|
+
return new Promise((resolve19) => {
|
|
112806
113531
|
process.stdout.write(source_default.bold(`${question} [Y/n] `));
|
|
112807
113532
|
process.stdin.setRawMode(true);
|
|
112808
113533
|
process.stdin.resume();
|
|
@@ -112815,9 +113540,9 @@ async function promptForConfirmation(question) {
|
|
|
112815
113540
|
process.stdout.write(`
|
|
112816
113541
|
`);
|
|
112817
113542
|
if (answer === "n") {
|
|
112818
|
-
|
|
113543
|
+
resolve19(false);
|
|
112819
113544
|
} else {
|
|
112820
|
-
|
|
113545
|
+
resolve19(true);
|
|
112821
113546
|
}
|
|
112822
113547
|
};
|
|
112823
113548
|
process.stdin.on("data", handler);
|
|
@@ -112846,7 +113571,7 @@ Next: nax generate --package ${options.package}`));
|
|
|
112846
113571
|
}
|
|
112847
113572
|
return;
|
|
112848
113573
|
}
|
|
112849
|
-
const naxDir =
|
|
113574
|
+
const naxDir = join101(workdir, ".nax");
|
|
112850
113575
|
if (existsSync39(naxDir) && !options.force) {
|
|
112851
113576
|
console.log(source_default.yellow("nax already initialized. Use --force to overwrite."));
|
|
112852
113577
|
return;
|
|
@@ -112875,11 +113600,11 @@ Next: nax generate --package ${options.package}`));
|
|
|
112875
113600
|
}
|
|
112876
113601
|
}
|
|
112877
113602
|
}
|
|
112878
|
-
mkdirSync8(
|
|
112879
|
-
mkdirSync8(
|
|
113603
|
+
mkdirSync8(join101(naxDir, "features"), { recursive: true });
|
|
113604
|
+
mkdirSync8(join101(naxDir, "hooks"), { recursive: true });
|
|
112880
113605
|
const initConfig = options.name ? { ...DEFAULT_CONFIG, name: options.name } : DEFAULT_CONFIG;
|
|
112881
|
-
await Bun.write(
|
|
112882
|
-
await Bun.write(
|
|
113606
|
+
await Bun.write(join101(naxDir, "config.json"), JSON.stringify(initConfig, null, 2));
|
|
113607
|
+
await Bun.write(join101(naxDir, "hooks.json"), JSON.stringify({
|
|
112883
113608
|
hooks: {
|
|
112884
113609
|
"on-start": { command: 'echo "nax started: $NAX_FEATURE"', enabled: false },
|
|
112885
113610
|
"on-complete": { command: 'echo "nax complete: $NAX_FEATURE"', enabled: false },
|
|
@@ -112887,12 +113612,12 @@ Next: nax generate --package ${options.package}`));
|
|
|
112887
113612
|
"on-error": { command: 'echo "nax error: $NAX_REASON"', enabled: false }
|
|
112888
113613
|
}
|
|
112889
113614
|
}, null, 2));
|
|
112890
|
-
await Bun.write(
|
|
113615
|
+
await Bun.write(join101(naxDir, ".gitignore"), `# nax temp files
|
|
112891
113616
|
*.tmp
|
|
112892
113617
|
.paused.json
|
|
112893
113618
|
.nax-verifier-verdict.json
|
|
112894
113619
|
`);
|
|
112895
|
-
await Bun.write(
|
|
113620
|
+
await Bun.write(join101(naxDir, "context.md"), `# Project Context
|
|
112896
113621
|
|
|
112897
113622
|
This document defines coding standards, architectural decisions, and forbidden patterns for this project.
|
|
112898
113623
|
Run \`nax generate\` to regenerate agent config files (CLAUDE.md, AGENTS.md, .cursorrules, etc.) from this file.
|
|
@@ -113076,7 +113801,7 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113076
113801
|
const cliOverrides = {};
|
|
113077
113802
|
const cliProfiles = options.profile ?? [];
|
|
113078
113803
|
const profileOverride = naxDir ? await resolveRunProfileOverride({
|
|
113079
|
-
prdPath:
|
|
113804
|
+
prdPath: join101(naxDir, "features", options.feature, "prd.json"),
|
|
113080
113805
|
projectRoot: workdir,
|
|
113081
113806
|
cliProfile: cliProfiles,
|
|
113082
113807
|
envProfile: process.env.NAX_PROFILE
|
|
@@ -113089,8 +113814,8 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113089
113814
|
console.error(source_default.red("nax not initialized. Run: nax init"));
|
|
113090
113815
|
process.exit(1);
|
|
113091
113816
|
}
|
|
113092
|
-
const featureDir =
|
|
113093
|
-
const prdPath =
|
|
113817
|
+
const featureDir = join101(naxDir, "features", options.feature);
|
|
113818
|
+
const prdPath = join101(featureDir, "prd.json");
|
|
113094
113819
|
if (options.plan && options.from) {
|
|
113095
113820
|
if (existsSync39(prdPath) && !options.force) {
|
|
113096
113821
|
console.error(source_default.red(`Error: prd.json already exists for feature "${options.feature}".`));
|
|
@@ -113112,10 +113837,10 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113112
113837
|
}
|
|
113113
113838
|
}
|
|
113114
113839
|
try {
|
|
113115
|
-
const planLogDir =
|
|
113840
|
+
const planLogDir = join101(featureDir, "plan");
|
|
113116
113841
|
mkdirSync8(planLogDir, { recursive: true });
|
|
113117
113842
|
const planLogId = new Date().toISOString().replace(/:/g, "-").replace(/\..+/, "");
|
|
113118
|
-
const planLogPath =
|
|
113843
|
+
const planLogPath = join101(planLogDir, `${planLogId}.jsonl`);
|
|
113119
113844
|
initLogger({ level: "info", filePath: planLogPath, useChalk: false, headless: true });
|
|
113120
113845
|
console.log(source_default.dim(` [Plan log: ${planLogPath}]`));
|
|
113121
113846
|
console.log(source_default.dim(" [Planning phase: generating PRD from spec]"));
|
|
@@ -113161,10 +113886,10 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113161
113886
|
resetLogger();
|
|
113162
113887
|
const projectKey = config2.name?.trim() || basename19(workdir);
|
|
113163
113888
|
const outputDir = projectOutputDir(projectKey, config2.outputDir);
|
|
113164
|
-
const runsDir =
|
|
113889
|
+
const runsDir = join101(outputDir, "features", options.feature, "runs");
|
|
113165
113890
|
mkdirSync8(runsDir, { recursive: true });
|
|
113166
113891
|
const runId = new Date().toISOString().replace(/:/g, "-").replace(/\..+/, "");
|
|
113167
|
-
const logFilePath =
|
|
113892
|
+
const logFilePath = join101(runsDir, `${runId}.jsonl`);
|
|
113168
113893
|
const isTTY = process.stdout.isTTY ?? false;
|
|
113169
113894
|
const headlessFlag = options.headless ?? false;
|
|
113170
113895
|
const headlessEnv = process.env.NAX_HEADLESS === "1";
|
|
@@ -113190,7 +113915,7 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113190
113915
|
}
|
|
113191
113916
|
config2.execution.costLimit = maxCost;
|
|
113192
113917
|
}
|
|
113193
|
-
const globalNaxDir =
|
|
113918
|
+
const globalNaxDir = join101(homedir3(), ".nax");
|
|
113194
113919
|
const hooks = await loadHooksConfig(naxDir, globalNaxDir);
|
|
113195
113920
|
const eventEmitter = new PipelineEventEmitter;
|
|
113196
113921
|
const agentStreamEvents = useHeadless ? undefined : new AgentStreamEventBus;
|
|
@@ -113209,12 +113934,12 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113209
113934
|
stories: initialStories,
|
|
113210
113935
|
events: eventEmitter,
|
|
113211
113936
|
agentStreamEvents,
|
|
113212
|
-
queueFilePath:
|
|
113937
|
+
queueFilePath: join101(workdir, ".queue.txt")
|
|
113213
113938
|
});
|
|
113214
113939
|
} else {
|
|
113215
113940
|
console.log(source_default.dim(" [Headless mode \u2014 pipe output]"));
|
|
113216
113941
|
}
|
|
113217
|
-
const statusFilePath =
|
|
113942
|
+
const statusFilePath = join101(outputDir, "status.json");
|
|
113218
113943
|
let parallel;
|
|
113219
113944
|
if (options.parallel !== undefined) {
|
|
113220
113945
|
parallel = Number.parseInt(options.parallel, 10);
|
|
@@ -113277,7 +114002,7 @@ Scheduled run cancelled.`));
|
|
|
113277
114002
|
agentStreamEvents,
|
|
113278
114003
|
resumeMode: options.fresh === true || options.resume === false ? "fresh" : "auto"
|
|
113279
114004
|
});
|
|
113280
|
-
const latestSymlink =
|
|
114005
|
+
const latestSymlink = join101(runsDir, "latest.jsonl");
|
|
113281
114006
|
try {
|
|
113282
114007
|
if (existsSync39(latestSymlink)) {
|
|
113283
114008
|
Bun.spawnSync(["rm", latestSymlink]);
|
|
@@ -113374,9 +114099,9 @@ features.command("create <name>").description("Create a new feature").option("-d
|
|
|
113374
114099
|
console.error(source_default.red("nax not initialized. Run: nax init"));
|
|
113375
114100
|
process.exit(1);
|
|
113376
114101
|
}
|
|
113377
|
-
const featureDir =
|
|
114102
|
+
const featureDir = join101(naxDir, "features", name);
|
|
113378
114103
|
mkdirSync8(featureDir, { recursive: true });
|
|
113379
|
-
await Bun.write(
|
|
114104
|
+
await Bun.write(join101(featureDir, "spec.md"), `# Feature: ${name}
|
|
113380
114105
|
|
|
113381
114106
|
## Overview
|
|
113382
114107
|
|
|
@@ -113409,7 +114134,7 @@ features.command("create <name>").description("Create a new feature").option("-d
|
|
|
113409
114134
|
|
|
113410
114135
|
<!-- What this feature explicitly does NOT cover. -->
|
|
113411
114136
|
`);
|
|
113412
|
-
await Bun.write(
|
|
114137
|
+
await Bun.write(join101(featureDir, "progress.txt"), `# Progress: ${name}
|
|
113413
114138
|
|
|
113414
114139
|
Created: ${new Date().toISOString()}
|
|
113415
114140
|
|
|
@@ -113435,7 +114160,7 @@ features.command("list").description("List all features").option("-d, --dir <pat
|
|
|
113435
114160
|
console.error(source_default.red("nax not initialized."));
|
|
113436
114161
|
process.exit(1);
|
|
113437
114162
|
}
|
|
113438
|
-
const featuresDir =
|
|
114163
|
+
const featuresDir = join101(naxDir, "features");
|
|
113439
114164
|
if (!existsSync39(featuresDir)) {
|
|
113440
114165
|
console.log(source_default.dim("No features yet."));
|
|
113441
114166
|
return;
|
|
@@ -113450,7 +114175,7 @@ features.command("list").description("List all features").option("-d, --dir <pat
|
|
|
113450
114175
|
Features:
|
|
113451
114176
|
`));
|
|
113452
114177
|
for (const name of entries) {
|
|
113453
|
-
const prdPath =
|
|
114178
|
+
const prdPath = join101(featuresDir, name, "prd.json");
|
|
113454
114179
|
if (existsSync39(prdPath)) {
|
|
113455
114180
|
const prd = await loadPRD(prdPath);
|
|
113456
114181
|
const c = countStories(prd);
|
|
@@ -113523,10 +114248,10 @@ Use: nax plan -f <feature> --from <spec>`));
|
|
|
113523
114248
|
cliOverrides.profile = cliProfiles;
|
|
113524
114249
|
}
|
|
113525
114250
|
const config2 = await loadConfig(workdir, cliOverrides);
|
|
113526
|
-
const featureLogDir =
|
|
114251
|
+
const featureLogDir = join101(naxDir, "features", options.feature, "plan");
|
|
113527
114252
|
mkdirSync8(featureLogDir, { recursive: true });
|
|
113528
114253
|
const planLogId = new Date().toISOString().replace(/:/g, "-").replace(/\..+/, "");
|
|
113529
|
-
const planLogPath =
|
|
114254
|
+
const planLogPath = join101(featureLogDir, `${planLogId}.jsonl`);
|
|
113530
114255
|
initLogger({ level: "info", filePath: planLogPath, useChalk: false, headless: true });
|
|
113531
114256
|
console.log(source_default.dim(` [Plan log: ${planLogPath}]`));
|
|
113532
114257
|
try {
|
|
@@ -113633,8 +114358,8 @@ configProfileCmd.command("current").description("Show the currently active profi
|
|
|
113633
114358
|
});
|
|
113634
114359
|
configProfileCmd.command("create <name>").description("Create a new empty profile").option("-d, --dir <path>", "Project directory", process.cwd()).action(async (name, options) => {
|
|
113635
114360
|
try {
|
|
113636
|
-
const
|
|
113637
|
-
console.log(`Created profile at: ${
|
|
114361
|
+
const path32 = await profileCreateCommand(name, options.dir);
|
|
114362
|
+
console.log(`Created profile at: ${path32}`);
|
|
113638
114363
|
} catch (err) {
|
|
113639
114364
|
console.error(source_default.red(`Error: ${err.message}`));
|
|
113640
114365
|
process.exit(1);
|