@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 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. **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
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 canonical(text) {
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 (LIST_ITEM_START.test(line))
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(canonical));
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 = canonical(stripTagPrefix(block));
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, LIST_ITEM_START, HEADING;
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
- LIST_ITEM_START = /^\s*(?:[-*]|\d+\.)\s/;
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
- PRD_MAX_FILE_SIZE: () => PRD_MAX_FILE_SIZE
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
- The story description may contain a "Scope" section with "In:" and "Out:" bullets. These are implementation guidelines, not ACs. A finding about code changed outside the stated scope (e.g., a file listed under "Out:") cannot cite a scope constraint as its \`acQuote\`/\`acIndex\` because scope text is not in the numbered AC list. Emit scope-violation findings as \`"warning"\` \u2014 never \`"error"\`. Never use \`acIndex: 0\`; \`acIndex\` is 1-based (first AC bullet = 1).
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
- var BLOCKING_SEVERITIES;
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
- return await normalizeCreatedContextFiles(validated, input.workdir, ctx.fileExists);
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 canonical2 = extractCanonical(parsed);
35483
- if (canonical2)
35484
- return canonical2;
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 } = filterByAcQuote(substantiated, input.story.acceptanceCriteria);
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.73.5",
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("6aa6f9d9"))
41920
- return "6aa6f9d9";
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 path21 from "path";
64789
+ import * as path22 from "path";
64090
64790
  function getSafeLogger6() {
64091
64791
  return getSafeLogger();
64092
64792
  }
64093
64793
  function extractPluginName(pluginPath) {
64094
- const basename12 = path21.basename(pluginPath);
64794
+ const basename12 = path22.basename(pluginPath);
64095
64795
  if (basename12 === "index.ts" || basename12 === "index.js" || basename12 === "index.mjs") {
64096
- return path21.basename(path21.dirname(pluginPath));
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 = path21.join(dir, entry.name);
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 = path21.join(fullPath, indexFile);
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 (path21.isAbsolute(modulePath) || !modulePath.startsWith("./") && !modulePath.startsWith("../")) {
64977
+ if (path22.isAbsolute(modulePath) || !modulePath.startsWith("./") && !modulePath.startsWith("../")) {
64267
64978
  return modulePath;
64268
64979
  }
64269
64980
  if (projectRoot) {
64270
- return path21.resolve(projectRoot, modulePath);
64981
+ return path22.resolve(projectRoot, modulePath);
64271
64982
  }
64272
- return path21.resolve(modulePath);
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 join81 } from "path";
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 = join81(featureDir, "checkpoint.jsonl");
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 join82 } from "path";
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(join82(featureDir, "checkpoint.jsonl"), runId);
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 join83 } from "path";
65245
+ import { join as join84 } from "path";
64534
65246
  function createDrainDeadline2(deadlineMs) {
64535
65247
  let timeoutId;
64536
- const promise2 = new Promise((resolve16) => {
64537
- timeoutId = setTimeout(() => resolve16(""), deadlineMs);
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 = join83(projectDir, "hooks.json");
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 = join83(globalDir, "hooks.json");
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 resolve16, sep as sep5 } from "path";
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 = resolve16(packageDir);
65090
- const fullPath = resolve16(resolvedPackageDir, relPath);
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 path23 from "path";
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 = path23.join(featureDir, "spec.md");
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 = path23.join(featureDir, configuredTestPath);
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 = path23.join(acceptanceContext.featureDir, "acceptance-meta.json");
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 ? path23.join(acceptanceContext.projectDir, acceptanceContext.story.workdir) : undefined;
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 = path23.join(workdir, file3);
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 dirname13, join as join84 } from "path";
66501
+ import { dirname as dirname14, join as join85 } from "path";
65790
66502
  async function purgeStaleScratch(projectDir, featureName, retentionDays, archiveInsteadOfDelete = false) {
65791
- const sessionsDir = join84(projectDir, ".nax", "features", featureName, "sessions");
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 = join84(sessionsDir, sessionId);
65797
- const descriptorPath = join84(sessionDir, "descriptor.json");
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 = join84(projectDir, ".nax", "features", featureName, "_archive", "sessions", sessionId);
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: (path24) => Bun.file(path24).exists(),
65837
- readFile: (path24) => Bun.file(path24).text(),
65838
- remove: (path24) => rm(path24, { recursive: true, force: true }),
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(dirname13(dest), { recursive: true });
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 path24 from "path";
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 = path24.relative(options.workdir, g.packageDir);
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(path24.join(options.workdir, ".nax", "config.json"), relativeWorkdir);
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 path25 from "path";
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 = path25.resolve(workdir, rel);
66952
- const rootWithSep = workdir.endsWith(path25.sep) ? workdir : workdir + path25.sep;
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 join85 } from "path";
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 = join85(getEventsRootDir(), project);
66999
- const eventsFile = join85(eventsDir, "events.jsonl");
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 join86 } from "path";
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 = join86(getRunsDir(), `${project}-${feature}-${runId}`);
67185
- const metaFile = join86(runDir, "meta.json");
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: join86(outputDir, "features", feature, "status.json"),
67196
- eventsDir: join86(outputDir, "features", feature, "runs"),
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 join87 } from "path";
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 ? join87(options.worktreeRoot, options.storyWorkdir) : options.worktreeRoot;
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(join87(directory, filename))));
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 join88 } from "path";
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 = join88(projectRoot, ".git", "info");
67536
- const excludePath = join88(infoDir, "exclude");
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 = join88(projectRoot, ".nax-wt", storyId);
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 = join88(projectRoot, ".env");
68336
+ const envSource = join89(projectRoot, ".env");
67625
68337
  if (existsSync34(envSource)) {
67626
- const envTarget = join88(worktreePath, ".env");
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 = join88(projectRoot, ".nax-wt", storyId);
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 (path26) => {
68823
+ readFile: async (path27) => {
68112
68824
  try {
68113
- return await Bun.file(path26).text();
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 path26 from "path";
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 = path26.join(workdir, ".nax-wt", storyId);
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 join89 } from "path";
69206
+ import { join as join90 } from "path";
68495
69207
  async function removeWorktreeDirectory(projectRoot, storyId) {
68496
69208
  const logger = getSafeLogger();
68497
- const worktreePath = join89(projectRoot, ".nax-wt", storyId);
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 join90 } from "path";
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 = join90(ctx.workdir, ".nax-wt", story.id);
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(join90(ctx.workdir, ".nax", "config.json"), story.workdir, profileOverride) : ctx.config;
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 ? join90(effectiveWorkdir, story.workdir) : effectiveWorkdir : story.workdir ? join90(ctx.workdir, story.workdir) : ctx.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 join91 } from "path";
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 ? join91(worktreePath, story.workdir) : worktreePath),
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 path27 from "path";
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, path27.join(workdir, ".nax-wt", story.id));
69844
+ worktreePaths.set(story.id, path28.join(workdir, ".nax-wt", story.id));
69133
69845
  }
69134
- const rootConfigPath = path27.join(workdir, ".nax", "config.json");
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 resolve17 } from "path";
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 = resolve17(filePath);
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 join92 } from "path";
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 = join92(featureDir, "status.json");
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 path28 from "path";
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: path28.join(naxDir, entry) });
70908
+ candidates.push({ name: entry, srcPath: path29.join(naxDir, entry) });
70197
70909
  }
70198
70910
  }
70199
- const featuresDir = path28.join(naxDir, "features");
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 = path28.join(featuresDir, fid);
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: path28.join("features", fid, sub),
70217
- srcPath: path28.join(featureDir, sub)
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 = path28.join(featureDir, "stories");
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 = path28.join(storiesDir, sid);
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: path28.join("features", fid, "stories", sid, se),
70240
- srcPath: path28.join(storyDir, se)
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 = path28.join(globalConfigDir(), options.reclaim);
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 = path28.join(globalConfigDir(), "_archive");
70269
- const archiveDest = path28.join(archiveBase, `${options.reclaim}-${Date.now()}`);
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 = path28.join(options.workdir, ".nax");
70307
- const configPath = path28.join(naxDir, "config.json");
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() || path28.basename(options.workdir);
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} -> ${path28.join(destBase, c.name)}`, {
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 = path28.join(destBase, candidate.name);
70342
- await mkdir16(path28.dirname(dest), { recursive: true });
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(path28.join(destBase, ".migrated-from"), JSON.stringify({ from: options.workdir, migratedAt: new Date().toISOString() }, null, 2));
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 path29 from "path";
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(path29.dirname(ctx.logFilePath), { recursive: true });
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 join93 } from "path";
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 ? join93(workdir, story.workdir) : 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 path30 from "path";
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 = path30.join(workdir, ".nax");
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() || path30.basename(workdir);
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 = path30.join(globalConfigDir(), "plugins");
71021
- const projectPluginsDir = path30.join(workdir, ".nax", "plugins");
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, resolve18, reject) {
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, resolve18, reject);
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)) : resolve18(returnValue);
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(resolve18, reject) {
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, resolve18, reject);
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
- resolve18(returnValue);
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(resolve18, reject) {
72892
+ then: function(resolve19, reject) {
72181
72893
  didAwaitActCall = true;
72182
72894
  prevActScopeDepth === 0 ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
72183
- return recursivelyFlushAsyncActWork(returnValue$jscomp$0, resolve18, reject);
72184
- })) : resolve18(returnValue$jscomp$0);
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, path31, index, value) {
72885
- if (index >= path31.length)
73596
+ function copyWithSetImpl(obj, path32, index, value) {
73597
+ if (index >= path32.length)
72886
73598
  return value;
72887
- var key = path31[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
72888
- updated[key] = copyWithSetImpl(obj[key], path31, index + 1, value);
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, path31, index) {
72909
- var key = path31[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
72910
- if (index + 1 === path31.length)
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], path31, index + 1);
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(resolve18) {
75027
- entangledListeners.push(resolve18);
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(resolve18) {
75052
- listeners.push(resolve18);
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, path31, value) {
83647
+ overrideHookState = function(fiber, id, path32, value) {
82936
83648
  id = findHook(fiber, id);
82937
- id !== null && (path31 = copyWithSetImpl(id.memoizedState, path31, 0, value), id.memoizedState = path31, id.baseState = path31, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path31 = enqueueConcurrentRenderForLane(fiber, 2), path31 !== null && scheduleUpdateOnFiber(path31, fiber, 2));
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, path31) {
83651
+ overrideHookStateDeletePath = function(fiber, id, path32) {
82940
83652
  id = findHook(fiber, id);
82941
- id !== null && (path31 = copyWithDeleteImpl(id.memoizedState, path31, 0), id.memoizedState = path31, id.baseState = path31, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path31 = enqueueConcurrentRenderForLane(fiber, 2), path31 !== null && scheduleUpdateOnFiber(path31, fiber, 2));
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, path31, value) {
82948
- fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path31, 0, value);
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
- path31 = enqueueConcurrentRenderForLane(fiber, 2);
82951
- path31 !== null && scheduleUpdateOnFiber(path31, fiber, 2);
83662
+ path32 = enqueueConcurrentRenderForLane(fiber, 2);
83663
+ path32 !== null && scheduleUpdateOnFiber(path32, fiber, 2);
82952
83664
  };
82953
- overridePropsDeletePath = function(fiber, path31) {
82954
- fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path31, 0);
83665
+ overridePropsDeletePath = function(fiber, path32) {
83666
+ fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path32, 0);
82955
83667
  fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
82956
- path31 = enqueueConcurrentRenderForLane(fiber, 2);
82957
- path31 !== null && scheduleUpdateOnFiber(path31, fiber, 2);
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, path31) {
87013
- return path31.reduce(function(reduced, attr2) {
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, path31) {
87026
- var length = path31.length;
87027
- var last2 = path31[length - 1];
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, path31.slice(0, length - 1));
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, path31, value) {
87056
- var length = path31.length;
87057
- var last2 = path31[length - 1];
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, path31.slice(0, length - 1));
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, path31) {
87591
- cleaned.push(path31);
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, path31, isPathAllowed) {
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(path31);
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(path31);
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(path31);
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(path31);
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(path31);
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(path31);
88370
+ isPathAllowedCheck = isPathAllowed(path32);
87659
88371
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
87660
- cleaned.push(path31);
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, path31.concat(["key"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
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, path31.concat(["ref"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
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, path31.concat(["props"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
87682
- unserializable.push(path31);
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(path31);
88398
+ isPathAllowedCheck = isPathAllowed(path32);
87687
88399
  var payload = data._payload;
87688
88400
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
87689
- cleaned.push(path31);
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, path31.concat(["_payload"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
87707
- unserializable.push(path31);
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(path31);
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(path31);
88434
+ isPathAllowedCheck = isPathAllowed(path32);
87723
88435
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
87724
- return createDehydrated(type, true, data, cleaned, path31);
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, path31.concat([i]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
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(path31);
88446
+ isPathAllowedCheck = isPathAllowed(path32);
87735
88447
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
87736
- return createDehydrated(type, true, data, cleaned, path31);
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, path31.concat([i2]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
88460
+ return _unserializableValue2[i2] = dehydrate(item, cleaned, unserializable, path32.concat([i2]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
87749
88461
  });
87750
- unserializable.push(path31);
88462
+ unserializable.push(path32);
87751
88463
  return _unserializableValue2;
87752
88464
  }
87753
88465
  case "opaque_iterator":
87754
- cleaned.push(path31);
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(path31);
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(path31);
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(path31);
88493
+ isPathAllowedCheck = isPathAllowed(path32);
87782
88494
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
87783
- cleaned.push(path31);
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, path31.concat(["value"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
87805
- unserializable.push(path31);
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, path31.concat(["reason"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
87817
- unserializable.push(path31);
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(path31);
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(path31);
88543
+ isPathAllowedCheck = isPathAllowed(path32);
87832
88544
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
87833
- return createDehydrated(type, true, data, cleaned, path31);
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, path31.concat([name]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
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(path31);
88555
+ isPathAllowedCheck = isPathAllowed(path32);
87844
88556
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
87845
- return createDehydrated(type, true, data, cleaned, path31);
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, path31.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
88569
+ value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path32.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
87858
88570
  });
87859
- unserializable.push(path31);
88571
+ unserializable.push(path32);
87860
88572
  return value;
87861
88573
  }
87862
88574
  case "error": {
87863
- isPathAllowedCheck = isPathAllowed(path31);
88575
+ isPathAllowedCheck = isPathAllowed(path32);
87864
88576
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
87865
- return createDehydrated(type, true, data, cleaned, path31);
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, path31.concat(["message"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
87876
- _value.stack = dehydrate(data.stack, cleaned, unserializable, path31.concat(["stack"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
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, path31.concat(["cause"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
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, path31.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
88594
+ _value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path32.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
87883
88595
  });
87884
- unserializable.push(path31);
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(path31);
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, path31, isPathAllowed) {
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, path31, isPathAllowed, level);
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(path31);
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, path31, value) {
87920
- var target = getInObject(object2, path31);
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 === path31.length;
87936
- for (var i = 0;i < path31.length; i++) {
87937
- if (path31[i] !== unserializablePath[i]) {
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, path31, value);
88658
+ setInObject(object2, path32, value);
87947
88659
  }
87948
88660
  function hydrate(object2, cleaned, unserializable) {
87949
- cleaned.forEach(function(path31) {
87950
- var length = path31.length;
87951
- var last2 = path31[length - 1];
87952
- var parent = getInObject(object2, path31.slice(0, length - 1));
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(path31) {
87979
- var length = path31.length;
87980
- var last2 = path31[length - 1];
87981
- var parent = getInObject(object2, path31.slice(0, length - 1));
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 path31 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
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, path31, isPathAllowed);
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, path31) {
88828
+ function copyWithDelete(obj, path32) {
88117
88829
  var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
88118
- var key = path31[index];
88830
+ var key = path32[index];
88119
88831
  var updated = shared_isArray(obj) ? obj.slice() : utils_objectSpread({}, obj);
88120
- if (index + 1 === path31.length) {
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], path31, index + 1);
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, path31, value) {
88860
+ function copyWithSet(obj, path32, value) {
88149
88861
  var index = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
88150
- if (index >= path31.length) {
88862
+ if (index >= path32.length) {
88151
88863
  return value;
88152
88864
  }
88153
- var key = path31[index];
88865
+ var key = path32[index];
88154
88866
  var updated = shared_isArray(obj) ? obj.slice() : utils_objectSpread({}, obj);
88155
- updated[key] = copyWithSet(obj[key], path31, value, index + 1);
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: path31, rendererID, type, value } = _ref;
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: path31,
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: path31,
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: path31,
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: path31,
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: path31, rendererID } = _ref5;
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, path31);
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: path31, rendererID, type } = _ref6;
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, path31);
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: path31, rendererID, requestID } = _ref9;
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, path31, forceFullData));
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 path31 = null;
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
- path31 = ["suspendedBy", suspendedByPathRendererIndex].concat(rendererPath);
90661
+ path32 = ["suspendedBy", suspendedByPathRendererIndex].concat(rendererPath);
89950
90662
  }
89951
90663
  }
89952
- var inspectedRootsPayload = renderer.inspectElement(requestID, id, path31, forceFullData);
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: path31, rendererID, type, value } = _ref15;
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, path31, value);
90763
+ renderer.overrideValueAtPath(type, id, hookID, path32, value);
90052
90764
  }
90053
90765
  });
90054
90766
  agent_defineProperty(_this, "overrideContext", function(_ref16) {
90055
- var { id, path: path31, rendererID, wasForwarded, value } = _ref16;
90767
+ var { id, path: path32, rendererID, wasForwarded, value } = _ref16;
90056
90768
  if (!wasForwarded) {
90057
90769
  _this.overrideValueAtPath({
90058
90770
  id,
90059
- path: path31,
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: path31, rendererID, wasForwarded, value } = _ref17;
90779
+ var { id, hookID, path: path32, rendererID, wasForwarded, value } = _ref17;
90068
90780
  if (!wasForwarded) {
90069
90781
  _this.overrideValueAtPath({
90070
90782
  id,
90071
- path: path31,
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: path31, rendererID, wasForwarded, value } = _ref18;
90791
+ var { id, path: path32, rendererID, wasForwarded, value } = _ref18;
90080
90792
  if (!wasForwarded) {
90081
90793
  _this.overrideValueAtPath({
90082
90794
  id,
90083
- path: path31,
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: path31, rendererID, wasForwarded, value } = _ref19;
90803
+ var { id, path: path32, rendererID, wasForwarded, value } = _ref19;
90092
90804
  if (!wasForwarded) {
90093
90805
  _this.overrideValueAtPath({
90094
90806
  id,
90095
- path: path31,
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: path31, rendererID } = _ref23;
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, path31, count);
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 path31 = renderer.getPathForElement(_this._lastSelectedElementID);
90185
- if (path31 !== null) {
90186
- renderer.setTrackedPath(path31);
90896
+ var path32 = renderer.getPathForElement(_this._lastSelectedElementID);
90897
+ if (path32 !== null) {
90898
+ renderer.setTrackedPath(path32);
90187
90899
  _this._persistedSelection = {
90188
90900
  rendererID,
90189
- path: path31
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 path31 = renderer != null ? renderer.getPathForElement(id) : null;
90265
- if (path31 !== null) {
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: path31
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, path31) {
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, path31) {
96973
+ function getElementAttributeByPath(id, path32) {
96262
96974
  if (isMostRecentlyInspectedElement(id)) {
96263
- return utils_getInObject(mostRecentlyInspectedElement, path31);
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(path31) {
97678
+ function mergeInspectedPaths(path32) {
96967
97679
  var current = currentlyInspectedPaths;
96968
- path31.forEach(function(key) {
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(path31) {
97688
+ return function isPathAllowed(path32) {
96977
97689
  switch (secondaryCategory) {
96978
97690
  case "hooks":
96979
- if (path31.length === 1) {
97691
+ if (path32.length === 1) {
96980
97692
  return true;
96981
97693
  }
96982
- if (path31[path31.length - 2] === "hookSource" && path31[path31.length - 1] === "fileName") {
97694
+ if (path32[path32.length - 2] === "hookSource" && path32[path32.length - 1] === "fileName") {
96983
97695
  return true;
96984
97696
  }
96985
- if (path31[path31.length - 1] === "subHooks" || path31[path31.length - 2] === "subHooks") {
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 (path31.length < 5) {
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 < path31.length; i++) {
97002
- current = current[path31[i]];
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, path31, count) {
97768
+ function storeAsGlobal(id, path32, count) {
97057
97769
  if (isMostRecentlyInspectedElement(id)) {
97058
- var value = utils_getInObject(mostRecentlyInspectedElement, path31);
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, path31) {
97777
+ function getSerializedElementValueByPath(id, path32) {
97066
97778
  if (isMostRecentlyInspectedElement(id)) {
97067
- var valueToCopy = utils_getInObject(mostRecentlyInspectedElement, path31);
97779
+ var valueToCopy = utils_getInObject(mostRecentlyInspectedElement, path32);
97068
97780
  return serializeToString(valueToCopy);
97069
97781
  }
97070
97782
  }
97071
- function inspectElement(requestID, id, path31, forceFullData) {
97072
- if (path31 !== null) {
97073
- mergeInspectedPaths(path31);
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 (path31 !== null) {
97789
+ if (path32 !== null) {
97078
97790
  var secondaryCategory = null;
97079
- if (path31[0] === "hooks" || path31[0] === "suspendedBy") {
97080
- secondaryCategory = path31[0];
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: path31,
97087
- value: cleanForBridge(utils_getInObject(mostRecentlyInspectedElement, path31), createIsPathAllowed(null, secondaryCategory), path31)
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, path31) {
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
- path31 = path31.slice(1);
98009
+ path32 = path32.slice(1);
97298
98010
  switch (fiber.tag) {
97299
98011
  case ClassComponent:
97300
- if (path31.length === 0) {} else {
97301
- deletePathInObject(instance2.context, path31);
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, path31);
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, path31);
98029
+ overridePropsDeletePath(fiber, path32);
97318
98030
  }
97319
98031
  } else {
97320
- fiber.pendingProps = copyWithDelete(instance2.props, path31);
98032
+ fiber.pendingProps = copyWithDelete(instance2.props, path32);
97321
98033
  instance2.forceUpdate();
97322
98034
  }
97323
98035
  break;
97324
98036
  case "state":
97325
- deletePathInObject(instance2.state, path31);
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, path31, value) {
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
- path31 = path31.slice(1);
98106
+ path32 = path32.slice(1);
97395
98107
  switch (fiber.tag) {
97396
98108
  case ClassComponent:
97397
- if (path31.length === 0) {
98109
+ if (path32.length === 0) {
97398
98110
  instance2.context = value;
97399
98111
  } else {
97400
- utils_setInObject(instance2.context, path31, value);
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, path31, value);
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, path31, value);
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, path31, value);
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, path31, value);
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(path31) {
97716
- if (path31 === null) {
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 = path31;
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(path31) {
99198
+ function mergeInspectedPaths(path32) {
98487
99199
  var current = currentlyInspectedPaths;
98488
- path31.forEach(function(key) {
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(path31) {
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 < path31.length; i++) {
98502
- current = current[path31[i]];
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, path31, count) {
99264
+ function storeAsGlobal(id, path32, count) {
98553
99265
  var inspectedElement = inspectElementRaw(id);
98554
99266
  if (inspectedElement !== null) {
98555
- var value = utils_getInObject(inspectedElement, path31);
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, path31) {
99274
+ function getSerializedElementValueByPath(id, path32) {
98563
99275
  var inspectedElement = inspectElementRaw(id);
98564
99276
  if (inspectedElement !== null) {
98565
- var valueToCopy = utils_getInObject(inspectedElement, path31);
99277
+ var valueToCopy = utils_getInObject(inspectedElement, path32);
98566
99278
  return serializeToString(valueToCopy);
98567
99279
  }
98568
99280
  }
98569
- function inspectElement(requestID, id, path31, forceFullData) {
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 (path31 !== null) {
98583
- mergeInspectedPaths(path31);
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, path31) {
99498
+ function getElementAttributeByPath(id, path32) {
98787
99499
  var inspectedElement = inspectElementRaw(id);
98788
99500
  if (inspectedElement !== null) {
98789
- return utils_getInObject(inspectedElement, path31);
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, path31) {
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, path31);
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, path31)
99533
+ props: copyWithDelete(element.props, path32)
98822
99534
  });
98823
99535
  forceUpdate(publicInstance);
98824
99536
  break;
98825
99537
  case "state":
98826
- deletePathInObject(publicInstance.state, path31);
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, path31, value) {
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, path31, value);
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, path31, value)
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, path31, value);
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(path31) {}
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 join98 } from "path";
101663
+ import { join as join99 } from "path";
100952
101664
  async function persistBakeoffResult(result2, outputDir) {
100953
- const filePath = join98(outputDir, "bakeoff.json");
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 join99 } from "path";
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 = join99(outputDir, "runs");
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 = join99(runsDir, runId);
101242
- const observationsPath = join99(runDir, "observations.jsonl");
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 = join99(runDir, "curator-proposals.md");
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 = join99(outputDir, "runs", options.runId);
101267
- const proposalsPath = join99(runDir, "curator-proposals.md");
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 = join99(resolved.projectDir, drop2.canonicalFile);
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 = join99(resolved.projectDir, drop2.canonicalFile);
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 = join99(resolved.projectDir, add2.canonicalFile);
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 = join99(outputDir, "runs");
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 = join99(runsDir, runId, "observations.jsonl");
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 = join99(outputDir, "runs");
102127
+ const perRunsDir = join100(outputDir, "runs");
101416
102128
  for (const runId of uniqueRunIds) {
101417
102129
  if (!keepSet.has(runId)) {
101418
- const runDir = join99(perRunsDir, runId);
101419
- await _curatorCmdDeps.removeFile(join99(runDir, "observations.jsonl"));
101420
- await _curatorCmdDeps.removeFile(join99(runDir, "curator-proposals.md"));
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 join100 } from "path";
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 withProject2 = { ...prd2, project: ctx.projectName };
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 prdToWrite = finalizePrdRouting({ ...verdict.prd, project: ctx.projectName }, ctx.config.routing?.agents, ctx.profileName);
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 path22 from "path";
102944
+ import * as path23 from "path";
102231
102945
  async function pluginsListCommand(config2, workdir, overrideGlobalPluginsDir) {
102232
- const globalPluginsDir = overrideGlobalPluginsDir ?? path22.join(globalConfigDir(), "plugins");
102233
- const projectPluginsDir = path22.join(workdir, ".nax", "plugins");
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 (${path22.basename(sourcePath)})`;
102997
+ return `global (${path23.basename(sourcePath)})`;
102284
102998
  }
102285
102999
  if (type === "project") {
102286
- return `project (${path22.basename(sourcePath)})`;
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 join67 } from "path";
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 = join67(workdir, options.package);
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 ? join67(workdir, options.context) : join67(workdir, ".nax/context.md");
102365
- const outputDir = options.output ? join67(workdir, options.output) : workdir;
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 join69 } from "path";
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 path23 = [...currentPath, key];
102680
- const pathStr = path23.join(".");
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, path23);
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 join68 } from "path";
102725
- async function loadConfigFile(path23) {
102726
- if (!existsSync25(path23))
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(path23).json();
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 = join68(projectDir, "config.json");
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 path23 = diff2.path.padEnd(40);
103490
+ const path24 = diff2.path.padEnd(40);
102777
103491
  const projectVal = formatValueForTable(diff2.projectValue);
102778
103492
  const globalVal = formatValueForTable(diff2.globalValue);
102779
- console.log(`${path23}${projectVal.padEnd(20)}${globalVal}`);
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 ? join69(projectDir, "config.json") : null;
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(path23) {
102813
- return existsSync26(path23);
103526
+ function fileExists(path24) {
103527
+ return existsSync26(path24);
102814
103528
  }
102815
- function displayConfigWithDescriptions(obj, path23, sources, indent = 0) {
103529
+ function displayConfigWithDescriptions(obj, path24, sources, indent = 0) {
102816
103530
  const indentStr = " ".repeat(indent);
102817
- const pathStr = path23.join(".");
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 = path23[path23.length - 1] || "";
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 = path23.join(".") === "prompts";
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 = [...path23, key];
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 join70 } from "path";
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 = join70(globalConfigDir(), "profiles");
102963
- const projectProfilesDir = join70(projectConfigDir(startDir), "profiles");
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 = join70(projectConfigDir(startDir), "config.json");
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 = join70(projectConfigDir(startDir), "profiles");
103042
- const profilePath = join70(profilesDir, `${profileName}.json`);
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 join71 } from "path";
103878
+ import { basename as basename13, join as join72 } from "path";
103165
103879
  var _rulesCLIDeps = {
103166
- readFile: async (path23) => Bun.file(path23).text(),
103167
- writeFile: async (path23, content) => {
103168
- await Bun.write(path23, content);
103880
+ readFile: async (path24) => Bun.file(path24).text(),
103881
+ writeFile: async (path24, content) => {
103882
+ await Bun.write(path24, content);
103169
103883
  },
103170
- fileExists: async (path23) => Bun.file(path23).exists(),
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) => join71(dir, 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 (path23) => {
103179
- await mkdir11(path23, { recursive: true });
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 = join71(workdir, shimFileName);
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 = join71(workdir, "CLAUDE.md");
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 = join71(workdir, ".claude", "rules");
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 = join71(workdir, CANONICAL_RULES_DIR);
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 = join71(targetDir, targetFileName);
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(join71(workdir, packageRel));
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 (path23) => {
103353
- const file3 = Bun.file(path23);
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 join73, relative as relative16 } from "path";
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 join72, relative as relative15 } from "path";
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 = join72(naxDir, "..");
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 = join72(naxDir, "features", featureName, "prd.json");
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: join73(naxDir, "features", name, "spec.md"), kind: "markdown" },
103442
- { abs: join73(naxDir, "specs", `${name}.md`), kind: "markdown" }
104155
+ { abs: join74(naxDir, "features", name, "spec.md"), kind: "markdown" },
104156
+ { abs: join74(naxDir, "specs", `${name}.md`), kind: "markdown" }
103443
104157
  ];
103444
- const docsSpecExact = join73(repoRoot, "docs", "specs", `SPEC-${name}.md`);
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 = join73(repoRoot, "docs", "specs");
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 = join73(docsSpecsDir, match);
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 = join73(naxDir, "features", name, "prd.json");
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 = join73(naxDir, "features");
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 = join73(featuresDir, e.name);
103488
- return existsSync28(join73(dir, "prd.json")) || existsSync28(join73(dir, "spec.md"));
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 = join73(naxDir, "..");
104213
+ const repoRoot = join74(naxDir, "..");
103500
104214
  if (name !== undefined && (name.startsWith("./") || name.startsWith("/") || name.endsWith(".md"))) {
103501
- const abs = name.startsWith("/") ? name : join73(workdir, 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 = join73(naxDir, "features", name);
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 join74 } from "path";
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 = join74(dir, "config.json");
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 join75 } from "path";
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(path23) {
103745
- const f = Bun.file(path23);
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(path23, data) {
103751
- await Bun.write(path23, `${JSON.stringify(data, null, 2)}
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 = join75(workdir, ".nax", "mono", dir, "config.json");
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 = join75(workdir, ".nax", "config.json");
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 ${join75(".nax", "config.json")}`));
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 = join75(workdir, ".nax", "mono", dir, "config.json");
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 ${join75(".nax", "mono", dir, "config.json")}`));
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 join78 } from "path";
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 join77 } from "path";
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 join76 } from "path";
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 = join76(runsDir, entry, "meta.json");
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 join76(matched.eventsDir, specificFile ?? files[0]);
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 join76(runsDir, files[0]);
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 = join77(runsDir, file3);
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 = join78(resolved.projectDir, ".nax");
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 = join78(naxDir, "features", featureName);
104182
- const runsDir = join78(featureDir, "runs");
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 join79 } from "path";
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 = join79(resolved.projectDir, ".nax");
104231
- const featureDir = join79(naxDir, "features", featureName);
104232
- const prdPath = join79(featureDir, "prd.json");
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 dirname12 } from "path";
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 join80 } from "path";
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(join80(runsDir, entry, "meta.json")).json();
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: join80(latest.eventsDir, `${latest.runId}.jsonl`) };
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: join80(meta3.eventsDir, `${meta3.runId}.jsonl`) };
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(path23) {
104540
- if (!existsSync32(path23))
105253
+ async function readJsonlLenient(path24) {
105254
+ if (!existsSync32(path24))
104541
105255
  return [];
104542
- const content = await Bun.file(path23).text();
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(path23) {
104557
- if (!existsSync32(path23))
105270
+ async function readJsonOrUndefined(path24) {
105271
+ if (!existsSync32(path24))
104558
105272
  return;
104559
105273
  try {
104560
- return await Bun.file(path23).json();
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 = dirname12(dirname12(dirname12(meta3.eventsDir)));
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 join94 } from "path";
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(join94(featureDir, "checkpoint.jsonl"));
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 = join94(naxDir, "features", cmdOpts.feature);
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 = join94(opts.featureDir ?? "", "prd.json");
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 = join94(outputDir, "status.json");
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 join95 } from "path";
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 = join95(runsDir, entry, "meta.json");
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 join96 } from "path";
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 = join96(workdir, "nax.lock");
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 = (path31) => {
109857
- return path31?.replace(`file://${cwd()}/`, "");
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((resolve18, reject2) => {
110562
- this.resolveExitPromise = resolve18;
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((resolve18) => {
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
- resolve18(false);
113543
+ resolve19(false);
112830
113544
  } else {
112831
- resolve18(true);
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 = join100(workdir, ".nax");
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(join100(naxDir, "features"), { recursive: true });
112890
- mkdirSync8(join100(naxDir, "hooks"), { recursive: true });
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(join100(naxDir, "config.json"), JSON.stringify(initConfig, null, 2));
112893
- await Bun.write(join100(naxDir, "hooks.json"), JSON.stringify({
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(join100(naxDir, ".gitignore"), `# nax temp files
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(join100(naxDir, "context.md"), `# Project Context
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: join100(naxDir, "features", options.feature, "prd.json"),
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 = join100(naxDir, "features", options.feature);
113104
- const prdPath = join100(featureDir, "prd.json");
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 = join100(featureDir, "plan");
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 = join100(planLogDir, `${planLogId}.jsonl`);
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 = join100(outputDir, "features", options.feature, "runs");
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 = join100(runsDir, `${runId}.jsonl`);
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 = join100(homedir3(), ".nax");
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: join100(workdir, ".queue.txt")
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 = join100(outputDir, "status.json");
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 = join100(runsDir, "latest.jsonl");
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 = join100(naxDir, "features", name);
114102
+ const featureDir = join101(naxDir, "features", name);
113389
114103
  mkdirSync8(featureDir, { recursive: true });
113390
- await Bun.write(join100(featureDir, "spec.md"), `# Feature: ${name}
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(join100(featureDir, "progress.txt"), `# Progress: ${name}
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 = join100(naxDir, "features");
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 = join100(featuresDir, name, "prd.json");
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 = join100(naxDir, "features", options.feature, "plan");
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 = join100(featureLogDir, `${planLogId}.jsonl`);
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 path31 = await profileCreateCommand(name, options.dir);
113648
- console.log(`Created profile at: ${path31}`);
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);