@nathapp/nax 0.73.5 → 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 +1240 -526
- 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();
|
|
@@ -63484,6 +63972,218 @@ var init_curator = __esm(() => {
|
|
|
63484
63972
|
};
|
|
63485
63973
|
});
|
|
63486
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
|
+
|
|
63487
64187
|
// src/plugins/builtin/reporter-shared/interpolate.ts
|
|
63488
64188
|
function interpolateHeaders(headers, env2 = process.env) {
|
|
63489
64189
|
const resolved = {};
|
|
@@ -64086,14 +64786,14 @@ var init_validator = __esm(() => {
|
|
|
64086
64786
|
|
|
64087
64787
|
// src/plugins/loader.ts
|
|
64088
64788
|
import * as fs from "fs/promises";
|
|
64089
|
-
import * as
|
|
64789
|
+
import * as path22 from "path";
|
|
64090
64790
|
function getSafeLogger6() {
|
|
64091
64791
|
return getSafeLogger();
|
|
64092
64792
|
}
|
|
64093
64793
|
function extractPluginName(pluginPath) {
|
|
64094
|
-
const basename12 =
|
|
64794
|
+
const basename12 = path22.basename(pluginPath);
|
|
64095
64795
|
if (basename12 === "index.ts" || basename12 === "index.js" || basename12 === "index.mjs") {
|
|
64096
|
-
return
|
|
64796
|
+
return path22.basename(path22.dirname(pluginPath));
|
|
64097
64797
|
}
|
|
64098
64798
|
return basename12.replace(/\.(ts|js|mjs)$/, "");
|
|
64099
64799
|
}
|
|
@@ -64129,6 +64829,17 @@ async function loadPlugins(globalDir, projectDir, configPlugins, projectRoot, di
|
|
|
64129
64829
|
} else {
|
|
64130
64830
|
logger?.info("plugins", `Skipping disabled plugin: '${autoPrPlugin.name}' (built-in)`);
|
|
64131
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
|
+
}
|
|
64132
64843
|
if (!disabledSet.has(autoRoutePlugin.name)) {
|
|
64133
64844
|
if (autoRoutePlugin.setup) {
|
|
64134
64845
|
const pluginLogger = createPluginLogger(autoRoutePlugin.name);
|
|
@@ -64230,7 +64941,7 @@ async function discoverPlugins(dir, isTestFileFn) {
|
|
|
64230
64941
|
try {
|
|
64231
64942
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
64232
64943
|
for (const entry of entries) {
|
|
64233
|
-
const fullPath =
|
|
64944
|
+
const fullPath = path22.join(dir, entry.name);
|
|
64234
64945
|
if (entry.isFile()) {
|
|
64235
64946
|
if (isPluginFile(entry.name, isTestFileFn)) {
|
|
64236
64947
|
discovered.push({ path: fullPath });
|
|
@@ -64238,7 +64949,7 @@ async function discoverPlugins(dir, isTestFileFn) {
|
|
|
64238
64949
|
} else if (entry.isDirectory()) {
|
|
64239
64950
|
const indexPaths = ["index.ts", "index.js", "index.mjs"];
|
|
64240
64951
|
for (const indexFile of indexPaths) {
|
|
64241
|
-
const indexPath =
|
|
64952
|
+
const indexPath = path22.join(fullPath, indexFile);
|
|
64242
64953
|
try {
|
|
64243
64954
|
await fs.access(indexPath);
|
|
64244
64955
|
discovered.push({ path: indexPath });
|
|
@@ -64263,13 +64974,13 @@ function isPluginFile(filename, isTestFileFn) {
|
|
|
64263
64974
|
return !FALLBACK_TEST_FILE_RE.test(filename);
|
|
64264
64975
|
}
|
|
64265
64976
|
function resolveModulePath(modulePath, projectRoot) {
|
|
64266
|
-
if (
|
|
64977
|
+
if (path22.isAbsolute(modulePath) || !modulePath.startsWith("./") && !modulePath.startsWith("../")) {
|
|
64267
64978
|
return modulePath;
|
|
64268
64979
|
}
|
|
64269
64980
|
if (projectRoot) {
|
|
64270
|
-
return
|
|
64981
|
+
return path22.resolve(projectRoot, modulePath);
|
|
64271
64982
|
}
|
|
64272
|
-
return
|
|
64983
|
+
return path22.resolve(modulePath);
|
|
64273
64984
|
}
|
|
64274
64985
|
async function loadAndValidatePlugin(initialModulePath, config2, allowedRoots = [], originalPath) {
|
|
64275
64986
|
let attemptedPath = initialModulePath;
|
|
@@ -64331,6 +65042,7 @@ var init_loader4 = __esm(() => {
|
|
|
64331
65042
|
init_auto_pr();
|
|
64332
65043
|
init_auto_route();
|
|
64333
65044
|
init_curator();
|
|
65045
|
+
init_nax_finish();
|
|
64334
65046
|
init_otel_reporter();
|
|
64335
65047
|
init_webhook_reporter();
|
|
64336
65048
|
init_plugin_logger();
|
|
@@ -64387,7 +65099,7 @@ var init_writer = __esm(() => {
|
|
|
64387
65099
|
});
|
|
64388
65100
|
|
|
64389
65101
|
// src/execution/checkpoint/reader.ts
|
|
64390
|
-
import { join as
|
|
65102
|
+
import { join as join82 } from "path";
|
|
64391
65103
|
function isValidRecord(value) {
|
|
64392
65104
|
if (!value || typeof value !== "object")
|
|
64393
65105
|
return false;
|
|
@@ -64420,7 +65132,7 @@ async function defaultRead(filePath) {
|
|
|
64420
65132
|
return file3.text();
|
|
64421
65133
|
}
|
|
64422
65134
|
async function loadCheckpoints(featureDir, options = { _deps: { read: defaultRead } }) {
|
|
64423
|
-
const filePath =
|
|
65135
|
+
const filePath = join82(featureDir, "checkpoint.jsonl");
|
|
64424
65136
|
const deps = options._deps ?? { read: defaultRead };
|
|
64425
65137
|
let content;
|
|
64426
65138
|
try {
|
|
@@ -64490,7 +65202,7 @@ var init_reader = __esm(() => {
|
|
|
64490
65202
|
});
|
|
64491
65203
|
|
|
64492
65204
|
// src/execution/checkpoint/resume-cli.ts
|
|
64493
|
-
import { join as
|
|
65205
|
+
import { join as join83 } from "path";
|
|
64494
65206
|
function applyResumeModeDeps(featureDir, mode = "auto") {
|
|
64495
65207
|
if (mode === "fresh" || mode === "no-resume") {
|
|
64496
65208
|
_storyOrchestratorDeps.loadCheckpoints = async (_fd) => new Map;
|
|
@@ -64500,7 +65212,7 @@ function applyResumeModeDeps(featureDir, mode = "auto") {
|
|
|
64500
65212
|
_storyOrchestratorDeps.loadCheckpoints = async (_fd) => loadCheckpoints(target);
|
|
64501
65213
|
}
|
|
64502
65214
|
function applyRecordGreenDeps(featureDir, runId) {
|
|
64503
|
-
const writer = createCheckpointWriter(
|
|
65215
|
+
const writer = createCheckpointWriter(join83(featureDir, "checkpoint.jsonl"), runId);
|
|
64504
65216
|
_storyOrchestratorDeps.recordGreen = (storyId, phase, tree) => writer.recordGreen(storyId, phase, tree);
|
|
64505
65217
|
}
|
|
64506
65218
|
var init_resume_cli = __esm(() => {
|
|
@@ -64530,11 +65242,11 @@ var init_checkpoint = __esm(() => {
|
|
|
64530
65242
|
});
|
|
64531
65243
|
|
|
64532
65244
|
// src/hooks/runner.ts
|
|
64533
|
-
import { join as
|
|
65245
|
+
import { join as join84 } from "path";
|
|
64534
65246
|
function createDrainDeadline2(deadlineMs) {
|
|
64535
65247
|
let timeoutId;
|
|
64536
|
-
const promise2 = new Promise((
|
|
64537
|
-
timeoutId = setTimeout(() =>
|
|
65248
|
+
const promise2 = new Promise((resolve17) => {
|
|
65249
|
+
timeoutId = setTimeout(() => resolve17(""), deadlineMs);
|
|
64538
65250
|
});
|
|
64539
65251
|
return {
|
|
64540
65252
|
promise: promise2,
|
|
@@ -64549,14 +65261,14 @@ async function loadHooksConfig(projectDir, globalDir) {
|
|
|
64549
65261
|
let globalHooks = { hooks: {} };
|
|
64550
65262
|
let projectHooks = { hooks: {} };
|
|
64551
65263
|
let skipGlobal = false;
|
|
64552
|
-
const projectPath =
|
|
65264
|
+
const projectPath = join84(projectDir, "hooks.json");
|
|
64553
65265
|
const projectData = await loadJsonFile(projectPath, "hooks");
|
|
64554
65266
|
if (projectData) {
|
|
64555
65267
|
projectHooks = projectData;
|
|
64556
65268
|
skipGlobal = projectData.skipGlobal ?? false;
|
|
64557
65269
|
}
|
|
64558
65270
|
if (!skipGlobal && globalDir) {
|
|
64559
|
-
const globalPath =
|
|
65271
|
+
const globalPath = join84(globalDir, "hooks.json");
|
|
64560
65272
|
const globalData = await loadJsonFile(globalPath, "hooks");
|
|
64561
65273
|
if (globalData) {
|
|
64562
65274
|
globalHooks = globalData;
|
|
@@ -65064,7 +65776,7 @@ var init_crash_recovery = __esm(() => {
|
|
|
65064
65776
|
});
|
|
65065
65777
|
|
|
65066
65778
|
// src/acceptance/import-resolution.ts
|
|
65067
|
-
import { resolve as
|
|
65779
|
+
import { resolve as resolve17, sep as sep5 } from "path";
|
|
65068
65780
|
function languageFromExtension(testFilePath) {
|
|
65069
65781
|
if (!testFilePath)
|
|
65070
65782
|
return;
|
|
@@ -65086,8 +65798,8 @@ async function resolveLanguage(opts) {
|
|
|
65086
65798
|
return "typescript";
|
|
65087
65799
|
}
|
|
65088
65800
|
async function readCapped(relPath, packageDir) {
|
|
65089
|
-
const resolvedPackageDir =
|
|
65090
|
-
const fullPath =
|
|
65801
|
+
const resolvedPackageDir = resolve17(packageDir);
|
|
65802
|
+
const fullPath = resolve17(resolvedPackageDir, relPath);
|
|
65091
65803
|
if (fullPath !== resolvedPackageDir && !fullPath.startsWith(resolvedPackageDir + sep5)) {
|
|
65092
65804
|
return null;
|
|
65093
65805
|
}
|
|
@@ -65269,7 +65981,7 @@ var init_fix_diagnosis = __esm(() => {
|
|
|
65269
65981
|
});
|
|
65270
65982
|
|
|
65271
65983
|
// src/execution/lifecycle/acceptance-helpers.ts
|
|
65272
|
-
import
|
|
65984
|
+
import path24 from "path";
|
|
65273
65985
|
function isStubTestFile(content) {
|
|
65274
65986
|
return isStubTestContent(content);
|
|
65275
65987
|
}
|
|
@@ -65288,7 +66000,7 @@ function isTestLevelFailure(failedACs, totalACs, semanticVerdicts) {
|
|
|
65288
66000
|
async function loadSpecContent(featureDir) {
|
|
65289
66001
|
if (!featureDir)
|
|
65290
66002
|
return "";
|
|
65291
|
-
const specPath =
|
|
66003
|
+
const specPath = path24.join(featureDir, "spec.md");
|
|
65292
66004
|
const specFile = Bun.file(specPath);
|
|
65293
66005
|
return await specFile.exists() ? await specFile.text() : "";
|
|
65294
66006
|
}
|
|
@@ -65308,7 +66020,7 @@ async function loadAcceptanceTestContent2(featureDir, testPaths, configuredTestP
|
|
|
65308
66020
|
}
|
|
65309
66021
|
if (!configuredTestPath)
|
|
65310
66022
|
return [];
|
|
65311
|
-
const resolvedPath =
|
|
66023
|
+
const resolvedPath = path24.join(featureDir, configuredTestPath);
|
|
65312
66024
|
const testFile = Bun.file(resolvedPath);
|
|
65313
66025
|
const content = await testFile.exists() ? await testFile.text() : "";
|
|
65314
66026
|
return [{ content, path: resolvedPath }];
|
|
@@ -65325,7 +66037,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
|
|
|
65325
66037
|
const { unlink: unlink3 } = await import("fs/promises");
|
|
65326
66038
|
await unlink3(testPath);
|
|
65327
66039
|
if (acceptanceContext.featureDir) {
|
|
65328
|
-
const metaPath =
|
|
66040
|
+
const metaPath = path24.join(acceptanceContext.featureDir, "acceptance-meta.json");
|
|
65329
66041
|
try {
|
|
65330
66042
|
await unlink3(metaPath);
|
|
65331
66043
|
} catch {}
|
|
@@ -65339,7 +66051,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
|
|
|
65339
66051
|
const changedFilesRaw = diffOutput.split(`
|
|
65340
66052
|
`).map((f) => f.trim()).filter((f) => f.length > 0);
|
|
65341
66053
|
const repoRoot = acceptanceContext.projectDir ?? workdir;
|
|
65342
|
-
const packageDir = acceptanceContext.story.workdir && acceptanceContext.projectDir ?
|
|
66054
|
+
const packageDir = acceptanceContext.story.workdir && acceptanceContext.projectDir ? path24.join(acceptanceContext.projectDir, acceptanceContext.story.workdir) : undefined;
|
|
65343
66055
|
const ignoreMatchers = acceptanceContext.naxIgnoreIndex?.getMatchers(packageDir) ?? await resolveNaxIgnorePatterns(repoRoot, packageDir);
|
|
65344
66056
|
const changedFiles = filterNaxInternalPaths(changedFilesRaw, ignoreMatchers);
|
|
65345
66057
|
const MAX_BYTES = 51200;
|
|
@@ -65348,7 +66060,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
|
|
|
65348
66060
|
for (const file3 of changedFiles) {
|
|
65349
66061
|
if (totalBytes >= MAX_BYTES)
|
|
65350
66062
|
break;
|
|
65351
|
-
const filePath =
|
|
66063
|
+
const filePath = path24.join(workdir, file3);
|
|
65352
66064
|
try {
|
|
65353
66065
|
const fileContent = await _regenerateDeps.readFile(filePath);
|
|
65354
66066
|
const remaining = MAX_BYTES - totalBytes;
|
|
@@ -65786,15 +66498,15 @@ var init_acceptance_loop = __esm(() => {
|
|
|
65786
66498
|
|
|
65787
66499
|
// src/session/scratch-purge.ts
|
|
65788
66500
|
import { mkdir as mkdir12, rename, rm } from "fs/promises";
|
|
65789
|
-
import { dirname as
|
|
66501
|
+
import { dirname as dirname14, join as join85 } from "path";
|
|
65790
66502
|
async function purgeStaleScratch(projectDir, featureName, retentionDays, archiveInsteadOfDelete = false) {
|
|
65791
|
-
const sessionsDir =
|
|
66503
|
+
const sessionsDir = join85(projectDir, ".nax", "features", featureName, "sessions");
|
|
65792
66504
|
const sessionIds = await _scratchPurgeDeps.listSessionDirs(sessionsDir);
|
|
65793
66505
|
const cutoffMs = _scratchPurgeDeps.now() - retentionDays * 86400000;
|
|
65794
66506
|
let purged = 0;
|
|
65795
66507
|
for (const sessionId of sessionIds) {
|
|
65796
|
-
const sessionDir =
|
|
65797
|
-
const descriptorPath =
|
|
66508
|
+
const sessionDir = join85(sessionsDir, sessionId);
|
|
66509
|
+
const descriptorPath = join85(sessionDir, "descriptor.json");
|
|
65798
66510
|
if (!await _scratchPurgeDeps.fileExists(descriptorPath))
|
|
65799
66511
|
continue;
|
|
65800
66512
|
let lastActivityAt;
|
|
@@ -65810,7 +66522,7 @@ async function purgeStaleScratch(projectDir, featureName, retentionDays, archive
|
|
|
65810
66522
|
if (new Date(lastActivityAt).getTime() >= cutoffMs)
|
|
65811
66523
|
continue;
|
|
65812
66524
|
if (archiveInsteadOfDelete) {
|
|
65813
|
-
const archiveDest =
|
|
66525
|
+
const archiveDest = join85(projectDir, ".nax", "features", featureName, "_archive", "sessions", sessionId);
|
|
65814
66526
|
await _scratchPurgeDeps.move(sessionDir, archiveDest);
|
|
65815
66527
|
} else {
|
|
65816
66528
|
await _scratchPurgeDeps.remove(sessionDir);
|
|
@@ -65833,11 +66545,11 @@ var init_scratch_purge = __esm(() => {
|
|
|
65833
66545
|
return [];
|
|
65834
66546
|
}
|
|
65835
66547
|
},
|
|
65836
|
-
fileExists: (
|
|
65837
|
-
readFile: (
|
|
65838
|
-
remove: (
|
|
66548
|
+
fileExists: (path25) => Bun.file(path25).exists(),
|
|
66549
|
+
readFile: (path25) => Bun.file(path25).text(),
|
|
66550
|
+
remove: (path25) => rm(path25, { recursive: true, force: true }),
|
|
65839
66551
|
move: async (src, dest) => {
|
|
65840
|
-
await mkdir12(
|
|
66552
|
+
await mkdir12(dirname14(dest), { recursive: true });
|
|
65841
66553
|
await rename(src, dest);
|
|
65842
66554
|
},
|
|
65843
66555
|
now: () => Date.now()
|
|
@@ -66681,7 +67393,7 @@ var init_headless_formatter = __esm(() => {
|
|
|
66681
67393
|
});
|
|
66682
67394
|
|
|
66683
67395
|
// src/execution/runner-completion.ts
|
|
66684
|
-
import
|
|
67396
|
+
import path25 from "path";
|
|
66685
67397
|
async function runCompletionPhase(options) {
|
|
66686
67398
|
const logger = getSafeLogger();
|
|
66687
67399
|
logger?.debug("execution", "Completion phase started", {
|
|
@@ -66701,11 +67413,11 @@ async function runCompletionPhase(options) {
|
|
|
66701
67413
|
options.statusWriter.setPostRunPhase("acceptance", { status: "running" });
|
|
66702
67414
|
pipelineEventBus.emit({ type: "postrun:phase:started", phase: "acceptance" });
|
|
66703
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) => {
|
|
66704
|
-
const relativeWorkdir =
|
|
67416
|
+
const relativeWorkdir = path25.relative(options.workdir, g.packageDir);
|
|
66705
67417
|
let groupConfig = options.config;
|
|
66706
67418
|
if (relativeWorkdir && relativeWorkdir !== ".") {
|
|
66707
67419
|
try {
|
|
66708
|
-
groupConfig = await _runnerCompletionDeps.loadConfigForWorkdir(
|
|
67420
|
+
groupConfig = await _runnerCompletionDeps.loadConfigForWorkdir(path25.join(options.workdir, ".nax", "config.json"), relativeWorkdir);
|
|
66709
67421
|
} catch (error48) {
|
|
66710
67422
|
logger?.warn("execution", "Falling back to root config for package acceptance settings", {
|
|
66711
67423
|
packageDir: g.packageDir,
|
|
@@ -66935,7 +67647,7 @@ function precomputeBatchPlan(stories, maxBatchSize = DEFAULT_MAX_BATCH_SIZE) {
|
|
|
66935
67647
|
var DEFAULT_MAX_BATCH_SIZE = 4;
|
|
66936
67648
|
|
|
66937
67649
|
// src/execution/ensure-package-dirs.ts
|
|
66938
|
-
import
|
|
67650
|
+
import path26 from "path";
|
|
66939
67651
|
async function ensureStoryPackageDirs(prd, workdir, deps = _ensurePackageDirsDeps) {
|
|
66940
67652
|
const logger = getSafeLogger();
|
|
66941
67653
|
const relToStoryId = new Map;
|
|
@@ -66948,8 +67660,8 @@ async function ensureStoryPackageDirs(prd, workdir, deps = _ensurePackageDirsDep
|
|
|
66948
67660
|
}
|
|
66949
67661
|
const created = [];
|
|
66950
67662
|
for (const [rel, storyId] of relToStoryId) {
|
|
66951
|
-
const abs =
|
|
66952
|
-
const rootWithSep = workdir.endsWith(
|
|
67663
|
+
const abs = path26.resolve(workdir, rel);
|
|
67664
|
+
const rootWithSep = workdir.endsWith(path26.sep) ? workdir : workdir + path26.sep;
|
|
66953
67665
|
if (abs !== workdir && !abs.startsWith(rootWithSep)) {
|
|
66954
67666
|
logger?.warn("execution", "Skipping story workdir outside repo root", {
|
|
66955
67667
|
storyId,
|
|
@@ -66991,12 +67703,12 @@ var init_ensure_package_dirs = __esm(() => {
|
|
|
66991
67703
|
|
|
66992
67704
|
// src/pipeline/subscribers/events-writer.ts
|
|
66993
67705
|
import { appendFile as appendFile5, mkdir as mkdir13 } from "fs/promises";
|
|
66994
|
-
import { basename as basename15, join as
|
|
67706
|
+
import { basename as basename15, join as join86 } from "path";
|
|
66995
67707
|
function wireEventsWriter(bus, feature, runId, workdir) {
|
|
66996
67708
|
const logger = getSafeLogger();
|
|
66997
67709
|
const project = basename15(workdir);
|
|
66998
|
-
const eventsDir =
|
|
66999
|
-
const eventsFile =
|
|
67710
|
+
const eventsDir = join86(getEventsRootDir(), project);
|
|
67711
|
+
const eventsFile = join86(eventsDir, "events.jsonl");
|
|
67000
67712
|
let dirReady = false;
|
|
67001
67713
|
const write = (line) => {
|
|
67002
67714
|
return (async () => {
|
|
@@ -67177,12 +67889,12 @@ var init_interaction2 = __esm(() => {
|
|
|
67177
67889
|
|
|
67178
67890
|
// src/pipeline/subscribers/registry.ts
|
|
67179
67891
|
import { mkdir as mkdir14, writeFile as writeFile2 } from "fs/promises";
|
|
67180
|
-
import { basename as basename16, join as
|
|
67892
|
+
import { basename as basename16, join as join87 } from "path";
|
|
67181
67893
|
function wireRegistry(bus, feature, runId, workdir, outputDir) {
|
|
67182
67894
|
const logger = getSafeLogger();
|
|
67183
67895
|
const project = basename16(workdir);
|
|
67184
|
-
const runDir =
|
|
67185
|
-
const metaFile =
|
|
67896
|
+
const runDir = join87(getRunsDir(), `${project}-${feature}-${runId}`);
|
|
67897
|
+
const metaFile = join87(runDir, "meta.json");
|
|
67186
67898
|
const unsub = bus.on("run:started", (_ev) => {
|
|
67187
67899
|
return (async () => {
|
|
67188
67900
|
try {
|
|
@@ -67192,8 +67904,8 @@ function wireRegistry(bus, feature, runId, workdir, outputDir) {
|
|
|
67192
67904
|
project,
|
|
67193
67905
|
feature,
|
|
67194
67906
|
workdir,
|
|
67195
|
-
statusPath:
|
|
67196
|
-
eventsDir:
|
|
67907
|
+
statusPath: join87(outputDir, "features", feature, "status.json"),
|
|
67908
|
+
eventsDir: join87(outputDir, "features", feature, "runs"),
|
|
67197
67909
|
registeredAt: new Date().toISOString()
|
|
67198
67910
|
};
|
|
67199
67911
|
await writeFile2(metaFile, JSON.stringify(meta3, null, 2));
|
|
@@ -67439,7 +68151,7 @@ var init_types10 = __esm(() => {
|
|
|
67439
68151
|
|
|
67440
68152
|
// src/worktree/dependencies.ts
|
|
67441
68153
|
import { existsSync as existsSync33 } from "fs";
|
|
67442
|
-
import { join as
|
|
68154
|
+
import { join as join88 } from "path";
|
|
67443
68155
|
async function prepareWorktreeDependencies(options) {
|
|
67444
68156
|
const mode = options.config.execution.worktreeDependencies.mode;
|
|
67445
68157
|
const resolvedCwd = resolveDependencyCwd(options);
|
|
@@ -67453,7 +68165,7 @@ async function prepareWorktreeDependencies(options) {
|
|
|
67453
68165
|
}
|
|
67454
68166
|
}
|
|
67455
68167
|
function resolveDependencyCwd(options) {
|
|
67456
|
-
return options.storyWorkdir ?
|
|
68168
|
+
return options.storyWorkdir ? join88(options.worktreeRoot, options.storyWorkdir) : options.worktreeRoot;
|
|
67457
68169
|
}
|
|
67458
68170
|
function resolveInheritedDependencies(options, resolvedCwd) {
|
|
67459
68171
|
if (hasDependencyManifests(options.worktreeRoot, resolvedCwd)) {
|
|
@@ -67463,7 +68175,7 @@ function resolveInheritedDependencies(options, resolvedCwd) {
|
|
|
67463
68175
|
}
|
|
67464
68176
|
function hasDependencyManifests(worktreeRoot, resolvedCwd) {
|
|
67465
68177
|
const directories = resolvedCwd === worktreeRoot ? [worktreeRoot] : [worktreeRoot, resolvedCwd];
|
|
67466
|
-
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))));
|
|
67467
68179
|
}
|
|
67468
68180
|
async function provisionDependencies(config2, worktreeRoot, resolvedCwd) {
|
|
67469
68181
|
const setupCommand2 = config2.execution.worktreeDependencies.setupCommand;
|
|
@@ -67527,13 +68239,13 @@ __export(exports_manager, {
|
|
|
67527
68239
|
});
|
|
67528
68240
|
import { existsSync as existsSync34, symlinkSync } from "fs";
|
|
67529
68241
|
import { mkdir as mkdir15 } from "fs/promises";
|
|
67530
|
-
import { join as
|
|
68242
|
+
import { join as join89 } from "path";
|
|
67531
68243
|
|
|
67532
68244
|
class WorktreeManager {
|
|
67533
68245
|
async ensureGitExcludes(projectRoot) {
|
|
67534
68246
|
const logger = getSafeLogger();
|
|
67535
|
-
const infoDir =
|
|
67536
|
-
const excludePath =
|
|
68247
|
+
const infoDir = join89(projectRoot, ".git", "info");
|
|
68248
|
+
const excludePath = join89(infoDir, "exclude");
|
|
67537
68249
|
try {
|
|
67538
68250
|
await mkdir15(infoDir, { recursive: true });
|
|
67539
68251
|
let existing = "";
|
|
@@ -67560,7 +68272,7 @@ ${missing.join(`
|
|
|
67560
68272
|
}
|
|
67561
68273
|
async create(projectRoot, storyId) {
|
|
67562
68274
|
validateStoryId(storyId);
|
|
67563
|
-
const worktreePath =
|
|
68275
|
+
const worktreePath = join89(projectRoot, ".nax-wt", storyId);
|
|
67564
68276
|
const branchName = `nax/${storyId}`;
|
|
67565
68277
|
try {
|
|
67566
68278
|
const pruneProc = _managerDeps.spawn(["git", "worktree", "prune"], {
|
|
@@ -67621,9 +68333,9 @@ ${missing.join(`
|
|
|
67621
68333
|
projectRoot
|
|
67622
68334
|
});
|
|
67623
68335
|
}
|
|
67624
|
-
const envSource =
|
|
68336
|
+
const envSource = join89(projectRoot, ".env");
|
|
67625
68337
|
if (existsSync34(envSource)) {
|
|
67626
|
-
const envTarget =
|
|
68338
|
+
const envTarget = join89(worktreePath, ".env");
|
|
67627
68339
|
try {
|
|
67628
68340
|
symlinkSync(envSource, envTarget, "file");
|
|
67629
68341
|
} catch (error48) {
|
|
@@ -67639,7 +68351,7 @@ ${missing.join(`
|
|
|
67639
68351
|
}
|
|
67640
68352
|
async remove(projectRoot, storyId) {
|
|
67641
68353
|
validateStoryId(storyId);
|
|
67642
|
-
const worktreePath =
|
|
68354
|
+
const worktreePath = join89(projectRoot, ".nax-wt", storyId);
|
|
67643
68355
|
const branchName = `nax/${storyId}`;
|
|
67644
68356
|
try {
|
|
67645
68357
|
const proc = _managerDeps.spawn(["git", "worktree", "remove", worktreePath, "--force"], {
|
|
@@ -68108,9 +68820,9 @@ var _quoteIntegrityDeps, CONTEXT_LINES = 3;
|
|
|
68108
68820
|
var init_quote_integrity = __esm(() => {
|
|
68109
68821
|
init_logger2();
|
|
68110
68822
|
_quoteIntegrityDeps = {
|
|
68111
|
-
readFile: async (
|
|
68823
|
+
readFile: async (path27) => {
|
|
68112
68824
|
try {
|
|
68113
|
-
return await Bun.file(
|
|
68825
|
+
return await Bun.file(path27).text();
|
|
68114
68826
|
} catch {
|
|
68115
68827
|
return null;
|
|
68116
68828
|
}
|
|
@@ -68399,7 +69111,7 @@ var exports_merge_conflict_rectify = {};
|
|
|
68399
69111
|
__export(exports_merge_conflict_rectify, {
|
|
68400
69112
|
rectifyConflictedStory: () => rectifyConflictedStory
|
|
68401
69113
|
});
|
|
68402
|
-
import
|
|
69114
|
+
import path27 from "path";
|
|
68403
69115
|
async function closeStaleAcpSession(worktreePath, sessionName) {
|
|
68404
69116
|
const logger = getSafeLogger();
|
|
68405
69117
|
try {
|
|
@@ -68426,7 +69138,7 @@ async function rectifyConflictedStory(options) {
|
|
|
68426
69138
|
await worktreeManager.remove(workdir, storyId);
|
|
68427
69139
|
} catch {}
|
|
68428
69140
|
await worktreeManager.create(workdir, storyId);
|
|
68429
|
-
const worktreePath =
|
|
69141
|
+
const worktreePath = path27.join(workdir, ".nax-wt", storyId);
|
|
68430
69142
|
const { formatSessionName: formatSessionName2 } = await Promise.resolve().then(() => (init_naming(), exports_naming));
|
|
68431
69143
|
const staleSessionName = formatSessionName2({
|
|
68432
69144
|
workdir: worktreePath,
|
|
@@ -68491,10 +69203,10 @@ var init_merge_conflict_rectify = __esm(() => {
|
|
|
68491
69203
|
});
|
|
68492
69204
|
|
|
68493
69205
|
// src/execution/pipeline-result-handler.ts
|
|
68494
|
-
import { join as
|
|
69206
|
+
import { join as join90 } from "path";
|
|
68495
69207
|
async function removeWorktreeDirectory(projectRoot, storyId) {
|
|
68496
69208
|
const logger = getSafeLogger();
|
|
68497
|
-
const worktreePath =
|
|
69209
|
+
const worktreePath = join90(projectRoot, ".nax-wt", storyId);
|
|
68498
69210
|
try {
|
|
68499
69211
|
const proc = _resultHandlerDeps.spawn(["git", "worktree", "remove", worktreePath, "--force"], {
|
|
68500
69212
|
cwd: projectRoot,
|
|
@@ -68711,7 +69423,7 @@ var init_pipeline_result_handler = __esm(() => {
|
|
|
68711
69423
|
|
|
68712
69424
|
// src/execution/iteration-runner.ts
|
|
68713
69425
|
import { existsSync as existsSync35 } from "fs";
|
|
68714
|
-
import { join as
|
|
69426
|
+
import { join as join91 } from "path";
|
|
68715
69427
|
async function runIteration(ctx, prd, selection, iterations, totalCost2, allStoryMetrics) {
|
|
68716
69428
|
const { story, storiesToExecute, routing, isBatchExecution } = selection;
|
|
68717
69429
|
if (ctx.dryRun) {
|
|
@@ -68736,7 +69448,7 @@ async function runIteration(ctx, prd, selection, iterations, totalCost2, allStor
|
|
|
68736
69448
|
const storyStartTime = Date.now();
|
|
68737
69449
|
let effectiveWorkdir = ctx.workdir;
|
|
68738
69450
|
if (ctx.config.execution.storyIsolation === "worktree") {
|
|
68739
|
-
const worktreePath =
|
|
69451
|
+
const worktreePath = join91(ctx.workdir, ".nax-wt", story.id);
|
|
68740
69452
|
const worktreeExists = _iterationRunnerDeps.existsSync(worktreePath);
|
|
68741
69453
|
if (!worktreeExists) {
|
|
68742
69454
|
await _iterationRunnerDeps.worktreeManager.ensureGitExcludes(ctx.workdir);
|
|
@@ -68756,7 +69468,7 @@ async function runIteration(ctx, prd, selection, iterations, totalCost2, allStor
|
|
|
68756
69468
|
}
|
|
68757
69469
|
const accumulatedAttemptCost = (story.priorFailures || []).reduce((sum, f) => sum + (f.cost || 0), 0);
|
|
68758
69470
|
const profileOverride = profileOverrideFromConfig(ctx.config);
|
|
68759
|
-
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;
|
|
68760
69472
|
let dependencyContext;
|
|
68761
69473
|
if (ctx.config.execution.storyIsolation === "worktree") {
|
|
68762
69474
|
try {
|
|
@@ -68783,7 +69495,7 @@ async function runIteration(ctx, prd, selection, iterations, totalCost2, allStor
|
|
|
68783
69495
|
};
|
|
68784
69496
|
}
|
|
68785
69497
|
}
|
|
68786
|
-
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;
|
|
68787
69499
|
const pipelineContext = {
|
|
68788
69500
|
config: effectiveConfig,
|
|
68789
69501
|
rootConfig: ctx.config,
|
|
@@ -68986,7 +69698,7 @@ __export(exports_parallel_worker, {
|
|
|
68986
69698
|
buildWorktreePipelineContext: () => buildWorktreePipelineContext,
|
|
68987
69699
|
_parallelWorkerDeps: () => _parallelWorkerDeps
|
|
68988
69700
|
});
|
|
68989
|
-
import { join as
|
|
69701
|
+
import { join as join92 } from "path";
|
|
68990
69702
|
function buildWorktreePipelineContext(base, _story) {
|
|
68991
69703
|
return { ...base, prd: structuredClone(base.prd) };
|
|
68992
69704
|
}
|
|
@@ -69009,7 +69721,7 @@ async function executeStoryInWorktree(story, worktreePath, dependencyContext, co
|
|
|
69009
69721
|
story,
|
|
69010
69722
|
stories: [story],
|
|
69011
69723
|
projectDir: context.projectDir,
|
|
69012
|
-
workdir: dependencyContext.cwd ?? (story.workdir ?
|
|
69724
|
+
workdir: dependencyContext.cwd ?? (story.workdir ? join92(worktreePath, story.workdir) : worktreePath),
|
|
69013
69725
|
worktreeDependencyContext: dependencyContext,
|
|
69014
69726
|
routing,
|
|
69015
69727
|
storyGitRef: storyGitRef ?? undefined
|
|
@@ -69110,7 +69822,7 @@ __export(exports_parallel_batch, {
|
|
|
69110
69822
|
runParallelBatch: () => runParallelBatch,
|
|
69111
69823
|
_parallelBatchDeps: () => _parallelBatchDeps
|
|
69112
69824
|
});
|
|
69113
|
-
import
|
|
69825
|
+
import path28 from "path";
|
|
69114
69826
|
async function runParallelBatch(options) {
|
|
69115
69827
|
const { stories, ctx, prd } = options;
|
|
69116
69828
|
const { workdir, config: config2, maxConcurrency, pipelineContext, eventEmitter, agentGetFn, hooks, pluginRegistry } = ctx;
|
|
@@ -69129,9 +69841,9 @@ async function runParallelBatch(options) {
|
|
|
69129
69841
|
});
|
|
69130
69842
|
throw error48;
|
|
69131
69843
|
}
|
|
69132
|
-
worktreePaths.set(story.id,
|
|
69844
|
+
worktreePaths.set(story.id, path28.join(workdir, ".nax-wt", story.id));
|
|
69133
69845
|
}
|
|
69134
|
-
const rootConfigPath =
|
|
69846
|
+
const rootConfigPath = path28.join(workdir, ".nax", "config.json");
|
|
69135
69847
|
const profileOverride = profileOverrideFromConfig(config2);
|
|
69136
69848
|
const storyEffectiveConfigs = new Map;
|
|
69137
69849
|
const configResults = await Promise.allSettled(stories.filter((story) => story.workdir).map(async (story) => {
|
|
@@ -69969,7 +70681,7 @@ var init_runner_execution = __esm(() => {
|
|
|
69969
70681
|
|
|
69970
70682
|
// src/execution/status-file.ts
|
|
69971
70683
|
import { rename as rename2, unlink as unlink3 } from "fs/promises";
|
|
69972
|
-
import { resolve as
|
|
70684
|
+
import { resolve as resolve18 } from "path";
|
|
69973
70685
|
function countProgress(prd) {
|
|
69974
70686
|
const stories = prd.userStories;
|
|
69975
70687
|
const passed = stories.filter((s) => s.status === "passed").length;
|
|
@@ -70014,7 +70726,7 @@ function buildStatusSnapshot(state) {
|
|
|
70014
70726
|
return snapshot;
|
|
70015
70727
|
}
|
|
70016
70728
|
async function writeStatusFile(filePath, status) {
|
|
70017
|
-
const resolvedPath =
|
|
70729
|
+
const resolvedPath = resolve18(filePath);
|
|
70018
70730
|
if (filePath.includes("../") || filePath.includes("..\\")) {
|
|
70019
70731
|
throw new Error("Invalid status file path: path traversal detected");
|
|
70020
70732
|
}
|
|
@@ -70028,7 +70740,7 @@ async function writeStatusFile(filePath, status) {
|
|
|
70028
70740
|
var init_status_file = () => {};
|
|
70029
70741
|
|
|
70030
70742
|
// src/execution/status-writer.ts
|
|
70031
|
-
import { join as
|
|
70743
|
+
import { join as join93 } from "path";
|
|
70032
70744
|
|
|
70033
70745
|
class StatusWriter {
|
|
70034
70746
|
statusFile;
|
|
@@ -70147,7 +70859,7 @@ class StatusWriter {
|
|
|
70147
70859
|
if (!this._prd)
|
|
70148
70860
|
return;
|
|
70149
70861
|
const safeLogger = getSafeLogger();
|
|
70150
|
-
const featureStatusPath =
|
|
70862
|
+
const featureStatusPath = join93(featureDir, "status.json");
|
|
70151
70863
|
const write = async () => {
|
|
70152
70864
|
try {
|
|
70153
70865
|
const base = this.getSnapshot(totalCost2, iterations);
|
|
@@ -70180,7 +70892,7 @@ __export(exports_migrate, {
|
|
|
70180
70892
|
});
|
|
70181
70893
|
import { existsSync as existsSync36 } from "fs";
|
|
70182
70894
|
import { mkdir as mkdir16, readdir as readdir5, rename as rename3 } from "fs/promises";
|
|
70183
|
-
import
|
|
70895
|
+
import path29 from "path";
|
|
70184
70896
|
async function detectGeneratedContent(naxDir) {
|
|
70185
70897
|
if (!existsSync36(naxDir))
|
|
70186
70898
|
return [];
|
|
@@ -70193,17 +70905,17 @@ async function detectGeneratedContent(naxDir) {
|
|
|
70193
70905
|
}
|
|
70194
70906
|
for (const entry of entries) {
|
|
70195
70907
|
if (GENERATED_NAMES.has(entry)) {
|
|
70196
|
-
candidates.push({ name: entry, srcPath:
|
|
70908
|
+
candidates.push({ name: entry, srcPath: path29.join(naxDir, entry) });
|
|
70197
70909
|
}
|
|
70198
70910
|
}
|
|
70199
|
-
const featuresDir =
|
|
70911
|
+
const featuresDir = path29.join(naxDir, "features");
|
|
70200
70912
|
if (existsSync36(featuresDir)) {
|
|
70201
70913
|
let featureDirs = [];
|
|
70202
70914
|
try {
|
|
70203
70915
|
featureDirs = await readdir5(featuresDir);
|
|
70204
70916
|
} catch {}
|
|
70205
70917
|
for (const fid of featureDirs) {
|
|
70206
|
-
const featureDir =
|
|
70918
|
+
const featureDir = path29.join(featuresDir, fid);
|
|
70207
70919
|
let subEntries = [];
|
|
70208
70920
|
try {
|
|
70209
70921
|
subEntries = await readdir5(featureDir);
|
|
@@ -70213,12 +70925,12 @@ async function detectGeneratedContent(naxDir) {
|
|
|
70213
70925
|
for (const sub of subEntries) {
|
|
70214
70926
|
if (GENERATED_FEATURE_SUBNAMES.has(sub)) {
|
|
70215
70927
|
candidates.push({
|
|
70216
|
-
name:
|
|
70217
|
-
srcPath:
|
|
70928
|
+
name: path29.join("features", fid, sub),
|
|
70929
|
+
srcPath: path29.join(featureDir, sub)
|
|
70218
70930
|
});
|
|
70219
70931
|
}
|
|
70220
70932
|
if (sub === "stories") {
|
|
70221
|
-
const storiesDir =
|
|
70933
|
+
const storiesDir = path29.join(featureDir, "stories");
|
|
70222
70934
|
let storyDirs = [];
|
|
70223
70935
|
try {
|
|
70224
70936
|
storyDirs = await readdir5(storiesDir);
|
|
@@ -70226,7 +70938,7 @@ async function detectGeneratedContent(naxDir) {
|
|
|
70226
70938
|
continue;
|
|
70227
70939
|
}
|
|
70228
70940
|
for (const sid of storyDirs) {
|
|
70229
|
-
const storyDir =
|
|
70941
|
+
const storyDir = path29.join(storiesDir, sid);
|
|
70230
70942
|
let storyEntries = [];
|
|
70231
70943
|
try {
|
|
70232
70944
|
storyEntries = await readdir5(storyDir);
|
|
@@ -70236,8 +70948,8 @@ async function detectGeneratedContent(naxDir) {
|
|
|
70236
70948
|
for (const se of storyEntries) {
|
|
70237
70949
|
if (se.startsWith("context-manifest-") && se.endsWith(".json")) {
|
|
70238
70950
|
candidates.push({
|
|
70239
|
-
name:
|
|
70240
|
-
srcPath:
|
|
70951
|
+
name: path29.join("features", fid, "stories", sid, se),
|
|
70952
|
+
srcPath: path29.join(storyDir, se)
|
|
70241
70953
|
});
|
|
70242
70954
|
}
|
|
70243
70955
|
}
|
|
@@ -70258,15 +70970,15 @@ async function migrateCommand(options) {
|
|
|
70258
70970
|
name: options.reclaim
|
|
70259
70971
|
});
|
|
70260
70972
|
}
|
|
70261
|
-
const src =
|
|
70973
|
+
const src = path29.join(globalConfigDir(), options.reclaim);
|
|
70262
70974
|
if (!existsSync36(src)) {
|
|
70263
70975
|
throw new NaxError(`Nothing to reclaim: ~/.nax/${options.reclaim} does not exist`, "MIGRATE_RECLAIM_NOT_FOUND", {
|
|
70264
70976
|
stage: "migrate",
|
|
70265
70977
|
name: options.reclaim
|
|
70266
70978
|
});
|
|
70267
70979
|
}
|
|
70268
|
-
const archiveBase =
|
|
70269
|
-
const archiveDest =
|
|
70980
|
+
const archiveBase = path29.join(globalConfigDir(), "_archive");
|
|
70981
|
+
const archiveDest = path29.join(archiveBase, `${options.reclaim}-${Date.now()}`);
|
|
70270
70982
|
await mkdir16(archiveBase, { recursive: true });
|
|
70271
70983
|
await rename3(src, archiveDest);
|
|
70272
70984
|
logger.info("migrate", `Reclaimed: archived to ${archiveDest}`, { storyId: "_migrate" });
|
|
@@ -70303,8 +71015,8 @@ async function migrateCommand(options) {
|
|
|
70303
71015
|
logger.info("migrate", `Merged: identity for "${options.merge}" updated`, { storyId: "_migrate" });
|
|
70304
71016
|
return;
|
|
70305
71017
|
}
|
|
70306
|
-
const naxDir =
|
|
70307
|
-
const configPath =
|
|
71018
|
+
const naxDir = path29.join(options.workdir, ".nax");
|
|
71019
|
+
const configPath = path29.join(naxDir, "config.json");
|
|
70308
71020
|
if (!existsSync36(configPath)) {
|
|
70309
71021
|
throw new NaxError("No .nax/config.json found \u2014 run nax init first", "MIGRATE_NO_CONFIG", {
|
|
70310
71022
|
stage: "migrate",
|
|
@@ -70320,7 +71032,7 @@ async function migrateCommand(options) {
|
|
|
70320
71032
|
cause: e
|
|
70321
71033
|
});
|
|
70322
71034
|
}
|
|
70323
|
-
const projectKey = config2.name?.trim() ||
|
|
71035
|
+
const projectKey = config2.name?.trim() || path29.basename(options.workdir);
|
|
70324
71036
|
const destBase = projectOutputDir(projectKey, config2.outputDir);
|
|
70325
71037
|
const candidates = await detectGeneratedContent(naxDir);
|
|
70326
71038
|
if (candidates.length === 0) {
|
|
@@ -70329,7 +71041,7 @@ async function migrateCommand(options) {
|
|
|
70329
71041
|
}
|
|
70330
71042
|
if (options.dryRun) {
|
|
70331
71043
|
for (const c of candidates) {
|
|
70332
|
-
logger.info("migrate", `[dry-run] Would move: ${c.srcPath} -> ${
|
|
71044
|
+
logger.info("migrate", `[dry-run] Would move: ${c.srcPath} -> ${path29.join(destBase, c.name)}`, {
|
|
70333
71045
|
storyId: "_migrate"
|
|
70334
71046
|
});
|
|
70335
71047
|
}
|
|
@@ -70338,8 +71050,8 @@ async function migrateCommand(options) {
|
|
|
70338
71050
|
await mkdir16(destBase, { recursive: true });
|
|
70339
71051
|
let moved = 0;
|
|
70340
71052
|
for (const candidate of candidates) {
|
|
70341
|
-
const dest =
|
|
70342
|
-
await mkdir16(
|
|
71053
|
+
const dest = path29.join(destBase, candidate.name);
|
|
71054
|
+
await mkdir16(path29.dirname(dest), { recursive: true });
|
|
70343
71055
|
if (existsSync36(dest)) {
|
|
70344
71056
|
throw new NaxError(`Migration conflict: destination already exists.
|
|
70345
71057
|
Source: ${candidate.srcPath}
|
|
@@ -70369,7 +71081,7 @@ async function migrateCommand(options) {
|
|
|
70369
71081
|
moved++;
|
|
70370
71082
|
logger.info("migrate", `Moved: ${candidate.name}`, { storyId: "_migrate" });
|
|
70371
71083
|
}
|
|
70372
|
-
await Bun.write(
|
|
71084
|
+
await Bun.write(path29.join(destBase, ".migrated-from"), JSON.stringify({ from: options.workdir, migratedAt: new Date().toISOString() }, null, 2));
|
|
70373
71085
|
logger.info("migrate", `Migration complete: ${moved} entries moved`, {
|
|
70374
71086
|
storyId: "_migrate",
|
|
70375
71087
|
destBase
|
|
@@ -70486,7 +71198,7 @@ __export(exports_precheck_runner, {
|
|
|
70486
71198
|
runPrecheckValidation: () => runPrecheckValidation
|
|
70487
71199
|
});
|
|
70488
71200
|
import { mkdirSync as mkdirSync7 } from "fs";
|
|
70489
|
-
import
|
|
71201
|
+
import path30 from "path";
|
|
70490
71202
|
async function runPrecheckValidation(ctx) {
|
|
70491
71203
|
const logger = getSafeLogger();
|
|
70492
71204
|
if (process.env.NAX_PRECHECK !== "1") {
|
|
@@ -70501,7 +71213,7 @@ async function runPrecheckValidation(ctx) {
|
|
|
70501
71213
|
silent: true
|
|
70502
71214
|
});
|
|
70503
71215
|
if (ctx.logFilePath) {
|
|
70504
|
-
mkdirSync7(
|
|
71216
|
+
mkdirSync7(path30.dirname(ctx.logFilePath), { recursive: true });
|
|
70505
71217
|
const precheckLog = {
|
|
70506
71218
|
type: "precheck",
|
|
70507
71219
|
timestamp: new Date().toISOString(),
|
|
@@ -70591,7 +71303,7 @@ __export(exports_run_initialization, {
|
|
|
70591
71303
|
initializeRun: () => initializeRun,
|
|
70592
71304
|
_reconcileDeps: () => _reconcileDeps
|
|
70593
71305
|
});
|
|
70594
|
-
import { join as
|
|
71306
|
+
import { join as join94 } from "path";
|
|
70595
71307
|
async function reconcileState(prd, prdPath, workdir, config2) {
|
|
70596
71308
|
const logger = getSafeLogger();
|
|
70597
71309
|
let reconciledCount = 0;
|
|
@@ -70608,7 +71320,7 @@ async function reconcileState(prd, prdPath, workdir, config2) {
|
|
|
70608
71320
|
});
|
|
70609
71321
|
continue;
|
|
70610
71322
|
}
|
|
70611
|
-
const effectiveWorkdir = story.workdir ?
|
|
71323
|
+
const effectiveWorkdir = story.workdir ? join94(workdir, story.workdir) : workdir;
|
|
70612
71324
|
try {
|
|
70613
71325
|
const reviewResult = await _reconcileDeps.runReview(config2.review, effectiveWorkdir, config2.execution);
|
|
70614
71326
|
if (!reviewResult.success) {
|
|
@@ -70814,7 +71526,7 @@ __export(exports_run_setup, {
|
|
|
70814
71526
|
setupRun: () => setupRun,
|
|
70815
71527
|
_runSetupDeps: () => _runSetupDeps
|
|
70816
71528
|
});
|
|
70817
|
-
import
|
|
71529
|
+
import path31 from "path";
|
|
70818
71530
|
function warnProfileMismatch(prd, config2, logger) {
|
|
70819
71531
|
const profiles = config2.routing?.agents?.profiles ?? [];
|
|
70820
71532
|
const profileIds = new Set(profiles.map((p) => p.id));
|
|
@@ -70935,7 +71647,7 @@ async function setupRun(options) {
|
|
|
70935
71647
|
statusWriter.setPrd(prd);
|
|
70936
71648
|
{
|
|
70937
71649
|
const { detectGeneratedContent: detectGeneratedContent2, migrateCommand: migrateCommand2 } = await Promise.resolve().then(() => (init_migrate(), exports_migrate));
|
|
70938
|
-
const naxDir =
|
|
71650
|
+
const naxDir = path31.join(workdir, ".nax");
|
|
70939
71651
|
const candidates = await detectGeneratedContent2(naxDir).catch(() => []);
|
|
70940
71652
|
if (candidates.length > 0) {
|
|
70941
71653
|
logger?.info("setup", "Found generated content under .nax/ \u2014 migrating to output dir", {
|
|
@@ -70962,7 +71674,7 @@ async function setupRun(options) {
|
|
|
70962
71674
|
remoteUrl = new TextDecoder().decode(gitResult.stdout).trim() || null;
|
|
70963
71675
|
}
|
|
70964
71676
|
} catch {}
|
|
70965
|
-
const projectKey = config2.name?.trim() ||
|
|
71677
|
+
const projectKey = config2.name?.trim() || path31.basename(workdir);
|
|
70966
71678
|
await claimProjectIdentity2(projectKey, workdir, remoteUrl).catch((err) => {
|
|
70967
71679
|
if (err instanceof NaxError && err.code === "RUN_NAME_COLLISION") {
|
|
70968
71680
|
throw err;
|
|
@@ -71017,8 +71729,8 @@ async function setupRun(options) {
|
|
|
71017
71729
|
explicit: Object.fromEntries(explicitFields.map((f) => [f, existingProjectConfig[f]])),
|
|
71018
71730
|
detected: Object.fromEntries(autodetectedFields.map((f) => [f, detectedProfile[f]]))
|
|
71019
71731
|
});
|
|
71020
|
-
const globalPluginsDir =
|
|
71021
|
-
const projectPluginsDir =
|
|
71732
|
+
const globalPluginsDir = path31.join(globalConfigDir(), "plugins");
|
|
71733
|
+
const projectPluginsDir = path31.join(workdir, ".nax", "plugins");
|
|
71022
71734
|
const configPlugins = config2.plugins || [];
|
|
71023
71735
|
const resolvedPatterns = await resolveTestFilePatterns(config2, workdir);
|
|
71024
71736
|
const isTestFileFn = (filename) => resolvedPatterns.regex.some((re) => re.test(filename));
|
|
@@ -71952,14 +72664,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
71952
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. ");
|
|
71953
72665
|
actScopeDepth = prevActScopeDepth;
|
|
71954
72666
|
}
|
|
71955
|
-
function recursivelyFlushAsyncActWork(returnValue,
|
|
72667
|
+
function recursivelyFlushAsyncActWork(returnValue, resolve19, reject) {
|
|
71956
72668
|
var queue = ReactSharedInternals.actQueue;
|
|
71957
72669
|
if (queue !== null)
|
|
71958
72670
|
if (queue.length !== 0)
|
|
71959
72671
|
try {
|
|
71960
72672
|
flushActQueue(queue);
|
|
71961
72673
|
enqueueTask(function() {
|
|
71962
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
72674
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve19, reject);
|
|
71963
72675
|
});
|
|
71964
72676
|
return;
|
|
71965
72677
|
} catch (error48) {
|
|
@@ -71967,7 +72679,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
71967
72679
|
}
|
|
71968
72680
|
else
|
|
71969
72681
|
ReactSharedInternals.actQueue = null;
|
|
71970
|
-
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);
|
|
71971
72683
|
}
|
|
71972
72684
|
function flushActQueue(queue) {
|
|
71973
72685
|
if (!isFlushing) {
|
|
@@ -72143,14 +72855,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
72143
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 () => ...);"));
|
|
72144
72856
|
});
|
|
72145
72857
|
return {
|
|
72146
|
-
then: function(
|
|
72858
|
+
then: function(resolve19, reject) {
|
|
72147
72859
|
didAwaitActCall = true;
|
|
72148
72860
|
thenable.then(function(returnValue) {
|
|
72149
72861
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
72150
72862
|
if (prevActScopeDepth === 0) {
|
|
72151
72863
|
try {
|
|
72152
72864
|
flushActQueue(queue), enqueueTask(function() {
|
|
72153
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
72865
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve19, reject);
|
|
72154
72866
|
});
|
|
72155
72867
|
} catch (error$0) {
|
|
72156
72868
|
ReactSharedInternals.thrownErrors.push(error$0);
|
|
@@ -72161,7 +72873,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
72161
72873
|
reject(_thrownError);
|
|
72162
72874
|
}
|
|
72163
72875
|
} else
|
|
72164
|
-
|
|
72876
|
+
resolve19(returnValue);
|
|
72165
72877
|
}, function(error48) {
|
|
72166
72878
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
72167
72879
|
0 < ReactSharedInternals.thrownErrors.length ? (error48 = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(error48)) : reject(error48);
|
|
@@ -72177,11 +72889,11 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
72177
72889
|
if (0 < ReactSharedInternals.thrownErrors.length)
|
|
72178
72890
|
throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
|
|
72179
72891
|
return {
|
|
72180
|
-
then: function(
|
|
72892
|
+
then: function(resolve19, reject) {
|
|
72181
72893
|
didAwaitActCall = true;
|
|
72182
72894
|
prevActScopeDepth === 0 ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
|
|
72183
|
-
return recursivelyFlushAsyncActWork(returnValue$jscomp$0,
|
|
72184
|
-
})) :
|
|
72895
|
+
return recursivelyFlushAsyncActWork(returnValue$jscomp$0, resolve19, reject);
|
|
72896
|
+
})) : resolve19(returnValue$jscomp$0);
|
|
72185
72897
|
}
|
|
72186
72898
|
};
|
|
72187
72899
|
};
|
|
@@ -72881,11 +73593,11 @@ var require_react_reconciler_development = __commonJS((exports, module) => {
|
|
|
72881
73593
|
fiber = fiber.next, id--;
|
|
72882
73594
|
return fiber;
|
|
72883
73595
|
}
|
|
72884
|
-
function copyWithSetImpl(obj,
|
|
72885
|
-
if (index >=
|
|
73596
|
+
function copyWithSetImpl(obj, path32, index, value) {
|
|
73597
|
+
if (index >= path32.length)
|
|
72886
73598
|
return value;
|
|
72887
|
-
var key =
|
|
72888
|
-
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);
|
|
72889
73601
|
return updated;
|
|
72890
73602
|
}
|
|
72891
73603
|
function copyWithRename(obj, oldPath, newPath) {
|
|
@@ -72905,11 +73617,11 @@ var require_react_reconciler_development = __commonJS((exports, module) => {
|
|
|
72905
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);
|
|
72906
73618
|
return updated;
|
|
72907
73619
|
}
|
|
72908
|
-
function copyWithDeleteImpl(obj,
|
|
72909
|
-
var key =
|
|
72910
|
-
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)
|
|
72911
73623
|
return isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], updated;
|
|
72912
|
-
updated[key] = copyWithDeleteImpl(obj[key],
|
|
73624
|
+
updated[key] = copyWithDeleteImpl(obj[key], path32, index + 1);
|
|
72913
73625
|
return updated;
|
|
72914
73626
|
}
|
|
72915
73627
|
function shouldSuspendImpl() {
|
|
@@ -75023,8 +75735,8 @@ It can also happen if the client has a browser extension installed which messes
|
|
|
75023
75735
|
currentEntangledActionThenable = {
|
|
75024
75736
|
status: "pending",
|
|
75025
75737
|
value: undefined,
|
|
75026
|
-
then: function(
|
|
75027
|
-
entangledListeners.push(
|
|
75738
|
+
then: function(resolve19) {
|
|
75739
|
+
entangledListeners.push(resolve19);
|
|
75028
75740
|
}
|
|
75029
75741
|
};
|
|
75030
75742
|
}
|
|
@@ -75048,8 +75760,8 @@ It can also happen if the client has a browser extension installed which messes
|
|
|
75048
75760
|
status: "pending",
|
|
75049
75761
|
value: null,
|
|
75050
75762
|
reason: null,
|
|
75051
|
-
then: function(
|
|
75052
|
-
listeners.push(
|
|
75763
|
+
then: function(resolve19) {
|
|
75764
|
+
listeners.push(resolve19);
|
|
75053
75765
|
}
|
|
75054
75766
|
};
|
|
75055
75767
|
thenable.then(function() {
|
|
@@ -82932,29 +83644,29 @@ Check the top-level render call using <` + componentName2 + ">.");
|
|
|
82932
83644
|
var didWarnAboutNestedUpdates = false;
|
|
82933
83645
|
var didWarnAboutFindNodeInStrictMode = {};
|
|
82934
83646
|
var overrideHookState = null, overrideHookStateDeletePath = null, overrideHookStateRenamePath = null, overrideProps = null, overridePropsDeletePath = null, overridePropsRenamePath = null, scheduleUpdate = null, scheduleRetry = null, setErrorHandler = null, setSuspenseHandler = null;
|
|
82935
|
-
overrideHookState = function(fiber, id,
|
|
83647
|
+
overrideHookState = function(fiber, id, path32, value) {
|
|
82936
83648
|
id = findHook(fiber, id);
|
|
82937
|
-
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));
|
|
82938
83650
|
};
|
|
82939
|
-
overrideHookStateDeletePath = function(fiber, id,
|
|
83651
|
+
overrideHookStateDeletePath = function(fiber, id, path32) {
|
|
82940
83652
|
id = findHook(fiber, id);
|
|
82941
|
-
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));
|
|
82942
83654
|
};
|
|
82943
83655
|
overrideHookStateRenamePath = function(fiber, id, oldPath, newPath) {
|
|
82944
83656
|
id = findHook(fiber, id);
|
|
82945
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));
|
|
82946
83658
|
};
|
|
82947
|
-
overrideProps = function(fiber,
|
|
82948
|
-
fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps,
|
|
83659
|
+
overrideProps = function(fiber, path32, value) {
|
|
83660
|
+
fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path32, 0, value);
|
|
82949
83661
|
fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
|
|
82950
|
-
|
|
82951
|
-
|
|
83662
|
+
path32 = enqueueConcurrentRenderForLane(fiber, 2);
|
|
83663
|
+
path32 !== null && scheduleUpdateOnFiber(path32, fiber, 2);
|
|
82952
83664
|
};
|
|
82953
|
-
overridePropsDeletePath = function(fiber,
|
|
82954
|
-
fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps,
|
|
83665
|
+
overridePropsDeletePath = function(fiber, path32) {
|
|
83666
|
+
fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path32, 0);
|
|
82955
83667
|
fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
|
|
82956
|
-
|
|
82957
|
-
|
|
83668
|
+
path32 = enqueueConcurrentRenderForLane(fiber, 2);
|
|
83669
|
+
path32 !== null && scheduleUpdateOnFiber(path32, fiber, 2);
|
|
82958
83670
|
};
|
|
82959
83671
|
overridePropsRenamePath = function(fiber, oldPath, newPath) {
|
|
82960
83672
|
fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
|
|
@@ -87009,8 +87721,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87009
87721
|
}
|
|
87010
87722
|
return false;
|
|
87011
87723
|
}
|
|
87012
|
-
function utils_getInObject(object2,
|
|
87013
|
-
return
|
|
87724
|
+
function utils_getInObject(object2, path32) {
|
|
87725
|
+
return path32.reduce(function(reduced, attr2) {
|
|
87014
87726
|
if (reduced) {
|
|
87015
87727
|
if (utils_hasOwnProperty.call(reduced, attr2)) {
|
|
87016
87728
|
return reduced[attr2];
|
|
@@ -87022,11 +87734,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87022
87734
|
return null;
|
|
87023
87735
|
}, object2);
|
|
87024
87736
|
}
|
|
87025
|
-
function deletePathInObject(object2,
|
|
87026
|
-
var length =
|
|
87027
|
-
var last2 =
|
|
87737
|
+
function deletePathInObject(object2, path32) {
|
|
87738
|
+
var length = path32.length;
|
|
87739
|
+
var last2 = path32[length - 1];
|
|
87028
87740
|
if (object2 != null) {
|
|
87029
|
-
var parent = utils_getInObject(object2,
|
|
87741
|
+
var parent = utils_getInObject(object2, path32.slice(0, length - 1));
|
|
87030
87742
|
if (parent) {
|
|
87031
87743
|
if (src_isArray(parent)) {
|
|
87032
87744
|
parent.splice(last2, 1);
|
|
@@ -87052,11 +87764,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87052
87764
|
}
|
|
87053
87765
|
}
|
|
87054
87766
|
}
|
|
87055
|
-
function utils_setInObject(object2,
|
|
87056
|
-
var length =
|
|
87057
|
-
var last2 =
|
|
87767
|
+
function utils_setInObject(object2, path32, value) {
|
|
87768
|
+
var length = path32.length;
|
|
87769
|
+
var last2 = path32[length - 1];
|
|
87058
87770
|
if (object2 != null) {
|
|
87059
|
-
var parent = utils_getInObject(object2,
|
|
87771
|
+
var parent = utils_getInObject(object2, path32.slice(0, length - 1));
|
|
87060
87772
|
if (parent) {
|
|
87061
87773
|
parent[last2] = value;
|
|
87062
87774
|
}
|
|
@@ -87587,8 +88299,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87587
88299
|
unserializable: Symbol("unserializable")
|
|
87588
88300
|
};
|
|
87589
88301
|
var LEVEL_THRESHOLD = 2;
|
|
87590
|
-
function createDehydrated(type, inspectable, data, cleaned,
|
|
87591
|
-
cleaned.push(
|
|
88302
|
+
function createDehydrated(type, inspectable, data, cleaned, path32) {
|
|
88303
|
+
cleaned.push(path32);
|
|
87592
88304
|
var dehydrated = {
|
|
87593
88305
|
inspectable,
|
|
87594
88306
|
type,
|
|
@@ -87606,13 +88318,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87606
88318
|
}
|
|
87607
88319
|
return dehydrated;
|
|
87608
88320
|
}
|
|
87609
|
-
function dehydrate(data, cleaned, unserializable,
|
|
88321
|
+
function dehydrate(data, cleaned, unserializable, path32, isPathAllowed) {
|
|
87610
88322
|
var level = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
|
|
87611
88323
|
var type = getDataType(data);
|
|
87612
88324
|
var isPathAllowedCheck;
|
|
87613
88325
|
switch (type) {
|
|
87614
88326
|
case "html_element":
|
|
87615
|
-
cleaned.push(
|
|
88327
|
+
cleaned.push(path32);
|
|
87616
88328
|
return {
|
|
87617
88329
|
inspectable: false,
|
|
87618
88330
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87621,7 +88333,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87621
88333
|
type
|
|
87622
88334
|
};
|
|
87623
88335
|
case "function":
|
|
87624
|
-
cleaned.push(
|
|
88336
|
+
cleaned.push(path32);
|
|
87625
88337
|
return {
|
|
87626
88338
|
inspectable: false,
|
|
87627
88339
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87630,14 +88342,14 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87630
88342
|
type
|
|
87631
88343
|
};
|
|
87632
88344
|
case "string":
|
|
87633
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88345
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87634
88346
|
if (isPathAllowedCheck) {
|
|
87635
88347
|
return data;
|
|
87636
88348
|
} else {
|
|
87637
88349
|
return data.length <= 500 ? data : data.slice(0, 500) + "...";
|
|
87638
88350
|
}
|
|
87639
88351
|
case "bigint":
|
|
87640
|
-
cleaned.push(
|
|
88352
|
+
cleaned.push(path32);
|
|
87641
88353
|
return {
|
|
87642
88354
|
inspectable: false,
|
|
87643
88355
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87646,7 +88358,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87646
88358
|
type
|
|
87647
88359
|
};
|
|
87648
88360
|
case "symbol":
|
|
87649
|
-
cleaned.push(
|
|
88361
|
+
cleaned.push(path32);
|
|
87650
88362
|
return {
|
|
87651
88363
|
inspectable: false,
|
|
87652
88364
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87655,9 +88367,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87655
88367
|
type
|
|
87656
88368
|
};
|
|
87657
88369
|
case "react_element": {
|
|
87658
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88370
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87659
88371
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87660
|
-
cleaned.push(
|
|
88372
|
+
cleaned.push(path32);
|
|
87661
88373
|
return {
|
|
87662
88374
|
inspectable: true,
|
|
87663
88375
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87674,19 +88386,19 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87674
88386
|
preview_long: formatDataForPreview(data, true),
|
|
87675
88387
|
name: getDisplayNameForReactElement(data) || "Unknown"
|
|
87676
88388
|
};
|
|
87677
|
-
unserializableValue.key = dehydrate(data.key, cleaned, unserializable,
|
|
88389
|
+
unserializableValue.key = dehydrate(data.key, cleaned, unserializable, path32.concat(["key"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87678
88390
|
if (data.$$typeof === REACT_LEGACY_ELEMENT_TYPE) {
|
|
87679
|
-
unserializableValue.ref = dehydrate(data.ref, cleaned, unserializable,
|
|
88391
|
+
unserializableValue.ref = dehydrate(data.ref, cleaned, unserializable, path32.concat(["ref"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87680
88392
|
}
|
|
87681
|
-
unserializableValue.props = dehydrate(data.props, cleaned, unserializable,
|
|
87682
|
-
unserializable.push(
|
|
88393
|
+
unserializableValue.props = dehydrate(data.props, cleaned, unserializable, path32.concat(["props"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
88394
|
+
unserializable.push(path32);
|
|
87683
88395
|
return unserializableValue;
|
|
87684
88396
|
}
|
|
87685
88397
|
case "react_lazy": {
|
|
87686
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88398
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87687
88399
|
var payload = data._payload;
|
|
87688
88400
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87689
|
-
cleaned.push(
|
|
88401
|
+
cleaned.push(path32);
|
|
87690
88402
|
var inspectable = payload !== null && hydration_typeof(payload) === "object" && (payload._status === 1 || payload._status === 2 || payload.status === "fulfilled" || payload.status === "rejected");
|
|
87691
88403
|
return {
|
|
87692
88404
|
inspectable,
|
|
@@ -87703,13 +88415,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87703
88415
|
preview_long: formatDataForPreview(data, true),
|
|
87704
88416
|
name: "lazy()"
|
|
87705
88417
|
};
|
|
87706
|
-
_unserializableValue._payload = dehydrate(payload, cleaned, unserializable,
|
|
87707
|
-
unserializable.push(
|
|
88418
|
+
_unserializableValue._payload = dehydrate(payload, cleaned, unserializable, path32.concat(["_payload"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
88419
|
+
unserializable.push(path32);
|
|
87708
88420
|
return _unserializableValue;
|
|
87709
88421
|
}
|
|
87710
88422
|
case "array_buffer":
|
|
87711
88423
|
case "data_view":
|
|
87712
|
-
cleaned.push(
|
|
88424
|
+
cleaned.push(path32);
|
|
87713
88425
|
return {
|
|
87714
88426
|
inspectable: false,
|
|
87715
88427
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87719,21 +88431,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87719
88431
|
type
|
|
87720
88432
|
};
|
|
87721
88433
|
case "array":
|
|
87722
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88434
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87723
88435
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87724
|
-
return createDehydrated(type, true, data, cleaned,
|
|
88436
|
+
return createDehydrated(type, true, data, cleaned, path32);
|
|
87725
88437
|
}
|
|
87726
88438
|
var arr = [];
|
|
87727
88439
|
for (var i = 0;i < data.length; i++) {
|
|
87728
|
-
arr[i] = dehydrateKey(data, i, cleaned, unserializable,
|
|
88440
|
+
arr[i] = dehydrateKey(data, i, cleaned, unserializable, path32.concat([i]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87729
88441
|
}
|
|
87730
88442
|
return arr;
|
|
87731
88443
|
case "html_all_collection":
|
|
87732
88444
|
case "typed_array":
|
|
87733
88445
|
case "iterator":
|
|
87734
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88446
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87735
88447
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87736
|
-
return createDehydrated(type, true, data, cleaned,
|
|
88448
|
+
return createDehydrated(type, true, data, cleaned, path32);
|
|
87737
88449
|
} else {
|
|
87738
88450
|
var _unserializableValue2 = {
|
|
87739
88451
|
unserializable: true,
|
|
@@ -87745,13 +88457,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87745
88457
|
name: typeof data.constructor !== "function" || typeof data.constructor.name !== "string" || data.constructor.name === "Object" ? "" : data.constructor.name
|
|
87746
88458
|
};
|
|
87747
88459
|
Array.from(data).forEach(function(item, i2) {
|
|
87748
|
-
return _unserializableValue2[i2] = dehydrate(item, cleaned, unserializable,
|
|
88460
|
+
return _unserializableValue2[i2] = dehydrate(item, cleaned, unserializable, path32.concat([i2]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87749
88461
|
});
|
|
87750
|
-
unserializable.push(
|
|
88462
|
+
unserializable.push(path32);
|
|
87751
88463
|
return _unserializableValue2;
|
|
87752
88464
|
}
|
|
87753
88465
|
case "opaque_iterator":
|
|
87754
|
-
cleaned.push(
|
|
88466
|
+
cleaned.push(path32);
|
|
87755
88467
|
return {
|
|
87756
88468
|
inspectable: false,
|
|
87757
88469
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87760,7 +88472,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87760
88472
|
type
|
|
87761
88473
|
};
|
|
87762
88474
|
case "date":
|
|
87763
|
-
cleaned.push(
|
|
88475
|
+
cleaned.push(path32);
|
|
87764
88476
|
return {
|
|
87765
88477
|
inspectable: false,
|
|
87766
88478
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87769,7 +88481,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87769
88481
|
type
|
|
87770
88482
|
};
|
|
87771
88483
|
case "regexp":
|
|
87772
|
-
cleaned.push(
|
|
88484
|
+
cleaned.push(path32);
|
|
87773
88485
|
return {
|
|
87774
88486
|
inspectable: false,
|
|
87775
88487
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87778,9 +88490,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87778
88490
|
type
|
|
87779
88491
|
};
|
|
87780
88492
|
case "thenable":
|
|
87781
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88493
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87782
88494
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87783
|
-
cleaned.push(
|
|
88495
|
+
cleaned.push(path32);
|
|
87784
88496
|
return {
|
|
87785
88497
|
inspectable: data.status === "fulfilled" || data.status === "rejected",
|
|
87786
88498
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87801,8 +88513,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87801
88513
|
preview_long: formatDataForPreview(data, true),
|
|
87802
88514
|
name: "fulfilled Thenable"
|
|
87803
88515
|
};
|
|
87804
|
-
_unserializableValue3.value = dehydrate(data.value, cleaned, unserializable,
|
|
87805
|
-
unserializable.push(
|
|
88516
|
+
_unserializableValue3.value = dehydrate(data.value, cleaned, unserializable, path32.concat(["value"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
88517
|
+
unserializable.push(path32);
|
|
87806
88518
|
return _unserializableValue3;
|
|
87807
88519
|
}
|
|
87808
88520
|
case "rejected": {
|
|
@@ -87813,12 +88525,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87813
88525
|
preview_long: formatDataForPreview(data, true),
|
|
87814
88526
|
name: "rejected Thenable"
|
|
87815
88527
|
};
|
|
87816
|
-
_unserializableValue4.reason = dehydrate(data.reason, cleaned, unserializable,
|
|
87817
|
-
unserializable.push(
|
|
88528
|
+
_unserializableValue4.reason = dehydrate(data.reason, cleaned, unserializable, path32.concat(["reason"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
88529
|
+
unserializable.push(path32);
|
|
87818
88530
|
return _unserializableValue4;
|
|
87819
88531
|
}
|
|
87820
88532
|
default:
|
|
87821
|
-
cleaned.push(
|
|
88533
|
+
cleaned.push(path32);
|
|
87822
88534
|
return {
|
|
87823
88535
|
inspectable: false,
|
|
87824
88536
|
preview_short: formatDataForPreview(data, false),
|
|
@@ -87828,21 +88540,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87828
88540
|
};
|
|
87829
88541
|
}
|
|
87830
88542
|
case "object":
|
|
87831
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88543
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87832
88544
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87833
|
-
return createDehydrated(type, true, data, cleaned,
|
|
88545
|
+
return createDehydrated(type, true, data, cleaned, path32);
|
|
87834
88546
|
} else {
|
|
87835
88547
|
var object2 = {};
|
|
87836
88548
|
getAllEnumerableKeys(data).forEach(function(key) {
|
|
87837
88549
|
var name = key.toString();
|
|
87838
|
-
object2[name] = dehydrateKey(data, key, cleaned, unserializable,
|
|
88550
|
+
object2[name] = dehydrateKey(data, key, cleaned, unserializable, path32.concat([name]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87839
88551
|
});
|
|
87840
88552
|
return object2;
|
|
87841
88553
|
}
|
|
87842
88554
|
case "class_instance": {
|
|
87843
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88555
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87844
88556
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87845
|
-
return createDehydrated(type, true, data, cleaned,
|
|
88557
|
+
return createDehydrated(type, true, data, cleaned, path32);
|
|
87846
88558
|
}
|
|
87847
88559
|
var value = {
|
|
87848
88560
|
unserializable: true,
|
|
@@ -87854,15 +88566,15 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87854
88566
|
};
|
|
87855
88567
|
getAllEnumerableKeys(data).forEach(function(key) {
|
|
87856
88568
|
var keyAsString = key.toString();
|
|
87857
|
-
value[keyAsString] = dehydrate(data[key], cleaned, unserializable,
|
|
88569
|
+
value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path32.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87858
88570
|
});
|
|
87859
|
-
unserializable.push(
|
|
88571
|
+
unserializable.push(path32);
|
|
87860
88572
|
return value;
|
|
87861
88573
|
}
|
|
87862
88574
|
case "error": {
|
|
87863
|
-
isPathAllowedCheck = isPathAllowed(
|
|
88575
|
+
isPathAllowedCheck = isPathAllowed(path32);
|
|
87864
88576
|
if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
|
|
87865
|
-
return createDehydrated(type, true, data, cleaned,
|
|
88577
|
+
return createDehydrated(type, true, data, cleaned, path32);
|
|
87866
88578
|
}
|
|
87867
88579
|
var _value = {
|
|
87868
88580
|
unserializable: true,
|
|
@@ -87872,22 +88584,22 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87872
88584
|
preview_long: formatDataForPreview(data, true),
|
|
87873
88585
|
name: data.name
|
|
87874
88586
|
};
|
|
87875
|
-
_value.message = dehydrate(data.message, cleaned, unserializable,
|
|
87876
|
-
_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);
|
|
87877
88589
|
if ("cause" in data) {
|
|
87878
|
-
_value.cause = dehydrate(data.cause, cleaned, unserializable,
|
|
88590
|
+
_value.cause = dehydrate(data.cause, cleaned, unserializable, path32.concat(["cause"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87879
88591
|
}
|
|
87880
88592
|
getAllEnumerableKeys(data).forEach(function(key) {
|
|
87881
88593
|
var keyAsString = key.toString();
|
|
87882
|
-
_value[keyAsString] = dehydrate(data[key], cleaned, unserializable,
|
|
88594
|
+
_value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path32.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
|
|
87883
88595
|
});
|
|
87884
|
-
unserializable.push(
|
|
88596
|
+
unserializable.push(path32);
|
|
87885
88597
|
return _value;
|
|
87886
88598
|
}
|
|
87887
88599
|
case "infinity":
|
|
87888
88600
|
case "nan":
|
|
87889
88601
|
case "undefined":
|
|
87890
|
-
cleaned.push(
|
|
88602
|
+
cleaned.push(path32);
|
|
87891
88603
|
return {
|
|
87892
88604
|
type
|
|
87893
88605
|
};
|
|
@@ -87895,10 +88607,10 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87895
88607
|
return data;
|
|
87896
88608
|
}
|
|
87897
88609
|
}
|
|
87898
|
-
function dehydrateKey(parent, key, cleaned, unserializable,
|
|
88610
|
+
function dehydrateKey(parent, key, cleaned, unserializable, path32, isPathAllowed) {
|
|
87899
88611
|
var level = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0;
|
|
87900
88612
|
try {
|
|
87901
|
-
return dehydrate(parent[key], cleaned, unserializable,
|
|
88613
|
+
return dehydrate(parent[key], cleaned, unserializable, path32, isPathAllowed, level);
|
|
87902
88614
|
} catch (error48) {
|
|
87903
88615
|
var preview = "";
|
|
87904
88616
|
if (hydration_typeof(error48) === "object" && error48 !== null && typeof error48.stack === "string") {
|
|
@@ -87906,7 +88618,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87906
88618
|
} else if (typeof error48 === "string") {
|
|
87907
88619
|
preview = error48;
|
|
87908
88620
|
}
|
|
87909
|
-
cleaned.push(
|
|
88621
|
+
cleaned.push(path32);
|
|
87910
88622
|
return {
|
|
87911
88623
|
inspectable: false,
|
|
87912
88624
|
preview_short: "[Exception]",
|
|
@@ -87916,8 +88628,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87916
88628
|
};
|
|
87917
88629
|
}
|
|
87918
88630
|
}
|
|
87919
|
-
function fillInPath(object2, data,
|
|
87920
|
-
var target = getInObject(object2,
|
|
88631
|
+
function fillInPath(object2, data, path32, value) {
|
|
88632
|
+
var target = getInObject(object2, path32);
|
|
87921
88633
|
if (target != null) {
|
|
87922
88634
|
if (!target[meta3.unserializable]) {
|
|
87923
88635
|
delete target[meta3.inspectable];
|
|
@@ -87932,9 +88644,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87932
88644
|
}
|
|
87933
88645
|
if (value !== null && data.unserializable.length > 0) {
|
|
87934
88646
|
var unserializablePath = data.unserializable[0];
|
|
87935
|
-
var isMatch2 = unserializablePath.length ===
|
|
87936
|
-
for (var i = 0;i <
|
|
87937
|
-
if (
|
|
88647
|
+
var isMatch2 = unserializablePath.length === path32.length;
|
|
88648
|
+
for (var i = 0;i < path32.length; i++) {
|
|
88649
|
+
if (path32[i] !== unserializablePath[i]) {
|
|
87938
88650
|
isMatch2 = false;
|
|
87939
88651
|
break;
|
|
87940
88652
|
}
|
|
@@ -87943,13 +88655,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87943
88655
|
upgradeUnserializable(value, value);
|
|
87944
88656
|
}
|
|
87945
88657
|
}
|
|
87946
|
-
setInObject(object2,
|
|
88658
|
+
setInObject(object2, path32, value);
|
|
87947
88659
|
}
|
|
87948
88660
|
function hydrate(object2, cleaned, unserializable) {
|
|
87949
|
-
cleaned.forEach(function(
|
|
87950
|
-
var length =
|
|
87951
|
-
var last2 =
|
|
87952
|
-
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));
|
|
87953
88665
|
if (!parent || !parent.hasOwnProperty(last2)) {
|
|
87954
88666
|
return;
|
|
87955
88667
|
}
|
|
@@ -87975,10 +88687,10 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
87975
88687
|
parent[last2] = replaced;
|
|
87976
88688
|
}
|
|
87977
88689
|
});
|
|
87978
|
-
unserializable.forEach(function(
|
|
87979
|
-
var length =
|
|
87980
|
-
var last2 =
|
|
87981
|
-
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));
|
|
87982
88694
|
if (!parent || !parent.hasOwnProperty(last2)) {
|
|
87983
88695
|
return;
|
|
87984
88696
|
}
|
|
@@ -88099,11 +88811,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
88099
88811
|
return gte2(version2, FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER);
|
|
88100
88812
|
}
|
|
88101
88813
|
function cleanForBridge(data, isPathAllowed) {
|
|
88102
|
-
var
|
|
88814
|
+
var path32 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
88103
88815
|
if (data !== null) {
|
|
88104
88816
|
var cleanedPaths = [];
|
|
88105
88817
|
var unserializablePaths = [];
|
|
88106
|
-
var cleanedData = dehydrate(data, cleanedPaths, unserializablePaths,
|
|
88818
|
+
var cleanedData = dehydrate(data, cleanedPaths, unserializablePaths, path32, isPathAllowed);
|
|
88107
88819
|
return {
|
|
88108
88820
|
data: cleanedData,
|
|
88109
88821
|
cleaned: cleanedPaths,
|
|
@@ -88113,18 +88825,18 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
88113
88825
|
return null;
|
|
88114
88826
|
}
|
|
88115
88827
|
}
|
|
88116
|
-
function copyWithDelete(obj,
|
|
88828
|
+
function copyWithDelete(obj, path32) {
|
|
88117
88829
|
var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
88118
|
-
var key =
|
|
88830
|
+
var key = path32[index];
|
|
88119
88831
|
var updated = shared_isArray(obj) ? obj.slice() : utils_objectSpread({}, obj);
|
|
88120
|
-
if (index + 1 ===
|
|
88832
|
+
if (index + 1 === path32.length) {
|
|
88121
88833
|
if (shared_isArray(updated)) {
|
|
88122
88834
|
updated.splice(key, 1);
|
|
88123
88835
|
} else {
|
|
88124
88836
|
delete updated[key];
|
|
88125
88837
|
}
|
|
88126
88838
|
} else {
|
|
88127
|
-
updated[key] = copyWithDelete(obj[key],
|
|
88839
|
+
updated[key] = copyWithDelete(obj[key], path32, index + 1);
|
|
88128
88840
|
}
|
|
88129
88841
|
return updated;
|
|
88130
88842
|
}
|
|
@@ -88145,14 +88857,14 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
88145
88857
|
}
|
|
88146
88858
|
return updated;
|
|
88147
88859
|
}
|
|
88148
|
-
function copyWithSet(obj,
|
|
88860
|
+
function copyWithSet(obj, path32, value) {
|
|
88149
88861
|
var index = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
|
|
88150
|
-
if (index >=
|
|
88862
|
+
if (index >= path32.length) {
|
|
88151
88863
|
return value;
|
|
88152
88864
|
}
|
|
88153
|
-
var key =
|
|
88865
|
+
var key = path32[index];
|
|
88154
88866
|
var updated = shared_isArray(obj) ? obj.slice() : utils_objectSpread({}, obj);
|
|
88155
|
-
updated[key] = copyWithSet(obj[key],
|
|
88867
|
+
updated[key] = copyWithSet(obj[key], path32, value, index + 1);
|
|
88156
88868
|
return updated;
|
|
88157
88869
|
}
|
|
88158
88870
|
function getEffectDurations(root) {
|
|
@@ -89480,12 +90192,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89480
90192
|
}
|
|
89481
90193
|
});
|
|
89482
90194
|
bridge_defineProperty(_this, "overrideValueAtPath", function(_ref) {
|
|
89483
|
-
var { id, path:
|
|
90195
|
+
var { id, path: path32, rendererID, type, value } = _ref;
|
|
89484
90196
|
switch (type) {
|
|
89485
90197
|
case "context":
|
|
89486
90198
|
_this.send("overrideContext", {
|
|
89487
90199
|
id,
|
|
89488
|
-
path:
|
|
90200
|
+
path: path32,
|
|
89489
90201
|
rendererID,
|
|
89490
90202
|
wasForwarded: true,
|
|
89491
90203
|
value
|
|
@@ -89494,7 +90206,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89494
90206
|
case "hooks":
|
|
89495
90207
|
_this.send("overrideHookState", {
|
|
89496
90208
|
id,
|
|
89497
|
-
path:
|
|
90209
|
+
path: path32,
|
|
89498
90210
|
rendererID,
|
|
89499
90211
|
wasForwarded: true,
|
|
89500
90212
|
value
|
|
@@ -89503,7 +90215,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89503
90215
|
case "props":
|
|
89504
90216
|
_this.send("overrideProps", {
|
|
89505
90217
|
id,
|
|
89506
|
-
path:
|
|
90218
|
+
path: path32,
|
|
89507
90219
|
rendererID,
|
|
89508
90220
|
wasForwarded: true,
|
|
89509
90221
|
value
|
|
@@ -89512,7 +90224,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89512
90224
|
case "state":
|
|
89513
90225
|
_this.send("overrideState", {
|
|
89514
90226
|
id,
|
|
89515
|
-
path:
|
|
90227
|
+
path: path32,
|
|
89516
90228
|
rendererID,
|
|
89517
90229
|
wasForwarded: true,
|
|
89518
90230
|
value
|
|
@@ -89846,12 +90558,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89846
90558
|
}
|
|
89847
90559
|
});
|
|
89848
90560
|
agent_defineProperty(_this, "copyElementPath", function(_ref5) {
|
|
89849
|
-
var { id, path:
|
|
90561
|
+
var { id, path: path32, rendererID } = _ref5;
|
|
89850
90562
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
89851
90563
|
if (renderer == null) {
|
|
89852
90564
|
console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
|
|
89853
90565
|
} else {
|
|
89854
|
-
var value = renderer.getSerializedElementValueByPath(id,
|
|
90566
|
+
var value = renderer.getSerializedElementValueByPath(id, path32);
|
|
89855
90567
|
if (value != null) {
|
|
89856
90568
|
_this._bridge.send("saveToClipboard", value);
|
|
89857
90569
|
} else {
|
|
@@ -89860,12 +90572,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89860
90572
|
}
|
|
89861
90573
|
});
|
|
89862
90574
|
agent_defineProperty(_this, "deletePath", function(_ref6) {
|
|
89863
|
-
var { hookID, id, path:
|
|
90575
|
+
var { hookID, id, path: path32, rendererID, type } = _ref6;
|
|
89864
90576
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
89865
90577
|
if (renderer == null) {
|
|
89866
90578
|
console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
|
|
89867
90579
|
} else {
|
|
89868
|
-
renderer.deletePath(type, id, hookID,
|
|
90580
|
+
renderer.deletePath(type, id, hookID, path32);
|
|
89869
90581
|
}
|
|
89870
90582
|
});
|
|
89871
90583
|
agent_defineProperty(_this, "getBackendVersion", function() {
|
|
@@ -89902,12 +90614,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89902
90614
|
}
|
|
89903
90615
|
});
|
|
89904
90616
|
agent_defineProperty(_this, "inspectElement", function(_ref9) {
|
|
89905
|
-
var { forceFullData, id, path:
|
|
90617
|
+
var { forceFullData, id, path: path32, rendererID, requestID } = _ref9;
|
|
89906
90618
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
89907
90619
|
if (renderer == null) {
|
|
89908
90620
|
console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
|
|
89909
90621
|
} else {
|
|
89910
|
-
_this._bridge.send("inspectedElement", renderer.inspectElement(requestID, id,
|
|
90622
|
+
_this._bridge.send("inspectedElement", renderer.inspectElement(requestID, id, path32, forceFullData));
|
|
89911
90623
|
if (_this._persistedSelectionMatch === null || _this._persistedSelectionMatch.id !== id) {
|
|
89912
90624
|
_this._persistedSelection = null;
|
|
89913
90625
|
_this._persistedSelectionMatch = null;
|
|
@@ -89941,15 +90653,15 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89941
90653
|
}
|
|
89942
90654
|
for (var rendererID in _this._rendererInterfaces) {
|
|
89943
90655
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
89944
|
-
var
|
|
90656
|
+
var path32 = null;
|
|
89945
90657
|
if (suspendedByPathIndex !== null && rendererPath !== null) {
|
|
89946
90658
|
var suspendedByPathRendererIndex = suspendedByPathIndex - suspendedByOffset;
|
|
89947
90659
|
var rendererHasRequestedSuspendedByPath = renderer.getElementAttributeByPath(id, ["suspendedBy", suspendedByPathRendererIndex]) !== undefined;
|
|
89948
90660
|
if (rendererHasRequestedSuspendedByPath) {
|
|
89949
|
-
|
|
90661
|
+
path32 = ["suspendedBy", suspendedByPathRendererIndex].concat(rendererPath);
|
|
89950
90662
|
}
|
|
89951
90663
|
}
|
|
89952
|
-
var inspectedRootsPayload = renderer.inspectElement(requestID, id,
|
|
90664
|
+
var inspectedRootsPayload = renderer.inspectElement(requestID, id, path32, forceFullData);
|
|
89953
90665
|
switch (inspectedRootsPayload.type) {
|
|
89954
90666
|
case "hydrated-path":
|
|
89955
90667
|
inspectedRootsPayload.path[1] += suspendedByOffset;
|
|
@@ -90043,20 +90755,20 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90043
90755
|
}
|
|
90044
90756
|
});
|
|
90045
90757
|
agent_defineProperty(_this, "overrideValueAtPath", function(_ref15) {
|
|
90046
|
-
var { hookID, id, path:
|
|
90758
|
+
var { hookID, id, path: path32, rendererID, type, value } = _ref15;
|
|
90047
90759
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
90048
90760
|
if (renderer == null) {
|
|
90049
90761
|
console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
|
|
90050
90762
|
} else {
|
|
90051
|
-
renderer.overrideValueAtPath(type, id, hookID,
|
|
90763
|
+
renderer.overrideValueAtPath(type, id, hookID, path32, value);
|
|
90052
90764
|
}
|
|
90053
90765
|
});
|
|
90054
90766
|
agent_defineProperty(_this, "overrideContext", function(_ref16) {
|
|
90055
|
-
var { id, path:
|
|
90767
|
+
var { id, path: path32, rendererID, wasForwarded, value } = _ref16;
|
|
90056
90768
|
if (!wasForwarded) {
|
|
90057
90769
|
_this.overrideValueAtPath({
|
|
90058
90770
|
id,
|
|
90059
|
-
path:
|
|
90771
|
+
path: path32,
|
|
90060
90772
|
rendererID,
|
|
90061
90773
|
type: "context",
|
|
90062
90774
|
value
|
|
@@ -90064,11 +90776,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90064
90776
|
}
|
|
90065
90777
|
});
|
|
90066
90778
|
agent_defineProperty(_this, "overrideHookState", function(_ref17) {
|
|
90067
|
-
var { id, hookID, path:
|
|
90779
|
+
var { id, hookID, path: path32, rendererID, wasForwarded, value } = _ref17;
|
|
90068
90780
|
if (!wasForwarded) {
|
|
90069
90781
|
_this.overrideValueAtPath({
|
|
90070
90782
|
id,
|
|
90071
|
-
path:
|
|
90783
|
+
path: path32,
|
|
90072
90784
|
rendererID,
|
|
90073
90785
|
type: "hooks",
|
|
90074
90786
|
value
|
|
@@ -90076,11 +90788,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90076
90788
|
}
|
|
90077
90789
|
});
|
|
90078
90790
|
agent_defineProperty(_this, "overrideProps", function(_ref18) {
|
|
90079
|
-
var { id, path:
|
|
90791
|
+
var { id, path: path32, rendererID, wasForwarded, value } = _ref18;
|
|
90080
90792
|
if (!wasForwarded) {
|
|
90081
90793
|
_this.overrideValueAtPath({
|
|
90082
90794
|
id,
|
|
90083
|
-
path:
|
|
90795
|
+
path: path32,
|
|
90084
90796
|
rendererID,
|
|
90085
90797
|
type: "props",
|
|
90086
90798
|
value
|
|
@@ -90088,11 +90800,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90088
90800
|
}
|
|
90089
90801
|
});
|
|
90090
90802
|
agent_defineProperty(_this, "overrideState", function(_ref19) {
|
|
90091
|
-
var { id, path:
|
|
90803
|
+
var { id, path: path32, rendererID, wasForwarded, value } = _ref19;
|
|
90092
90804
|
if (!wasForwarded) {
|
|
90093
90805
|
_this.overrideValueAtPath({
|
|
90094
90806
|
id,
|
|
90095
|
-
path:
|
|
90807
|
+
path: path32,
|
|
90096
90808
|
rendererID,
|
|
90097
90809
|
type: "state",
|
|
90098
90810
|
value
|
|
@@ -90159,12 +90871,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90159
90871
|
_this._bridge.send("stopInspectingHost", selected);
|
|
90160
90872
|
});
|
|
90161
90873
|
agent_defineProperty(_this, "storeAsGlobal", function(_ref23) {
|
|
90162
|
-
var { count, id, path:
|
|
90874
|
+
var { count, id, path: path32, rendererID } = _ref23;
|
|
90163
90875
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
90164
90876
|
if (renderer == null) {
|
|
90165
90877
|
console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
|
|
90166
90878
|
} else {
|
|
90167
|
-
renderer.storeAsGlobal(id,
|
|
90879
|
+
renderer.storeAsGlobal(id, path32, count);
|
|
90168
90880
|
}
|
|
90169
90881
|
});
|
|
90170
90882
|
agent_defineProperty(_this, "updateHookSettings", function(settings) {
|
|
@@ -90181,12 +90893,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90181
90893
|
var rendererID = +rendererIDString;
|
|
90182
90894
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
90183
90895
|
if (_this._lastSelectedRendererID === rendererID) {
|
|
90184
|
-
var
|
|
90185
|
-
if (
|
|
90186
|
-
renderer.setTrackedPath(
|
|
90896
|
+
var path32 = renderer.getPathForElement(_this._lastSelectedElementID);
|
|
90897
|
+
if (path32 !== null) {
|
|
90898
|
+
renderer.setTrackedPath(path32);
|
|
90187
90899
|
_this._persistedSelection = {
|
|
90188
90900
|
rendererID,
|
|
90189
|
-
path:
|
|
90901
|
+
path: path32
|
|
90190
90902
|
};
|
|
90191
90903
|
}
|
|
90192
90904
|
}
|
|
@@ -90261,11 +90973,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90261
90973
|
var rendererID = _this._lastSelectedRendererID;
|
|
90262
90974
|
var id = _this._lastSelectedElementID;
|
|
90263
90975
|
var renderer = _this._rendererInterfaces[rendererID];
|
|
90264
|
-
var
|
|
90265
|
-
if (
|
|
90976
|
+
var path32 = renderer != null ? renderer.getPathForElement(id) : null;
|
|
90977
|
+
if (path32 !== null) {
|
|
90266
90978
|
storage_sessionStorageSetItem(SESSION_STORAGE_LAST_SELECTION_KEY, JSON.stringify({
|
|
90267
90979
|
rendererID,
|
|
90268
|
-
path:
|
|
90980
|
+
path: path32
|
|
90269
90981
|
}));
|
|
90270
90982
|
} else {
|
|
90271
90983
|
storage_sessionStorageRemoveItem(SESSION_STORAGE_LAST_SELECTION_KEY);
|
|
@@ -90988,7 +91700,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
90988
91700
|
hasElementWithId: function hasElementWithId() {
|
|
90989
91701
|
return false;
|
|
90990
91702
|
},
|
|
90991
|
-
inspectElement: function inspectElement(requestID, id,
|
|
91703
|
+
inspectElement: function inspectElement(requestID, id, path32) {
|
|
90992
91704
|
return {
|
|
90993
91705
|
id,
|
|
90994
91706
|
responseID: requestID,
|
|
@@ -96258,9 +96970,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
96258
96970
|
}
|
|
96259
96971
|
return null;
|
|
96260
96972
|
}
|
|
96261
|
-
function getElementAttributeByPath(id,
|
|
96973
|
+
function getElementAttributeByPath(id, path32) {
|
|
96262
96974
|
if (isMostRecentlyInspectedElement(id)) {
|
|
96263
|
-
return utils_getInObject(mostRecentlyInspectedElement,
|
|
96975
|
+
return utils_getInObject(mostRecentlyInspectedElement, path32);
|
|
96264
96976
|
}
|
|
96265
96977
|
return;
|
|
96266
96978
|
}
|
|
@@ -96963,9 +97675,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
96963
97675
|
function isMostRecentlyInspectedElementCurrent(id) {
|
|
96964
97676
|
return isMostRecentlyInspectedElement(id) && !hasElementUpdatedSinceLastInspected;
|
|
96965
97677
|
}
|
|
96966
|
-
function mergeInspectedPaths(
|
|
97678
|
+
function mergeInspectedPaths(path32) {
|
|
96967
97679
|
var current = currentlyInspectedPaths;
|
|
96968
|
-
|
|
97680
|
+
path32.forEach(function(key) {
|
|
96969
97681
|
if (!current[key]) {
|
|
96970
97682
|
current[key] = {};
|
|
96971
97683
|
}
|
|
@@ -96973,21 +97685,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
96973
97685
|
});
|
|
96974
97686
|
}
|
|
96975
97687
|
function createIsPathAllowed(key, secondaryCategory) {
|
|
96976
|
-
return function isPathAllowed(
|
|
97688
|
+
return function isPathAllowed(path32) {
|
|
96977
97689
|
switch (secondaryCategory) {
|
|
96978
97690
|
case "hooks":
|
|
96979
|
-
if (
|
|
97691
|
+
if (path32.length === 1) {
|
|
96980
97692
|
return true;
|
|
96981
97693
|
}
|
|
96982
|
-
if (
|
|
97694
|
+
if (path32[path32.length - 2] === "hookSource" && path32[path32.length - 1] === "fileName") {
|
|
96983
97695
|
return true;
|
|
96984
97696
|
}
|
|
96985
|
-
if (
|
|
97697
|
+
if (path32[path32.length - 1] === "subHooks" || path32[path32.length - 2] === "subHooks") {
|
|
96986
97698
|
return true;
|
|
96987
97699
|
}
|
|
96988
97700
|
break;
|
|
96989
97701
|
case "suspendedBy":
|
|
96990
|
-
if (
|
|
97702
|
+
if (path32.length < 5) {
|
|
96991
97703
|
return true;
|
|
96992
97704
|
}
|
|
96993
97705
|
break;
|
|
@@ -96998,8 +97710,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
96998
97710
|
if (!current) {
|
|
96999
97711
|
return false;
|
|
97000
97712
|
}
|
|
97001
|
-
for (var i = 0;i <
|
|
97002
|
-
current = current[
|
|
97713
|
+
for (var i = 0;i < path32.length; i++) {
|
|
97714
|
+
current = current[path32[i]];
|
|
97003
97715
|
if (!current) {
|
|
97004
97716
|
return false;
|
|
97005
97717
|
}
|
|
@@ -97053,38 +97765,38 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
97053
97765
|
break;
|
|
97054
97766
|
}
|
|
97055
97767
|
}
|
|
97056
|
-
function storeAsGlobal(id,
|
|
97768
|
+
function storeAsGlobal(id, path32, count) {
|
|
97057
97769
|
if (isMostRecentlyInspectedElement(id)) {
|
|
97058
|
-
var value = utils_getInObject(mostRecentlyInspectedElement,
|
|
97770
|
+
var value = utils_getInObject(mostRecentlyInspectedElement, path32);
|
|
97059
97771
|
var key = "$reactTemp".concat(count);
|
|
97060
97772
|
window[key] = value;
|
|
97061
97773
|
console.log(key);
|
|
97062
97774
|
console.log(value);
|
|
97063
97775
|
}
|
|
97064
97776
|
}
|
|
97065
|
-
function getSerializedElementValueByPath(id,
|
|
97777
|
+
function getSerializedElementValueByPath(id, path32) {
|
|
97066
97778
|
if (isMostRecentlyInspectedElement(id)) {
|
|
97067
|
-
var valueToCopy = utils_getInObject(mostRecentlyInspectedElement,
|
|
97779
|
+
var valueToCopy = utils_getInObject(mostRecentlyInspectedElement, path32);
|
|
97068
97780
|
return serializeToString(valueToCopy);
|
|
97069
97781
|
}
|
|
97070
97782
|
}
|
|
97071
|
-
function inspectElement(requestID, id,
|
|
97072
|
-
if (
|
|
97073
|
-
mergeInspectedPaths(
|
|
97783
|
+
function inspectElement(requestID, id, path32, forceFullData) {
|
|
97784
|
+
if (path32 !== null) {
|
|
97785
|
+
mergeInspectedPaths(path32);
|
|
97074
97786
|
}
|
|
97075
97787
|
if (isMostRecentlyInspectedElement(id) && !forceFullData) {
|
|
97076
97788
|
if (!hasElementUpdatedSinceLastInspected) {
|
|
97077
|
-
if (
|
|
97789
|
+
if (path32 !== null) {
|
|
97078
97790
|
var secondaryCategory = null;
|
|
97079
|
-
if (
|
|
97080
|
-
secondaryCategory =
|
|
97791
|
+
if (path32[0] === "hooks" || path32[0] === "suspendedBy") {
|
|
97792
|
+
secondaryCategory = path32[0];
|
|
97081
97793
|
}
|
|
97082
97794
|
return {
|
|
97083
97795
|
id,
|
|
97084
97796
|
responseID: requestID,
|
|
97085
97797
|
type: "hydrated-path",
|
|
97086
|
-
path:
|
|
97087
|
-
value: cleanForBridge(utils_getInObject(mostRecentlyInspectedElement,
|
|
97798
|
+
path: path32,
|
|
97799
|
+
value: cleanForBridge(utils_getInObject(mostRecentlyInspectedElement, path32), createIsPathAllowed(null, secondaryCategory), path32)
|
|
97088
97800
|
};
|
|
97089
97801
|
} else {
|
|
97090
97802
|
return {
|
|
@@ -97280,7 +97992,7 @@ The error thrown in the component is:
|
|
|
97280
97992
|
console.groupEnd();
|
|
97281
97993
|
}
|
|
97282
97994
|
}
|
|
97283
|
-
function deletePath(type, id, hookID,
|
|
97995
|
+
function deletePath(type, id, hookID, path32) {
|
|
97284
97996
|
var devtoolsInstance = idToDevToolsInstanceMap.get(id);
|
|
97285
97997
|
if (devtoolsInstance === undefined) {
|
|
97286
97998
|
console.warn('Could not find DevToolsInstance with id "'.concat(id, '"'));
|
|
@@ -97294,11 +98006,11 @@ The error thrown in the component is:
|
|
|
97294
98006
|
var instance2 = fiber.stateNode;
|
|
97295
98007
|
switch (type) {
|
|
97296
98008
|
case "context":
|
|
97297
|
-
|
|
98009
|
+
path32 = path32.slice(1);
|
|
97298
98010
|
switch (fiber.tag) {
|
|
97299
98011
|
case ClassComponent:
|
|
97300
|
-
if (
|
|
97301
|
-
deletePathInObject(instance2.context,
|
|
98012
|
+
if (path32.length === 0) {} else {
|
|
98013
|
+
deletePathInObject(instance2.context, path32);
|
|
97302
98014
|
}
|
|
97303
98015
|
instance2.forceUpdate();
|
|
97304
98016
|
break;
|
|
@@ -97308,21 +98020,21 @@ The error thrown in the component is:
|
|
|
97308
98020
|
break;
|
|
97309
98021
|
case "hooks":
|
|
97310
98022
|
if (typeof overrideHookStateDeletePath === "function") {
|
|
97311
|
-
overrideHookStateDeletePath(fiber, hookID,
|
|
98023
|
+
overrideHookStateDeletePath(fiber, hookID, path32);
|
|
97312
98024
|
}
|
|
97313
98025
|
break;
|
|
97314
98026
|
case "props":
|
|
97315
98027
|
if (instance2 === null) {
|
|
97316
98028
|
if (typeof overridePropsDeletePath === "function") {
|
|
97317
|
-
overridePropsDeletePath(fiber,
|
|
98029
|
+
overridePropsDeletePath(fiber, path32);
|
|
97318
98030
|
}
|
|
97319
98031
|
} else {
|
|
97320
|
-
fiber.pendingProps = copyWithDelete(instance2.props,
|
|
98032
|
+
fiber.pendingProps = copyWithDelete(instance2.props, path32);
|
|
97321
98033
|
instance2.forceUpdate();
|
|
97322
98034
|
}
|
|
97323
98035
|
break;
|
|
97324
98036
|
case "state":
|
|
97325
|
-
deletePathInObject(instance2.state,
|
|
98037
|
+
deletePathInObject(instance2.state, path32);
|
|
97326
98038
|
instance2.forceUpdate();
|
|
97327
98039
|
break;
|
|
97328
98040
|
}
|
|
@@ -97377,7 +98089,7 @@ The error thrown in the component is:
|
|
|
97377
98089
|
}
|
|
97378
98090
|
}
|
|
97379
98091
|
}
|
|
97380
|
-
function overrideValueAtPath(type, id, hookID,
|
|
98092
|
+
function overrideValueAtPath(type, id, hookID, path32, value) {
|
|
97381
98093
|
var devtoolsInstance = idToDevToolsInstanceMap.get(id);
|
|
97382
98094
|
if (devtoolsInstance === undefined) {
|
|
97383
98095
|
console.warn('Could not find DevToolsInstance with id "'.concat(id, '"'));
|
|
@@ -97391,13 +98103,13 @@ The error thrown in the component is:
|
|
|
97391
98103
|
var instance2 = fiber.stateNode;
|
|
97392
98104
|
switch (type) {
|
|
97393
98105
|
case "context":
|
|
97394
|
-
|
|
98106
|
+
path32 = path32.slice(1);
|
|
97395
98107
|
switch (fiber.tag) {
|
|
97396
98108
|
case ClassComponent:
|
|
97397
|
-
if (
|
|
98109
|
+
if (path32.length === 0) {
|
|
97398
98110
|
instance2.context = value;
|
|
97399
98111
|
} else {
|
|
97400
|
-
utils_setInObject(instance2.context,
|
|
98112
|
+
utils_setInObject(instance2.context, path32, value);
|
|
97401
98113
|
}
|
|
97402
98114
|
instance2.forceUpdate();
|
|
97403
98115
|
break;
|
|
@@ -97407,18 +98119,18 @@ The error thrown in the component is:
|
|
|
97407
98119
|
break;
|
|
97408
98120
|
case "hooks":
|
|
97409
98121
|
if (typeof overrideHookState === "function") {
|
|
97410
|
-
overrideHookState(fiber, hookID,
|
|
98122
|
+
overrideHookState(fiber, hookID, path32, value);
|
|
97411
98123
|
}
|
|
97412
98124
|
break;
|
|
97413
98125
|
case "props":
|
|
97414
98126
|
switch (fiber.tag) {
|
|
97415
98127
|
case ClassComponent:
|
|
97416
|
-
fiber.pendingProps = copyWithSet(instance2.props,
|
|
98128
|
+
fiber.pendingProps = copyWithSet(instance2.props, path32, value);
|
|
97417
98129
|
instance2.forceUpdate();
|
|
97418
98130
|
break;
|
|
97419
98131
|
default:
|
|
97420
98132
|
if (typeof overrideProps === "function") {
|
|
97421
|
-
overrideProps(fiber,
|
|
98133
|
+
overrideProps(fiber, path32, value);
|
|
97422
98134
|
}
|
|
97423
98135
|
break;
|
|
97424
98136
|
}
|
|
@@ -97426,7 +98138,7 @@ The error thrown in the component is:
|
|
|
97426
98138
|
case "state":
|
|
97427
98139
|
switch (fiber.tag) {
|
|
97428
98140
|
case ClassComponent:
|
|
97429
|
-
utils_setInObject(instance2.state,
|
|
98141
|
+
utils_setInObject(instance2.state, path32, value);
|
|
97430
98142
|
instance2.forceUpdate();
|
|
97431
98143
|
break;
|
|
97432
98144
|
}
|
|
@@ -97712,14 +98424,14 @@ The error thrown in the component is:
|
|
|
97712
98424
|
var trackedPathMatchInstance = null;
|
|
97713
98425
|
var trackedPathMatchDepth = -1;
|
|
97714
98426
|
var mightBeOnTrackedPath = false;
|
|
97715
|
-
function setTrackedPath(
|
|
97716
|
-
if (
|
|
98427
|
+
function setTrackedPath(path32) {
|
|
98428
|
+
if (path32 === null) {
|
|
97717
98429
|
trackedPathMatchFiber = null;
|
|
97718
98430
|
trackedPathMatchInstance = null;
|
|
97719
98431
|
trackedPathMatchDepth = -1;
|
|
97720
98432
|
mightBeOnTrackedPath = false;
|
|
97721
98433
|
}
|
|
97722
|
-
trackedPath =
|
|
98434
|
+
trackedPath = path32;
|
|
97723
98435
|
}
|
|
97724
98436
|
function updateTrackedPathStateBeforeMount(fiber, fiberInstance) {
|
|
97725
98437
|
if (trackedPath === null || !mightBeOnTrackedPath) {
|
|
@@ -98483,9 +99195,9 @@ The error thrown in the component is:
|
|
|
98483
99195
|
}
|
|
98484
99196
|
var currentlyInspectedElementID = null;
|
|
98485
99197
|
var currentlyInspectedPaths = {};
|
|
98486
|
-
function mergeInspectedPaths(
|
|
99198
|
+
function mergeInspectedPaths(path32) {
|
|
98487
99199
|
var current = currentlyInspectedPaths;
|
|
98488
|
-
|
|
99200
|
+
path32.forEach(function(key) {
|
|
98489
99201
|
if (!current[key]) {
|
|
98490
99202
|
current[key] = {};
|
|
98491
99203
|
}
|
|
@@ -98493,13 +99205,13 @@ The error thrown in the component is:
|
|
|
98493
99205
|
});
|
|
98494
99206
|
}
|
|
98495
99207
|
function createIsPathAllowed(key) {
|
|
98496
|
-
return function isPathAllowed(
|
|
99208
|
+
return function isPathAllowed(path32) {
|
|
98497
99209
|
var current = currentlyInspectedPaths[key];
|
|
98498
99210
|
if (!current) {
|
|
98499
99211
|
return false;
|
|
98500
99212
|
}
|
|
98501
|
-
for (var i = 0;i <
|
|
98502
|
-
current = current[
|
|
99213
|
+
for (var i = 0;i < path32.length; i++) {
|
|
99214
|
+
current = current[path32[i]];
|
|
98503
99215
|
if (!current) {
|
|
98504
99216
|
return false;
|
|
98505
99217
|
}
|
|
@@ -98549,24 +99261,24 @@ The error thrown in the component is:
|
|
|
98549
99261
|
break;
|
|
98550
99262
|
}
|
|
98551
99263
|
}
|
|
98552
|
-
function storeAsGlobal(id,
|
|
99264
|
+
function storeAsGlobal(id, path32, count) {
|
|
98553
99265
|
var inspectedElement = inspectElementRaw(id);
|
|
98554
99266
|
if (inspectedElement !== null) {
|
|
98555
|
-
var value = utils_getInObject(inspectedElement,
|
|
99267
|
+
var value = utils_getInObject(inspectedElement, path32);
|
|
98556
99268
|
var key = "$reactTemp".concat(count);
|
|
98557
99269
|
window[key] = value;
|
|
98558
99270
|
console.log(key);
|
|
98559
99271
|
console.log(value);
|
|
98560
99272
|
}
|
|
98561
99273
|
}
|
|
98562
|
-
function getSerializedElementValueByPath(id,
|
|
99274
|
+
function getSerializedElementValueByPath(id, path32) {
|
|
98563
99275
|
var inspectedElement = inspectElementRaw(id);
|
|
98564
99276
|
if (inspectedElement !== null) {
|
|
98565
|
-
var valueToCopy = utils_getInObject(inspectedElement,
|
|
99277
|
+
var valueToCopy = utils_getInObject(inspectedElement, path32);
|
|
98566
99278
|
return serializeToString(valueToCopy);
|
|
98567
99279
|
}
|
|
98568
99280
|
}
|
|
98569
|
-
function inspectElement(requestID, id,
|
|
99281
|
+
function inspectElement(requestID, id, path32, forceFullData) {
|
|
98570
99282
|
if (forceFullData || currentlyInspectedElementID !== id) {
|
|
98571
99283
|
currentlyInspectedElementID = id;
|
|
98572
99284
|
currentlyInspectedPaths = {};
|
|
@@ -98579,8 +99291,8 @@ The error thrown in the component is:
|
|
|
98579
99291
|
type: "not-found"
|
|
98580
99292
|
};
|
|
98581
99293
|
}
|
|
98582
|
-
if (
|
|
98583
|
-
mergeInspectedPaths(
|
|
99294
|
+
if (path32 !== null) {
|
|
99295
|
+
mergeInspectedPaths(path32);
|
|
98584
99296
|
}
|
|
98585
99297
|
updateSelectedElement(id);
|
|
98586
99298
|
inspectedElement.context = cleanForBridge(inspectedElement.context, createIsPathAllowed("context"));
|
|
@@ -98783,10 +99495,10 @@ The error thrown in the component is:
|
|
|
98783
99495
|
console.groupEnd();
|
|
98784
99496
|
}
|
|
98785
99497
|
}
|
|
98786
|
-
function getElementAttributeByPath(id,
|
|
99498
|
+
function getElementAttributeByPath(id, path32) {
|
|
98787
99499
|
var inspectedElement = inspectElementRaw(id);
|
|
98788
99500
|
if (inspectedElement !== null) {
|
|
98789
|
-
return utils_getInObject(inspectedElement,
|
|
99501
|
+
return utils_getInObject(inspectedElement, path32);
|
|
98790
99502
|
}
|
|
98791
99503
|
return;
|
|
98792
99504
|
}
|
|
@@ -98803,14 +99515,14 @@ The error thrown in the component is:
|
|
|
98803
99515
|
}
|
|
98804
99516
|
return element.type;
|
|
98805
99517
|
}
|
|
98806
|
-
function deletePath(type, id, hookID,
|
|
99518
|
+
function deletePath(type, id, hookID, path32) {
|
|
98807
99519
|
var internalInstance = idToInternalInstanceMap.get(id);
|
|
98808
99520
|
if (internalInstance != null) {
|
|
98809
99521
|
var publicInstance = internalInstance._instance;
|
|
98810
99522
|
if (publicInstance != null) {
|
|
98811
99523
|
switch (type) {
|
|
98812
99524
|
case "context":
|
|
98813
|
-
deletePathInObject(publicInstance.context,
|
|
99525
|
+
deletePathInObject(publicInstance.context, path32);
|
|
98814
99526
|
forceUpdate(publicInstance);
|
|
98815
99527
|
break;
|
|
98816
99528
|
case "hooks":
|
|
@@ -98818,12 +99530,12 @@ The error thrown in the component is:
|
|
|
98818
99530
|
case "props":
|
|
98819
99531
|
var element = internalInstance._currentElement;
|
|
98820
99532
|
internalInstance._currentElement = legacy_renderer_objectSpread(legacy_renderer_objectSpread({}, element), {}, {
|
|
98821
|
-
props: copyWithDelete(element.props,
|
|
99533
|
+
props: copyWithDelete(element.props, path32)
|
|
98822
99534
|
});
|
|
98823
99535
|
forceUpdate(publicInstance);
|
|
98824
99536
|
break;
|
|
98825
99537
|
case "state":
|
|
98826
|
-
deletePathInObject(publicInstance.state,
|
|
99538
|
+
deletePathInObject(publicInstance.state, path32);
|
|
98827
99539
|
forceUpdate(publicInstance);
|
|
98828
99540
|
break;
|
|
98829
99541
|
}
|
|
@@ -98857,14 +99569,14 @@ The error thrown in the component is:
|
|
|
98857
99569
|
}
|
|
98858
99570
|
}
|
|
98859
99571
|
}
|
|
98860
|
-
function overrideValueAtPath(type, id, hookID,
|
|
99572
|
+
function overrideValueAtPath(type, id, hookID, path32, value) {
|
|
98861
99573
|
var internalInstance = idToInternalInstanceMap.get(id);
|
|
98862
99574
|
if (internalInstance != null) {
|
|
98863
99575
|
var publicInstance = internalInstance._instance;
|
|
98864
99576
|
if (publicInstance != null) {
|
|
98865
99577
|
switch (type) {
|
|
98866
99578
|
case "context":
|
|
98867
|
-
utils_setInObject(publicInstance.context,
|
|
99579
|
+
utils_setInObject(publicInstance.context, path32, value);
|
|
98868
99580
|
forceUpdate(publicInstance);
|
|
98869
99581
|
break;
|
|
98870
99582
|
case "hooks":
|
|
@@ -98872,12 +99584,12 @@ The error thrown in the component is:
|
|
|
98872
99584
|
case "props":
|
|
98873
99585
|
var element = internalInstance._currentElement;
|
|
98874
99586
|
internalInstance._currentElement = legacy_renderer_objectSpread(legacy_renderer_objectSpread({}, element), {}, {
|
|
98875
|
-
props: copyWithSet(element.props,
|
|
99587
|
+
props: copyWithSet(element.props, path32, value)
|
|
98876
99588
|
});
|
|
98877
99589
|
forceUpdate(publicInstance);
|
|
98878
99590
|
break;
|
|
98879
99591
|
case "state":
|
|
98880
|
-
utils_setInObject(publicInstance.state,
|
|
99592
|
+
utils_setInObject(publicInstance.state, path32, value);
|
|
98881
99593
|
forceUpdate(publicInstance);
|
|
98882
99594
|
break;
|
|
98883
99595
|
}
|
|
@@ -98918,7 +99630,7 @@ The error thrown in the component is:
|
|
|
98918
99630
|
return [];
|
|
98919
99631
|
}
|
|
98920
99632
|
function setTraceUpdatesEnabled(enabled) {}
|
|
98921
|
-
function setTrackedPath(
|
|
99633
|
+
function setTrackedPath(path32) {}
|
|
98922
99634
|
function getOwnersList(id) {
|
|
98923
99635
|
return null;
|
|
98924
99636
|
}
|
|
@@ -100948,9 +101660,9 @@ var init_ranking = __esm(() => {
|
|
|
100948
101660
|
});
|
|
100949
101661
|
|
|
100950
101662
|
// src/bakeoff/coordinator.ts
|
|
100951
|
-
import { join as
|
|
101663
|
+
import { join as join99 } from "path";
|
|
100952
101664
|
async function persistBakeoffResult(result2, outputDir) {
|
|
100953
|
-
const filePath =
|
|
101665
|
+
const filePath = join99(outputDir, "bakeoff.json");
|
|
100954
101666
|
await Bun.write(filePath, JSON.stringify(result2, null, 2));
|
|
100955
101667
|
}
|
|
100956
101668
|
async function runBakeoff(options, deps = {}) {
|
|
@@ -101138,7 +101850,7 @@ __export(exports_curator, {
|
|
|
101138
101850
|
});
|
|
101139
101851
|
import { readdirSync as readdirSync9 } from "fs";
|
|
101140
101852
|
import { unlink as unlink4 } from "fs/promises";
|
|
101141
|
-
import { basename as basename18, join as
|
|
101853
|
+
import { basename as basename18, join as join100 } from "path";
|
|
101142
101854
|
function getProjectKey(config2, projectDir) {
|
|
101143
101855
|
return config2.name?.trim() || basename18(projectDir);
|
|
101144
101856
|
}
|
|
@@ -101221,7 +101933,7 @@ async function curatorStatus(options) {
|
|
|
101221
101933
|
const config2 = await _curatorCmdDeps.loadConfig(resolved.projectDir);
|
|
101222
101934
|
const projectKey = getProjectKey(config2, resolved.projectDir);
|
|
101223
101935
|
const outputDir = _curatorCmdDeps.projectOutputDir(projectKey, config2.outputDir);
|
|
101224
|
-
const runsDir =
|
|
101936
|
+
const runsDir = join100(outputDir, "runs");
|
|
101225
101937
|
const runIds = listRunIds(runsDir);
|
|
101226
101938
|
let runId;
|
|
101227
101939
|
if (options.run) {
|
|
@@ -101238,8 +101950,8 @@ async function curatorStatus(options) {
|
|
|
101238
101950
|
runId = runIds[runIds.length - 1];
|
|
101239
101951
|
}
|
|
101240
101952
|
console.log(`Run: ${runId}`);
|
|
101241
|
-
const runDir =
|
|
101242
|
-
const observationsPath =
|
|
101953
|
+
const runDir = join100(runsDir, runId);
|
|
101954
|
+
const observationsPath = join100(runDir, "observations.jsonl");
|
|
101243
101955
|
const observations = await parseObservations(observationsPath);
|
|
101244
101956
|
const counts = new Map;
|
|
101245
101957
|
for (const obs of observations) {
|
|
@@ -101249,7 +101961,7 @@ async function curatorStatus(options) {
|
|
|
101249
101961
|
for (const [kind, count] of counts.entries()) {
|
|
101250
101962
|
console.log(` ${kind}: ${count}`);
|
|
101251
101963
|
}
|
|
101252
|
-
const proposalsPath =
|
|
101964
|
+
const proposalsPath = join100(runDir, "curator-proposals.md");
|
|
101253
101965
|
const proposalText = await _curatorCmdDeps.readFile(proposalsPath).catch(() => null);
|
|
101254
101966
|
if (proposalText !== null) {
|
|
101255
101967
|
console.log("");
|
|
@@ -101263,8 +101975,8 @@ async function curatorCommit(options) {
|
|
|
101263
101975
|
const config2 = await _curatorCmdDeps.loadConfig(resolved.projectDir);
|
|
101264
101976
|
const projectKey = getProjectKey(config2, resolved.projectDir);
|
|
101265
101977
|
const outputDir = _curatorCmdDeps.projectOutputDir(projectKey, config2.outputDir);
|
|
101266
|
-
const runDir =
|
|
101267
|
-
const proposalsPath =
|
|
101978
|
+
const runDir = join100(outputDir, "runs", options.runId);
|
|
101979
|
+
const proposalsPath = join100(runDir, "curator-proposals.md");
|
|
101268
101980
|
const proposalText = await _curatorCmdDeps.readFile(proposalsPath).catch(() => null);
|
|
101269
101981
|
if (proposalText === null) {
|
|
101270
101982
|
console.log(`curator-proposals.md not found for run ${options.runId}.`);
|
|
@@ -101280,7 +101992,7 @@ async function curatorCommit(options) {
|
|
|
101280
101992
|
const dropFileState = new Map;
|
|
101281
101993
|
const skippedDrops = new Set;
|
|
101282
101994
|
for (const drop2 of drops) {
|
|
101283
|
-
const targetPath =
|
|
101995
|
+
const targetPath = join100(resolved.projectDir, drop2.canonicalFile);
|
|
101284
101996
|
if (!dropFileState.has(targetPath)) {
|
|
101285
101997
|
const fileExists2 = await Bun.file(targetPath).exists();
|
|
101286
101998
|
const existing = fileExists2 ? await _curatorCmdDeps.readFile(targetPath).catch(() => "") : "";
|
|
@@ -101314,7 +102026,7 @@ async function curatorCommit(options) {
|
|
|
101314
102026
|
if (skippedDrops.has(drop2)) {
|
|
101315
102027
|
continue;
|
|
101316
102028
|
}
|
|
101317
|
-
const targetPath =
|
|
102029
|
+
const targetPath = join100(resolved.projectDir, drop2.canonicalFile);
|
|
101318
102030
|
const existing = await _curatorCmdDeps.readFile(targetPath).catch(() => "");
|
|
101319
102031
|
const filtered = filterDropContent(existing, drop2.description);
|
|
101320
102032
|
await _curatorCmdDeps.writeFile(targetPath, filtered);
|
|
@@ -101323,7 +102035,7 @@ async function curatorCommit(options) {
|
|
|
101323
102035
|
}
|
|
101324
102036
|
const adds = proposals.filter((p) => p.action === "add" || p.action === "advisory");
|
|
101325
102037
|
for (const add2 of adds) {
|
|
101326
|
-
const targetPath =
|
|
102038
|
+
const targetPath = join100(resolved.projectDir, add2.canonicalFile);
|
|
101327
102039
|
const content = buildAddContent(add2);
|
|
101328
102040
|
await _curatorCmdDeps.appendFile(targetPath, content);
|
|
101329
102041
|
modifiedFiles.add(targetPath);
|
|
@@ -101360,7 +102072,7 @@ async function curatorDryrun(options) {
|
|
|
101360
102072
|
const config2 = await _curatorCmdDeps.loadConfig(resolved.projectDir);
|
|
101361
102073
|
const projectKey = getProjectKey(config2, resolved.projectDir);
|
|
101362
102074
|
const outputDir = _curatorCmdDeps.projectOutputDir(projectKey, config2.outputDir);
|
|
101363
|
-
const runsDir =
|
|
102075
|
+
const runsDir = join100(outputDir, "runs");
|
|
101364
102076
|
const runIds = listRunIds(runsDir);
|
|
101365
102077
|
if (runIds.length === 0) {
|
|
101366
102078
|
console.log("No runs found.");
|
|
@@ -101371,7 +102083,7 @@ async function curatorDryrun(options) {
|
|
|
101371
102083
|
console.log(`Run ${options.run} not found in ${runsDir}.`);
|
|
101372
102084
|
return;
|
|
101373
102085
|
}
|
|
101374
|
-
const observationsPath =
|
|
102086
|
+
const observationsPath = join100(runsDir, runId, "observations.jsonl");
|
|
101375
102087
|
const observations = await parseObservations(observationsPath);
|
|
101376
102088
|
const thresholds = getThresholds(config2);
|
|
101377
102089
|
const proposals = runHeuristics(observations, thresholds);
|
|
@@ -101412,12 +102124,12 @@ async function curatorGc(options) {
|
|
|
101412
102124
|
await _curatorCmdDeps.writeFile(rollupPath, newContent);
|
|
101413
102125
|
const projectKey = getProjectKey(config2, resolved.projectDir);
|
|
101414
102126
|
const outputDir = _curatorCmdDeps.projectOutputDir(projectKey, config2.outputDir);
|
|
101415
|
-
const perRunsDir =
|
|
102127
|
+
const perRunsDir = join100(outputDir, "runs");
|
|
101416
102128
|
for (const runId of uniqueRunIds) {
|
|
101417
102129
|
if (!keepSet.has(runId)) {
|
|
101418
|
-
const runDir =
|
|
101419
|
-
await _curatorCmdDeps.removeFile(
|
|
101420
|
-
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"));
|
|
101421
102133
|
}
|
|
101422
102134
|
}
|
|
101423
102135
|
console.log(`[gc] Pruned rollup to ${keep} most recent runs (was ${uniqueRunIds.length}).`);
|
|
@@ -101462,7 +102174,7 @@ var init_curator2 = __esm(() => {
|
|
|
101462
102174
|
init_source();
|
|
101463
102175
|
import { existsSync as existsSync39, mkdirSync as mkdirSync8 } from "fs";
|
|
101464
102176
|
import { homedir as homedir3 } from "os";
|
|
101465
|
-
import { basename as basename19, join as
|
|
102177
|
+
import { basename as basename19, join as join101 } from "path";
|
|
101466
102178
|
|
|
101467
102179
|
// node_modules/commander/esm.mjs
|
|
101468
102180
|
var import__ = __toESM(require_commander(), 1);
|
|
@@ -101727,7 +102439,8 @@ class DebatePlanStrategy {
|
|
|
101727
102439
|
if (debateResult.outcome !== "failed" && debateResult.output) {
|
|
101728
102440
|
const prd2 = validatePlanOutput(debateResult.output, ctx.options.feature, ctx.branchName);
|
|
101729
102441
|
warnOnDroppedVerbatimAcs(prd2, ctx.specContent, ctx.options.feature);
|
|
101730
|
-
const
|
|
102442
|
+
const scoped2 = backfillOutOfScope(prd2, ctx.specContent, ctx.options.feature);
|
|
102443
|
+
const withProject2 = { ...scoped2, project: ctx.projectName };
|
|
101731
102444
|
return _debatePlanDeps.writeOrRecoverPrd(ctx, withProject2);
|
|
101732
102445
|
}
|
|
101733
102446
|
const prd = await callOp({
|
|
@@ -101825,7 +102538,8 @@ class PipelinePlanStrategy {
|
|
|
101825
102538
|
if (verdict.outcome !== "passed") {
|
|
101826
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 });
|
|
101827
102540
|
}
|
|
101828
|
-
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);
|
|
101829
102543
|
await ctx.deps.writeFile(ctx.outputPath, JSON.stringify(prdToWrite, null, 2));
|
|
101830
102544
|
return ctx.outputPath;
|
|
101831
102545
|
} finally {
|
|
@@ -102227,10 +102941,10 @@ init_setup_write();
|
|
|
102227
102941
|
// src/cli/plugins.ts
|
|
102228
102942
|
init_paths();
|
|
102229
102943
|
init_loader4();
|
|
102230
|
-
import * as
|
|
102944
|
+
import * as path23 from "path";
|
|
102231
102945
|
async function pluginsListCommand(config2, workdir, overrideGlobalPluginsDir) {
|
|
102232
|
-
const globalPluginsDir = overrideGlobalPluginsDir ??
|
|
102233
|
-
const projectPluginsDir =
|
|
102946
|
+
const globalPluginsDir = overrideGlobalPluginsDir ?? path23.join(globalConfigDir(), "plugins");
|
|
102947
|
+
const projectPluginsDir = path23.join(workdir, ".nax", "plugins");
|
|
102234
102948
|
const configPlugins = config2.plugins || [];
|
|
102235
102949
|
const registry3 = await loadPlugins(globalPluginsDir, projectPluginsDir, configPlugins, workdir, config2.disabledPlugins);
|
|
102236
102950
|
const plugins = registry3.plugins;
|
|
@@ -102280,10 +102994,10 @@ function formatSource(type, sourcePath) {
|
|
|
102280
102994
|
return `built-in (${sourcePath})`;
|
|
102281
102995
|
}
|
|
102282
102996
|
if (type === "global") {
|
|
102283
|
-
return `global (${
|
|
102997
|
+
return `global (${path23.basename(sourcePath)})`;
|
|
102284
102998
|
}
|
|
102285
102999
|
if (type === "project") {
|
|
102286
|
-
return `project (${
|
|
103000
|
+
return `project (${path23.basename(sourcePath)})`;
|
|
102287
103001
|
}
|
|
102288
103002
|
return `config (${sourcePath})`;
|
|
102289
103003
|
}
|
|
@@ -102298,7 +103012,7 @@ init_source();
|
|
|
102298
103012
|
init_loader();
|
|
102299
103013
|
init_generator2();
|
|
102300
103014
|
import { existsSync as existsSync24 } from "fs";
|
|
102301
|
-
import { join as
|
|
103015
|
+
import { join as join68 } from "path";
|
|
102302
103016
|
var VALID_AGENTS = ["claude", "codex", "opencode", "cursor", "windsurf", "aider", "gemini"];
|
|
102303
103017
|
async function generateCommand(options) {
|
|
102304
103018
|
const workdir = options.dir ?? process.cwd();
|
|
@@ -102341,7 +103055,7 @@ async function generateCommand(options) {
|
|
|
102341
103055
|
return;
|
|
102342
103056
|
}
|
|
102343
103057
|
if (options.package) {
|
|
102344
|
-
const packageDir =
|
|
103058
|
+
const packageDir = join68(workdir, options.package);
|
|
102345
103059
|
if (dryRun) {
|
|
102346
103060
|
console.log(source_default.yellow("\u26A0 Dry run \u2014 no files will be written"));
|
|
102347
103061
|
}
|
|
@@ -102361,8 +103075,8 @@ async function generateCommand(options) {
|
|
|
102361
103075
|
process.exit(1);
|
|
102362
103076
|
return;
|
|
102363
103077
|
}
|
|
102364
|
-
const contextPath = options.context ?
|
|
102365
|
-
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;
|
|
102366
103080
|
const autoInject = !options.noAutoInject;
|
|
102367
103081
|
if (!existsSync24(contextPath)) {
|
|
102368
103082
|
console.error(source_default.red(`\u2717 Context file not found: ${contextPath}`));
|
|
@@ -102468,7 +103182,7 @@ async function generateCommand(options) {
|
|
|
102468
103182
|
// src/cli/config-display.ts
|
|
102469
103183
|
init_loader();
|
|
102470
103184
|
import { existsSync as existsSync26 } from "fs";
|
|
102471
|
-
import { join as
|
|
103185
|
+
import { join as join70 } from "path";
|
|
102472
103186
|
|
|
102473
103187
|
// src/cli/config-descriptions.ts
|
|
102474
103188
|
var FIELD_DESCRIPTIONS = {
|
|
@@ -102676,10 +103390,10 @@ function deepDiffConfigs(global2, project, currentPath = []) {
|
|
|
102676
103390
|
for (const key of Object.keys(project)) {
|
|
102677
103391
|
const projectValue = project[key];
|
|
102678
103392
|
const globalValue = global2[key];
|
|
102679
|
-
const
|
|
102680
|
-
const pathStr =
|
|
103393
|
+
const path24 = [...currentPath, key];
|
|
103394
|
+
const pathStr = path24.join(".");
|
|
102681
103395
|
if (projectValue !== null && typeof projectValue === "object" && !Array.isArray(projectValue) && globalValue !== null && typeof globalValue === "object" && !Array.isArray(globalValue)) {
|
|
102682
|
-
const nestedDiffs = deepDiffConfigs(globalValue, projectValue,
|
|
103396
|
+
const nestedDiffs = deepDiffConfigs(globalValue, projectValue, path24);
|
|
102683
103397
|
diffs.push(...nestedDiffs);
|
|
102684
103398
|
} else {
|
|
102685
103399
|
if (!deepEqual(projectValue, globalValue)) {
|
|
@@ -102721,12 +103435,12 @@ function deepEqual(a, b) {
|
|
|
102721
103435
|
init_defaults();
|
|
102722
103436
|
init_loader();
|
|
102723
103437
|
import { existsSync as existsSync25 } from "fs";
|
|
102724
|
-
import { join as
|
|
102725
|
-
async function loadConfigFile(
|
|
102726
|
-
if (!existsSync25(
|
|
103438
|
+
import { join as join69 } from "path";
|
|
103439
|
+
async function loadConfigFile(path24) {
|
|
103440
|
+
if (!existsSync25(path24))
|
|
102727
103441
|
return null;
|
|
102728
103442
|
try {
|
|
102729
|
-
return await Bun.file(
|
|
103443
|
+
return await Bun.file(path24).json();
|
|
102730
103444
|
} catch {
|
|
102731
103445
|
return null;
|
|
102732
103446
|
}
|
|
@@ -102743,7 +103457,7 @@ async function loadProjectConfig() {
|
|
|
102743
103457
|
const projectDir = findProjectDir();
|
|
102744
103458
|
if (!projectDir)
|
|
102745
103459
|
return null;
|
|
102746
|
-
const projectPath =
|
|
103460
|
+
const projectPath = join69(projectDir, "config.json");
|
|
102747
103461
|
return await loadConfigFile(projectPath);
|
|
102748
103462
|
}
|
|
102749
103463
|
|
|
@@ -102773,10 +103487,10 @@ async function configCommand(config2, options = {}) {
|
|
|
102773
103487
|
console.log(`${"Field".padEnd(40)}${"Project Value".padEnd(20)}Global Value`);
|
|
102774
103488
|
console.log("\u2500".repeat(80));
|
|
102775
103489
|
for (const diff2 of diffs) {
|
|
102776
|
-
const
|
|
103490
|
+
const path24 = diff2.path.padEnd(40);
|
|
102777
103491
|
const projectVal = formatValueForTable(diff2.projectValue);
|
|
102778
103492
|
const globalVal = formatValueForTable(diff2.globalValue);
|
|
102779
|
-
console.log(`${
|
|
103493
|
+
console.log(`${path24}${projectVal.padEnd(20)}${globalVal}`);
|
|
102780
103494
|
const description = FIELD_DESCRIPTIONS[diff2.path];
|
|
102781
103495
|
if (description) {
|
|
102782
103496
|
console.log(`${"".padEnd(40)}\u21B3 ${description}`);
|
|
@@ -102803,32 +103517,32 @@ async function configCommand(config2, options = {}) {
|
|
|
102803
103517
|
function determineConfigSources() {
|
|
102804
103518
|
const globalPath = globalConfigPath();
|
|
102805
103519
|
const projectDir = findProjectDir();
|
|
102806
|
-
const projectPath = projectDir ?
|
|
103520
|
+
const projectPath = projectDir ? join70(projectDir, "config.json") : null;
|
|
102807
103521
|
return {
|
|
102808
103522
|
global: fileExists(globalPath) ? globalPath : null,
|
|
102809
103523
|
project: projectPath && fileExists(projectPath) ? projectPath : null
|
|
102810
103524
|
};
|
|
102811
103525
|
}
|
|
102812
|
-
function fileExists(
|
|
102813
|
-
return existsSync26(
|
|
103526
|
+
function fileExists(path24) {
|
|
103527
|
+
return existsSync26(path24);
|
|
102814
103528
|
}
|
|
102815
|
-
function displayConfigWithDescriptions(obj,
|
|
103529
|
+
function displayConfigWithDescriptions(obj, path24, sources, indent = 0) {
|
|
102816
103530
|
const indentStr = " ".repeat(indent);
|
|
102817
|
-
const pathStr =
|
|
103531
|
+
const pathStr = path24.join(".");
|
|
102818
103532
|
if (obj === null || obj === undefined || typeof obj !== "object" || Array.isArray(obj)) {
|
|
102819
103533
|
const description = FIELD_DESCRIPTIONS[pathStr];
|
|
102820
103534
|
const value = formatValue(obj);
|
|
102821
103535
|
if (description) {
|
|
102822
103536
|
console.log(`${indentStr}# ${description}`);
|
|
102823
103537
|
}
|
|
102824
|
-
const key =
|
|
103538
|
+
const key = path24[path24.length - 1] || "";
|
|
102825
103539
|
console.log(`${indentStr}${key}: ${value}`);
|
|
102826
103540
|
console.log();
|
|
102827
103541
|
return;
|
|
102828
103542
|
}
|
|
102829
103543
|
const entries = Object.entries(obj);
|
|
102830
103544
|
const objAsRecord = obj;
|
|
102831
|
-
const isPromptsSection =
|
|
103545
|
+
const isPromptsSection = path24.join(".") === "prompts";
|
|
102832
103546
|
if (isPromptsSection && !objAsRecord.overrides) {
|
|
102833
103547
|
const description = FIELD_DESCRIPTIONS["prompts.overrides"];
|
|
102834
103548
|
if (description) {
|
|
@@ -102851,7 +103565,7 @@ function displayConfigWithDescriptions(obj, path23, sources, indent = 0) {
|
|
|
102851
103565
|
}
|
|
102852
103566
|
for (let i = 0;i < entries.length; i++) {
|
|
102853
103567
|
const [key, value] = entries[i];
|
|
102854
|
-
const currentPath = [...
|
|
103568
|
+
const currentPath = [...path24, key];
|
|
102855
103569
|
const currentPathStr = currentPath.join(".");
|
|
102856
103570
|
const description = FIELD_DESCRIPTIONS[currentPathStr];
|
|
102857
103571
|
if (description) {
|
|
@@ -102952,15 +103666,15 @@ init_paths();
|
|
|
102952
103666
|
init_profile();
|
|
102953
103667
|
import { mkdirSync as mkdirSync5 } from "fs";
|
|
102954
103668
|
import { readdirSync as readdirSync5 } from "fs";
|
|
102955
|
-
import { join as
|
|
103669
|
+
import { join as join71 } from "path";
|
|
102956
103670
|
var _profileCLIDeps = {
|
|
102957
103671
|
env: process.env
|
|
102958
103672
|
};
|
|
102959
103673
|
var SENSITIVE_KEY_PATTERN = /key|token|secret|password|credential/i;
|
|
102960
103674
|
var VAR_PATTERN = /\$[A-Za-z_][A-Za-z0-9_]*/;
|
|
102961
103675
|
async function profileListCommand(startDir) {
|
|
102962
|
-
const globalProfilesDir =
|
|
102963
|
-
const projectProfilesDir =
|
|
103676
|
+
const globalProfilesDir = join71(globalConfigDir(), "profiles");
|
|
103677
|
+
const projectProfilesDir = join71(projectConfigDir(startDir), "profiles");
|
|
102964
103678
|
const globalProfiles = scanProfileDir(globalProfilesDir);
|
|
102965
103679
|
const projectProfiles = scanProfileDir(projectProfilesDir);
|
|
102966
103680
|
const activeProfile = await resolveProfileName({}, _profileCLIDeps.env, startDir);
|
|
@@ -103019,7 +103733,7 @@ function maskProfileValues(obj) {
|
|
|
103019
103733
|
return result;
|
|
103020
103734
|
}
|
|
103021
103735
|
async function profileUseCommand(profileName, startDir) {
|
|
103022
|
-
const configPath =
|
|
103736
|
+
const configPath = join71(projectConfigDir(startDir), "config.json");
|
|
103023
103737
|
const configFile = Bun.file(configPath);
|
|
103024
103738
|
let existing = {};
|
|
103025
103739
|
if (await configFile.exists()) {
|
|
@@ -103038,8 +103752,8 @@ async function profileCurrentCommand(startDir) {
|
|
|
103038
103752
|
return resolveProfileName({}, _profileCLIDeps.env, startDir);
|
|
103039
103753
|
}
|
|
103040
103754
|
async function profileCreateCommand(profileName, startDir) {
|
|
103041
|
-
const profilesDir =
|
|
103042
|
-
const profilePath =
|
|
103755
|
+
const profilesDir = join71(projectConfigDir(startDir), "profiles");
|
|
103756
|
+
const profilePath = join71(profilesDir, `${profileName}.json`);
|
|
103043
103757
|
const profileFile = Bun.file(profilePath);
|
|
103044
103758
|
if (await profileFile.exists()) {
|
|
103045
103759
|
throw new Error(`Profile "${profileName}" already exists at ${profilePath}`);
|
|
@@ -103161,22 +103875,22 @@ async function contextInspectCommand(options) {
|
|
|
103161
103875
|
init_canonical_loader();
|
|
103162
103876
|
init_errors();
|
|
103163
103877
|
import { mkdir as mkdir11 } from "fs/promises";
|
|
103164
|
-
import { basename as basename13, join as
|
|
103878
|
+
import { basename as basename13, join as join72 } from "path";
|
|
103165
103879
|
var _rulesCLIDeps = {
|
|
103166
|
-
readFile: async (
|
|
103167
|
-
writeFile: async (
|
|
103168
|
-
await Bun.write(
|
|
103880
|
+
readFile: async (path24) => Bun.file(path24).text(),
|
|
103881
|
+
writeFile: async (path24, content) => {
|
|
103882
|
+
await Bun.write(path24, content);
|
|
103169
103883
|
},
|
|
103170
|
-
fileExists: async (
|
|
103884
|
+
fileExists: async (path24) => Bun.file(path24).exists(),
|
|
103171
103885
|
globInDir: (dir) => {
|
|
103172
103886
|
try {
|
|
103173
|
-
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));
|
|
103174
103888
|
} catch {
|
|
103175
103889
|
return [];
|
|
103176
103890
|
}
|
|
103177
103891
|
},
|
|
103178
|
-
mkdir: async (
|
|
103179
|
-
await mkdir11(
|
|
103892
|
+
mkdir: async (path24) => {
|
|
103893
|
+
await mkdir11(path24, { recursive: true });
|
|
103180
103894
|
},
|
|
103181
103895
|
globCanonicalRuleFiles: (workdir) => {
|
|
103182
103896
|
try {
|
|
@@ -103219,7 +103933,7 @@ ${r.content}`).join(`
|
|
|
103219
103933
|
`);
|
|
103220
103934
|
const shimContent = `${header + body}
|
|
103221
103935
|
`;
|
|
103222
|
-
const shimPath =
|
|
103936
|
+
const shimPath = join72(workdir, shimFileName);
|
|
103223
103937
|
if (options.dryRun) {
|
|
103224
103938
|
console.log(`[dry-run] Would write ${shimPath} (${shimContent.length} bytes)`);
|
|
103225
103939
|
return;
|
|
@@ -103248,14 +103962,14 @@ function neutralizeContent(content) {
|
|
|
103248
103962
|
}
|
|
103249
103963
|
async function collectMigrationSources(workdir) {
|
|
103250
103964
|
const sources = [];
|
|
103251
|
-
const claudeMdPath =
|
|
103965
|
+
const claudeMdPath = join72(workdir, "CLAUDE.md");
|
|
103252
103966
|
if (await _rulesCLIDeps.fileExists(claudeMdPath)) {
|
|
103253
103967
|
const content = await _rulesCLIDeps.readFile(claudeMdPath);
|
|
103254
103968
|
if (content.trim()) {
|
|
103255
103969
|
sources.push({ sourcePath: claudeMdPath, targetFileName: "project-conventions.md", content });
|
|
103256
103970
|
}
|
|
103257
103971
|
}
|
|
103258
|
-
const rulesDir =
|
|
103972
|
+
const rulesDir = join72(workdir, ".claude", "rules");
|
|
103259
103973
|
const ruleFiles = _rulesCLIDeps.globInDir(rulesDir);
|
|
103260
103974
|
for (const filePath of ruleFiles) {
|
|
103261
103975
|
try {
|
|
@@ -103275,7 +103989,7 @@ async function rulesMigrateCommand(options) {
|
|
|
103275
103989
|
console.log("[WARN] No source files found (checked CLAUDE.md and .claude/rules/*.md). Nothing to migrate.");
|
|
103276
103990
|
return;
|
|
103277
103991
|
}
|
|
103278
|
-
const targetDir =
|
|
103992
|
+
const targetDir = join72(workdir, CANONICAL_RULES_DIR);
|
|
103279
103993
|
if (!options.dryRun) {
|
|
103280
103994
|
try {
|
|
103281
103995
|
await _rulesCLIDeps.mkdir(targetDir);
|
|
@@ -103286,7 +104000,7 @@ async function rulesMigrateCommand(options) {
|
|
|
103286
104000
|
let written = 0;
|
|
103287
104001
|
let skipped = 0;
|
|
103288
104002
|
for (const { sourcePath, targetFileName, content } of sources) {
|
|
103289
|
-
const targetPath =
|
|
104003
|
+
const targetPath = join72(targetDir, targetFileName);
|
|
103290
104004
|
if (!force && !options.dryRun && await _rulesCLIDeps.fileExists(targetPath)) {
|
|
103291
104005
|
console.log(`[skip] ${targetFileName} already exists (use --force to overwrite)`);
|
|
103292
104006
|
skipped++;
|
|
@@ -103325,7 +104039,7 @@ function collectCanonicalRuleRoots(workdir) {
|
|
|
103325
104039
|
const packageRel = normalized.slice(0, idx);
|
|
103326
104040
|
if (!packageRel)
|
|
103327
104041
|
continue;
|
|
103328
|
-
roots.add(
|
|
104042
|
+
roots.add(join72(workdir, packageRel));
|
|
103329
104043
|
}
|
|
103330
104044
|
return [...roots].sort();
|
|
103331
104045
|
}
|
|
@@ -103349,8 +104063,8 @@ async function resolveRunProfileOverride(opts) {
|
|
|
103349
104063
|
return cliChain;
|
|
103350
104064
|
if (opts.envProfile)
|
|
103351
104065
|
return;
|
|
103352
|
-
const readJson = opts._readJson ?? (async (
|
|
103353
|
-
const file3 = Bun.file(
|
|
104066
|
+
const readJson = opts._readJson ?? (async (path24) => {
|
|
104067
|
+
const file3 = Bun.file(path24);
|
|
103354
104068
|
if (!await file3.exists())
|
|
103355
104069
|
return;
|
|
103356
104070
|
return file3.json();
|
|
@@ -103373,7 +104087,7 @@ async function resolveRunProfileOverride(opts) {
|
|
|
103373
104087
|
// src/cli/features-resolve.ts
|
|
103374
104088
|
init_config();
|
|
103375
104089
|
import { existsSync as existsSync28, readdirSync as readdirSync6 } from "fs";
|
|
103376
|
-
import { join as
|
|
104090
|
+
import { join as join74, relative as relative16 } from "path";
|
|
103377
104091
|
|
|
103378
104092
|
// src/cli/features-acceptance.ts
|
|
103379
104093
|
init_acceptance2();
|
|
@@ -103381,7 +104095,7 @@ init_config();
|
|
|
103381
104095
|
init_logger2();
|
|
103382
104096
|
init_prd();
|
|
103383
104097
|
import { existsSync as existsSync27 } from "fs";
|
|
103384
|
-
import { join as
|
|
104098
|
+
import { join as join73, relative as relative15 } from "path";
|
|
103385
104099
|
async function resolveFeatureAcceptance(featureName, workdir) {
|
|
103386
104100
|
let enabled = true;
|
|
103387
104101
|
try {
|
|
@@ -103389,13 +104103,13 @@ async function resolveFeatureAcceptance(featureName, workdir) {
|
|
|
103389
104103
|
if (!naxDir) {
|
|
103390
104104
|
return { status: "no-prd", enabled, groups: [] };
|
|
103391
104105
|
}
|
|
103392
|
-
const repoRoot =
|
|
104106
|
+
const repoRoot = join73(naxDir, "..");
|
|
103393
104107
|
const config2 = await loadConfig(workdir);
|
|
103394
104108
|
enabled = config2.acceptance?.enabled ?? true;
|
|
103395
104109
|
if (!enabled) {
|
|
103396
104110
|
return { status: "disabled", enabled: false, groups: [] };
|
|
103397
104111
|
}
|
|
103398
|
-
const prdPath =
|
|
104112
|
+
const prdPath = join73(naxDir, "features", featureName, "prd.json");
|
|
103399
104113
|
if (!existsSync27(prdPath)) {
|
|
103400
104114
|
return { status: "no-prd", enabled, groups: [] };
|
|
103401
104115
|
}
|
|
@@ -103438,10 +104152,10 @@ async function isNonEmptyFile(absolutePath) {
|
|
|
103438
104152
|
}
|
|
103439
104153
|
async function searchSpecSource(naxDir, repoRoot, name) {
|
|
103440
104154
|
const candidates = [
|
|
103441
|
-
{ abs:
|
|
103442
|
-
{ abs:
|
|
104155
|
+
{ abs: join74(naxDir, "features", name, "spec.md"), kind: "markdown" },
|
|
104156
|
+
{ abs: join74(naxDir, "specs", `${name}.md`), kind: "markdown" }
|
|
103443
104157
|
];
|
|
103444
|
-
const docsSpecExact =
|
|
104158
|
+
const docsSpecExact = join74(repoRoot, "docs", "specs", `SPEC-${name}.md`);
|
|
103445
104159
|
candidates.push({ abs: docsSpecExact, kind: "markdown" });
|
|
103446
104160
|
const checked = candidates.map((c) => relative16(repoRoot, c.abs));
|
|
103447
104161
|
for (const { abs, kind } of candidates.slice(0, 2)) {
|
|
@@ -103455,11 +104169,11 @@ async function searchSpecSource(naxDir, repoRoot, name) {
|
|
|
103455
104169
|
if (await isNonEmptyFile(docsSpecExact)) {
|
|
103456
104170
|
return { source: { kind: "markdown", path: relative16(repoRoot, docsSpecExact) }, checked };
|
|
103457
104171
|
}
|
|
103458
|
-
const docsSpecsDir =
|
|
104172
|
+
const docsSpecsDir = join74(repoRoot, "docs", "specs");
|
|
103459
104173
|
if (existsSync28(docsSpecsDir)) {
|
|
103460
104174
|
const glob = new Bun.Glob(`*${name}*.md`);
|
|
103461
104175
|
for (const match of glob.scanSync({ cwd: docsSpecsDir, absolute: false })) {
|
|
103462
|
-
const abs =
|
|
104176
|
+
const abs = join74(docsSpecsDir, match);
|
|
103463
104177
|
if (await isNonEmptyFile(abs)) {
|
|
103464
104178
|
const relPath = relative16(repoRoot, abs);
|
|
103465
104179
|
if (!checked.includes(relPath))
|
|
@@ -103468,7 +104182,7 @@ async function searchSpecSource(naxDir, repoRoot, name) {
|
|
|
103468
104182
|
}
|
|
103469
104183
|
}
|
|
103470
104184
|
}
|
|
103471
|
-
const prdAbs =
|
|
104185
|
+
const prdAbs = join74(naxDir, "features", name, "prd.json");
|
|
103472
104186
|
const prdRel = relative16(repoRoot, prdAbs);
|
|
103473
104187
|
if (!checked.includes(prdRel))
|
|
103474
104188
|
checked.push(prdRel);
|
|
@@ -103478,14 +104192,14 @@ async function searchSpecSource(naxDir, repoRoot, name) {
|
|
|
103478
104192
|
return { source: null, checked };
|
|
103479
104193
|
}
|
|
103480
104194
|
function discoverCandidates(naxDir) {
|
|
103481
|
-
const featuresDir =
|
|
104195
|
+
const featuresDir = join74(naxDir, "features");
|
|
103482
104196
|
if (!existsSync28(featuresDir))
|
|
103483
104197
|
return [];
|
|
103484
104198
|
return readdirSync6(featuresDir, { withFileTypes: true }).filter((e) => {
|
|
103485
104199
|
if (!e.isDirectory())
|
|
103486
104200
|
return false;
|
|
103487
|
-
const dir =
|
|
103488
|
-
return existsSync28(
|
|
104201
|
+
const dir = join74(featuresDir, e.name);
|
|
104202
|
+
return existsSync28(join74(dir, "prd.json")) || existsSync28(join74(dir, "spec.md"));
|
|
103489
104203
|
}).map((e) => e.name).sort();
|
|
103490
104204
|
}
|
|
103491
104205
|
async function resolveFeatureSpec(name, workdir) {
|
|
@@ -103496,9 +104210,9 @@ async function resolveFeatureSpec(name, workdir) {
|
|
|
103496
104210
|
message: `not a nax repo: no .nax/config.json found from ${workdir}`
|
|
103497
104211
|
};
|
|
103498
104212
|
}
|
|
103499
|
-
const repoRoot =
|
|
104213
|
+
const repoRoot = join74(naxDir, "..");
|
|
103500
104214
|
if (name !== undefined && (name.startsWith("./") || name.startsWith("/") || name.endsWith(".md"))) {
|
|
103501
|
-
const abs = name.startsWith("/") ? name :
|
|
104215
|
+
const abs = name.startsWith("/") ? name : join74(workdir, name);
|
|
103502
104216
|
if (!existsSync28(abs)) {
|
|
103503
104217
|
return {
|
|
103504
104218
|
status: "missing",
|
|
@@ -103537,7 +104251,7 @@ async function resolveFeatureSpec(name, workdir) {
|
|
|
103537
104251
|
message: `resolved spec: ${source2.path}`
|
|
103538
104252
|
};
|
|
103539
104253
|
}
|
|
103540
|
-
const featureDir =
|
|
104254
|
+
const featureDir = join74(naxDir, "features", name);
|
|
103541
104255
|
if (existsSync28(featureDir)) {
|
|
103542
104256
|
return {
|
|
103543
104257
|
status: "missing",
|
|
@@ -103599,14 +104313,14 @@ init_runtime();
|
|
|
103599
104313
|
init_json_file();
|
|
103600
104314
|
init_routing();
|
|
103601
104315
|
import { mkdirSync as mkdirSync6 } from "fs";
|
|
103602
|
-
import { basename as basename14, join as
|
|
104316
|
+
import { basename as basename14, join as join75 } from "path";
|
|
103603
104317
|
var _routingCalibrateDeps = {
|
|
103604
104318
|
loadRunMetrics: (outputDir) => loadRunMetrics(outputDir),
|
|
103605
104319
|
readConfig: (workdir) => loadConfig(workdir),
|
|
103606
104320
|
writeConfig: async (workdir, config2) => {
|
|
103607
104321
|
const dir = projectInputDir(workdir);
|
|
103608
104322
|
mkdirSync6(dir, { recursive: true });
|
|
103609
|
-
const filePath =
|
|
104323
|
+
const filePath = join75(dir, "config.json");
|
|
103610
104324
|
await saveJsonFile(filePath, config2, "routing-calibrate");
|
|
103611
104325
|
},
|
|
103612
104326
|
stdout: (msg) => {
|
|
@@ -103733,7 +104447,7 @@ init_logger2();
|
|
|
103733
104447
|
init_detect2();
|
|
103734
104448
|
init_workspace();
|
|
103735
104449
|
init_common();
|
|
103736
|
-
import { join as
|
|
104450
|
+
import { join as join76 } from "path";
|
|
103737
104451
|
function resolveEffective(detected, configPatterns) {
|
|
103738
104452
|
if (configPatterns !== undefined)
|
|
103739
104453
|
return "config";
|
|
@@ -103741,14 +104455,14 @@ function resolveEffective(detected, configPatterns) {
|
|
|
103741
104455
|
return "detected";
|
|
103742
104456
|
return "none";
|
|
103743
104457
|
}
|
|
103744
|
-
async function loadRawConfig(
|
|
103745
|
-
const f = Bun.file(
|
|
104458
|
+
async function loadRawConfig(path24) {
|
|
104459
|
+
const f = Bun.file(path24);
|
|
103746
104460
|
if (!await f.exists())
|
|
103747
104461
|
return {};
|
|
103748
104462
|
return JSON.parse(await f.text());
|
|
103749
104463
|
}
|
|
103750
|
-
async function writeRawConfig(
|
|
103751
|
-
await Bun.write(
|
|
104464
|
+
async function writeRawConfig(path24, data) {
|
|
104465
|
+
await Bun.write(path24, `${JSON.stringify(data, null, 2)}
|
|
103752
104466
|
`);
|
|
103753
104467
|
}
|
|
103754
104468
|
function deepSet(obj, keyPath, value) {
|
|
@@ -103818,7 +104532,7 @@ async function detectCommand(options) {
|
|
|
103818
104532
|
const rootDetected = detectionMap[""] ?? { patterns: [], confidence: "empty", sources: [] };
|
|
103819
104533
|
const pkgEntries = await Promise.all(packageDirs.map(async (dir) => {
|
|
103820
104534
|
const det = detectionMap[dir] ?? { patterns: [], confidence: "empty", sources: [] };
|
|
103821
|
-
const pkgConfigPath =
|
|
104535
|
+
const pkgConfigPath = join76(workdir, ".nax", "mono", dir, "config.json");
|
|
103822
104536
|
const pkgRaw = await loadRawConfig(pkgConfigPath);
|
|
103823
104537
|
const pkgPatterns = deepGet(pkgRaw, TEST_PATTERNS_KEY);
|
|
103824
104538
|
const effective = Array.isArray(pkgPatterns) ? pkgPatterns : undefined;
|
|
@@ -103872,13 +104586,13 @@ async function detectCommand(options) {
|
|
|
103872
104586
|
if (rootDetected.confidence === "empty") {
|
|
103873
104587
|
console.log(source_default.yellow(" root: skipped (empty detection)"));
|
|
103874
104588
|
} else {
|
|
103875
|
-
const rootConfigPath =
|
|
104589
|
+
const rootConfigPath = join76(workdir, ".nax", "config.json");
|
|
103876
104590
|
try {
|
|
103877
104591
|
const status = await applyToConfig(rootConfigPath, rootDetected.patterns, options.force ?? false);
|
|
103878
104592
|
if (status === "skipped") {
|
|
103879
104593
|
console.log(source_default.dim(" root: skipped (testFilePatterns already set; use --force to overwrite)"));
|
|
103880
104594
|
} else {
|
|
103881
|
-
console.log(source_default.green(` root: ${status} \u2192 ${
|
|
104595
|
+
console.log(source_default.green(` root: ${status} \u2192 ${join76(".nax", "config.json")}`));
|
|
103882
104596
|
}
|
|
103883
104597
|
} catch (err) {
|
|
103884
104598
|
console.error(source_default.red(` root: write failed \u2014 ${err.message}`));
|
|
@@ -103891,13 +104605,13 @@ async function detectCommand(options) {
|
|
|
103891
104605
|
console.log(source_default.dim(` ${dir}: skipped (empty detection)`));
|
|
103892
104606
|
continue;
|
|
103893
104607
|
}
|
|
103894
|
-
const pkgConfigPath =
|
|
104608
|
+
const pkgConfigPath = join76(workdir, ".nax", "mono", dir, "config.json");
|
|
103895
104609
|
try {
|
|
103896
104610
|
const status = await applyToConfig(pkgConfigPath, det.patterns, options.force ?? false);
|
|
103897
104611
|
if (status === "skipped") {
|
|
103898
104612
|
console.log(source_default.dim(` ${dir}: skipped (already set)`));
|
|
103899
104613
|
} else {
|
|
103900
|
-
console.log(source_default.green(` ${dir}: ${status} \u2192 ${
|
|
104614
|
+
console.log(source_default.green(` ${dir}: ${status} \u2192 ${join76(".nax", "mono", dir, "config.json")}`));
|
|
103901
104615
|
}
|
|
103902
104616
|
} catch (err) {
|
|
103903
104617
|
console.error(source_default.red(` ${dir}: write failed \u2014 ${err.message}`));
|
|
@@ -103915,19 +104629,19 @@ async function detectCommand(options) {
|
|
|
103915
104629
|
// src/commands/logs.ts
|
|
103916
104630
|
init_common();
|
|
103917
104631
|
import { existsSync as existsSync30 } from "fs";
|
|
103918
|
-
import { join as
|
|
104632
|
+
import { join as join79 } from "path";
|
|
103919
104633
|
|
|
103920
104634
|
// src/commands/logs-formatter.ts
|
|
103921
104635
|
init_source();
|
|
103922
104636
|
init_formatter();
|
|
103923
104637
|
import { readdirSync as readdirSync8 } from "fs";
|
|
103924
|
-
import { join as
|
|
104638
|
+
import { join as join78 } from "path";
|
|
103925
104639
|
|
|
103926
104640
|
// src/commands/logs-reader.ts
|
|
103927
104641
|
init_paths3();
|
|
103928
104642
|
import { existsSync as existsSync29, readdirSync as readdirSync7 } from "fs";
|
|
103929
104643
|
import { readdir as readdir3 } from "fs/promises";
|
|
103930
|
-
import { join as
|
|
104644
|
+
import { join as join77 } from "path";
|
|
103931
104645
|
var _logsReaderDeps = {
|
|
103932
104646
|
getRunsDir
|
|
103933
104647
|
};
|
|
@@ -103941,7 +104655,7 @@ async function resolveRunFileFromRegistry(runId) {
|
|
|
103941
104655
|
}
|
|
103942
104656
|
let matched = null;
|
|
103943
104657
|
for (const entry of entries) {
|
|
103944
|
-
const metaPath =
|
|
104658
|
+
const metaPath = join77(runsDir, entry, "meta.json");
|
|
103945
104659
|
try {
|
|
103946
104660
|
const meta3 = await Bun.file(metaPath).json();
|
|
103947
104661
|
if (meta3.runId === runId || meta3.runId.startsWith(runId)) {
|
|
@@ -103963,14 +104677,14 @@ async function resolveRunFileFromRegistry(runId) {
|
|
|
103963
104677
|
return null;
|
|
103964
104678
|
}
|
|
103965
104679
|
const specificFile = files.find((f) => f === `${matched.runId}.jsonl`);
|
|
103966
|
-
return
|
|
104680
|
+
return join77(matched.eventsDir, specificFile ?? files[0]);
|
|
103967
104681
|
}
|
|
103968
104682
|
async function selectRunFile(runsDir) {
|
|
103969
104683
|
const files = readdirSync7(runsDir).filter((f) => f.endsWith(".jsonl") && f !== "latest.jsonl").sort().reverse();
|
|
103970
104684
|
if (files.length === 0) {
|
|
103971
104685
|
return null;
|
|
103972
104686
|
}
|
|
103973
|
-
return
|
|
104687
|
+
return join77(runsDir, files[0]);
|
|
103974
104688
|
}
|
|
103975
104689
|
async function extractRunSummary(filePath) {
|
|
103976
104690
|
const file3 = Bun.file(filePath);
|
|
@@ -104056,7 +104770,7 @@ Runs:
|
|
|
104056
104770
|
console.log(source_default.gray(" Timestamp Stories Duration Cost Status"));
|
|
104057
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"));
|
|
104058
104772
|
for (const file3 of files) {
|
|
104059
|
-
const filePath =
|
|
104773
|
+
const filePath = join78(runsDir, file3);
|
|
104060
104774
|
const summary = await extractRunSummary(filePath);
|
|
104061
104775
|
const timestamp = file3.replace(".jsonl", "");
|
|
104062
104776
|
const stories = summary ? `${summary.passed}/${summary.total}` : "?/?";
|
|
@@ -104170,7 +104884,7 @@ async function logsCommand(options) {
|
|
|
104170
104884
|
return;
|
|
104171
104885
|
}
|
|
104172
104886
|
const resolved = resolveProject2({ dir: options.dir });
|
|
104173
|
-
const naxDir =
|
|
104887
|
+
const naxDir = join79(resolved.projectDir, ".nax");
|
|
104174
104888
|
const configPath = resolved.configPath;
|
|
104175
104889
|
const configFile = Bun.file(configPath);
|
|
104176
104890
|
const config2 = await configFile.json();
|
|
@@ -104178,8 +104892,8 @@ async function logsCommand(options) {
|
|
|
104178
104892
|
if (!featureName) {
|
|
104179
104893
|
throw new Error("No feature specified in config.json");
|
|
104180
104894
|
}
|
|
104181
|
-
const featureDir =
|
|
104182
|
-
const runsDir =
|
|
104895
|
+
const featureDir = join79(naxDir, "features", featureName);
|
|
104896
|
+
const runsDir = join79(featureDir, "runs");
|
|
104183
104897
|
if (!existsSync30(runsDir)) {
|
|
104184
104898
|
throw new Error(`No runs directory found for feature: ${featureName}`);
|
|
104185
104899
|
}
|
|
@@ -104205,7 +104919,7 @@ init_prd();
|
|
|
104205
104919
|
init_precheck();
|
|
104206
104920
|
init_common();
|
|
104207
104921
|
import { existsSync as existsSync31 } from "fs";
|
|
104208
|
-
import { join as
|
|
104922
|
+
import { join as join80 } from "path";
|
|
104209
104923
|
async function precheckCommand(options) {
|
|
104210
104924
|
const resolved = resolveProject2({
|
|
104211
104925
|
dir: options.dir,
|
|
@@ -104227,9 +104941,9 @@ async function precheckCommand(options) {
|
|
|
104227
104941
|
process.exit(1);
|
|
104228
104942
|
}
|
|
104229
104943
|
}
|
|
104230
|
-
const naxDir =
|
|
104231
|
-
const featureDir =
|
|
104232
|
-
const prdPath =
|
|
104944
|
+
const naxDir = join80(resolved.projectDir, ".nax");
|
|
104945
|
+
const featureDir = join80(naxDir, "features", featureName);
|
|
104946
|
+
const prdPath = join80(featureDir, "prd.json");
|
|
104233
104947
|
if (!existsSync31(featureDir)) {
|
|
104234
104948
|
console.error(source_default.red(`Feature not found: ${featureName}`));
|
|
104235
104949
|
process.exit(1);
|
|
@@ -104251,13 +104965,13 @@ async function precheckCommand(options) {
|
|
|
104251
104965
|
// src/commands/replay.ts
|
|
104252
104966
|
init_errors();
|
|
104253
104967
|
import { existsSync as existsSync32 } from "fs";
|
|
104254
|
-
import { dirname as
|
|
104968
|
+
import { dirname as dirname13 } from "path";
|
|
104255
104969
|
|
|
104256
104970
|
// src/replay/discovery.ts
|
|
104257
104971
|
init_errors();
|
|
104258
104972
|
init_paths3();
|
|
104259
104973
|
import { readdir as readdir4 } from "fs/promises";
|
|
104260
|
-
import { join as
|
|
104974
|
+
import { join as join81 } from "path";
|
|
104261
104975
|
var _discoveryDeps = {
|
|
104262
104976
|
getRunsDir
|
|
104263
104977
|
};
|
|
@@ -104271,7 +104985,7 @@ async function loadMetas(runsDir) {
|
|
|
104271
104985
|
const metas = [];
|
|
104272
104986
|
for (const entry of entries) {
|
|
104273
104987
|
try {
|
|
104274
|
-
const meta3 = await Bun.file(
|
|
104988
|
+
const meta3 = await Bun.file(join81(runsDir, entry, "meta.json")).json();
|
|
104275
104989
|
metas.push(meta3);
|
|
104276
104990
|
} catch {}
|
|
104277
104991
|
}
|
|
@@ -104288,7 +105002,7 @@ async function discoverRun(query, depsArg = _discoveryDeps) {
|
|
|
104288
105002
|
throw new NaxError("No runs registered", "RUN_NOT_FOUND", { runsDir });
|
|
104289
105003
|
}
|
|
104290
105004
|
const latest = metas.reduce((acc, m) => m.runId > acc.runId ? m : acc);
|
|
104291
|
-
return { meta: latest, jsonlPath:
|
|
105005
|
+
return { meta: latest, jsonlPath: join81(latest.eventsDir, `${latest.runId}.jsonl`) };
|
|
104292
105006
|
}
|
|
104293
105007
|
const matched = metas.filter((m) => matches(m, query));
|
|
104294
105008
|
if (matched.length === 0) {
|
|
@@ -104305,7 +105019,7 @@ async function discoverRun(query, depsArg = _discoveryDeps) {
|
|
|
104305
105019
|
});
|
|
104306
105020
|
}
|
|
104307
105021
|
const meta3 = matched[0];
|
|
104308
|
-
return { meta: meta3, jsonlPath:
|
|
105022
|
+
return { meta: meta3, jsonlPath: join81(meta3.eventsDir, `${meta3.runId}.jsonl`) };
|
|
104309
105023
|
}
|
|
104310
105024
|
|
|
104311
105025
|
// src/replay/json.ts
|
|
@@ -104536,10 +105250,10 @@ function renderReport(timeline, options = {}) {
|
|
|
104536
105250
|
}
|
|
104537
105251
|
|
|
104538
105252
|
// src/commands/replay.ts
|
|
104539
|
-
async function readJsonlLenient(
|
|
104540
|
-
if (!existsSync32(
|
|
105253
|
+
async function readJsonlLenient(path24) {
|
|
105254
|
+
if (!existsSync32(path24))
|
|
104541
105255
|
return [];
|
|
104542
|
-
const content = await Bun.file(
|
|
105256
|
+
const content = await Bun.file(path24).text();
|
|
104543
105257
|
const lines = content.split(`
|
|
104544
105258
|
`);
|
|
104545
105259
|
const entries = [];
|
|
@@ -104553,18 +105267,18 @@ async function readJsonlLenient(path23) {
|
|
|
104553
105267
|
}
|
|
104554
105268
|
return entries;
|
|
104555
105269
|
}
|
|
104556
|
-
async function readJsonOrUndefined(
|
|
104557
|
-
if (!existsSync32(
|
|
105270
|
+
async function readJsonOrUndefined(path24) {
|
|
105271
|
+
if (!existsSync32(path24))
|
|
104558
105272
|
return;
|
|
104559
105273
|
try {
|
|
104560
|
-
return await Bun.file(
|
|
105274
|
+
return await Bun.file(path24).json();
|
|
104561
105275
|
} catch {
|
|
104562
105276
|
return;
|
|
104563
105277
|
}
|
|
104564
105278
|
}
|
|
104565
105279
|
async function readMetricsFromProject(meta3) {
|
|
104566
105280
|
const { loadRunMetrics: loadRunMetrics2 } = await Promise.resolve().then(() => (init_tracker(), exports_tracker));
|
|
104567
|
-
const outputDir =
|
|
105281
|
+
const outputDir = dirname13(dirname13(dirname13(meta3.eventsDir)));
|
|
104568
105282
|
const all = await loadRunMetrics2(outputDir);
|
|
104569
105283
|
return all.find((m) => m.runId === meta3.runId);
|
|
104570
105284
|
}
|
|
@@ -104643,11 +105357,11 @@ init_errors();
|
|
|
104643
105357
|
init_checkpoint();
|
|
104644
105358
|
init_runtime();
|
|
104645
105359
|
import { existsSync as existsSync37 } from "fs";
|
|
104646
|
-
import { basename as basename17, join as
|
|
105360
|
+
import { basename as basename17, join as join95 } from "path";
|
|
104647
105361
|
async function defaultCheckpointExists(featureDir) {
|
|
104648
105362
|
if (!featureDir || !existsSync37(featureDir))
|
|
104649
105363
|
return false;
|
|
104650
|
-
return existsSync37(
|
|
105364
|
+
return existsSync37(join95(featureDir, "checkpoint.jsonl"));
|
|
104651
105365
|
}
|
|
104652
105366
|
async function defaultLoadCheckpoints(featureDir) {
|
|
104653
105367
|
return loadCheckpoints(featureDir);
|
|
@@ -104707,12 +105421,12 @@ function registerResumeCommand(program2) {
|
|
|
104707
105421
|
`);
|
|
104708
105422
|
process.exit(1);
|
|
104709
105423
|
}
|
|
104710
|
-
const featureDir =
|
|
105424
|
+
const featureDir = join95(naxDir, "features", cmdOpts.feature);
|
|
104711
105425
|
const deps = {
|
|
104712
105426
|
..._resumeCmdDeps,
|
|
104713
105427
|
runInvocation: async (feature, opts) => {
|
|
104714
105428
|
const config2 = await loadConfig2(naxDir ?? undefined);
|
|
104715
|
-
const prdPath =
|
|
105429
|
+
const prdPath = join95(opts.featureDir ?? "", "prd.json");
|
|
104716
105430
|
if (!existsSync38(prdPath)) {
|
|
104717
105431
|
process.stderr.write(`Feature "${feature}" not found or missing prd.json
|
|
104718
105432
|
`);
|
|
@@ -104724,7 +105438,7 @@ function registerResumeCommand(program2) {
|
|
|
104724
105438
|
applyResumeModeDeps2(opts.featureDir ?? "", "auto");
|
|
104725
105439
|
const projectKey = config2.name?.trim() || basename17(cmdOpts.dir);
|
|
104726
105440
|
const outputDir = projectOutputDir(projectKey, config2.outputDir);
|
|
104727
|
-
const statusFilePath =
|
|
105441
|
+
const statusFilePath = join95(outputDir, "status.json");
|
|
104728
105442
|
const result = await run2({
|
|
104729
105443
|
prdPath,
|
|
104730
105444
|
workdir: cmdOpts.dir,
|
|
@@ -104759,7 +105473,7 @@ function registerResumeCommand(program2) {
|
|
|
104759
105473
|
init_source();
|
|
104760
105474
|
init_paths3();
|
|
104761
105475
|
import { readdir as readdir6 } from "fs/promises";
|
|
104762
|
-
import { join as
|
|
105476
|
+
import { join as join96 } from "path";
|
|
104763
105477
|
var DEFAULT_LIMIT = 20;
|
|
104764
105478
|
var _runsCmdDeps = {
|
|
104765
105479
|
getRunsDir
|
|
@@ -104816,7 +105530,7 @@ async function runsCommand(options = {}) {
|
|
|
104816
105530
|
}
|
|
104817
105531
|
const rows = [];
|
|
104818
105532
|
for (const entry of entries) {
|
|
104819
|
-
const metaPath =
|
|
105533
|
+
const metaPath = join96(runsDir, entry, "meta.json");
|
|
104820
105534
|
let meta3;
|
|
104821
105535
|
try {
|
|
104822
105536
|
meta3 = await Bun.file(metaPath).json();
|
|
@@ -104893,7 +105607,7 @@ async function runsCommand(options = {}) {
|
|
|
104893
105607
|
|
|
104894
105608
|
// src/commands/unlock.ts
|
|
104895
105609
|
init_source();
|
|
104896
|
-
import { join as
|
|
105610
|
+
import { join as join97 } from "path";
|
|
104897
105611
|
function isProcessAlive2(pid) {
|
|
104898
105612
|
try {
|
|
104899
105613
|
process.kill(pid, 0);
|
|
@@ -104908,7 +105622,7 @@ function formatLockAge(ageMs) {
|
|
|
104908
105622
|
}
|
|
104909
105623
|
async function unlockCommand(options) {
|
|
104910
105624
|
const workdir = options.dir ?? process.cwd();
|
|
104911
|
-
const lockPath =
|
|
105625
|
+
const lockPath = join97(workdir, "nax.lock");
|
|
104912
105626
|
const lockFile = Bun.file(lockPath);
|
|
104913
105627
|
const exists = await lockFile.exists();
|
|
104914
105628
|
if (!exists) {
|
|
@@ -109853,8 +110567,8 @@ function Text({ color, backgroundColor, dimColor = false, bold = false, italic =
|
|
|
109853
110567
|
}
|
|
109854
110568
|
|
|
109855
110569
|
// node_modules/ink/build/components/ErrorOverview.js
|
|
109856
|
-
var cleanupPath = (
|
|
109857
|
-
return
|
|
110570
|
+
var cleanupPath = (path32) => {
|
|
110571
|
+
return path32?.replace(`file://${cwd()}/`, "");
|
|
109858
110572
|
};
|
|
109859
110573
|
var stackUtils = new import_stack_utils.default({
|
|
109860
110574
|
cwd: cwd(),
|
|
@@ -110558,8 +111272,8 @@ class Ink {
|
|
|
110558
111272
|
}
|
|
110559
111273
|
}
|
|
110560
111274
|
async waitUntilExit() {
|
|
110561
|
-
this.exitPromise ||= new Promise((
|
|
110562
|
-
this.resolveExitPromise =
|
|
111275
|
+
this.exitPromise ||= new Promise((resolve19, reject2) => {
|
|
111276
|
+
this.resolveExitPromise = resolve19;
|
|
110563
111277
|
this.rejectExitPromise = reject2;
|
|
110564
111278
|
});
|
|
110565
111279
|
if (!this.beforeExitHandler) {
|
|
@@ -112813,7 +113527,7 @@ async function promptForConfirmation(question) {
|
|
|
112813
113527
|
if (!process.stdin.isTTY) {
|
|
112814
113528
|
return true;
|
|
112815
113529
|
}
|
|
112816
|
-
return new Promise((
|
|
113530
|
+
return new Promise((resolve19) => {
|
|
112817
113531
|
process.stdout.write(source_default.bold(`${question} [Y/n] `));
|
|
112818
113532
|
process.stdin.setRawMode(true);
|
|
112819
113533
|
process.stdin.resume();
|
|
@@ -112826,9 +113540,9 @@ async function promptForConfirmation(question) {
|
|
|
112826
113540
|
process.stdout.write(`
|
|
112827
113541
|
`);
|
|
112828
113542
|
if (answer === "n") {
|
|
112829
|
-
|
|
113543
|
+
resolve19(false);
|
|
112830
113544
|
} else {
|
|
112831
|
-
|
|
113545
|
+
resolve19(true);
|
|
112832
113546
|
}
|
|
112833
113547
|
};
|
|
112834
113548
|
process.stdin.on("data", handler);
|
|
@@ -112857,7 +113571,7 @@ Next: nax generate --package ${options.package}`));
|
|
|
112857
113571
|
}
|
|
112858
113572
|
return;
|
|
112859
113573
|
}
|
|
112860
|
-
const naxDir =
|
|
113574
|
+
const naxDir = join101(workdir, ".nax");
|
|
112861
113575
|
if (existsSync39(naxDir) && !options.force) {
|
|
112862
113576
|
console.log(source_default.yellow("nax already initialized. Use --force to overwrite."));
|
|
112863
113577
|
return;
|
|
@@ -112886,11 +113600,11 @@ Next: nax generate --package ${options.package}`));
|
|
|
112886
113600
|
}
|
|
112887
113601
|
}
|
|
112888
113602
|
}
|
|
112889
|
-
mkdirSync8(
|
|
112890
|
-
mkdirSync8(
|
|
113603
|
+
mkdirSync8(join101(naxDir, "features"), { recursive: true });
|
|
113604
|
+
mkdirSync8(join101(naxDir, "hooks"), { recursive: true });
|
|
112891
113605
|
const initConfig = options.name ? { ...DEFAULT_CONFIG, name: options.name } : DEFAULT_CONFIG;
|
|
112892
|
-
await Bun.write(
|
|
112893
|
-
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({
|
|
112894
113608
|
hooks: {
|
|
112895
113609
|
"on-start": { command: 'echo "nax started: $NAX_FEATURE"', enabled: false },
|
|
112896
113610
|
"on-complete": { command: 'echo "nax complete: $NAX_FEATURE"', enabled: false },
|
|
@@ -112898,12 +113612,12 @@ Next: nax generate --package ${options.package}`));
|
|
|
112898
113612
|
"on-error": { command: 'echo "nax error: $NAX_REASON"', enabled: false }
|
|
112899
113613
|
}
|
|
112900
113614
|
}, null, 2));
|
|
112901
|
-
await Bun.write(
|
|
113615
|
+
await Bun.write(join101(naxDir, ".gitignore"), `# nax temp files
|
|
112902
113616
|
*.tmp
|
|
112903
113617
|
.paused.json
|
|
112904
113618
|
.nax-verifier-verdict.json
|
|
112905
113619
|
`);
|
|
112906
|
-
await Bun.write(
|
|
113620
|
+
await Bun.write(join101(naxDir, "context.md"), `# Project Context
|
|
112907
113621
|
|
|
112908
113622
|
This document defines coding standards, architectural decisions, and forbidden patterns for this project.
|
|
112909
113623
|
Run \`nax generate\` to regenerate agent config files (CLAUDE.md, AGENTS.md, .cursorrules, etc.) from this file.
|
|
@@ -113087,7 +113801,7 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113087
113801
|
const cliOverrides = {};
|
|
113088
113802
|
const cliProfiles = options.profile ?? [];
|
|
113089
113803
|
const profileOverride = naxDir ? await resolveRunProfileOverride({
|
|
113090
|
-
prdPath:
|
|
113804
|
+
prdPath: join101(naxDir, "features", options.feature, "prd.json"),
|
|
113091
113805
|
projectRoot: workdir,
|
|
113092
113806
|
cliProfile: cliProfiles,
|
|
113093
113807
|
envProfile: process.env.NAX_PROFILE
|
|
@@ -113100,8 +113814,8 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113100
113814
|
console.error(source_default.red("nax not initialized. Run: nax init"));
|
|
113101
113815
|
process.exit(1);
|
|
113102
113816
|
}
|
|
113103
|
-
const featureDir =
|
|
113104
|
-
const prdPath =
|
|
113817
|
+
const featureDir = join101(naxDir, "features", options.feature);
|
|
113818
|
+
const prdPath = join101(featureDir, "prd.json");
|
|
113105
113819
|
if (options.plan && options.from) {
|
|
113106
113820
|
if (existsSync39(prdPath) && !options.force) {
|
|
113107
113821
|
console.error(source_default.red(`Error: prd.json already exists for feature "${options.feature}".`));
|
|
@@ -113123,10 +113837,10 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113123
113837
|
}
|
|
113124
113838
|
}
|
|
113125
113839
|
try {
|
|
113126
|
-
const planLogDir =
|
|
113840
|
+
const planLogDir = join101(featureDir, "plan");
|
|
113127
113841
|
mkdirSync8(planLogDir, { recursive: true });
|
|
113128
113842
|
const planLogId = new Date().toISOString().replace(/:/g, "-").replace(/\..+/, "");
|
|
113129
|
-
const planLogPath =
|
|
113843
|
+
const planLogPath = join101(planLogDir, `${planLogId}.jsonl`);
|
|
113130
113844
|
initLogger({ level: "info", filePath: planLogPath, useChalk: false, headless: true });
|
|
113131
113845
|
console.log(source_default.dim(` [Plan log: ${planLogPath}]`));
|
|
113132
113846
|
console.log(source_default.dim(" [Planning phase: generating PRD from spec]"));
|
|
@@ -113172,10 +113886,10 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113172
113886
|
resetLogger();
|
|
113173
113887
|
const projectKey = config2.name?.trim() || basename19(workdir);
|
|
113174
113888
|
const outputDir = projectOutputDir(projectKey, config2.outputDir);
|
|
113175
|
-
const runsDir =
|
|
113889
|
+
const runsDir = join101(outputDir, "features", options.feature, "runs");
|
|
113176
113890
|
mkdirSync8(runsDir, { recursive: true });
|
|
113177
113891
|
const runId = new Date().toISOString().replace(/:/g, "-").replace(/\..+/, "");
|
|
113178
|
-
const logFilePath =
|
|
113892
|
+
const logFilePath = join101(runsDir, `${runId}.jsonl`);
|
|
113179
113893
|
const isTTY = process.stdout.isTTY ?? false;
|
|
113180
113894
|
const headlessFlag = options.headless ?? false;
|
|
113181
113895
|
const headlessEnv = process.env.NAX_HEADLESS === "1";
|
|
@@ -113201,7 +113915,7 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113201
113915
|
}
|
|
113202
113916
|
config2.execution.costLimit = maxCost;
|
|
113203
113917
|
}
|
|
113204
|
-
const globalNaxDir =
|
|
113918
|
+
const globalNaxDir = join101(homedir3(), ".nax");
|
|
113205
113919
|
const hooks = await loadHooksConfig(naxDir, globalNaxDir);
|
|
113206
113920
|
const eventEmitter = new PipelineEventEmitter;
|
|
113207
113921
|
const agentStreamEvents = useHeadless ? undefined : new AgentStreamEventBus;
|
|
@@ -113220,12 +113934,12 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
113220
113934
|
stories: initialStories,
|
|
113221
113935
|
events: eventEmitter,
|
|
113222
113936
|
agentStreamEvents,
|
|
113223
|
-
queueFilePath:
|
|
113937
|
+
queueFilePath: join101(workdir, ".queue.txt")
|
|
113224
113938
|
});
|
|
113225
113939
|
} else {
|
|
113226
113940
|
console.log(source_default.dim(" [Headless mode \u2014 pipe output]"));
|
|
113227
113941
|
}
|
|
113228
|
-
const statusFilePath =
|
|
113942
|
+
const statusFilePath = join101(outputDir, "status.json");
|
|
113229
113943
|
let parallel;
|
|
113230
113944
|
if (options.parallel !== undefined) {
|
|
113231
113945
|
parallel = Number.parseInt(options.parallel, 10);
|
|
@@ -113288,7 +114002,7 @@ Scheduled run cancelled.`));
|
|
|
113288
114002
|
agentStreamEvents,
|
|
113289
114003
|
resumeMode: options.fresh === true || options.resume === false ? "fresh" : "auto"
|
|
113290
114004
|
});
|
|
113291
|
-
const latestSymlink =
|
|
114005
|
+
const latestSymlink = join101(runsDir, "latest.jsonl");
|
|
113292
114006
|
try {
|
|
113293
114007
|
if (existsSync39(latestSymlink)) {
|
|
113294
114008
|
Bun.spawnSync(["rm", latestSymlink]);
|
|
@@ -113385,9 +114099,9 @@ features.command("create <name>").description("Create a new feature").option("-d
|
|
|
113385
114099
|
console.error(source_default.red("nax not initialized. Run: nax init"));
|
|
113386
114100
|
process.exit(1);
|
|
113387
114101
|
}
|
|
113388
|
-
const featureDir =
|
|
114102
|
+
const featureDir = join101(naxDir, "features", name);
|
|
113389
114103
|
mkdirSync8(featureDir, { recursive: true });
|
|
113390
|
-
await Bun.write(
|
|
114104
|
+
await Bun.write(join101(featureDir, "spec.md"), `# Feature: ${name}
|
|
113391
114105
|
|
|
113392
114106
|
## Overview
|
|
113393
114107
|
|
|
@@ -113420,7 +114134,7 @@ features.command("create <name>").description("Create a new feature").option("-d
|
|
|
113420
114134
|
|
|
113421
114135
|
<!-- What this feature explicitly does NOT cover. -->
|
|
113422
114136
|
`);
|
|
113423
|
-
await Bun.write(
|
|
114137
|
+
await Bun.write(join101(featureDir, "progress.txt"), `# Progress: ${name}
|
|
113424
114138
|
|
|
113425
114139
|
Created: ${new Date().toISOString()}
|
|
113426
114140
|
|
|
@@ -113446,7 +114160,7 @@ features.command("list").description("List all features").option("-d, --dir <pat
|
|
|
113446
114160
|
console.error(source_default.red("nax not initialized."));
|
|
113447
114161
|
process.exit(1);
|
|
113448
114162
|
}
|
|
113449
|
-
const featuresDir =
|
|
114163
|
+
const featuresDir = join101(naxDir, "features");
|
|
113450
114164
|
if (!existsSync39(featuresDir)) {
|
|
113451
114165
|
console.log(source_default.dim("No features yet."));
|
|
113452
114166
|
return;
|
|
@@ -113461,7 +114175,7 @@ features.command("list").description("List all features").option("-d, --dir <pat
|
|
|
113461
114175
|
Features:
|
|
113462
114176
|
`));
|
|
113463
114177
|
for (const name of entries) {
|
|
113464
|
-
const prdPath =
|
|
114178
|
+
const prdPath = join101(featuresDir, name, "prd.json");
|
|
113465
114179
|
if (existsSync39(prdPath)) {
|
|
113466
114180
|
const prd = await loadPRD(prdPath);
|
|
113467
114181
|
const c = countStories(prd);
|
|
@@ -113534,10 +114248,10 @@ Use: nax plan -f <feature> --from <spec>`));
|
|
|
113534
114248
|
cliOverrides.profile = cliProfiles;
|
|
113535
114249
|
}
|
|
113536
114250
|
const config2 = await loadConfig(workdir, cliOverrides);
|
|
113537
|
-
const featureLogDir =
|
|
114251
|
+
const featureLogDir = join101(naxDir, "features", options.feature, "plan");
|
|
113538
114252
|
mkdirSync8(featureLogDir, { recursive: true });
|
|
113539
114253
|
const planLogId = new Date().toISOString().replace(/:/g, "-").replace(/\..+/, "");
|
|
113540
|
-
const planLogPath =
|
|
114254
|
+
const planLogPath = join101(featureLogDir, `${planLogId}.jsonl`);
|
|
113541
114255
|
initLogger({ level: "info", filePath: planLogPath, useChalk: false, headless: true });
|
|
113542
114256
|
console.log(source_default.dim(` [Plan log: ${planLogPath}]`));
|
|
113543
114257
|
try {
|
|
@@ -113644,8 +114358,8 @@ configProfileCmd.command("current").description("Show the currently active profi
|
|
|
113644
114358
|
});
|
|
113645
114359
|
configProfileCmd.command("create <name>").description("Create a new empty profile").option("-d, --dir <path>", "Project directory", process.cwd()).action(async (name, options) => {
|
|
113646
114360
|
try {
|
|
113647
|
-
const
|
|
113648
|
-
console.log(`Created profile at: ${
|
|
114361
|
+
const path32 = await profileCreateCommand(name, options.dir);
|
|
114362
|
+
console.log(`Created profile at: ${path32}`);
|
|
113649
114363
|
} catch (err) {
|
|
113650
114364
|
console.error(source_default.red(`Error: ${err.message}`));
|
|
113651
114365
|
process.exit(1);
|