@nathapp/nax 0.77.1 → 0.77.3

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
@@ -16865,7 +16865,10 @@ var init_schemas_execution = __esm(() => {
16865
16865
  maxFailureSummaryChars: exports_external.number().int().min(500).max(1e4).default(2000),
16866
16866
  abortOnIncreasingFailures: exports_external.boolean().default(true),
16867
16867
  consecutiveIncreasesToBail: exports_external.number().int().min(1).max(10).default(2),
16868
+ abortOnNoProgress: exports_external.boolean().default(true),
16869
+ consecutiveNoProgressToBail: exports_external.number().int().min(1).max(10).default(3),
16868
16870
  escalateOnExhaustion: exports_external.boolean().optional().default(true),
16871
+ storyScopedFixBudget: exports_external.boolean().default(true),
16869
16872
  rethinkAtAttempt: exports_external.number().int().min(1).default(2),
16870
16873
  urgencyAtAttempt: exports_external.number().int().min(1).default(3)
16871
16874
  });
@@ -17531,7 +17534,10 @@ var init_schemas3 = __esm(() => {
17531
17534
  maxFailureSummaryChars: 2000,
17532
17535
  abortOnIncreasingFailures: true,
17533
17536
  consecutiveIncreasesToBail: 2,
17537
+ abortOnNoProgress: true,
17538
+ consecutiveNoProgressToBail: 3,
17534
17539
  escalateOnExhaustion: true,
17540
+ storyScopedFixBudget: true,
17535
17541
  rethinkAtAttempt: 2,
17536
17542
  urgencyAtAttempt: 3
17537
17543
  },
@@ -17831,6 +17837,10 @@ var init_schemas3 = __esm(() => {
17831
17837
  defaultAgent: exports_external.string().nullable().default(null),
17832
17838
  model: exports_external.string().min(1, "model must be non-empty").nullable().default(null),
17833
17839
  narrative: exports_external.boolean().default(true),
17840
+ prBody: exports_external.object({
17841
+ template: exports_external.enum(["merge", "strict", "ignore"]).default("merge"),
17842
+ sectionMap: exports_external.record(exports_external.string(), exports_external.string()).default({})
17843
+ }).default({ template: "merge", sectionMap: {} }),
17834
17844
  reviewers: exports_external.object({
17835
17845
  spec: exports_external.string().nullable().default(null),
17836
17846
  quality: exports_external.string().nullable().default(null),
@@ -17850,6 +17860,7 @@ var init_schemas3 = __esm(() => {
17850
17860
  defaultAgent: null,
17851
17861
  model: null,
17852
17862
  narrative: true,
17863
+ prBody: { template: "merge", sectionMap: {} },
17853
17864
  reviewers: { spec: null, quality: null, narrative: null },
17854
17865
  escalate: { telegram: true },
17855
17866
  notify: { mode: "escalation" },
@@ -17862,6 +17873,7 @@ var init_schemas3 = __esm(() => {
17862
17873
  defaultAgent: null,
17863
17874
  model: null,
17864
17875
  narrative: true,
17876
+ prBody: { template: "merge", sectionMap: {} },
17865
17877
  reviewers: { spec: null, quality: null, narrative: null },
17866
17878
  escalate: { telegram: true },
17867
17879
  notify: { mode: "escalation" },
@@ -23592,7 +23604,7 @@ function parseFrontmatter(raw, filePath) {
23592
23604
  const doc2 = parsed ?? {};
23593
23605
  const unknownKeys = Object.keys(doc2).filter((key) => !KNOWN_FRONTMATTER_KEYS.has(key));
23594
23606
  if (unknownKeys.length > 0) {
23595
- throw new RulesFrontmatterError(`Canonical rule frontmatter declares unknown key(s): ${unknownKeys.join(", ")}. Only priority, paths, appliesTo, and stages are recognised.`, filePath);
23607
+ throw new RulesFrontmatterError(`Canonical rule frontmatter declares unknown key(s): ${unknownKeys.join(", ")}. Only priority, paths, appliesTo, stages, and description are recognised.`, filePath);
23596
23608
  }
23597
23609
  const priorityRaw = doc2.priority;
23598
23610
  let priority = FRONTMATTER_PRIORITY_DEFAULT;
@@ -23645,12 +23657,29 @@ function parseFrontmatter(raw, filePath) {
23645
23657
  }
23646
23658
  }
23647
23659
  }
23660
+ const descriptionRaw = doc2.description;
23661
+ let description;
23662
+ if (descriptionRaw !== undefined) {
23663
+ if (typeof descriptionRaw !== "string") {
23664
+ throw new RulesFrontmatterError("frontmatter.description must be a string", filePath);
23665
+ }
23666
+ if (descriptionRaw.includes(`
23667
+ `) || descriptionRaw.includes("\r")) {
23668
+ throw new RulesFrontmatterError("frontmatter.description must be a single line", filePath);
23669
+ }
23670
+ const trimmed = descriptionRaw.trim();
23671
+ if (!trimmed) {
23672
+ throw new RulesFrontmatterError("frontmatter.description cannot be empty", filePath);
23673
+ }
23674
+ description = trimmed;
23675
+ }
23648
23676
  return {
23649
23677
  content: effectiveContent.slice(close[0].length).trim(),
23650
23678
  priority,
23651
23679
  ...paths && { paths },
23652
23680
  ...appliesTo && { appliesTo },
23653
23681
  ...stages && { stages },
23682
+ ...description && { description },
23654
23683
  warnings
23655
23684
  };
23656
23685
  }
@@ -23658,7 +23687,7 @@ var KNOWN_FRONTMATTER_KEYS, FRONTMATTER_PRIORITY_DEFAULT = 100, EXTRA_KNOWN_STAG
23658
23687
  var init_rules_frontmatter = __esm(() => {
23659
23688
  init_errors();
23660
23689
  init_stage_config();
23661
- KNOWN_FRONTMATTER_KEYS = new Set(["priority", "paths", "appliesTo", "stages"]);
23690
+ KNOWN_FRONTMATTER_KEYS = new Set(["priority", "paths", "appliesTo", "stages", "description"]);
23662
23691
  EXTRA_KNOWN_STAGES = [
23663
23692
  "queue-check",
23664
23693
  "routing",
@@ -23821,6 +23850,7 @@ async function loadCanonicalRules(workdir, options = {}) {
23821
23850
  ...parsed.paths && { paths: parsed.paths },
23822
23851
  ...parsed.appliesTo && { appliesTo: parsed.appliesTo },
23823
23852
  ...parsed.stages && { stages: parsed.stages },
23853
+ ...parsed.description && { description: parsed.description },
23824
23854
  ...parsed.warnings.length > 0 && { warnings: parsed.warnings }
23825
23855
  });
23826
23856
  }
@@ -26439,6 +26469,144 @@ function isInside(root, filePath) {
26439
26469
  }
26440
26470
  var init_realpath = () => {};
26441
26471
 
26472
+ // src/utils/porcelain.ts
26473
+ function parsePorcelainForNaxPaths(porcelain) {
26474
+ const protectedPaths = [];
26475
+ if (!porcelain)
26476
+ return protectedPaths;
26477
+ for (const rawLine of porcelain.split(`
26478
+ `)) {
26479
+ if (!rawLine)
26480
+ continue;
26481
+ if (rawLine.length < 4)
26482
+ continue;
26483
+ const xStatus = rawLine[0];
26484
+ const yStatus = rawLine[1];
26485
+ if (xStatus === "?" && yStatus === "?")
26486
+ continue;
26487
+ const isDeleted = xStatus === "D" || yStatus === "D";
26488
+ const isRename = xStatus === "R" || yStatus === "R";
26489
+ if (!isDeleted && !isRename)
26490
+ continue;
26491
+ const staged = xStatus === "D" || xStatus === "R";
26492
+ const pathField = rawLine.slice(3);
26493
+ let targetPath;
26494
+ if (isRename) {
26495
+ const oldPath = splitRenameOldPath(pathField);
26496
+ if (oldPath === null)
26497
+ continue;
26498
+ targetPath = oldPath;
26499
+ } else {
26500
+ targetPath = pathField;
26501
+ }
26502
+ targetPath = unquotePorcelainPath(targetPath);
26503
+ if (!targetPath.split("/").includes(".nax"))
26504
+ continue;
26505
+ protectedPaths.push({ path: targetPath, staged });
26506
+ }
26507
+ return protectedPaths;
26508
+ }
26509
+ function unquotePorcelainPath(p) {
26510
+ if (p.length < 2 || p[0] !== '"' || p[p.length - 1] !== '"')
26511
+ return p;
26512
+ const inner = p.slice(1, -1);
26513
+ const bytes = [];
26514
+ for (let i = 0;i < inner.length; i++) {
26515
+ const c = inner[i];
26516
+ if (c !== "\\" || i + 1 >= inner.length) {
26517
+ bytes.push(c.charCodeAt(0));
26518
+ continue;
26519
+ }
26520
+ const next = inner[i + 1];
26521
+ if (next === '"' || next === "\\") {
26522
+ bytes.push(next.charCodeAt(0));
26523
+ i++;
26524
+ continue;
26525
+ }
26526
+ if (next === "a") {
26527
+ bytes.push(7);
26528
+ i++;
26529
+ continue;
26530
+ }
26531
+ if (next === "b") {
26532
+ bytes.push(8);
26533
+ i++;
26534
+ continue;
26535
+ }
26536
+ if (next === "t") {
26537
+ bytes.push(9);
26538
+ i++;
26539
+ continue;
26540
+ }
26541
+ if (next === "n") {
26542
+ bytes.push(10);
26543
+ i++;
26544
+ continue;
26545
+ }
26546
+ if (next === "v") {
26547
+ bytes.push(11);
26548
+ i++;
26549
+ continue;
26550
+ }
26551
+ if (next === "f") {
26552
+ bytes.push(12);
26553
+ i++;
26554
+ continue;
26555
+ }
26556
+ if (next === "r") {
26557
+ bytes.push(13);
26558
+ i++;
26559
+ continue;
26560
+ }
26561
+ if (next >= "0" && next <= "7") {
26562
+ let j = i + 1;
26563
+ let digits = "";
26564
+ while (j < inner.length && digits.length < 3 && inner[j] >= "0" && inner[j] <= "7") {
26565
+ digits += inner[j];
26566
+ j++;
26567
+ }
26568
+ const byte = Number.parseInt(digits, 8);
26569
+ if (!Number.isNaN(byte)) {
26570
+ bytes.push(byte);
26571
+ i = j - 1;
26572
+ continue;
26573
+ }
26574
+ }
26575
+ if (next === "x") {
26576
+ const slice = inner.slice(i + 2, i + 4);
26577
+ if (slice.length === 2 && /^[0-9a-fA-F]{2}$/.test(slice)) {
26578
+ bytes.push(Number.parseInt(slice, 16));
26579
+ i += 3;
26580
+ continue;
26581
+ }
26582
+ }
26583
+ bytes.push(c.charCodeAt(0));
26584
+ }
26585
+ return new TextDecoder("utf-8").decode(new Uint8Array(bytes));
26586
+ }
26587
+ function splitRenameOldPath(pathField) {
26588
+ let start = 0;
26589
+ if (pathField.startsWith('"')) {
26590
+ let i = 1;
26591
+ while (i < pathField.length) {
26592
+ const c = pathField[i];
26593
+ if (c === "\\" && i + 1 < pathField.length) {
26594
+ i += 2;
26595
+ continue;
26596
+ }
26597
+ if (c === '"') {
26598
+ start = i + 1;
26599
+ break;
26600
+ }
26601
+ i++;
26602
+ }
26603
+ }
26604
+ const arrowIdx = pathField.indexOf(" -> ", start);
26605
+ if (arrowIdx < 0)
26606
+ return null;
26607
+ return pathField.slice(0, arrowIdx);
26608
+ }
26609
+
26442
26610
  // src/utils/git.ts
26443
26611
  async function getGitRoot(workdir) {
26444
26612
  try {
@@ -26583,6 +26751,32 @@ async function autoCommitIfDirty(workdir, stage, role, storyId, blockedWorktrees
26583
26751
  dirtyFiles: statusOutput.trim().split(`
26584
26752
  `).length
26585
26753
  });
26754
+ const naxPaths = parsePorcelainForNaxPaths(statusOutput);
26755
+ for (const { path: protectedPath, staged } of naxPaths) {
26756
+ logger?.error(stage, "Restoring deleted .nax/ path before auto-commit", {
26757
+ storyId,
26758
+ role,
26759
+ path: protectedPath,
26760
+ staged
26761
+ });
26762
+ const checkoutArgs = staged ? ["git", "checkout", "HEAD", "--", protectedPath] : ["git", "checkout", "--", protectedPath];
26763
+ const checkoutProc = _gitDeps.spawn(checkoutArgs, {
26764
+ cwd: realGitRoot,
26765
+ stdout: "pipe",
26766
+ stderr: "pipe"
26767
+ });
26768
+ const checkoutExit = await checkoutProc.exited;
26769
+ if (checkoutExit !== 0) {
26770
+ const stderr = await new Response(checkoutProc.stderr).text();
26771
+ logger?.error(stage, "Failed to restore .nax/ path before auto-commit", {
26772
+ storyId,
26773
+ role,
26774
+ path: protectedPath,
26775
+ exitCode: checkoutExit,
26776
+ stderr: stderr.trim()
26777
+ });
26778
+ }
26779
+ }
26586
26780
  const addProc = _gitDeps.spawn(["git", "add", "-A"], { cwd: realGitRoot, stdout: "pipe", stderr: "pipe" });
26587
26781
  await addProc.exited;
26588
26782
  const commitProc = _gitDeps.spawn(["git", "commit", "-m", `chore(${storyId}): auto-commit after ${role} session`], {
@@ -33409,6 +33603,20 @@ Include the story ID when known \u2014 \`feat(<story-id>): <description>\`.
33409
33603
  When the story is ambiguous, pick an interpretation, proceed, and document the choice in the commit body under \`Assumptions:\`. Do not invent requirements; do not silently choose when the story is genuinely under-specified \u2014 note it.`;
33410
33604
  }
33411
33605
 
33606
+ // src/prompts/sections/nax-artifacts.ts
33607
+ function buildNaxArtifactsSection(role, _variant, _isolation) {
33608
+ return `# .nax/ artifact immutability
33609
+
33610
+ Files under \`.nax/\` are nax's own artifacts (acceptance scaffolds, plan state, generated acceptance
33611
+ tests). They must NEVER be moved, renamed, or deleted \u2014 \`.nax/\` is a tool-managed directory and
33612
+ modifying it breaks the orchestrator.
33613
+
33614
+ - A test under \`.nax/\` is NOT a reason to skip writing source-tree tests. \`.nax/\` is generated
33615
+ scaffolding, not real coverage of the package's code.
33616
+ - A source-tree test is NOT a reason to remove a test under \`.nax/\`. The two serve different
33617
+ purposes and must coexist.`;
33618
+ }
33619
+
33412
33620
  // src/prompts/sections/test-quality.ts
33413
33621
  function buildTestQualitySection(role, variant, storyId) {
33414
33622
  const authors = AUTHORING_ROLES.has(role) || role === "implementer" && variant === "lite";
@@ -33597,6 +33805,9 @@ class TddPromptBuilder {
33597
33805
  const guardrails = buildBehavioralGuardrailsSection(this.role, guardrailLevel, guardrailVariant, guardrailIsolation);
33598
33806
  if (guardrails)
33599
33807
  acc.add(this.s("guardrails", guardrails));
33808
+ const naxArtifacts = buildNaxArtifactsSection(this.role, guardrailVariant, guardrailIsolation);
33809
+ if (naxArtifacts)
33810
+ acc.add(this.s("nax-artifacts", naxArtifacts));
33600
33811
  const testQuality = buildTestQualitySection(this.role, this.options.variant, this.story_?.id);
33601
33812
  if (testQuality)
33602
33813
  acc.add(this.s("test-quality", testQuality));
@@ -43501,12 +43712,23 @@ var init_mutation_check = __esm(() => {
43501
43712
  candidates: 0,
43502
43713
  checked: false
43503
43714
  };
43504
- const record2 = (result) => {
43715
+ const logger = getLogger();
43716
+ const record2 = (result, skipReason) => {
43505
43717
  if (ctx.storyId) {
43506
43718
  ctx.runtime?.mutationSummaries?.set(ctx.storyId, { storyId: ctx.storyId, ...result });
43507
43719
  }
43720
+ if (result.checked) {
43721
+ logger.info("mutation-check", "Mutation spot-check outcomes", {
43722
+ storyId: input.storyId,
43723
+ killed: result.outcomes.killed,
43724
+ survived: result.outcomes.survived,
43725
+ errored: result.outcomes.errored,
43726
+ candidates: result.candidates,
43727
+ ...skipReason ? { skipReason } : {},
43728
+ ...result.revertFailed ? { revertFailed: true } : {}
43729
+ });
43730
+ }
43508
43731
  };
43509
- const logger = getLogger();
43510
43732
  if (!cfg?.enabled) {
43511
43733
  if (await mayHaveJournal([input.workdir, input.repoRoot])) {
43512
43734
  await sweepLeftoverMutants(await deps.getGitRoot(input.workdir) ?? input.workdir, input.storyId);
@@ -43544,7 +43766,7 @@ var init_mutation_check = __esm(() => {
43544
43766
  logger.warn("mutation-check", "Failed to obtain changed-line ranges \u2014 skipping mutation spot-check", {
43545
43767
  storyId: input.storyId
43546
43768
  });
43547
- record2({ ...emptyOutput, checked: true });
43769
+ record2({ ...emptyOutput, checked: true }, "changed-line-ranges-unavailable");
43548
43770
  return { success: true, ...emptyOutput, checked: true };
43549
43771
  }
43550
43772
  const survivors = [];
@@ -43779,8 +44001,8 @@ var init_cycle_iteration_log = __esm(() => {
43779
44001
  });
43780
44002
 
43781
44003
  // src/findings/cycle-retirement.ts
43782
- function createDeclineLedger() {
43783
- const declinedByStrategy = new Map;
44004
+ function createDeclineLedger(backing) {
44005
+ const declinedByStrategy = backing ?? new Map;
43784
44006
  const hasDeclined = (strategyName, finding) => declinedByStrategy.get(strategyName)?.has(findingKey(finding)) === true;
43785
44007
  const isRetiredFor = (strategy, findings) => {
43786
44008
  const claimed = findings.filter((f) => strategy.appliesTo(f));
@@ -43872,13 +44094,14 @@ async function runFixCycle(cycle, ctx, cycleName, _deps = {}) {
43872
44094
  const storyId = ctx.storyId;
43873
44095
  const packageDir = ctx.packageDir;
43874
44096
  let totalCostUsd = 0;
43875
- const declines = createDeclineLedger();
44097
+ const declines = createDeclineLedger(_deps.declineBacking);
43876
44098
  let unresolvedDetail;
43877
44099
  const finish = (result) => unresolvedDetail !== undefined && result.unresolvedDetail === undefined ? { ...result, unresolvedDetail } : result;
43878
44100
  for (;; ) {
43879
44101
  if (cycle.findings.length === 0 && cycle.verdict === undefined) {
43880
44102
  return { iterations: cycle.iterations, finalFindings: [], exitReason: "resolved", costUsd: totalCostUsd };
43881
44103
  }
44104
+ const history = cycle.priorIterations ? [...cycle.priorIterations, ...cycle.iterations] : cycle.iterations;
43882
44105
  const selectable = cycle.strategies.filter((s) => !declines.isRetiredFor(s, cycle.findings));
43883
44106
  const active = selectActiveStrategies(selectable, cycle.findings, cycle.verdict);
43884
44107
  if (active.length === 0) {
@@ -43900,9 +44123,9 @@ async function runFixCycle(cycle, ctx, cycleName, _deps = {}) {
43900
44123
  costUsd: totalCostUsd
43901
44124
  });
43902
44125
  }
43903
- const uncappedActive = active.filter((s) => countStrategyAttempts(cycle.iterations, s.name) < s.maxAttempts);
44126
+ const uncappedActive = active.filter((s) => countStrategyAttempts(history, s.name) < s.maxAttempts);
43904
44127
  if (uncappedActive.length === 0) {
43905
- const exhaustedStrategy = active.find((s) => countStrategyAttempts(cycle.iterations, s.name) >= s.maxAttempts);
44128
+ const exhaustedStrategy = active.find((s) => countStrategyAttempts(history, s.name) >= s.maxAttempts);
43906
44129
  logger?.info("findings.cycle", "cycle exited \u2014 all active strategies exhausted", {
43907
44130
  storyId,
43908
44131
  packageDir,
@@ -43918,7 +44141,7 @@ async function runFixCycle(cycle, ctx, cycleName, _deps = {}) {
43918
44141
  costUsd: totalCostUsd
43919
44142
  });
43920
44143
  }
43921
- const totalAttempts = countTotalAttempts(cycle.iterations);
44144
+ const totalAttempts = countTotalAttempts(history);
43922
44145
  if (totalAttempts >= cycle.config.maxAttemptsTotal) {
43923
44146
  logger?.info("findings.cycle", "cycle exited \u2014 total attempt cap reached", {
43924
44147
  storyId,
@@ -43936,7 +44159,7 @@ async function runFixCycle(cycle, ctx, cycleName, _deps = {}) {
43936
44159
  });
43937
44160
  }
43938
44161
  for (const strategy of uncappedActive) {
43939
- const bailReason = strategy.bailWhen?.(cycle.iterations) ?? null;
44162
+ const bailReason = strategy.bailWhen?.(history) ?? null;
43940
44163
  if (bailReason !== null) {
43941
44164
  logger?.info("findings.cycle", "cycle exited \u2014 bail predicate fired", {
43942
44165
  storyId,
@@ -44024,7 +44247,7 @@ async function runFixCycle(cycle, ctx, cycleName, _deps = {}) {
44024
44247
  });
44025
44248
  }
44026
44249
  const allExhausted = group.every((s) => {
44027
- const prior = countStrategyAttempts(cycle.iterations, s.name);
44250
+ const prior = countStrategyAttempts(history, s.name);
44028
44251
  const current = fixesApplied.filter((fa) => fa.strategyName === s.name).length;
44029
44252
  return prior + current >= s.maxAttempts;
44030
44253
  });
@@ -44192,6 +44415,55 @@ var init_cycle = __esm(() => {
44192
44415
  };
44193
44416
  });
44194
44417
 
44418
+ // src/findings/bail-marker.ts
44419
+ function markNaxBailWrapper(predicate) {
44420
+ Object.assign(predicate, { [NAX_BAIL_WRAPPER]: true });
44421
+ return predicate;
44422
+ }
44423
+ function isNaxBailWrapper(predicate) {
44424
+ if (!predicate)
44425
+ return false;
44426
+ return predicate[NAX_BAIL_WRAPPER] === true;
44427
+ }
44428
+ var NAX_BAIL_WRAPPER = "__naxBailWrapper";
44429
+
44430
+ // src/findings/story-fix-history.ts
44431
+ function createStoryFixHistory() {
44432
+ return new Map;
44433
+ }
44434
+ function storyFixKey(storyId, tier) {
44435
+ return `${storyId}::${tier ?? "default"}`;
44436
+ }
44437
+ function getStoryFixState(store, key) {
44438
+ let existing = store.get(key);
44439
+ if (!existing) {
44440
+ existing = { iterations: [], declines: new Map };
44441
+ store.set(key, existing);
44442
+ }
44443
+ return existing;
44444
+ }
44445
+ function appendStoryFixIterations(store, key, iterations) {
44446
+ const existing = store.get(key);
44447
+ if (existing) {
44448
+ store.set(key, {
44449
+ iterations: [...existing.iterations, ...iterations],
44450
+ declines: existing.declines
44451
+ });
44452
+ } else {
44453
+ store.set(key, {
44454
+ iterations: [...iterations],
44455
+ declines: new Map
44456
+ });
44457
+ }
44458
+ }
44459
+ function mergeStoryFixDeclines(store, key, declines) {
44460
+ const existing = store.get(key);
44461
+ store.set(key, {
44462
+ iterations: existing?.iterations ?? [],
44463
+ declines: new Map([...declines].map(([name, keys]) => [name, new Set(keys)]))
44464
+ });
44465
+ }
44466
+
44195
44467
  // src/findings/index.ts
44196
44468
  var init_findings = __esm(() => {
44197
44469
  init_types6();
@@ -44199,6 +44471,7 @@ var init_findings = __esm(() => {
44199
44471
  init_path_utils();
44200
44472
  init_cycle();
44201
44473
  init_cycle_iteration_log();
44474
+ init_cycle_retirement();
44202
44475
  });
44203
44476
 
44204
44477
  // src/review/review-iteration-store.ts
@@ -44685,7 +44958,7 @@ var package_default;
44685
44958
  var init_package = __esm(() => {
44686
44959
  package_default = {
44687
44960
  name: "@nathapp/nax",
44688
- version: "0.77.1",
44961
+ version: "0.77.3",
44689
44962
  description: "AI Coding Agent Orchestrator \u2014 loops until done",
44690
44963
  type: "module",
44691
44964
  bin: {
@@ -44749,7 +45022,7 @@ var init_package = __esm(() => {
44749
45022
  "@biomejs/biome": "^1.9.4",
44750
45023
  "@types/bun": "^1.3.8",
44751
45024
  "react-devtools-core": "^7.0.1",
44752
- typescript: "^5.7.3"
45025
+ typescript: "^7.0.2"
44753
45026
  },
44754
45027
  license: "MIT",
44755
45028
  author: "William Khoo",
@@ -44789,8 +45062,8 @@ var init_version = __esm(() => {
44789
45062
  NAX_VERSION = package_default.version;
44790
45063
  NAX_COMMIT = (() => {
44791
45064
  try {
44792
- if (/^[0-9a-f]{6,10}$/.test("a50be624"))
44793
- return "a50be624";
45065
+ if (/^[0-9a-f]{6,10}$/.test("e42ce962"))
45066
+ return "e42ce962";
44794
45067
  } catch {}
44795
45068
  try {
44796
45069
  const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
@@ -46848,6 +47121,8 @@ evidence that an acceptance criterion is already tested, and you may NOT emit UN
46848
47121
  The only valid response to a missing-test finding is to
46849
47122
  author a real test under the package's resolved test path.
46850
47123
 
47124
+ ${buildNaxArtifactsSection("implementer")}
47125
+
46851
47126
  ## Test-file edit exceptions
46852
47127
 
46853
47128
  The "do not modify test files" rule has ${countWord} narrow escape valves. Each requires a
@@ -51912,6 +52187,7 @@ function createRuntime(config2, workdir, opts) {
51912
52187
  const adversarialIterations = new Map;
51913
52188
  const semanticIterations = new Map;
51914
52189
  const rectificationOscillations = new Map;
52190
+ const storyFixHistory = createStoryFixHistory();
51915
52191
  const mutationSummaries = new Map;
51916
52192
  const dirtyWorktrees = new Set;
51917
52193
  let closed = false;
@@ -51938,6 +52214,7 @@ function createRuntime(config2, workdir, opts) {
51938
52214
  adversarialIterations,
51939
52215
  semanticIterations,
51940
52216
  rectificationOscillations,
52217
+ storyFixHistory,
51941
52218
  mutationSummaries,
51942
52219
  dirtyWorktrees,
51943
52220
  get signal() {
@@ -51985,6 +52262,7 @@ var init_runtime = __esm(() => {
51985
52262
  init_config();
51986
52263
  init_errors();
51987
52264
  init_pid_registry();
52265
+ init_findings();
51988
52266
  init_logger2();
51989
52267
  init_review_audit();
51990
52268
  init_session();
@@ -59101,6 +59379,7 @@ __export(exports_acceptance2, {
59101
59379
  acceptanceStage: () => acceptanceStage,
59102
59380
  _acceptanceStageDeps: () => _acceptanceStageDeps
59103
59381
  });
59382
+ import path12 from "path";
59104
59383
  function areAllStoriesComplete(ctx) {
59105
59384
  const counts = countStories(ctx.prd);
59106
59385
  const totalComplete = counts.passed + counts.failed + counts.skipped;
@@ -59145,18 +59424,42 @@ var init_acceptance3 = __esm(() => {
59145
59424
  packageDir: ctx.workdir
59146
59425
  }
59147
59426
  ];
59427
+ const storiesByPackageDir = new Map;
59428
+ for (const s of ctx.prd.userStories) {
59429
+ if (s.id.startsWith("US-FIX-") || s.status === "decomposed")
59430
+ continue;
59431
+ const wd = s.workdir ?? "";
59432
+ const pkgDir = wd ? path12.join(ctx.workdir, wd) : ctx.workdir;
59433
+ storiesByPackageDir.set(pkgDir, (storiesByPackageDir.get(pkgDir) ?? 0) + 1);
59434
+ }
59148
59435
  const allFailedACs = [];
59149
59436
  const allFindings = [];
59150
59437
  const failedPackages = [];
59438
+ const missingTargets = [];
59151
59439
  const allOutputParts = [];
59152
59440
  let anyError = false;
59153
59441
  let errorExitCode = 0;
59154
59442
  let hardeningPromoted = 0;
59155
- for (const { testPath, packageDir, testFramework, commandOverride } of testGroups) {
59443
+ for (const { testPath, packageDir, testFramework, commandOverride, storyCount, acceptanceEnabled } of testGroups) {
59156
59444
  const testFile = Bun.file(testPath);
59157
59445
  const exists = await testFile.exists();
59158
59446
  if (!exists) {
59159
- logger.warn("acceptance", "Acceptance test file not found \u2014 skipping", { storyId: ctx.story.id, testPath });
59447
+ const resolvedStoryCount = storyCount ?? storiesByPackageDir.get(packageDir) ?? 0;
59448
+ const resolvedAcceptanceEnabled = acceptanceEnabled ?? true;
59449
+ if (resolvedStoryCount > 0 && resolvedAcceptanceEnabled) {
59450
+ logger.warn("acceptance", "Required acceptance test file missing", {
59451
+ storyId: ctx.story.id,
59452
+ testPath,
59453
+ packageDir
59454
+ });
59455
+ missingTargets.push(packageDir);
59456
+ } else {
59457
+ logger.warn("acceptance", "Acceptance test file not found \u2014 skipping", {
59458
+ storyId: ctx.story.id,
59459
+ testPath,
59460
+ packageDir
59461
+ });
59462
+ }
59160
59463
  continue;
59161
59464
  }
59162
59465
  const resolvedFramework = testFramework ?? ctx.config.project?.testFramework;
@@ -59233,6 +59536,29 @@ ${stderr}`;
59233
59536
  const combinedOutput = allOutputParts.join(`
59234
59537
  `);
59235
59538
  const durationMs = Date.now() - startTime;
59539
+ if (missingTargets.length > 0) {
59540
+ ctx.acceptanceFailures = {
59541
+ failedACs: allFailedACs,
59542
+ findings: allFindings,
59543
+ testOutput: combinedOutput,
59544
+ failedPackages,
59545
+ missingTargets
59546
+ };
59547
+ logger.info("acceptance", "verdict", {
59548
+ storyId: ctx.story.id,
59549
+ packageDir: ctx.workdir,
59550
+ passed: false,
59551
+ failedACs: allFailedACs,
59552
+ retries: ctx.acceptanceRetries ?? 0,
59553
+ hardeningPromoted,
59554
+ durationMs,
59555
+ missingTargets
59556
+ });
59557
+ return {
59558
+ action: "fail",
59559
+ reason: `Required acceptance test files are missing for packages: ${missingTargets.join(", ")}`
59560
+ };
59561
+ }
59236
59562
  if (allFailedACs.length === 0) {
59237
59563
  logger.info("acceptance", "All acceptance tests passed", { storyId: ctx.story.id });
59238
59564
  const hardeningEnabled = ctx.config.acceptance?.hardening?.enabled !== false;
@@ -59380,7 +59706,7 @@ __export(exports_acceptance_setup, {
59380
59706
  acceptanceSetupStage: () => acceptanceSetupStage,
59381
59707
  _acceptanceSetupDeps: () => _acceptanceSetupDeps
59382
59708
  });
59383
- import path12 from "path";
59709
+ import path13 from "path";
59384
59710
  function computeACFingerprint(criteria) {
59385
59711
  const sorted = [...criteria].sort().join(`
59386
59712
  `);
@@ -59391,7 +59717,7 @@ function computeACFingerprint(criteria) {
59391
59717
  async function runAcceptanceSetup(ctx, featureDir, phaseStartTime) {
59392
59718
  const language = ctx.config.project?.language;
59393
59719
  const testPathConfig = ctx.config.acceptance.testPath;
59394
- const metaPath = path12.join(featureDir, "acceptance-meta.json");
59720
+ const metaPath = path13.join(featureDir, "acceptance-meta.json");
59395
59721
  const allCriteria = ctx.prd.userStories.filter((s) => !s.id.startsWith("US-FIX-") && s.status !== "decomposed").flatMap((s) => s.acceptanceCriteria);
59396
59722
  const featureName = ctx.prd.feature ?? ctx.prd.featureName;
59397
59723
  const groups = await groupStoriesByPackage(ctx.prd, ctx.workdir, featureName, testPathConfig, language);
@@ -59518,7 +59844,7 @@ async function runAcceptanceSetup(ctx, featureDir, phaseStartTime) {
59518
59844
  testable: c.testable,
59519
59845
  storyId: c.storyId
59520
59846
  })), null, 2);
59521
- await _acceptanceSetupDeps.writeFile(path12.join(featureDir, "acceptance-refined.json"), refinedJsonContent);
59847
+ await _acceptanceSetupDeps.writeFile(path13.join(featureDir, "acceptance-refined.json"), refinedJsonContent);
59522
59848
  }
59523
59849
  const fingerprint2 = computeACFingerprint(allCriteria);
59524
59850
  await _acceptanceSetupDeps.writeMeta(metaPath, {
@@ -59532,7 +59858,7 @@ async function runAcceptanceSetup(ctx, featureDir, phaseStartTime) {
59532
59858
  }
59533
59859
  const acceptanceTestPaths = [];
59534
59860
  for (const g of groups) {
59535
- const relativeWorkdir = path12.relative(ctx.projectDir, g.packageDir);
59861
+ const relativeWorkdir = path13.relative(ctx.projectDir, g.packageDir);
59536
59862
  let groupConfig = ctx.config;
59537
59863
  if (relativeWorkdir && relativeWorkdir !== ".") {
59538
59864
  try {
@@ -59545,7 +59871,9 @@ async function runAcceptanceSetup(ctx, featureDir, phaseStartTime) {
59545
59871
  testPath: g.testPath,
59546
59872
  packageDir: g.packageDir,
59547
59873
  testFramework: groupConfig.project?.testFramework,
59548
- commandOverride: groupConfig.acceptance.command
59874
+ commandOverride: groupConfig.acceptance.command,
59875
+ storyCount: g.stories.length,
59876
+ acceptanceEnabled: groupConfig.acceptance.enabled
59549
59877
  });
59550
59878
  }
59551
59879
  ctx.acceptanceTestPaths = acceptanceTestPaths;
@@ -59662,7 +59990,7 @@ var init_acceptance_setup = __esm(() => {
59662
59990
  },
59663
59991
  autoCommitIfDirty,
59664
59992
  loadGroupConfig: async (projectDir, relativeWorkdir) => {
59665
- return loadConfigForWorkdir(path12.join(projectDir, ".nax", "config.json"), relativeWorkdir || undefined);
59993
+ return loadConfigForWorkdir(path13.join(projectDir, ".nax", "config.json"), relativeWorkdir || undefined);
59666
59994
  },
59667
59995
  runTest: async (_testPath, _workdir, _cmd) => {
59668
59996
  const cmd = _cmd;
@@ -60299,7 +60627,7 @@ var init_story_context = __esm(() => {
60299
60627
 
60300
60628
  // src/execution/lock.ts
60301
60629
  import { unlink as unlink2 } from "fs/promises";
60302
- import path13 from "path";
60630
+ import path14 from "path";
60303
60631
  function getSafeLogger3() {
60304
60632
  try {
60305
60633
  return getLogger();
@@ -60316,7 +60644,7 @@ function isProcessAlive(pid) {
60316
60644
  }
60317
60645
  }
60318
60646
  async function acquireLock(workdir) {
60319
- const lockPath = path13.join(workdir, "nax.lock");
60647
+ const lockPath = path14.join(workdir, "nax.lock");
60320
60648
  const lockFile = Bun.file(lockPath);
60321
60649
  try {
60322
60650
  const exists = await lockFile.exists();
@@ -60368,7 +60696,7 @@ async function acquireLock(workdir) {
60368
60696
  }
60369
60697
  }
60370
60698
  async function releaseLock(workdir) {
60371
- const lockPath = path13.join(workdir, "nax.lock");
60699
+ const lockPath = path14.join(workdir, "nax.lock");
60372
60700
  try {
60373
60701
  await unlink2(lockPath);
60374
60702
  } catch (error48) {
@@ -61274,6 +61602,45 @@ function countOscillationOutcomes(iterations) {
61274
61602
  return count;
61275
61603
  }
61276
61604
 
61605
+ // src/execution/story-orchestrator/no-progress-bail.ts
61606
+ function madeNoProgress(iteration) {
61607
+ if (iteration.findingsBefore.length === 0)
61608
+ return false;
61609
+ const after = new Set(iteration.findingsAfter.map(findingKey));
61610
+ return iteration.findingsBefore.every((finding) => after.has(findingKey(finding)));
61611
+ }
61612
+ function withNoProgressBail(strategies, enabled, consecutiveNoProgress) {
61613
+ if (!enabled)
61614
+ return strategies;
61615
+ const threshold = Math.max(1, consecutiveNoProgress);
61616
+ return strategies.map((strategy) => {
61617
+ const innerBail = strategy.bailWhen;
61618
+ const isUserBail = innerBail !== undefined && !isNaxBailWrapper(innerBail);
61619
+ return {
61620
+ ...strategy,
61621
+ bailWhen: markNaxBailWrapper((iterations) => {
61622
+ if (isUserBail) {
61623
+ const userReason = innerBail(iterations);
61624
+ if (userReason !== null)
61625
+ return userReason;
61626
+ }
61627
+ if (iterations.length >= threshold) {
61628
+ const trailing = iterations.slice(-threshold);
61629
+ if (trailing.every(madeNoProgress)) {
61630
+ return `no finding resolved for ${threshold} consecutive iteration(s); ${trailing.at(-1)?.findingsBefore.length ?? 0} finding(s) persisted`;
61631
+ }
61632
+ }
61633
+ if (!isUserBail && innerBail)
61634
+ return innerBail(iterations);
61635
+ return null;
61636
+ })
61637
+ };
61638
+ });
61639
+ }
61640
+ var init_no_progress_bail = __esm(() => {
61641
+ init_findings();
61642
+ });
61643
+
61277
61644
  // src/execution/checkpoint/resume-plan.ts
61278
61645
  function buildResumePlan(cp, current) {
61279
61646
  if (!cp) {
@@ -61806,7 +62173,7 @@ function withIncreasingFailuresBail(strategies, enabled, consecutiveIncreases) {
61806
62173
  const threshold = Math.max(1, consecutiveIncreases);
61807
62174
  return strategies.map((strategy) => ({
61808
62175
  ...strategy,
61809
- bailWhen: (iterations) => {
62176
+ bailWhen: markNaxBailWrapper((iterations) => {
61810
62177
  const userReason = strategy.bailWhen?.(iterations) ?? null;
61811
62178
  if (userReason !== null)
61812
62179
  return userReason;
@@ -61820,7 +62187,7 @@ function withIncreasingFailuresBail(strategies, enabled, consecutiveIncreases) {
61820
62187
  return `failure count increased for ${threshold} consecutive iteration(s): ${first.findingsBefore.length} -> ${last.findingsAfter.length}`;
61821
62188
  }
61822
62189
  return null;
61823
- }
62190
+ })
61824
62191
  }));
61825
62192
  }
61826
62193
  var _storyOrchestratorDeps, ALL_FINDING_SEVERITIES;
@@ -61986,6 +62353,12 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs, overrides)
61986
62353
  if (!ctx.storyId) {
61987
62354
  return {};
61988
62355
  }
62356
+ const storyFixBudgetEnabled = !nbfPath && ctx.runtime.configLoader.current().execution?.rectification?.storyScopedFixBudget === true;
62357
+ const store = ctx.runtime.storyFixHistory;
62358
+ const fixKey = storyFixBudgetEnabled ? storyFixKey(ctx.storyId, ctx.phaseTelemetry?.tier) : undefined;
62359
+ const fixState = fixKey !== undefined && store ? getStoryFixState(store, fixKey) : undefined;
62360
+ const priorIterationCount = fixState?.iterations.length ?? 0;
62361
+ const declineSnapshot = fixState ? new Map([...fixState.declines].map(([name, keys]) => [name, new Set(keys)])) : undefined;
61989
62362
  const fixOpPhaseOutputs = {};
61990
62363
  const wrappedCallOp = async (cycleCtx, op, input) => {
61991
62364
  const slot = { op, input };
@@ -61994,7 +62367,8 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs, overrides)
61994
62367
  const cycle = {
61995
62368
  findings: [...initialFindings],
61996
62369
  iterations: [],
61997
- strategies: withIncreasingFailuresBail(overrides?.strategies ?? rectification2.strategies, rectification2.abortOnIncreasingFailures, rectification2.consecutiveIncreasesToBail ?? 1),
62370
+ priorIterations: fixState?.iterations,
62371
+ strategies: withNoProgressBail(withIncreasingFailuresBail(overrides?.strategies ?? rectification2.strategies, rectification2.abortOnIncreasingFailures, rectification2.consecutiveIncreasesToBail ?? 1), rectification2.abortOnNoProgress ?? true, rectification2.consecutiveNoProgressToBail ?? 3),
61998
62372
  config: { maxAttemptsTotal: overrides?.maxAttempts ?? rectification2.maxAttempts, validatorRetries: 1 },
61999
62373
  validate: async (_validateCtx, opts) => {
62000
62374
  if (ctx.runtime.signal?.aborted)
@@ -62055,15 +62429,22 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs, overrides)
62055
62429
  return { findings: validated, shortCircuited };
62056
62430
  }
62057
62431
  };
62058
- const cycleResult = await _storyOrchestratorDeps.runFixCycle(cycle, ctx, "story-orchestrator-rectification", { callOp: wrappedCallOp });
62432
+ const cycleResult = await _storyOrchestratorDeps.runFixCycle(cycle, ctx, "story-orchestrator-rectification", { callOp: wrappedCallOp, declineBacking: declineSnapshot });
62433
+ if (fixKey !== undefined && store && cycleResult.iterations.length > 0) {
62434
+ appendStoryFixIterations(store, fixKey, cycleResult.iterations);
62435
+ }
62436
+ if (fixKey !== undefined && store && declineSnapshot) {
62437
+ mergeStoryFixDeclines(store, fixKey, declineSnapshot);
62438
+ }
62059
62439
  const oscillationCount = countOscillationOutcomes(cycleResult.iterations);
62060
62440
  if (oscillationCount > 0) {
62061
62441
  recordOscillations(ctx.runtime.rectificationOscillations, ctx.storyId, oscillationCount);
62062
62442
  }
62443
+ const reportedExitReason = cycleResult.exitReason === "validate-short-circuit" && priorIterationCount > 0 ? "max-attempts-per-strategy" : cycleResult.exitReason;
62063
62444
  phaseOutputs.rectification = {
62064
62445
  success: cycleResult.exitReason === "resolved",
62065
62446
  iterationCount: cycleResult.iterations.length,
62066
- exitReason: cycleResult.exitReason,
62447
+ exitReason: reportedExitReason,
62067
62448
  finalFindingsCount: cycleResult.finalFindings.length
62068
62449
  };
62069
62450
  const rectLogger = getSafeLogger();
@@ -62072,7 +62453,7 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs, overrides)
62072
62453
  initialFindingsCount: initialFindings.length,
62073
62454
  iterationCount: cycleResult.iterations.length,
62074
62455
  finalFindingsCount: cycleResult.finalFindings.length,
62075
- exitReason: cycleResult.exitReason,
62456
+ exitReason: reportedExitReason,
62076
62457
  costUsd: cycleResult.costUsd
62077
62458
  };
62078
62459
  if (cycleResult.exitReason === "resolved") {
@@ -62098,8 +62479,10 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs, overrides)
62098
62479
  return {};
62099
62480
  }
62100
62481
  var init_rectification = __esm(() => {
62482
+ init_findings();
62101
62483
  init_logger2();
62102
62484
  init_nbf_flake_triage();
62485
+ init_no_progress_bail();
62103
62486
  init_phase_eval();
62104
62487
  init_phase_eval();
62105
62488
  init_run_phase();
@@ -62453,6 +62836,7 @@ var init_story_orchestrator = __esm(() => {
62453
62836
  init_phase_eval();
62454
62837
  init_rectification();
62455
62838
  init_nbf_flake_triage();
62839
+ init_no_progress_bail();
62456
62840
  init_run_phase();
62457
62841
  init_review_decision();
62458
62842
  init_types9();
@@ -62873,7 +63257,9 @@ async function assemblePlanInputsFromCtx(ctx) {
62873
63257
  maxAttempts: ctx.config.execution.rectification.maxAttemptsTotal,
62874
63258
  strategies: [],
62875
63259
  abortOnIncreasingFailures: ctx.config.execution.rectification.abortOnIncreasingFailures,
62876
- consecutiveIncreasesToBail: ctx.config.execution.rectification.consecutiveIncreasesToBail
63260
+ consecutiveIncreasesToBail: ctx.config.execution.rectification.consecutiveIncreasesToBail,
63261
+ abortOnNoProgress: ctx.config.execution.rectification.abortOnNoProgress,
63262
+ consecutiveNoProgressToBail: ctx.config.execution.rectification.consecutiveNoProgressToBail
62877
63263
  } : undefined;
62878
63264
  const mutationCheckInput = ctx.config.execution?.mutationCheck?.enabled === true ? {
62879
63265
  story,
@@ -63834,7 +64220,7 @@ function parseQueueFile(content) {
63834
64220
  var init_queue = () => {};
63835
64221
 
63836
64222
  // src/execution/queue-handler.ts
63837
- import path14 from "path";
64223
+ import path15 from "path";
63838
64224
  function getSafeLogger4() {
63839
64225
  try {
63840
64226
  return getLogger();
@@ -63843,8 +64229,8 @@ function getSafeLogger4() {
63843
64229
  }
63844
64230
  }
63845
64231
  async function readQueueFile(workdir) {
63846
- const queuePath = path14.join(workdir, ".queue.txt");
63847
- const processingPath = path14.join(workdir, ".queue.txt.processing");
64232
+ const queuePath = path15.join(workdir, ".queue.txt");
64233
+ const processingPath = path15.join(workdir, ".queue.txt.processing");
63848
64234
  const logger = getSafeLogger4();
63849
64235
  try {
63850
64236
  const file3 = Bun.file(queuePath);
@@ -63869,7 +64255,7 @@ async function readQueueFile(workdir) {
63869
64255
  }
63870
64256
  }
63871
64257
  async function clearQueueFile(workdir) {
63872
- const processingPath = path14.join(workdir, ".queue.txt.processing");
64258
+ const processingPath = path15.join(workdir, ".queue.txt.processing");
63873
64259
  const logger = getSafeLogger4();
63874
64260
  try {
63875
64261
  const file3 = Bun.file(processingPath);
@@ -63889,7 +64275,7 @@ var init_queue_handler = __esm(() => {
63889
64275
  });
63890
64276
 
63891
64277
  // src/pipeline/stages/queue-check.ts
63892
- import path15 from "path";
64278
+ import path16 from "path";
63893
64279
  var queueCheckStage;
63894
64280
  var init_queue_check = __esm(() => {
63895
64281
  init_config();
@@ -63943,10 +64329,10 @@ var init_queue_check = __esm(() => {
63943
64329
  }
63944
64330
  if (cmd.type === "INJECT") {
63945
64331
  try {
63946
- if (path15.isAbsolute(cmd.storyFile)) {
64332
+ if (path16.isAbsolute(cmd.storyFile)) {
63947
64333
  throw new NaxError(`INJECT storyFile must be a relative path within the workspace: ${cmd.storyFile}`, "INJECT_PATH_ABSOLUTE", { stage: "queue-check", storyId: ctx.story?.id ?? "unknown", storyFile: cmd.storyFile });
63948
64334
  }
63949
- const storyFilePath = validateFilePath(path15.join(ctx.workdir, cmd.storyFile), ctx.workdir);
64335
+ const storyFilePath = validateFilePath(path16.join(ctx.workdir, cmd.storyFile), ctx.workdir);
63950
64336
  const raw = await Bun.file(storyFilePath).json();
63951
64337
  const existingIds = new Set(ctx.prd.userStories.map((s) => s.id));
63952
64338
  const story = validateInjectedStory(raw, existingIds);
@@ -64760,11 +65146,11 @@ __export(exports_init_context, {
64760
65146
  generateContextTemplate: () => generateContextTemplate
64761
65147
  });
64762
65148
  import { basename as basename12, join as join56 } from "path";
64763
- async function bunFileExists(path16) {
64764
- return Bun.file(path16).exists();
65149
+ async function bunFileExists(path17) {
65150
+ return Bun.file(path17).exists();
64765
65151
  }
64766
- async function bunMkdirp(path16) {
64767
- const proc = Bun.spawn(["mkdir", "-p", path16]);
65152
+ async function bunMkdirp(path17) {
65153
+ const proc = Bun.spawn(["mkdir", "-p", path17]);
64768
65154
  await proc.exited;
64769
65155
  }
64770
65156
  async function findFiles(dir, maxFiles = 200) {
@@ -64830,8 +65216,8 @@ async function detectEntryPoints(projectRoot) {
64830
65216
  const candidates = ["src/index.ts", "src/main.ts", "main.go", "src/lib.rs"];
64831
65217
  const found = [];
64832
65218
  for (const candidate of candidates) {
64833
- const path16 = join56(projectRoot, candidate);
64834
- if (await bunFileExists(path16)) {
65219
+ const path17 = join56(projectRoot, candidate);
65220
+ if (await bunFileExists(path17)) {
64835
65221
  found.push(candidate);
64836
65222
  }
64837
65223
  }
@@ -64841,8 +65227,8 @@ async function detectConfigFiles(projectRoot) {
64841
65227
  const candidates = ["tsconfig.json", "biome.json", "turbo.json", ".env.example"];
64842
65228
  const found = [];
64843
65229
  for (const candidate of candidates) {
64844
- const path16 = join56(projectRoot, candidate);
64845
- if (await bunFileExists(path16)) {
65230
+ const path17 = join56(projectRoot, candidate);
65231
+ if (await bunFileExists(path17)) {
64846
65232
  found.push(candidate);
64847
65233
  }
64848
65234
  }
@@ -65584,10 +65970,10 @@ var init_setup_analyze = __esm(() => {
65584
65970
  init_workspace();
65585
65971
  CANONICAL_SCRIPTS = ["build", "test", "lint", "type-check", "lint:fix"];
65586
65972
  _analyzeRepoDeps = {
65587
- fileExists: async (path16) => Bun.file(path16).exists(),
65588
- readJson: async (path16) => {
65973
+ fileExists: async (path17) => Bun.file(path17).exists(),
65974
+ readJson: async (path17) => {
65589
65975
  try {
65590
- const f = Bun.file(path16);
65976
+ const f = Bun.file(path17);
65591
65977
  if (!await f.exists())
65592
65978
  return null;
65593
65979
  return JSON.parse(await f.text());
@@ -65642,9 +66028,9 @@ async function fillScripts(workdir, analysis) {
65642
66028
  var TYPE_CHECK_KEY = "type-check", TYPE_CHECK_SCRIPT = "tsc --noEmit -p tsconfig.json", TYPE_CHECK_TURBO_PASSTHROUGH = "turbo run type-check", _fillScriptsDeps;
65643
66029
  var init_setup_fill = __esm(() => {
65644
66030
  _fillScriptsDeps = {
65645
- readJson: async (path16) => {
66031
+ readJson: async (path17) => {
65646
66032
  try {
65647
- const f = Bun.file(path16);
66033
+ const f = Bun.file(path17);
65648
66034
  if (!await f.exists())
65649
66035
  return null;
65650
66036
  return JSON.parse(await f.text());
@@ -65652,8 +66038,8 @@ var init_setup_fill = __esm(() => {
65652
66038
  return null;
65653
66039
  }
65654
66040
  },
65655
- writeFile: async (path16, content) => {
65656
- await Bun.write(path16, content);
66041
+ writeFile: async (path17, content) => {
66042
+ await Bun.write(path17, content);
65657
66043
  }
65658
66044
  };
65659
66045
  });
@@ -65712,9 +66098,9 @@ async function writeSetupConfig(workdir, config2, monoConfigs, _opts, deps = _wr
65712
66098
  var _writeSetupDeps;
65713
66099
  var init_setup_write = __esm(() => {
65714
66100
  _writeSetupDeps = {
65715
- writeFile: (path16, content) => Bun.write(path16, content).then(() => {}),
65716
- mkdir: async (path16) => {
65717
- const proc = Bun.spawn(["mkdir", "-p", path16]);
66101
+ writeFile: (path17, content) => Bun.write(path17, content).then(() => {}),
66102
+ mkdir: async (path17) => {
66103
+ const proc = Bun.spawn(["mkdir", "-p", path17]);
65718
66104
  await proc.exited;
65719
66105
  }
65720
66106
  };
@@ -65798,7 +66184,7 @@ var init_setup = __esm(() => {
65798
66184
  },
65799
66185
  generateSetupPlan: (ctx, analysis) => generateSetupPlan(ctx, analysis),
65800
66186
  runGate: (workdir, config2) => runSetupGate(workdir, config2),
65801
- fileExists: (path16) => Bun.file(path16).exists(),
66187
+ fileExists: (path17) => Bun.file(path17).exists(),
65802
66188
  writeSetupConfig: (workdir, config2, monoConfigs, opts) => writeSetupConfig(workdir, config2, monoConfigs, opts),
65803
66189
  stdout: (msg) => {
65804
66190
  process.stdout.write(`${msg}
@@ -65854,6 +66240,130 @@ var init_forge = __esm(() => {
65854
66240
  URL_REGEX = /https?:\/\/\S+/;
65855
66241
  });
65856
66242
 
66243
+ // flows/nax-finish/pr-template-merge.ts
66244
+ function normalizeHeading(heading) {
66245
+ return heading.toLowerCase().replace(/[^a-z0-9\s]/g, " ").replace(/\s+/g, " ").trim();
66246
+ }
66247
+ function cleanTemplateText(text) {
66248
+ return text.replace(HTML_COMMENT_RE, "").split(`
66249
+ `).filter((line) => !DANGLING_ISSUE_RE.test(line) && !UNCHECKED_BOX_RE.test(line)).map((line) => line.trimEnd()).join(`
66250
+ `).trim();
66251
+ }
66252
+ function parseTemplate(rawText) {
66253
+ const text = rawText.replace(/\r\n/g, `
66254
+ `);
66255
+ const frontmatterMatch = FRONTMATTER_RE.exec(text);
66256
+ const frontmatter = frontmatterMatch ? frontmatterMatch[0].trimEnd() : "";
66257
+ const rest = frontmatterMatch ? text.slice(frontmatterMatch[0].length) : text;
66258
+ const preambleLines = [];
66259
+ const sections2 = [];
66260
+ let current = null;
66261
+ for (const line of rest.split(`
66262
+ `)) {
66263
+ const heading = HEADING_RE.exec(line);
66264
+ if (heading) {
66265
+ if (current)
66266
+ sections2.push({ heading: current.heading, body: current.lines.join(`
66267
+ `) });
66268
+ current = { heading: heading[1], lines: [] };
66269
+ continue;
66270
+ }
66271
+ if (current)
66272
+ current.lines.push(line);
66273
+ else
66274
+ preambleLines.push(line);
66275
+ }
66276
+ if (current)
66277
+ sections2.push({ heading: current.heading, body: current.lines.join(`
66278
+ `) });
66279
+ return { frontmatter, preamble: preambleLines.join(`
66280
+ `), sections: sections2 };
66281
+ }
66282
+ function renderSection2(heading, body) {
66283
+ if (heading.length === 0)
66284
+ return body;
66285
+ return body.length === 0 ? `## ${heading}` : `## ${heading}
66286
+
66287
+ ${body}`;
66288
+ }
66289
+ function renderSections(sections2) {
66290
+ return sections2.filter((s) => s.body.trim().length > 0).map((s) => renderSection2(s.heading, s.body.trim())).join(`
66291
+
66292
+ `).trim();
66293
+ }
66294
+ function mergeTemplate(template, sections2, opts = {}) {
66295
+ const mode = opts.mode ?? "merge";
66296
+ if (mode === "ignore" || !template || template.trim().length === 0)
66297
+ return renderSections(sections2);
66298
+ const parsed = parseTemplate(template);
66299
+ if (parsed.sections.length === 0)
66300
+ return renderSections(sections2);
66301
+ const aliases = { ...DEFAULT_SECTION_ALIASES };
66302
+ for (const [heading, key] of Object.entries(opts.sectionMap ?? {}))
66303
+ aliases[normalizeHeading(heading)] = key;
66304
+ const fillable = sections2.filter((s) => s.heading.length > 0 && s.body.trim().length > 0);
66305
+ const consumed = new Set;
66306
+ const parts = [];
66307
+ if (parsed.frontmatter.length > 0)
66308
+ parts.push(parsed.frontmatter);
66309
+ const preamble = cleanTemplateText(parsed.preamble);
66310
+ if (preamble.length > 0)
66311
+ parts.push(preamble);
66312
+ for (const templateSection of parsed.sections) {
66313
+ const key = aliases[normalizeHeading(templateSection.heading)];
66314
+ const match = key ? fillable.find((s) => s.key === key && !consumed.has(s.key)) : undefined;
66315
+ if (match) {
66316
+ consumed.add(match.key);
66317
+ parts.push(renderSection2(templateSection.heading, match.body.trim()));
66318
+ } else if (mode === "strict") {
66319
+ parts.push(renderSection2(templateSection.heading, ""));
66320
+ }
66321
+ }
66322
+ for (const section of sections2) {
66323
+ if (consumed.has(section.key) || section.body.trim().length === 0)
66324
+ continue;
66325
+ parts.push(renderSection2(section.heading, section.body.trim()));
66326
+ }
66327
+ return parts.join(`
66328
+
66329
+ `).trim();
66330
+ }
66331
+ var DEFAULT_SECTION_ALIASES, HEADING_RE, FRONTMATTER_RE, HTML_COMMENT_RE, DANGLING_ISSUE_RE, UNCHECKED_BOX_RE;
66332
+ var init_pr_template_merge = __esm(() => {
66333
+ DEFAULT_SECTION_ALIASES = {
66334
+ what: "narrative",
66335
+ "what changed": "narrative",
66336
+ "whats changed": "narrative",
66337
+ summary: "narrative",
66338
+ description: "narrative",
66339
+ overview: "narrative",
66340
+ changes: "narrative",
66341
+ "what does this do": "narrative",
66342
+ "what does this mr do and why": "narrative",
66343
+ "what does this pr do": "narrative",
66344
+ how: "stories",
66345
+ implementation: "stories",
66346
+ "implementation details": "stories",
66347
+ "changes made": "stories",
66348
+ approach: "stories",
66349
+ design: "stories",
66350
+ testing: "verification",
66351
+ tests: "verification",
66352
+ "test plan": "verification",
66353
+ verification: "verification",
66354
+ qa: "verification",
66355
+ validation: "verification",
66356
+ "how to test": "verification",
66357
+ "how has this been tested": "verification",
66358
+ "how to set up and validate locally": "verification"
66359
+ };
66360
+ HEADING_RE = /^##[ \t]+(.+?)[ \t]*$/;
66361
+ FRONTMATTER_RE = /^---[ \t]*\r?\n[\s\S]*?\r?\n---[ \t]*(?:\r?\n|$)/;
66362
+ HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
66363
+ DANGLING_ISSUE_RE = /^[ \t]*(?:closes?|fixe?s?|resolves?)[ \t]*:?[ \t]*#[ \t]*(?:\([^)]*\))?[ \t]*$/i;
66364
+ UNCHECKED_BOX_RE = /^[ \t]*[-*+][ \t]+\[[ \t]\]/;
66365
+ });
66366
+
65857
66367
  // src/plugins/builtin/auto-pr/pr-body.ts
65858
66368
  function buildTitle(ctx) {
65859
66369
  return `feat: ${ctx.feature}`;
@@ -65871,7 +66381,6 @@ function buildSummaryLines(ctx) {
65871
66381
  const failed = `${storySummary.failed} failed`;
65872
66382
  const skipped = `${storySummary.skipped} skipped`;
65873
66383
  return [
65874
- "## Run summary",
65875
66384
  `- Feature: ${ctx.feature}`,
65876
66385
  `- Stories: ${passed} / ${failed} / ${skipped}`,
65877
66386
  `- Duration: ${formatDuration3(ctx.totalDurationMs)}`,
@@ -65895,26 +66404,30 @@ function buildStoryTable(stories) {
65895
66404
  lines.push("");
65896
66405
  return lines;
65897
66406
  }
65898
- function buildBody2(ctx, template) {
65899
- const blocks = [];
65900
- blocks.push("> Auto-opened by nax \u2014 review pending. Run nax-finish before merge.");
65901
- blocks.push("");
65902
- blocks.push(...buildSummaryLines(ctx));
65903
- blocks.push(...buildStoryTable(ctx.stories));
65904
- if (template !== null) {
65905
- blocks.push("---");
65906
- blocks.push(template);
65907
- }
65908
- return blocks.join(`
65909
- `);
66407
+ function buildBody2(ctx, template, opts = {}) {
66408
+ const sections2 = [
66409
+ {
66410
+ key: "stories",
66411
+ heading: "Run summary",
66412
+ body: [...buildSummaryLines(ctx), ...buildStoryTable(ctx.stories)].join(`
66413
+ `).trim()
66414
+ }
66415
+ ];
66416
+ const merged = mergeTemplate(template, sections2, opts);
66417
+ return merged.length > 0 ? `${REVIEW_PENDING_BANNER}
66418
+
66419
+ ${merged}` : REVIEW_PENDING_BANNER;
65910
66420
  }
65911
- var SECONDS_PER_MINUTE = 60, MS_PER_SECOND = 1000;
66421
+ var SECONDS_PER_MINUTE = 60, MS_PER_SECOND = 1000, REVIEW_PENDING_BANNER = "> Auto-opened by nax \u2014 review pending. Run nax-finish before merge.";
66422
+ var init_pr_body = __esm(() => {
66423
+ init_pr_template_merge();
66424
+ });
65912
66425
 
65913
66426
  // src/plugins/builtin/auto-pr/template.ts
65914
- import * as path16 from "path";
66427
+ import * as path17 from "path";
65915
66428
  async function firstExisting(workdir, deps, paths) {
65916
66429
  for (const relPath of paths) {
65917
- const content = await deps.readText(path16.join(workdir, relPath));
66430
+ const content = await deps.readText(path17.join(workdir, relPath));
65918
66431
  if (content !== null) {
65919
66432
  return content;
65920
66433
  }
@@ -65941,7 +66454,7 @@ var init_template = __esm(() => {
65941
66454
  });
65942
66455
 
65943
66456
  // src/plugins/builtin/auto-pr/index.ts
65944
- import * as path17 from "path";
66457
+ import * as path18 from "path";
65945
66458
  async function defaultRun(cmd, opts) {
65946
66459
  const proc = Bun.spawn(cmd, { cwd: opts.cwd, stdout: "pipe", stderr: "pipe" });
65947
66460
  const [exitCode, stdout, stderr] = await Promise.all([
@@ -65951,8 +66464,8 @@ async function defaultRun(cmd, opts) {
65951
66464
  ]);
65952
66465
  return { exitCode, stdout, stderr };
65953
66466
  }
65954
- async function defaultReadText(path18) {
65955
- const file3 = Bun.file(path18);
66467
+ async function defaultReadText(path19) {
66468
+ const file3 = Bun.file(path19);
65956
66469
  if (!await file3.exists())
65957
66470
  return null;
65958
66471
  return file3.text();
@@ -65982,8 +66495,8 @@ function getStorySummary(context) {
65982
66495
  function relativePrdPath(workdir, prdPath) {
65983
66496
  if (!prdPath)
65984
66497
  return prdPath;
65985
- const rel = path17.relative(workdir, prdPath);
65986
- return rel && !rel.startsWith("..") && !path17.isAbsolute(rel) ? rel : prdPath;
66498
+ const rel = path18.relative(workdir, prdPath);
66499
+ return rel && !rel.startsWith("..") && !path18.isAbsolute(rel) ? rel : prdPath;
65987
66500
  }
65988
66501
  function toPrBodyContext(context) {
65989
66502
  const summary = getStorySummary(context);
@@ -66002,6 +66515,7 @@ function toPrBodyContext(context) {
66002
66515
  var PLUGIN_NAME = "nax-auto-pr", PLUGIN_VERSION = "0.1.0", GIT_REMOTE_CMD, _autoPrDeps, autoPrAction, autoPrPlugin;
66003
66516
  var init_auto_pr = __esm(() => {
66004
66517
  init_forge();
66518
+ init_pr_body();
66005
66519
  init_template();
66006
66520
  GIT_REMOTE_CMD = ["git", "remote", "get-url", "origin"];
66007
66521
  _autoPrDeps = {
@@ -66213,7 +66727,7 @@ var init_auto_route = __esm(() => {
66213
66727
  });
66214
66728
 
66215
66729
  // src/plugins/builtin/curator/collect.ts
66216
- import * as path18 from "path";
66730
+ import * as path19 from "path";
66217
66731
  function now() {
66218
66732
  return new Date().toISOString();
66219
66733
  }
@@ -66263,7 +66777,7 @@ function tokenCount(story) {
66263
66777
  }
66264
66778
  async function collectFromMetrics(context) {
66265
66779
  const observations = [];
66266
- const metricsPath = path18.join(context.outputDir, "metrics.json");
66780
+ const metricsPath = path19.join(context.outputDir, "metrics.json");
66267
66781
  try {
66268
66782
  const data = await readJsonFile(metricsPath);
66269
66783
  const runs = Array.isArray(data) ? data : [data];
@@ -66332,11 +66846,11 @@ function findingMessage(finding) {
66332
66846
  }
66333
66847
  async function collectFromReviewAudit(context) {
66334
66848
  const observations = [];
66335
- const auditDir = path18.join(context.outputDir, "review-audit");
66849
+ const auditDir = path19.join(context.outputDir, "review-audit");
66336
66850
  try {
66337
66851
  const glob = new Bun.Glob("**/*.json");
66338
66852
  for await (const file3 of glob.scan({ cwd: auditDir, absolute: false })) {
66339
- const fullPath = path18.join(auditDir, file3);
66853
+ const fullPath = path19.join(auditDir, file3);
66340
66854
  try {
66341
66855
  const audit = asRecord3(await readJsonFile(fullPath));
66342
66856
  if (!audit)
@@ -66382,12 +66896,12 @@ async function collectFromReviewAudit(context) {
66382
66896
  }
66383
66897
  async function collectFromContextManifests(context) {
66384
66898
  const observations = [];
66385
- const featuresDir = path18.join(context.workdir, ".nax", "features");
66899
+ const featuresDir = path19.join(context.workdir, ".nax", "features");
66386
66900
  let skippedManifests = 0;
66387
66901
  try {
66388
66902
  const glob = new Bun.Glob("*/stories/*/context-manifest-*.json");
66389
66903
  for await (const file3 of glob.scan({ cwd: featuresDir, absolute: false })) {
66390
- const fullPath = path18.join(featuresDir, file3);
66904
+ const fullPath = path19.join(featuresDir, file3);
66391
66905
  try {
66392
66906
  const parts = file3.split("/");
66393
66907
  const featureId = parts[0] ?? context.feature;
@@ -66991,10 +67505,10 @@ async function* streamJsonlLines(file3) {
66991
67505
 
66992
67506
  // src/plugins/builtin/curator/rollup.ts
66993
67507
  import { appendFile as appendFile3, mkdir as mkdir9, writeFile } from "fs/promises";
66994
- import * as path19 from "path";
67508
+ import * as path20 from "path";
66995
67509
  async function appendToRollup(observations, rollupPath) {
66996
67510
  try {
66997
- const dir = path19.dirname(rollupPath);
67511
+ const dir = path20.dirname(rollupPath);
66998
67512
  await mkdir9(dir, { recursive: true });
66999
67513
  if (observations.length === 0) {
67000
67514
  const f = Bun.file(rollupPath);
@@ -67078,7 +67592,7 @@ var init_rollup = __esm(() => {
67078
67592
 
67079
67593
  // src/plugins/builtin/curator/index.ts
67080
67594
  import { mkdir as mkdir10 } from "fs/promises";
67081
- import * as path20 from "path";
67595
+ import * as path21 from "path";
67082
67596
  function getCuratorEnabled(context) {
67083
67597
  const cfg = context.config;
67084
67598
  if (!cfg)
@@ -67152,7 +67666,7 @@ var init_curator = __esm(() => {
67152
67666
  const observations = await collectObservations(curatorContext);
67153
67667
  if (context.outputDir) {
67154
67668
  const { observationsPath, rollupPath } = resolveCuratorOutputs(curatorContext);
67155
- const runDir = path20.dirname(observationsPath);
67669
+ const runDir = path21.dirname(observationsPath);
67156
67670
  await mkdir10(runDir, { recursive: true });
67157
67671
  await Bun.write(observationsPath, observations.map((o) => JSON.stringify(o)).join(`
67158
67672
  `) + (observations.length > 0 ? `
@@ -67171,7 +67685,7 @@ var init_curator = __esm(() => {
67171
67685
  }
67172
67686
  const proposals = runHeuristics(window2.observations.length > 0 ? window2.observations : observations, thresholds);
67173
67687
  const markdown = renderProposals(proposals, context.runId, observations.length);
67174
- const proposalsMdPath = path20.join(runDir, "curator-proposals.md");
67688
+ const proposalsMdPath = path21.join(runDir, "curator-proposals.md");
67175
67689
  await Bun.write(proposalsMdPath, markdown);
67176
67690
  }
67177
67691
  return {
@@ -67221,6 +67735,10 @@ function getFinishAutoFlowConfig(ctx) {
67221
67735
  defaultAgent: resolveFlowAgent(ctx.config, autoFlow.defaultAgent),
67222
67736
  model: autoFlow.model ?? null,
67223
67737
  narrative: autoFlow.narrative !== false,
67738
+ prBody: {
67739
+ template: autoFlow.prBody?.template ?? defaults.prBody.template,
67740
+ sectionMap: autoFlow.prBody?.sectionMap ?? defaults.prBody.sectionMap
67741
+ },
67224
67742
  reviewers: {
67225
67743
  spec: autoFlow.reviewers?.spec ?? null,
67226
67744
  quality: autoFlow.reviewers?.quality ?? null,
@@ -67252,6 +67770,7 @@ var init_config2 = __esm(() => {
67252
67770
  flowPath: "flows/nax-finish/nax-finish.flow.ts",
67253
67771
  model: null,
67254
67772
  narrative: true,
67773
+ prBody: { template: "merge", sectionMap: {} },
67255
67774
  reviewers: { spec: null, quality: null, narrative: null },
67256
67775
  escalate: { telegram: true },
67257
67776
  notify: { mode: "escalation" },
@@ -67321,7 +67840,7 @@ var init_telegram2 = __esm(() => {
67321
67840
  });
67322
67841
 
67323
67842
  // src/plugins/builtin/nax-finish/index.ts
67324
- import * as path21 from "path";
67843
+ import * as path22 from "path";
67325
67844
  async function defaultRun2(cmd, opts) {
67326
67845
  const proc = Bun.spawn(cmd, { cwd: opts.cwd, env: opts.env, stdout: "pipe", stderr: "pipe" });
67327
67846
  let timedOut = false;
@@ -67347,11 +67866,11 @@ async function defaultRun2(cmd, opts) {
67347
67866
  }
67348
67867
  }
67349
67868
  function finishAuditDir(ctx) {
67350
- const root = ctx.outputDir ?? path21.join(ctx.workdir, ".nax");
67351
- return path21.join(root, "finish-audit", ctx.feature);
67869
+ const root = ctx.outputDir ?? path22.join(ctx.workdir, ".nax");
67870
+ return path22.join(root, "finish-audit", ctx.feature);
67352
67871
  }
67353
67872
  function finishResultPath(ctx, runId) {
67354
- return path21.join(finishAuditDir(ctx), `${runId}.result.json`);
67873
+ return path22.join(finishAuditDir(ctx), `${runId}.result.json`);
67355
67874
  }
67356
67875
  async function defaultReadResult(resultPath) {
67357
67876
  const f = Bun.file(resultPath);
@@ -67368,17 +67887,17 @@ function isFeatureBranch(b) {
67368
67887
  return b !== "main" && b !== "master" && b.length > 0;
67369
67888
  }
67370
67889
  async function resolveFlowPath(workdir, flowPath, deps = _naxFinishDeps) {
67371
- if (path21.isAbsolute(flowPath)) {
67890
+ if (path22.isAbsolute(flowPath)) {
67372
67891
  return await deps.exists(flowPath) ? flowPath : null;
67373
67892
  }
67374
67893
  const candidates = [];
67375
67894
  let dir = deps.moduleDir;
67376
67895
  for (let i = 0;i < PACKAGE_ROOT_SEARCH_DEPTH; i += 1) {
67377
- dir = path21.dirname(dir);
67378
- if (await deps.exists(path21.join(dir, "package.json")))
67379
- candidates.push(path21.resolve(dir, flowPath));
67896
+ dir = path22.dirname(dir);
67897
+ if (await deps.exists(path22.join(dir, "package.json")))
67898
+ candidates.push(path22.resolve(dir, flowPath));
67380
67899
  }
67381
- candidates.push(path21.resolve(workdir, flowPath));
67900
+ candidates.push(path22.resolve(workdir, flowPath));
67382
67901
  for (const candidate of candidates) {
67383
67902
  if (await deps.exists(candidate))
67384
67903
  return candidate;
@@ -67401,7 +67920,14 @@ function buildFlowArgv(flowPath, inputJson, opts = {}) {
67401
67920
  ];
67402
67921
  }
67403
67922
  function buildFlowEnv(cfg) {
67404
- const env2 = { ...process.env };
67923
+ const {
67924
+ NAX_FINISH_SPEC_PROFILE: _spec,
67925
+ NAX_FINISH_QUALITY_PROFILE: _quality,
67926
+ NAX_FINISH_NARRATIVE_PROFILE: _narrative,
67927
+ NAX_FINISH_NARRATIVE: _narrativeSwitch,
67928
+ ...rest
67929
+ } = process.env;
67930
+ const env2 = { ...rest };
67405
67931
  if (cfg.reviewers.spec)
67406
67932
  env2.NAX_FINISH_SPEC_PROFILE = cfg.reviewers.spec;
67407
67933
  if (cfg.reviewers.quality)
@@ -67449,7 +67975,8 @@ async function executeFinishFlow(options) {
67449
67975
  auditDir: finishAuditDir(ctx),
67450
67976
  runId: ctx.runId,
67451
67977
  escalateTelegram,
67452
- timeouts: { acceptanceMs: cfg.timeouts.acceptanceMs, gateMs: cfg.timeouts.gateMs }
67978
+ timeouts: { acceptanceMs: cfg.timeouts.acceptanceMs, gateMs: cfg.timeouts.gateMs },
67979
+ prBody: { template: cfg.prBody.template, sectionMap: cfg.prBody.sectionMap }
67453
67980
  };
67454
67981
  const cmd = buildFlowArgv(flowPath, JSON.stringify(input), {
67455
67982
  defaultAgent: cfg.defaultAgent,
@@ -68939,14 +69466,14 @@ var init_validator = __esm(() => {
68939
69466
 
68940
69467
  // src/plugins/loader.ts
68941
69468
  import * as fs from "fs/promises";
68942
- import * as path22 from "path";
69469
+ import * as path23 from "path";
68943
69470
  function getSafeLogger6() {
68944
69471
  return getSafeLogger();
68945
69472
  }
68946
69473
  function extractPluginName(pluginPath) {
68947
- const basename14 = path22.basename(pluginPath);
69474
+ const basename14 = path23.basename(pluginPath);
68948
69475
  if (basename14 === "index.ts" || basename14 === "index.js" || basename14 === "index.mjs") {
68949
- return path22.basename(path22.dirname(pluginPath));
69476
+ return path23.basename(path23.dirname(pluginPath));
68950
69477
  }
68951
69478
  return basename14.replace(/\.(ts|js|mjs)$/, "");
68952
69479
  }
@@ -69094,7 +69621,7 @@ async function discoverPlugins(dir, isTestFileFn) {
69094
69621
  try {
69095
69622
  const entries = await fs.readdir(dir, { withFileTypes: true });
69096
69623
  for (const entry of entries) {
69097
- const fullPath = path22.join(dir, entry.name);
69624
+ const fullPath = path23.join(dir, entry.name);
69098
69625
  if (entry.isFile()) {
69099
69626
  if (isPluginFile(entry.name, isTestFileFn)) {
69100
69627
  discovered.push({ path: fullPath });
@@ -69102,7 +69629,7 @@ async function discoverPlugins(dir, isTestFileFn) {
69102
69629
  } else if (entry.isDirectory()) {
69103
69630
  const indexPaths = ["index.ts", "index.js", "index.mjs"];
69104
69631
  for (const indexFile of indexPaths) {
69105
- const indexPath = path22.join(fullPath, indexFile);
69632
+ const indexPath = path23.join(fullPath, indexFile);
69106
69633
  try {
69107
69634
  await fs.access(indexPath);
69108
69635
  discovered.push({ path: indexPath });
@@ -69127,13 +69654,13 @@ function isPluginFile(filename, isTestFileFn) {
69127
69654
  return !FALLBACK_TEST_FILE_RE.test(filename);
69128
69655
  }
69129
69656
  function resolveModulePath(modulePath, projectRoot) {
69130
- if (path22.isAbsolute(modulePath) || !modulePath.startsWith("./") && !modulePath.startsWith("../")) {
69657
+ if (path23.isAbsolute(modulePath) || !modulePath.startsWith("./") && !modulePath.startsWith("../")) {
69131
69658
  return modulePath;
69132
69659
  }
69133
69660
  if (projectRoot) {
69134
- return path22.resolve(projectRoot, modulePath);
69661
+ return path23.resolve(projectRoot, modulePath);
69135
69662
  }
69136
- return path22.resolve(modulePath);
69663
+ return path23.resolve(modulePath);
69137
69664
  }
69138
69665
  async function loadAndValidatePlugin(initialModulePath, config2, allowedRoots = [], originalPath) {
69139
69666
  let attemptedPath = initialModulePath;
@@ -70161,7 +70688,7 @@ var init_fix_diagnosis = __esm(() => {
70161
70688
  });
70162
70689
 
70163
70690
  // src/execution/lifecycle/acceptance-helpers.ts
70164
- import path24 from "path";
70691
+ import path25 from "path";
70165
70692
  function isStubTestFile(content) {
70166
70693
  return isStubTestContent(content);
70167
70694
  }
@@ -70180,7 +70707,7 @@ function isTestLevelFailure(failedACs, totalACs, semanticVerdicts) {
70180
70707
  async function loadSpecContent(featureDir) {
70181
70708
  if (!featureDir)
70182
70709
  return "";
70183
- const specPath = path24.join(featureDir, "spec.md");
70710
+ const specPath = path25.join(featureDir, "spec.md");
70184
70711
  const specFile = Bun.file(specPath);
70185
70712
  return await specFile.exists() ? await specFile.text() : "";
70186
70713
  }
@@ -70200,13 +70727,26 @@ async function loadAcceptanceTestContent2(featureDir, testPaths, configuredTestP
70200
70727
  }
70201
70728
  if (!configuredTestPath)
70202
70729
  return [];
70203
- const resolvedPath = path24.join(featureDir, configuredTestPath);
70730
+ const resolvedPath = path25.join(featureDir, configuredTestPath);
70204
70731
  const testFile = Bun.file(resolvedPath);
70205
70732
  const content = await testFile.exists() ? await testFile.text() : "";
70206
70733
  return [{ content, path: resolvedPath }];
70207
70734
  }
70208
- function buildResult(success2, prd, totalCost2, iterations, storiesCompleted, prdDirty, failedACs, retries) {
70209
- return { success: success2, prd, totalCost: totalCost2, iterations, storiesCompleted, prdDirty, failedACs, retries };
70735
+ function buildResult(success2, prd, totalCost2, iterations, storiesCompleted, prdDirty, failedACs, retries, skippedPackages) {
70736
+ return { success: success2, prd, totalCost: totalCost2, iterations, storiesCompleted, prdDirty, failedACs, retries, skippedPackages };
70737
+ }
70738
+ function buildFailureResult(prd, totalCost2, iterations, storiesCompleted, failedACs, retries, skippedPackages) {
70739
+ return {
70740
+ success: false,
70741
+ prd,
70742
+ totalCost: totalCost2,
70743
+ iterations,
70744
+ storiesCompleted,
70745
+ prdDirty: false,
70746
+ failedACs,
70747
+ retries,
70748
+ skippedPackages
70749
+ };
70210
70750
  }
70211
70751
  async function regenerateAcceptanceTest(testPath, acceptanceContext) {
70212
70752
  const logger = getSafeLogger();
@@ -70217,7 +70757,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
70217
70757
  const { unlink: unlink3 } = await import("fs/promises");
70218
70758
  await unlink3(testPath);
70219
70759
  if (acceptanceContext.featureDir) {
70220
- const metaPath = path24.join(acceptanceContext.featureDir, "acceptance-meta.json");
70760
+ const metaPath = path25.join(acceptanceContext.featureDir, "acceptance-meta.json");
70221
70761
  try {
70222
70762
  await unlink3(metaPath);
70223
70763
  } catch {}
@@ -70231,7 +70771,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
70231
70771
  const changedFilesRaw = diffOutput.split(`
70232
70772
  `).map((f) => f.trim()).filter((f) => f.length > 0);
70233
70773
  const repoRoot = acceptanceContext.projectDir ?? workdir;
70234
- const packageDir = acceptanceContext.story.workdir && acceptanceContext.projectDir ? path24.join(acceptanceContext.projectDir, acceptanceContext.story.workdir) : undefined;
70774
+ const packageDir = acceptanceContext.story.workdir && acceptanceContext.projectDir ? path25.join(acceptanceContext.projectDir, acceptanceContext.story.workdir) : undefined;
70235
70775
  const ignoreMatchers = acceptanceContext.naxIgnoreIndex?.getMatchers(packageDir) ?? await resolveNaxIgnorePatterns(repoRoot, packageDir);
70236
70776
  const changedFiles = filterNaxInternalPaths(changedFilesRaw, ignoreMatchers);
70237
70777
  const MAX_BYTES = 51200;
@@ -70240,7 +70780,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
70240
70780
  for (const file3 of changedFiles) {
70241
70781
  if (totalBytes >= MAX_BYTES)
70242
70782
  break;
70243
- const filePath = path24.join(workdir, file3);
70783
+ const filePath = path25.join(workdir, file3);
70244
70784
  try {
70245
70785
  const fileContent = await _regenerateDeps.readFile(filePath);
70246
70786
  const remaining = MAX_BYTES - totalBytes;
@@ -70460,6 +71000,15 @@ async function runAcceptanceTestsOnce(ctx, prd, packageFilter) {
70460
71000
  if (result.action !== "fail")
70461
71001
  return { passed: true, failedACs: [], testOutput: "" };
70462
71002
  const failures = acceptanceContext.acceptanceFailures;
71003
+ if (failures?.missingTargets && failures.missingTargets.length > 0) {
71004
+ return {
71005
+ passed: false,
71006
+ failedACs: [],
71007
+ testOutput: failures.testOutput,
71008
+ failedPackages: failures.failedPackages,
71009
+ missingTargets: failures.missingTargets
71010
+ };
71011
+ }
70463
71012
  if (!failures || failures.failedACs.length === 0)
70464
71013
  return { passed: true, failedACs: [], testOutput: "" };
70465
71014
  return {
@@ -70557,10 +71106,11 @@ async function runAcceptanceLoop(ctx) {
70557
71106
  return buildResult(false, prd, totalCost2, iterations, storiesCompleted, prdDirty);
70558
71107
  }
70559
71108
  const failures = acceptanceContext.acceptanceFailures;
71109
+ const skippedPackages = acceptanceResult.skippedPackages ?? failures?.missingTargets;
70560
71110
  if (!failures || failures.failedACs.length === 0) {
70561
71111
  logger?.error("acceptance", "Acceptance tests failed but no specific failures detected");
70562
71112
  await fireHook(ctx.hooks, "on-pause", hookCtx(ctx.feature, { reason: "Acceptance tests failed (no failures detected)", cost: totalCost2 }), ctx.workdir);
70563
- return buildResult(false, prd, totalCost2, iterations, storiesCompleted, prdDirty);
71113
+ return buildFailureResult(prd, totalCost2, iterations, storiesCompleted, undefined, undefined, skippedPackages);
70564
71114
  }
70565
71115
  acceptanceRetries++;
70566
71116
  logger?.warn("acceptance", `Acceptance retry ${acceptanceRetries}/${maxRetries}`, {
@@ -70573,7 +71123,7 @@ async function runAcceptanceLoop(ctx) {
70573
71123
  reason: `Acceptance validation failed after ${maxRetries} retries: ${failures.failedACs.join(", ")}`,
70574
71124
  cost: totalCost2
70575
71125
  }), ctx.workdir);
70576
- return buildResult(false, prd, totalCost2, iterations, storiesCompleted, prdDirty, failures.failedACs, acceptanceRetries);
71126
+ return buildFailureResult(prd, totalCost2, iterations, storiesCompleted, failures.failedACs, acceptanceRetries, skippedPackages);
70577
71127
  }
70578
71128
  if (ctx.featureDir) {
70579
71129
  const existingStubPath = await findExistingAcceptanceTestPath({
@@ -70588,7 +71138,7 @@ async function runAcceptanceLoop(ctx) {
70588
71138
  storyId: firstStory?.id,
70589
71139
  stubRegenCount
70590
71140
  });
70591
- return buildResult(false, prd, totalCost2, iterations, storiesCompleted, prdDirty, failures.failedACs, acceptanceRetries);
71141
+ return buildFailureResult(prd, totalCost2, iterations, storiesCompleted, failures.failedACs, acceptanceRetries, skippedPackages);
70592
71142
  }
70593
71143
  stubRegenCount++;
70594
71144
  logger?.warn("acceptance", "Stub test detected \u2014 full regen", {
@@ -70604,7 +71154,7 @@ async function runAcceptanceLoop(ctx) {
70604
71154
  const totalACs = prd.userStories.filter((s) => !s.id.startsWith("US-FIX-")).flatMap((s) => s.acceptanceCriteria).length;
70605
71155
  if (!ctx.runtime) {
70606
71156
  logger?.error("acceptance", "Runtime not found for diagnosis", { storyId: firstStory?.id });
70607
- return buildResult(false, prd, totalCost2, iterations, storiesCompleted, prdDirty, failures.failedACs, acceptanceRetries);
71157
+ return buildFailureResult(prd, totalCost2, iterations, storiesCompleted, failures.failedACs, acceptanceRetries, skippedPackages);
70608
71158
  }
70609
71159
  const failedPkgs = failures.failedPackages && failures.failedPackages.length > 0 ? failures.failedPackages : [{ testPath: "", packageDir: ctx.workdir, output: failures.testOutput, failedACs: failures.failedACs }];
70610
71160
  const strategy = ctx.config.acceptance.fix?.strategy ?? "diagnose-first";
@@ -70647,7 +71197,7 @@ async function runAcceptanceLoop(ctx) {
70647
71197
  const finalCheck = await runAcceptanceTestsOnce(attemptCtx, prd);
70648
71198
  const success2 = finalCheck.passed && remainingFindings.length === 0;
70649
71199
  const failureMessages = !success2 ? finalCheck.failedACs.length > 0 ? finalCheck.failedACs : remainingFindings.length > 0 ? remainingFindings.map((f) => f.message) : ["acceptance validation failed (unknown cause)"] : undefined;
70650
- return buildResult(success2, prd, totalCost2, iterations, storiesCompleted, prdDirty, failureMessages, acceptanceRetries + totalInternalIterations);
71200
+ return buildResult(success2, prd, totalCost2, iterations, storiesCompleted, prdDirty, failureMessages, acceptanceRetries + totalInternalIterations, finalCheck.missingTargets);
70651
71201
  }
70652
71202
  return buildResult(false, prd, totalCost2, iterations, storiesCompleted, prdDirty);
70653
71203
  }
@@ -70724,9 +71274,9 @@ var init_scratch_purge = __esm(() => {
70724
71274
  return [];
70725
71275
  }
70726
71276
  },
70727
- fileExists: (path25) => Bun.file(path25).exists(),
70728
- readFile: (path25) => Bun.file(path25).text(),
70729
- remove: (path25) => rm(path25, { recursive: true, force: true }),
71277
+ fileExists: (path26) => Bun.file(path26).exists(),
71278
+ readFile: (path26) => Bun.file(path26).text(),
71279
+ remove: (path26) => rm(path26, { recursive: true, force: true }),
70730
71280
  move: async (src, dest) => {
70731
71281
  await mkdir12(dirname15(dest), { recursive: true });
70732
71282
  await rename(src, dest);
@@ -71616,7 +72166,7 @@ var init_headless_formatter = __esm(() => {
71616
72166
  });
71617
72167
 
71618
72168
  // src/execution/runner-completion.ts
71619
- import path25 from "path";
72169
+ import path26 from "path";
71620
72170
  async function runCompletionPhase(options) {
71621
72171
  const logger = getSafeLogger();
71622
72172
  logger?.debug("execution", "Completion phase started", {
@@ -71637,11 +72187,11 @@ async function runCompletionPhase(options) {
71637
72187
  const acceptanceStartTime = Date.now();
71638
72188
  pipelineEventBus.emit({ type: "postrun:phase:started", phase: "acceptance" });
71639
72189
  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) => {
71640
- const relativeWorkdir = path25.relative(options.workdir, g.packageDir);
72190
+ const relativeWorkdir = path26.relative(options.workdir, g.packageDir);
71641
72191
  let groupConfig = options.config;
71642
72192
  if (relativeWorkdir && relativeWorkdir !== ".") {
71643
72193
  try {
71644
- groupConfig = await _runnerCompletionDeps.loadConfigForWorkdir(path25.join(options.workdir, ".nax", "config.json"), relativeWorkdir);
72194
+ groupConfig = await _runnerCompletionDeps.loadConfigForWorkdir(path26.join(options.workdir, ".nax", "config.json"), relativeWorkdir);
71645
72195
  } catch (error48) {
71646
72196
  logger?.warn("execution", "Falling back to root config for package acceptance settings", {
71647
72197
  packageDir: g.packageDir,
@@ -71654,7 +72204,9 @@ async function runCompletionPhase(options) {
71654
72204
  testPath: g.testPath,
71655
72205
  packageDir: g.packageDir,
71656
72206
  testFramework: groupConfig.project?.testFramework,
71657
- commandOverride: groupConfig.acceptance.command
72207
+ commandOverride: groupConfig.acceptance.command,
72208
+ storyCount: g.stories.length,
72209
+ acceptanceEnabled: groupConfig.acceptance.enabled
71658
72210
  };
71659
72211
  })) : undefined;
71660
72212
  let acceptanceResult;
@@ -71679,7 +72231,8 @@ async function runCompletionPhase(options) {
71679
72231
  sessionManager: options.sessionManager,
71680
72232
  runtime: options.runtime,
71681
72233
  abortSignal: options.abortSignal,
71682
- acceptanceTestPaths
72234
+ acceptanceTestPaths,
72235
+ skippedPackages: postRunStatus?.acceptance?.skippedPackages
71683
72236
  });
71684
72237
  } catch (err) {
71685
72238
  pipelineEventBus.emit({
@@ -71693,7 +72246,11 @@ async function runCompletionPhase(options) {
71693
72246
  const lastRunAt = new Date().toISOString();
71694
72247
  const acceptanceDurationMs = Date.now() - acceptanceStartTime;
71695
72248
  if (acceptanceResult.success) {
71696
- options.statusWriter.setPostRunPhase("acceptance", { status: "passed", lastRunAt });
72249
+ options.statusWriter.setPostRunPhase("acceptance", {
72250
+ status: "passed",
72251
+ lastRunAt,
72252
+ skippedPackages: undefined
72253
+ });
71697
72254
  pipelineEventBus.emit({
71698
72255
  type: "postrun:phase:completed",
71699
72256
  phase: "acceptance",
@@ -71707,12 +72264,14 @@ async function runCompletionPhase(options) {
71707
72264
  });
71708
72265
  } else {
71709
72266
  acceptancePassed = false;
71710
- options.statusWriter.setPostRunPhase("acceptance", {
72267
+ const failureUpdate = {
71711
72268
  status: "failed",
71712
72269
  failedACs: acceptanceResult.failedACs ?? [],
71713
72270
  retries: acceptanceResult.retries ?? 0,
71714
- lastRunAt
71715
- });
72271
+ lastRunAt,
72272
+ skippedPackages: acceptanceResult.skippedPackages && acceptanceResult.skippedPackages.length > 0 ? acceptanceResult.skippedPackages : undefined
72273
+ };
72274
+ options.statusWriter.setPostRunPhase("acceptance", failureUpdate);
71716
72275
  pipelineEventBus.emit({
71717
72276
  type: "postrun:phase:completed",
71718
72277
  phase: "acceptance",
@@ -71913,7 +72472,7 @@ function precomputeBatchPlan(stories, maxBatchSize = DEFAULT_MAX_BATCH_SIZE2) {
71913
72472
  var DEFAULT_MAX_BATCH_SIZE2 = 4;
71914
72473
 
71915
72474
  // src/execution/ensure-package-dirs.ts
71916
- import path26 from "path";
72475
+ import path27 from "path";
71917
72476
  async function ensureStoryPackageDirs(prd, workdir, deps = _ensurePackageDirsDeps) {
71918
72477
  const logger = getSafeLogger();
71919
72478
  const relToStoryId = new Map;
@@ -71926,8 +72485,8 @@ async function ensureStoryPackageDirs(prd, workdir, deps = _ensurePackageDirsDep
71926
72485
  }
71927
72486
  const created = [];
71928
72487
  for (const [rel, storyId] of relToStoryId) {
71929
- const abs = path26.resolve(workdir, rel);
71930
- const rootWithSep = workdir.endsWith(path26.sep) ? workdir : workdir + path26.sep;
72488
+ const abs = path27.resolve(workdir, rel);
72489
+ const rootWithSep = workdir.endsWith(path27.sep) ? workdir : workdir + path27.sep;
71931
72490
  if (abs !== workdir && !abs.startsWith(rootWithSep)) {
71932
72491
  logger?.warn("execution", "Skipping story workdir outside repo root", {
71933
72492
  storyId,
@@ -72961,9 +73520,9 @@ var _quoteIntegrityDeps, CONTEXT_LINES = 3;
72961
73520
  var init_quote_integrity = __esm(() => {
72962
73521
  init_logger2();
72963
73522
  _quoteIntegrityDeps = {
72964
- readFile: async (path27) => {
73523
+ readFile: async (path28) => {
72965
73524
  try {
72966
- return await Bun.file(path27).text();
73525
+ return await Bun.file(path28).text();
72967
73526
  } catch {
72968
73527
  return null;
72969
73528
  }
@@ -73252,7 +73811,7 @@ var exports_merge_conflict_rectify = {};
73252
73811
  __export(exports_merge_conflict_rectify, {
73253
73812
  rectifyConflictedStory: () => rectifyConflictedStory
73254
73813
  });
73255
- import path27 from "path";
73814
+ import path28 from "path";
73256
73815
  async function closeStaleAcpSession(worktreePath, sessionName) {
73257
73816
  const logger = getSafeLogger();
73258
73817
  try {
@@ -73279,7 +73838,7 @@ async function rectifyConflictedStory(options) {
73279
73838
  await worktreeManager.remove(workdir, storyId);
73280
73839
  } catch {}
73281
73840
  await worktreeManager.create(workdir, storyId);
73282
- const worktreePath = path27.join(workdir, ".nax-wt", storyId);
73841
+ const worktreePath = path28.join(workdir, ".nax-wt", storyId);
73283
73842
  const { formatSessionName: formatSessionName2 } = await Promise.resolve().then(() => (init_naming(), exports_naming));
73284
73843
  const staleSessionName = formatSessionName2({
73285
73844
  workdir: worktreePath,
@@ -73979,7 +74538,7 @@ __export(exports_parallel_batch, {
73979
74538
  runParallelBatch: () => runParallelBatch,
73980
74539
  _parallelBatchDeps: () => _parallelBatchDeps
73981
74540
  });
73982
- import path28 from "path";
74541
+ import path29 from "path";
73983
74542
  async function runParallelBatch(options) {
73984
74543
  const { stories, ctx, prd } = options;
73985
74544
  const { workdir, config: config2, maxConcurrency, pipelineContext, eventEmitter, agentGetFn, hooks, pluginRegistry } = ctx;
@@ -73998,9 +74557,9 @@ async function runParallelBatch(options) {
73998
74557
  });
73999
74558
  throw error48;
74000
74559
  }
74001
- worktreePaths.set(story.id, path28.join(workdir, ".nax-wt", story.id));
74560
+ worktreePaths.set(story.id, path29.join(workdir, ".nax-wt", story.id));
74002
74561
  }
74003
- const rootConfigPath = path28.join(workdir, ".nax", "config.json");
74562
+ const rootConfigPath = path29.join(workdir, ".nax", "config.json");
74004
74563
  const profileOverride = profileOverrideFromConfig(config2);
74005
74564
  const storyEffectiveConfigs = new Map;
74006
74565
  const configResults = await Promise.allSettled(stories.filter((story) => story.workdir).map(async (story) => {
@@ -74847,7 +75406,7 @@ import { resolve as resolve21 } from "path";
74847
75406
  function countProgress(prd) {
74848
75407
  const stories = prd.userStories;
74849
75408
  const passed = stories.filter((s) => s.status === "passed").length;
74850
- const failed = stories.filter((s) => s.status === "failed").length;
75409
+ const failed = stories.filter((s) => s.status === "failed" || s.status === "regression-failed").length;
74851
75410
  const paused = stories.filter((s) => s.status === "paused").length;
74852
75411
  const blocked = stories.filter((s) => s.status === "blocked").length;
74853
75412
  const total = stories.length;
@@ -75054,7 +75613,7 @@ __export(exports_migrate, {
75054
75613
  });
75055
75614
  import { existsSync as existsSync36 } from "fs";
75056
75615
  import { mkdir as mkdir16, readdir as readdir5, rename as rename3 } from "fs/promises";
75057
- import path29 from "path";
75616
+ import path30 from "path";
75058
75617
  async function detectGeneratedContent(naxDir) {
75059
75618
  if (!existsSync36(naxDir))
75060
75619
  return [];
@@ -75067,17 +75626,17 @@ async function detectGeneratedContent(naxDir) {
75067
75626
  }
75068
75627
  for (const entry of entries) {
75069
75628
  if (GENERATED_NAMES.has(entry)) {
75070
- candidates.push({ name: entry, srcPath: path29.join(naxDir, entry) });
75629
+ candidates.push({ name: entry, srcPath: path30.join(naxDir, entry) });
75071
75630
  }
75072
75631
  }
75073
- const featuresDir = path29.join(naxDir, "features");
75632
+ const featuresDir = path30.join(naxDir, "features");
75074
75633
  if (existsSync36(featuresDir)) {
75075
75634
  let featureDirs = [];
75076
75635
  try {
75077
75636
  featureDirs = await readdir5(featuresDir);
75078
75637
  } catch {}
75079
75638
  for (const fid of featureDirs) {
75080
- const featureDir = path29.join(featuresDir, fid);
75639
+ const featureDir = path30.join(featuresDir, fid);
75081
75640
  let subEntries = [];
75082
75641
  try {
75083
75642
  subEntries = await readdir5(featureDir);
@@ -75087,12 +75646,12 @@ async function detectGeneratedContent(naxDir) {
75087
75646
  for (const sub of subEntries) {
75088
75647
  if (GENERATED_FEATURE_SUBNAMES.has(sub)) {
75089
75648
  candidates.push({
75090
- name: path29.join("features", fid, sub),
75091
- srcPath: path29.join(featureDir, sub)
75649
+ name: path30.join("features", fid, sub),
75650
+ srcPath: path30.join(featureDir, sub)
75092
75651
  });
75093
75652
  }
75094
75653
  if (sub === "stories") {
75095
- const storiesDir = path29.join(featureDir, "stories");
75654
+ const storiesDir = path30.join(featureDir, "stories");
75096
75655
  let storyDirs = [];
75097
75656
  try {
75098
75657
  storyDirs = await readdir5(storiesDir);
@@ -75100,7 +75659,7 @@ async function detectGeneratedContent(naxDir) {
75100
75659
  continue;
75101
75660
  }
75102
75661
  for (const sid of storyDirs) {
75103
- const storyDir = path29.join(storiesDir, sid);
75662
+ const storyDir = path30.join(storiesDir, sid);
75104
75663
  let storyEntries = [];
75105
75664
  try {
75106
75665
  storyEntries = await readdir5(storyDir);
@@ -75110,8 +75669,8 @@ async function detectGeneratedContent(naxDir) {
75110
75669
  for (const se of storyEntries) {
75111
75670
  if (se.startsWith("context-manifest-") && se.endsWith(".json")) {
75112
75671
  candidates.push({
75113
- name: path29.join("features", fid, "stories", sid, se),
75114
- srcPath: path29.join(storyDir, se)
75672
+ name: path30.join("features", fid, "stories", sid, se),
75673
+ srcPath: path30.join(storyDir, se)
75115
75674
  });
75116
75675
  }
75117
75676
  }
@@ -75132,15 +75691,15 @@ async function migrateCommand(options) {
75132
75691
  name: options.reclaim
75133
75692
  });
75134
75693
  }
75135
- const src = path29.join(globalConfigDir(), options.reclaim);
75694
+ const src = path30.join(globalConfigDir(), options.reclaim);
75136
75695
  if (!existsSync36(src)) {
75137
75696
  throw new NaxError(`Nothing to reclaim: ~/.nax/${options.reclaim} does not exist`, "MIGRATE_RECLAIM_NOT_FOUND", {
75138
75697
  stage: "migrate",
75139
75698
  name: options.reclaim
75140
75699
  });
75141
75700
  }
75142
- const archiveBase = path29.join(globalConfigDir(), "_archive");
75143
- const archiveDest = path29.join(archiveBase, `${options.reclaim}-${Date.now()}`);
75701
+ const archiveBase = path30.join(globalConfigDir(), "_archive");
75702
+ const archiveDest = path30.join(archiveBase, `${options.reclaim}-${Date.now()}`);
75144
75703
  await mkdir16(archiveBase, { recursive: true });
75145
75704
  await rename3(src, archiveDest);
75146
75705
  logger.info("migrate", `Reclaimed: archived to ${archiveDest}`, { storyId: "_migrate" });
@@ -75177,8 +75736,8 @@ async function migrateCommand(options) {
75177
75736
  logger.info("migrate", `Merged: identity for "${options.merge}" updated`, { storyId: "_migrate" });
75178
75737
  return;
75179
75738
  }
75180
- const naxDir = path29.join(options.workdir, ".nax");
75181
- const configPath = path29.join(naxDir, "config.json");
75739
+ const naxDir = path30.join(options.workdir, ".nax");
75740
+ const configPath = path30.join(naxDir, "config.json");
75182
75741
  if (!existsSync36(configPath)) {
75183
75742
  throw new NaxError("No .nax/config.json found \u2014 run nax init first", "MIGRATE_NO_CONFIG", {
75184
75743
  stage: "migrate",
@@ -75194,7 +75753,7 @@ async function migrateCommand(options) {
75194
75753
  cause: e
75195
75754
  });
75196
75755
  }
75197
- const projectKey = config2.name?.trim() || path29.basename(options.workdir);
75756
+ const projectKey = config2.name?.trim() || path30.basename(options.workdir);
75198
75757
  const destBase = projectOutputDir(projectKey, config2.outputDir);
75199
75758
  const candidates = await detectGeneratedContent(naxDir);
75200
75759
  if (candidates.length === 0) {
@@ -75203,7 +75762,7 @@ async function migrateCommand(options) {
75203
75762
  }
75204
75763
  if (options.dryRun) {
75205
75764
  for (const c of candidates) {
75206
- logger.info("migrate", `[dry-run] Would move: ${c.srcPath} -> ${path29.join(destBase, c.name)}`, {
75765
+ logger.info("migrate", `[dry-run] Would move: ${c.srcPath} -> ${path30.join(destBase, c.name)}`, {
75207
75766
  storyId: "_migrate"
75208
75767
  });
75209
75768
  }
@@ -75212,8 +75771,8 @@ async function migrateCommand(options) {
75212
75771
  await mkdir16(destBase, { recursive: true });
75213
75772
  let moved = 0;
75214
75773
  for (const candidate of candidates) {
75215
- const dest = path29.join(destBase, candidate.name);
75216
- await mkdir16(path29.dirname(dest), { recursive: true });
75774
+ const dest = path30.join(destBase, candidate.name);
75775
+ await mkdir16(path30.dirname(dest), { recursive: true });
75217
75776
  if (existsSync36(dest)) {
75218
75777
  throw new NaxError(`Migration conflict: destination already exists.
75219
75778
  Source: ${candidate.srcPath}
@@ -75243,7 +75802,7 @@ async function migrateCommand(options) {
75243
75802
  moved++;
75244
75803
  logger.info("migrate", `Moved: ${candidate.name}`, { storyId: "_migrate" });
75245
75804
  }
75246
- await Bun.write(path29.join(destBase, ".migrated-from"), JSON.stringify({ from: options.workdir, migratedAt: new Date().toISOString() }, null, 2));
75805
+ await Bun.write(path30.join(destBase, ".migrated-from"), JSON.stringify({ from: options.workdir, migratedAt: new Date().toISOString() }, null, 2));
75247
75806
  logger.info("migrate", `Migration complete: ${moved} entries moved`, {
75248
75807
  storyId: "_migrate",
75249
75808
  destBase
@@ -75360,7 +75919,7 @@ __export(exports_precheck_runner, {
75360
75919
  runPrecheckValidation: () => runPrecheckValidation
75361
75920
  });
75362
75921
  import { mkdirSync as mkdirSync7 } from "fs";
75363
- import path30 from "path";
75922
+ import path31 from "path";
75364
75923
  async function runPrecheckValidation(ctx) {
75365
75924
  const logger = getSafeLogger();
75366
75925
  if (process.env.NAX_PRECHECK !== "1") {
@@ -75375,7 +75934,7 @@ async function runPrecheckValidation(ctx) {
75375
75934
  silent: true
75376
75935
  });
75377
75936
  if (ctx.logFilePath) {
75378
- mkdirSync7(path30.dirname(ctx.logFilePath), { recursive: true });
75937
+ mkdirSync7(path31.dirname(ctx.logFilePath), { recursive: true });
75379
75938
  const precheckLog = {
75380
75939
  type: "precheck",
75381
75940
  timestamp: new Date().toISOString(),
@@ -75688,7 +76247,7 @@ __export(exports_run_setup, {
75688
76247
  setupRun: () => setupRun,
75689
76248
  _runSetupDeps: () => _runSetupDeps
75690
76249
  });
75691
- import path31 from "path";
76250
+ import path32 from "path";
75692
76251
  function warnProfileMismatch(prd, config2, logger) {
75693
76252
  const profiles = config2.routing?.agents?.profiles ?? [];
75694
76253
  const profileIds = new Set(profiles.map((p) => p.id));
@@ -75809,7 +76368,7 @@ async function setupRun(options) {
75809
76368
  statusWriter.setPrd(prd);
75810
76369
  {
75811
76370
  const { detectGeneratedContent: detectGeneratedContent2, migrateCommand: migrateCommand2 } = await Promise.resolve().then(() => (init_migrate(), exports_migrate));
75812
- const naxDir = path31.join(workdir, ".nax");
76371
+ const naxDir = path32.join(workdir, ".nax");
75813
76372
  const candidates = await detectGeneratedContent2(naxDir).catch(() => []);
75814
76373
  if (candidates.length > 0) {
75815
76374
  logger?.info("setup", "Found generated content under .nax/ \u2014 migrating to output dir", {
@@ -75836,7 +76395,7 @@ async function setupRun(options) {
75836
76395
  remoteUrl = new TextDecoder().decode(gitResult.stdout).trim() || null;
75837
76396
  }
75838
76397
  } catch {}
75839
- const projectKey = config2.name?.trim() || path31.basename(workdir);
76398
+ const projectKey = config2.name?.trim() || path32.basename(workdir);
75840
76399
  await claimProjectIdentity2(projectKey, workdir, remoteUrl).catch((err) => {
75841
76400
  if (err instanceof NaxError && err.code === "RUN_NAME_COLLISION") {
75842
76401
  throw err;
@@ -75891,8 +76450,8 @@ async function setupRun(options) {
75891
76450
  explicit: Object.fromEntries(explicitFields.map((f) => [f, existingProjectConfig[f]])),
75892
76451
  detected: Object.fromEntries(autodetectedFields.map((f) => [f, detectedProfile[f]]))
75893
76452
  });
75894
- const globalPluginsDir = path31.join(globalConfigDir(), "plugins");
75895
- const projectPluginsDir = path31.join(workdir, ".nax", "plugins");
76453
+ const globalPluginsDir = path32.join(globalConfigDir(), "plugins");
76454
+ const projectPluginsDir = path32.join(workdir, ".nax", "plugins");
75896
76455
  const configPlugins = config2.plugins || [];
75897
76456
  const resolvedPatterns = await resolveTestFilePatterns(config2, workdir);
75898
76457
  const isTestFileFn = (filename) => resolvedPatterns.regex.some((re) => re.test(filename));
@@ -76417,6 +76976,7 @@ var init_lifecycle = __esm(() => {
76417
76976
  var exports_execution = {};
76418
76977
  __export(exports_execution, {
76419
76978
  writeExitSummary: () => writeExitSummary,
76979
+ withNoProgressBail: () => withNoProgressBail,
76420
76980
  withIncreasingFailuresBail: () => withIncreasingFailuresBail,
76421
76981
  toReviewDecisionPayload: () => toReviewDecisionPayload,
76422
76982
  synthesizeBackfillMetric: () => synthesizeBackfillMetric,
@@ -76496,6 +77056,7 @@ __export(exports_execution, {
76496
77056
  _pidRegistryDeps: () => _pidRegistryDeps,
76497
77057
  _newPackageSetupDeps: () => _newPackageSetupDeps,
76498
77058
  StoryOrchestratorBuilder: () => StoryOrchestratorBuilder,
77059
+ StatusWriter: () => StatusWriter,
76499
77060
  STRICT_VERDICT_PHASE_NAMES: () => STRICT_VERDICT_PHASE_NAMES,
76500
77061
  PidRegistry: () => PidRegistry,
76501
77062
  PHASE_KIND_TO_STATE_KEY: () => PHASE_KIND_TO_STATE_KEY,
@@ -76511,6 +77072,7 @@ var init_execution2 = __esm(() => {
76511
77072
  init_iteration_runner();
76512
77073
  init_escalation();
76513
77074
  init_queue_handler();
77075
+ init_status_writer();
76514
77076
  init_ensure_package_dirs();
76515
77077
  init_new_package_setup();
76516
77078
  init_helpers();
@@ -77813,11 +78375,11 @@ var require_react_reconciler_development = __commonJS((exports, module) => {
77813
78375
  fiber = fiber.next, id--;
77814
78376
  return fiber;
77815
78377
  }
77816
- function copyWithSetImpl(obj, path32, index, value) {
77817
- if (index >= path32.length)
78378
+ function copyWithSetImpl(obj, path33, index, value) {
78379
+ if (index >= path33.length)
77818
78380
  return value;
77819
- var key = path32[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
77820
- updated[key] = copyWithSetImpl(obj[key], path32, index + 1, value);
78381
+ var key = path33[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
78382
+ updated[key] = copyWithSetImpl(obj[key], path33, index + 1, value);
77821
78383
  return updated;
77822
78384
  }
77823
78385
  function copyWithRename(obj, oldPath, newPath) {
@@ -77837,11 +78399,11 @@ var require_react_reconciler_development = __commonJS((exports, module) => {
77837
78399
  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);
77838
78400
  return updated;
77839
78401
  }
77840
- function copyWithDeleteImpl(obj, path32, index) {
77841
- var key = path32[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
77842
- if (index + 1 === path32.length)
78402
+ function copyWithDeleteImpl(obj, path33, index) {
78403
+ var key = path33[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
78404
+ if (index + 1 === path33.length)
77843
78405
  return isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], updated;
77844
- updated[key] = copyWithDeleteImpl(obj[key], path32, index + 1);
78406
+ updated[key] = copyWithDeleteImpl(obj[key], path33, index + 1);
77845
78407
  return updated;
77846
78408
  }
77847
78409
  function shouldSuspendImpl() {
@@ -87864,29 +88426,29 @@ Check the top-level render call using <` + componentName2 + ">.");
87864
88426
  var didWarnAboutNestedUpdates = false;
87865
88427
  var didWarnAboutFindNodeInStrictMode = {};
87866
88428
  var overrideHookState = null, overrideHookStateDeletePath = null, overrideHookStateRenamePath = null, overrideProps = null, overridePropsDeletePath = null, overridePropsRenamePath = null, scheduleUpdate = null, scheduleRetry = null, setErrorHandler = null, setSuspenseHandler = null;
87867
- overrideHookState = function(fiber, id, path32, value) {
88429
+ overrideHookState = function(fiber, id, path33, value) {
87868
88430
  id = findHook(fiber, id);
87869
- 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));
88431
+ id !== null && (path33 = copyWithSetImpl(id.memoizedState, path33, 0, value), id.memoizedState = path33, id.baseState = path33, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path33 = enqueueConcurrentRenderForLane(fiber, 2), path33 !== null && scheduleUpdateOnFiber(path33, fiber, 2));
87870
88432
  };
87871
- overrideHookStateDeletePath = function(fiber, id, path32) {
88433
+ overrideHookStateDeletePath = function(fiber, id, path33) {
87872
88434
  id = findHook(fiber, id);
87873
- 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));
88435
+ id !== null && (path33 = copyWithDeleteImpl(id.memoizedState, path33, 0), id.memoizedState = path33, id.baseState = path33, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path33 = enqueueConcurrentRenderForLane(fiber, 2), path33 !== null && scheduleUpdateOnFiber(path33, fiber, 2));
87874
88436
  };
87875
88437
  overrideHookStateRenamePath = function(fiber, id, oldPath, newPath) {
87876
88438
  id = findHook(fiber, id);
87877
88439
  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));
87878
88440
  };
87879
- overrideProps = function(fiber, path32, value) {
87880
- fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path32, 0, value);
88441
+ overrideProps = function(fiber, path33, value) {
88442
+ fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path33, 0, value);
87881
88443
  fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
87882
- path32 = enqueueConcurrentRenderForLane(fiber, 2);
87883
- path32 !== null && scheduleUpdateOnFiber(path32, fiber, 2);
88444
+ path33 = enqueueConcurrentRenderForLane(fiber, 2);
88445
+ path33 !== null && scheduleUpdateOnFiber(path33, fiber, 2);
87884
88446
  };
87885
- overridePropsDeletePath = function(fiber, path32) {
87886
- fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path32, 0);
88447
+ overridePropsDeletePath = function(fiber, path33) {
88448
+ fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path33, 0);
87887
88449
  fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
87888
- path32 = enqueueConcurrentRenderForLane(fiber, 2);
87889
- path32 !== null && scheduleUpdateOnFiber(path32, fiber, 2);
88450
+ path33 = enqueueConcurrentRenderForLane(fiber, 2);
88451
+ path33 !== null && scheduleUpdateOnFiber(path33, fiber, 2);
87890
88452
  };
87891
88453
  overridePropsRenamePath = function(fiber, oldPath, newPath) {
87892
88454
  fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
@@ -91941,8 +92503,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
91941
92503
  }
91942
92504
  return false;
91943
92505
  }
91944
- function utils_getInObject(object2, path32) {
91945
- return path32.reduce(function(reduced, attr2) {
92506
+ function utils_getInObject(object2, path33) {
92507
+ return path33.reduce(function(reduced, attr2) {
91946
92508
  if (reduced) {
91947
92509
  if (utils_hasOwnProperty.call(reduced, attr2)) {
91948
92510
  return reduced[attr2];
@@ -91954,11 +92516,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
91954
92516
  return null;
91955
92517
  }, object2);
91956
92518
  }
91957
- function deletePathInObject(object2, path32) {
91958
- var length = path32.length;
91959
- var last2 = path32[length - 1];
92519
+ function deletePathInObject(object2, path33) {
92520
+ var length = path33.length;
92521
+ var last2 = path33[length - 1];
91960
92522
  if (object2 != null) {
91961
- var parent = utils_getInObject(object2, path32.slice(0, length - 1));
92523
+ var parent = utils_getInObject(object2, path33.slice(0, length - 1));
91962
92524
  if (parent) {
91963
92525
  if (src_isArray(parent)) {
91964
92526
  parent.splice(last2, 1);
@@ -91984,11 +92546,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
91984
92546
  }
91985
92547
  }
91986
92548
  }
91987
- function utils_setInObject(object2, path32, value) {
91988
- var length = path32.length;
91989
- var last2 = path32[length - 1];
92549
+ function utils_setInObject(object2, path33, value) {
92550
+ var length = path33.length;
92551
+ var last2 = path33[length - 1];
91990
92552
  if (object2 != null) {
91991
- var parent = utils_getInObject(object2, path32.slice(0, length - 1));
92553
+ var parent = utils_getInObject(object2, path33.slice(0, length - 1));
91992
92554
  if (parent) {
91993
92555
  parent[last2] = value;
91994
92556
  }
@@ -92519,8 +93081,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92519
93081
  unserializable: Symbol("unserializable")
92520
93082
  };
92521
93083
  var LEVEL_THRESHOLD = 2;
92522
- function createDehydrated(type, inspectable, data, cleaned, path32) {
92523
- cleaned.push(path32);
93084
+ function createDehydrated(type, inspectable, data, cleaned, path33) {
93085
+ cleaned.push(path33);
92524
93086
  var dehydrated = {
92525
93087
  inspectable,
92526
93088
  type,
@@ -92538,13 +93100,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92538
93100
  }
92539
93101
  return dehydrated;
92540
93102
  }
92541
- function dehydrate(data, cleaned, unserializable, path32, isPathAllowed) {
93103
+ function dehydrate(data, cleaned, unserializable, path33, isPathAllowed) {
92542
93104
  var level = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
92543
93105
  var type = getDataType(data);
92544
93106
  var isPathAllowedCheck;
92545
93107
  switch (type) {
92546
93108
  case "html_element":
92547
- cleaned.push(path32);
93109
+ cleaned.push(path33);
92548
93110
  return {
92549
93111
  inspectable: false,
92550
93112
  preview_short: formatDataForPreview(data, false),
@@ -92553,7 +93115,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92553
93115
  type
92554
93116
  };
92555
93117
  case "function":
92556
- cleaned.push(path32);
93118
+ cleaned.push(path33);
92557
93119
  return {
92558
93120
  inspectable: false,
92559
93121
  preview_short: formatDataForPreview(data, false),
@@ -92562,14 +93124,14 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92562
93124
  type
92563
93125
  };
92564
93126
  case "string":
92565
- isPathAllowedCheck = isPathAllowed(path32);
93127
+ isPathAllowedCheck = isPathAllowed(path33);
92566
93128
  if (isPathAllowedCheck) {
92567
93129
  return data;
92568
93130
  } else {
92569
93131
  return data.length <= 500 ? data : data.slice(0, 500) + "...";
92570
93132
  }
92571
93133
  case "bigint":
92572
- cleaned.push(path32);
93134
+ cleaned.push(path33);
92573
93135
  return {
92574
93136
  inspectable: false,
92575
93137
  preview_short: formatDataForPreview(data, false),
@@ -92578,7 +93140,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92578
93140
  type
92579
93141
  };
92580
93142
  case "symbol":
92581
- cleaned.push(path32);
93143
+ cleaned.push(path33);
92582
93144
  return {
92583
93145
  inspectable: false,
92584
93146
  preview_short: formatDataForPreview(data, false),
@@ -92587,9 +93149,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92587
93149
  type
92588
93150
  };
92589
93151
  case "react_element": {
92590
- isPathAllowedCheck = isPathAllowed(path32);
93152
+ isPathAllowedCheck = isPathAllowed(path33);
92591
93153
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
92592
- cleaned.push(path32);
93154
+ cleaned.push(path33);
92593
93155
  return {
92594
93156
  inspectable: true,
92595
93157
  preview_short: formatDataForPreview(data, false),
@@ -92606,19 +93168,19 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92606
93168
  preview_long: formatDataForPreview(data, true),
92607
93169
  name: getDisplayNameForReactElement(data) || "Unknown"
92608
93170
  };
92609
- unserializableValue.key = dehydrate(data.key, cleaned, unserializable, path32.concat(["key"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93171
+ unserializableValue.key = dehydrate(data.key, cleaned, unserializable, path33.concat(["key"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92610
93172
  if (data.$$typeof === REACT_LEGACY_ELEMENT_TYPE) {
92611
- unserializableValue.ref = dehydrate(data.ref, cleaned, unserializable, path32.concat(["ref"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93173
+ unserializableValue.ref = dehydrate(data.ref, cleaned, unserializable, path33.concat(["ref"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92612
93174
  }
92613
- unserializableValue.props = dehydrate(data.props, cleaned, unserializable, path32.concat(["props"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92614
- unserializable.push(path32);
93175
+ unserializableValue.props = dehydrate(data.props, cleaned, unserializable, path33.concat(["props"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93176
+ unserializable.push(path33);
92615
93177
  return unserializableValue;
92616
93178
  }
92617
93179
  case "react_lazy": {
92618
- isPathAllowedCheck = isPathAllowed(path32);
93180
+ isPathAllowedCheck = isPathAllowed(path33);
92619
93181
  var payload = data._payload;
92620
93182
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
92621
- cleaned.push(path32);
93183
+ cleaned.push(path33);
92622
93184
  var inspectable = payload !== null && hydration_typeof(payload) === "object" && (payload._status === 1 || payload._status === 2 || payload.status === "fulfilled" || payload.status === "rejected");
92623
93185
  return {
92624
93186
  inspectable,
@@ -92635,13 +93197,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92635
93197
  preview_long: formatDataForPreview(data, true),
92636
93198
  name: "lazy()"
92637
93199
  };
92638
- _unserializableValue._payload = dehydrate(payload, cleaned, unserializable, path32.concat(["_payload"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92639
- unserializable.push(path32);
93200
+ _unserializableValue._payload = dehydrate(payload, cleaned, unserializable, path33.concat(["_payload"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93201
+ unserializable.push(path33);
92640
93202
  return _unserializableValue;
92641
93203
  }
92642
93204
  case "array_buffer":
92643
93205
  case "data_view":
92644
- cleaned.push(path32);
93206
+ cleaned.push(path33);
92645
93207
  return {
92646
93208
  inspectable: false,
92647
93209
  preview_short: formatDataForPreview(data, false),
@@ -92651,21 +93213,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92651
93213
  type
92652
93214
  };
92653
93215
  case "array":
92654
- isPathAllowedCheck = isPathAllowed(path32);
93216
+ isPathAllowedCheck = isPathAllowed(path33);
92655
93217
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
92656
- return createDehydrated(type, true, data, cleaned, path32);
93218
+ return createDehydrated(type, true, data, cleaned, path33);
92657
93219
  }
92658
93220
  var arr = [];
92659
93221
  for (var i = 0;i < data.length; i++) {
92660
- arr[i] = dehydrateKey(data, i, cleaned, unserializable, path32.concat([i]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93222
+ arr[i] = dehydrateKey(data, i, cleaned, unserializable, path33.concat([i]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92661
93223
  }
92662
93224
  return arr;
92663
93225
  case "html_all_collection":
92664
93226
  case "typed_array":
92665
93227
  case "iterator":
92666
- isPathAllowedCheck = isPathAllowed(path32);
93228
+ isPathAllowedCheck = isPathAllowed(path33);
92667
93229
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
92668
- return createDehydrated(type, true, data, cleaned, path32);
93230
+ return createDehydrated(type, true, data, cleaned, path33);
92669
93231
  } else {
92670
93232
  var _unserializableValue2 = {
92671
93233
  unserializable: true,
@@ -92677,13 +93239,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92677
93239
  name: typeof data.constructor !== "function" || typeof data.constructor.name !== "string" || data.constructor.name === "Object" ? "" : data.constructor.name
92678
93240
  };
92679
93241
  Array.from(data).forEach(function(item, i2) {
92680
- return _unserializableValue2[i2] = dehydrate(item, cleaned, unserializable, path32.concat([i2]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93242
+ return _unserializableValue2[i2] = dehydrate(item, cleaned, unserializable, path33.concat([i2]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92681
93243
  });
92682
- unserializable.push(path32);
93244
+ unserializable.push(path33);
92683
93245
  return _unserializableValue2;
92684
93246
  }
92685
93247
  case "opaque_iterator":
92686
- cleaned.push(path32);
93248
+ cleaned.push(path33);
92687
93249
  return {
92688
93250
  inspectable: false,
92689
93251
  preview_short: formatDataForPreview(data, false),
@@ -92692,7 +93254,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92692
93254
  type
92693
93255
  };
92694
93256
  case "date":
92695
- cleaned.push(path32);
93257
+ cleaned.push(path33);
92696
93258
  return {
92697
93259
  inspectable: false,
92698
93260
  preview_short: formatDataForPreview(data, false),
@@ -92701,7 +93263,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92701
93263
  type
92702
93264
  };
92703
93265
  case "regexp":
92704
- cleaned.push(path32);
93266
+ cleaned.push(path33);
92705
93267
  return {
92706
93268
  inspectable: false,
92707
93269
  preview_short: formatDataForPreview(data, false),
@@ -92710,9 +93272,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92710
93272
  type
92711
93273
  };
92712
93274
  case "thenable":
92713
- isPathAllowedCheck = isPathAllowed(path32);
93275
+ isPathAllowedCheck = isPathAllowed(path33);
92714
93276
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
92715
- cleaned.push(path32);
93277
+ cleaned.push(path33);
92716
93278
  return {
92717
93279
  inspectable: data.status === "fulfilled" || data.status === "rejected",
92718
93280
  preview_short: formatDataForPreview(data, false),
@@ -92733,8 +93295,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92733
93295
  preview_long: formatDataForPreview(data, true),
92734
93296
  name: "fulfilled Thenable"
92735
93297
  };
92736
- _unserializableValue3.value = dehydrate(data.value, cleaned, unserializable, path32.concat(["value"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92737
- unserializable.push(path32);
93298
+ _unserializableValue3.value = dehydrate(data.value, cleaned, unserializable, path33.concat(["value"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93299
+ unserializable.push(path33);
92738
93300
  return _unserializableValue3;
92739
93301
  }
92740
93302
  case "rejected": {
@@ -92745,12 +93307,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92745
93307
  preview_long: formatDataForPreview(data, true),
92746
93308
  name: "rejected Thenable"
92747
93309
  };
92748
- _unserializableValue4.reason = dehydrate(data.reason, cleaned, unserializable, path32.concat(["reason"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92749
- unserializable.push(path32);
93310
+ _unserializableValue4.reason = dehydrate(data.reason, cleaned, unserializable, path33.concat(["reason"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93311
+ unserializable.push(path33);
92750
93312
  return _unserializableValue4;
92751
93313
  }
92752
93314
  default:
92753
- cleaned.push(path32);
93315
+ cleaned.push(path33);
92754
93316
  return {
92755
93317
  inspectable: false,
92756
93318
  preview_short: formatDataForPreview(data, false),
@@ -92760,21 +93322,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92760
93322
  };
92761
93323
  }
92762
93324
  case "object":
92763
- isPathAllowedCheck = isPathAllowed(path32);
93325
+ isPathAllowedCheck = isPathAllowed(path33);
92764
93326
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
92765
- return createDehydrated(type, true, data, cleaned, path32);
93327
+ return createDehydrated(type, true, data, cleaned, path33);
92766
93328
  } else {
92767
93329
  var object2 = {};
92768
93330
  getAllEnumerableKeys(data).forEach(function(key) {
92769
93331
  var name = key.toString();
92770
- object2[name] = dehydrateKey(data, key, cleaned, unserializable, path32.concat([name]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93332
+ object2[name] = dehydrateKey(data, key, cleaned, unserializable, path33.concat([name]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92771
93333
  });
92772
93334
  return object2;
92773
93335
  }
92774
93336
  case "class_instance": {
92775
- isPathAllowedCheck = isPathAllowed(path32);
93337
+ isPathAllowedCheck = isPathAllowed(path33);
92776
93338
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
92777
- return createDehydrated(type, true, data, cleaned, path32);
93339
+ return createDehydrated(type, true, data, cleaned, path33);
92778
93340
  }
92779
93341
  var value = {
92780
93342
  unserializable: true,
@@ -92786,15 +93348,15 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92786
93348
  };
92787
93349
  getAllEnumerableKeys(data).forEach(function(key) {
92788
93350
  var keyAsString = key.toString();
92789
- value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path32.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93351
+ value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path33.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92790
93352
  });
92791
- unserializable.push(path32);
93353
+ unserializable.push(path33);
92792
93354
  return value;
92793
93355
  }
92794
93356
  case "error": {
92795
- isPathAllowedCheck = isPathAllowed(path32);
93357
+ isPathAllowedCheck = isPathAllowed(path33);
92796
93358
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
92797
- return createDehydrated(type, true, data, cleaned, path32);
93359
+ return createDehydrated(type, true, data, cleaned, path33);
92798
93360
  }
92799
93361
  var _value = {
92800
93362
  unserializable: true,
@@ -92804,22 +93366,22 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92804
93366
  preview_long: formatDataForPreview(data, true),
92805
93367
  name: data.name
92806
93368
  };
92807
- _value.message = dehydrate(data.message, cleaned, unserializable, path32.concat(["message"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92808
- _value.stack = dehydrate(data.stack, cleaned, unserializable, path32.concat(["stack"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93369
+ _value.message = dehydrate(data.message, cleaned, unserializable, path33.concat(["message"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93370
+ _value.stack = dehydrate(data.stack, cleaned, unserializable, path33.concat(["stack"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92809
93371
  if ("cause" in data) {
92810
- _value.cause = dehydrate(data.cause, cleaned, unserializable, path32.concat(["cause"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93372
+ _value.cause = dehydrate(data.cause, cleaned, unserializable, path33.concat(["cause"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92811
93373
  }
92812
93374
  getAllEnumerableKeys(data).forEach(function(key) {
92813
93375
  var keyAsString = key.toString();
92814
- _value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path32.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
93376
+ _value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path33.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
92815
93377
  });
92816
- unserializable.push(path32);
93378
+ unserializable.push(path33);
92817
93379
  return _value;
92818
93380
  }
92819
93381
  case "infinity":
92820
93382
  case "nan":
92821
93383
  case "undefined":
92822
- cleaned.push(path32);
93384
+ cleaned.push(path33);
92823
93385
  return {
92824
93386
  type
92825
93387
  };
@@ -92827,10 +93389,10 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92827
93389
  return data;
92828
93390
  }
92829
93391
  }
92830
- function dehydrateKey(parent, key, cleaned, unserializable, path32, isPathAllowed) {
93392
+ function dehydrateKey(parent, key, cleaned, unserializable, path33, isPathAllowed) {
92831
93393
  var level = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0;
92832
93394
  try {
92833
- return dehydrate(parent[key], cleaned, unserializable, path32, isPathAllowed, level);
93395
+ return dehydrate(parent[key], cleaned, unserializable, path33, isPathAllowed, level);
92834
93396
  } catch (error48) {
92835
93397
  var preview = "";
92836
93398
  if (hydration_typeof(error48) === "object" && error48 !== null && typeof error48.stack === "string") {
@@ -92838,7 +93400,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92838
93400
  } else if (typeof error48 === "string") {
92839
93401
  preview = error48;
92840
93402
  }
92841
- cleaned.push(path32);
93403
+ cleaned.push(path33);
92842
93404
  return {
92843
93405
  inspectable: false,
92844
93406
  preview_short: "[Exception]",
@@ -92848,8 +93410,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92848
93410
  };
92849
93411
  }
92850
93412
  }
92851
- function fillInPath(object2, data, path32, value) {
92852
- var target = getInObject(object2, path32);
93413
+ function fillInPath(object2, data, path33, value) {
93414
+ var target = getInObject(object2, path33);
92853
93415
  if (target != null) {
92854
93416
  if (!target[meta3.unserializable]) {
92855
93417
  delete target[meta3.inspectable];
@@ -92864,9 +93426,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92864
93426
  }
92865
93427
  if (value !== null && data.unserializable.length > 0) {
92866
93428
  var unserializablePath = data.unserializable[0];
92867
- var isMatch2 = unserializablePath.length === path32.length;
92868
- for (var i = 0;i < path32.length; i++) {
92869
- if (path32[i] !== unserializablePath[i]) {
93429
+ var isMatch2 = unserializablePath.length === path33.length;
93430
+ for (var i = 0;i < path33.length; i++) {
93431
+ if (path33[i] !== unserializablePath[i]) {
92870
93432
  isMatch2 = false;
92871
93433
  break;
92872
93434
  }
@@ -92875,13 +93437,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92875
93437
  upgradeUnserializable(value, value);
92876
93438
  }
92877
93439
  }
92878
- setInObject(object2, path32, value);
93440
+ setInObject(object2, path33, value);
92879
93441
  }
92880
93442
  function hydrate(object2, cleaned, unserializable) {
92881
- cleaned.forEach(function(path32) {
92882
- var length = path32.length;
92883
- var last2 = path32[length - 1];
92884
- var parent = getInObject(object2, path32.slice(0, length - 1));
93443
+ cleaned.forEach(function(path33) {
93444
+ var length = path33.length;
93445
+ var last2 = path33[length - 1];
93446
+ var parent = getInObject(object2, path33.slice(0, length - 1));
92885
93447
  if (!parent || !parent.hasOwnProperty(last2)) {
92886
93448
  return;
92887
93449
  }
@@ -92907,10 +93469,10 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
92907
93469
  parent[last2] = replaced;
92908
93470
  }
92909
93471
  });
92910
- unserializable.forEach(function(path32) {
92911
- var length = path32.length;
92912
- var last2 = path32[length - 1];
92913
- var parent = getInObject(object2, path32.slice(0, length - 1));
93472
+ unserializable.forEach(function(path33) {
93473
+ var length = path33.length;
93474
+ var last2 = path33[length - 1];
93475
+ var parent = getInObject(object2, path33.slice(0, length - 1));
92914
93476
  if (!parent || !parent.hasOwnProperty(last2)) {
92915
93477
  return;
92916
93478
  }
@@ -93031,11 +93593,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
93031
93593
  return gte2(version2, FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER);
93032
93594
  }
93033
93595
  function cleanForBridge(data, isPathAllowed) {
93034
- var path32 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
93596
+ var path33 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
93035
93597
  if (data !== null) {
93036
93598
  var cleanedPaths = [];
93037
93599
  var unserializablePaths = [];
93038
- var cleanedData = dehydrate(data, cleanedPaths, unserializablePaths, path32, isPathAllowed);
93600
+ var cleanedData = dehydrate(data, cleanedPaths, unserializablePaths, path33, isPathAllowed);
93039
93601
  return {
93040
93602
  data: cleanedData,
93041
93603
  cleaned: cleanedPaths,
@@ -93045,18 +93607,18 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
93045
93607
  return null;
93046
93608
  }
93047
93609
  }
93048
- function copyWithDelete(obj, path32) {
93610
+ function copyWithDelete(obj, path33) {
93049
93611
  var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
93050
- var key = path32[index];
93612
+ var key = path33[index];
93051
93613
  var updated = shared_isArray(obj) ? obj.slice() : utils_objectSpread({}, obj);
93052
- if (index + 1 === path32.length) {
93614
+ if (index + 1 === path33.length) {
93053
93615
  if (shared_isArray(updated)) {
93054
93616
  updated.splice(key, 1);
93055
93617
  } else {
93056
93618
  delete updated[key];
93057
93619
  }
93058
93620
  } else {
93059
- updated[key] = copyWithDelete(obj[key], path32, index + 1);
93621
+ updated[key] = copyWithDelete(obj[key], path33, index + 1);
93060
93622
  }
93061
93623
  return updated;
93062
93624
  }
@@ -93077,14 +93639,14 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
93077
93639
  }
93078
93640
  return updated;
93079
93641
  }
93080
- function copyWithSet(obj, path32, value) {
93642
+ function copyWithSet(obj, path33, value) {
93081
93643
  var index = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
93082
- if (index >= path32.length) {
93644
+ if (index >= path33.length) {
93083
93645
  return value;
93084
93646
  }
93085
- var key = path32[index];
93647
+ var key = path33[index];
93086
93648
  var updated = shared_isArray(obj) ? obj.slice() : utils_objectSpread({}, obj);
93087
- updated[key] = copyWithSet(obj[key], path32, value, index + 1);
93649
+ updated[key] = copyWithSet(obj[key], path33, value, index + 1);
93088
93650
  return updated;
93089
93651
  }
93090
93652
  function getEffectDurations(root) {
@@ -94412,12 +94974,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
94412
94974
  }
94413
94975
  });
94414
94976
  bridge_defineProperty(_this, "overrideValueAtPath", function(_ref) {
94415
- var { id, path: path32, rendererID, type, value } = _ref;
94977
+ var { id, path: path33, rendererID, type, value } = _ref;
94416
94978
  switch (type) {
94417
94979
  case "context":
94418
94980
  _this.send("overrideContext", {
94419
94981
  id,
94420
- path: path32,
94982
+ path: path33,
94421
94983
  rendererID,
94422
94984
  wasForwarded: true,
94423
94985
  value
@@ -94426,7 +94988,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
94426
94988
  case "hooks":
94427
94989
  _this.send("overrideHookState", {
94428
94990
  id,
94429
- path: path32,
94991
+ path: path33,
94430
94992
  rendererID,
94431
94993
  wasForwarded: true,
94432
94994
  value
@@ -94435,7 +94997,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
94435
94997
  case "props":
94436
94998
  _this.send("overrideProps", {
94437
94999
  id,
94438
- path: path32,
95000
+ path: path33,
94439
95001
  rendererID,
94440
95002
  wasForwarded: true,
94441
95003
  value
@@ -94444,7 +95006,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
94444
95006
  case "state":
94445
95007
  _this.send("overrideState", {
94446
95008
  id,
94447
- path: path32,
95009
+ path: path33,
94448
95010
  rendererID,
94449
95011
  wasForwarded: true,
94450
95012
  value
@@ -94778,12 +95340,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
94778
95340
  }
94779
95341
  });
94780
95342
  agent_defineProperty(_this, "copyElementPath", function(_ref5) {
94781
- var { id, path: path32, rendererID } = _ref5;
95343
+ var { id, path: path33, rendererID } = _ref5;
94782
95344
  var renderer = _this._rendererInterfaces[rendererID];
94783
95345
  if (renderer == null) {
94784
95346
  console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
94785
95347
  } else {
94786
- var value = renderer.getSerializedElementValueByPath(id, path32);
95348
+ var value = renderer.getSerializedElementValueByPath(id, path33);
94787
95349
  if (value != null) {
94788
95350
  _this._bridge.send("saveToClipboard", value);
94789
95351
  } else {
@@ -94792,12 +95354,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
94792
95354
  }
94793
95355
  });
94794
95356
  agent_defineProperty(_this, "deletePath", function(_ref6) {
94795
- var { hookID, id, path: path32, rendererID, type } = _ref6;
95357
+ var { hookID, id, path: path33, rendererID, type } = _ref6;
94796
95358
  var renderer = _this._rendererInterfaces[rendererID];
94797
95359
  if (renderer == null) {
94798
95360
  console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
94799
95361
  } else {
94800
- renderer.deletePath(type, id, hookID, path32);
95362
+ renderer.deletePath(type, id, hookID, path33);
94801
95363
  }
94802
95364
  });
94803
95365
  agent_defineProperty(_this, "getBackendVersion", function() {
@@ -94834,12 +95396,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
94834
95396
  }
94835
95397
  });
94836
95398
  agent_defineProperty(_this, "inspectElement", function(_ref9) {
94837
- var { forceFullData, id, path: path32, rendererID, requestID } = _ref9;
95399
+ var { forceFullData, id, path: path33, rendererID, requestID } = _ref9;
94838
95400
  var renderer = _this._rendererInterfaces[rendererID];
94839
95401
  if (renderer == null) {
94840
95402
  console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
94841
95403
  } else {
94842
- _this._bridge.send("inspectedElement", renderer.inspectElement(requestID, id, path32, forceFullData));
95404
+ _this._bridge.send("inspectedElement", renderer.inspectElement(requestID, id, path33, forceFullData));
94843
95405
  if (_this._persistedSelectionMatch === null || _this._persistedSelectionMatch.id !== id) {
94844
95406
  _this._persistedSelection = null;
94845
95407
  _this._persistedSelectionMatch = null;
@@ -94873,15 +95435,15 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
94873
95435
  }
94874
95436
  for (var rendererID in _this._rendererInterfaces) {
94875
95437
  var renderer = _this._rendererInterfaces[rendererID];
94876
- var path32 = null;
95438
+ var path33 = null;
94877
95439
  if (suspendedByPathIndex !== null && rendererPath !== null) {
94878
95440
  var suspendedByPathRendererIndex = suspendedByPathIndex - suspendedByOffset;
94879
95441
  var rendererHasRequestedSuspendedByPath = renderer.getElementAttributeByPath(id, ["suspendedBy", suspendedByPathRendererIndex]) !== undefined;
94880
95442
  if (rendererHasRequestedSuspendedByPath) {
94881
- path32 = ["suspendedBy", suspendedByPathRendererIndex].concat(rendererPath);
95443
+ path33 = ["suspendedBy", suspendedByPathRendererIndex].concat(rendererPath);
94882
95444
  }
94883
95445
  }
94884
- var inspectedRootsPayload = renderer.inspectElement(requestID, id, path32, forceFullData);
95446
+ var inspectedRootsPayload = renderer.inspectElement(requestID, id, path33, forceFullData);
94885
95447
  switch (inspectedRootsPayload.type) {
94886
95448
  case "hydrated-path":
94887
95449
  inspectedRootsPayload.path[1] += suspendedByOffset;
@@ -94975,20 +95537,20 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
94975
95537
  }
94976
95538
  });
94977
95539
  agent_defineProperty(_this, "overrideValueAtPath", function(_ref15) {
94978
- var { hookID, id, path: path32, rendererID, type, value } = _ref15;
95540
+ var { hookID, id, path: path33, rendererID, type, value } = _ref15;
94979
95541
  var renderer = _this._rendererInterfaces[rendererID];
94980
95542
  if (renderer == null) {
94981
95543
  console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
94982
95544
  } else {
94983
- renderer.overrideValueAtPath(type, id, hookID, path32, value);
95545
+ renderer.overrideValueAtPath(type, id, hookID, path33, value);
94984
95546
  }
94985
95547
  });
94986
95548
  agent_defineProperty(_this, "overrideContext", function(_ref16) {
94987
- var { id, path: path32, rendererID, wasForwarded, value } = _ref16;
95549
+ var { id, path: path33, rendererID, wasForwarded, value } = _ref16;
94988
95550
  if (!wasForwarded) {
94989
95551
  _this.overrideValueAtPath({
94990
95552
  id,
94991
- path: path32,
95553
+ path: path33,
94992
95554
  rendererID,
94993
95555
  type: "context",
94994
95556
  value
@@ -94996,11 +95558,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
94996
95558
  }
94997
95559
  });
94998
95560
  agent_defineProperty(_this, "overrideHookState", function(_ref17) {
94999
- var { id, hookID, path: path32, rendererID, wasForwarded, value } = _ref17;
95561
+ var { id, hookID, path: path33, rendererID, wasForwarded, value } = _ref17;
95000
95562
  if (!wasForwarded) {
95001
95563
  _this.overrideValueAtPath({
95002
95564
  id,
95003
- path: path32,
95565
+ path: path33,
95004
95566
  rendererID,
95005
95567
  type: "hooks",
95006
95568
  value
@@ -95008,11 +95570,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
95008
95570
  }
95009
95571
  });
95010
95572
  agent_defineProperty(_this, "overrideProps", function(_ref18) {
95011
- var { id, path: path32, rendererID, wasForwarded, value } = _ref18;
95573
+ var { id, path: path33, rendererID, wasForwarded, value } = _ref18;
95012
95574
  if (!wasForwarded) {
95013
95575
  _this.overrideValueAtPath({
95014
95576
  id,
95015
- path: path32,
95577
+ path: path33,
95016
95578
  rendererID,
95017
95579
  type: "props",
95018
95580
  value
@@ -95020,11 +95582,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
95020
95582
  }
95021
95583
  });
95022
95584
  agent_defineProperty(_this, "overrideState", function(_ref19) {
95023
- var { id, path: path32, rendererID, wasForwarded, value } = _ref19;
95585
+ var { id, path: path33, rendererID, wasForwarded, value } = _ref19;
95024
95586
  if (!wasForwarded) {
95025
95587
  _this.overrideValueAtPath({
95026
95588
  id,
95027
- path: path32,
95589
+ path: path33,
95028
95590
  rendererID,
95029
95591
  type: "state",
95030
95592
  value
@@ -95091,12 +95653,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
95091
95653
  _this._bridge.send("stopInspectingHost", selected);
95092
95654
  });
95093
95655
  agent_defineProperty(_this, "storeAsGlobal", function(_ref23) {
95094
- var { count, id, path: path32, rendererID } = _ref23;
95656
+ var { count, id, path: path33, rendererID } = _ref23;
95095
95657
  var renderer = _this._rendererInterfaces[rendererID];
95096
95658
  if (renderer == null) {
95097
95659
  console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
95098
95660
  } else {
95099
- renderer.storeAsGlobal(id, path32, count);
95661
+ renderer.storeAsGlobal(id, path33, count);
95100
95662
  }
95101
95663
  });
95102
95664
  agent_defineProperty(_this, "updateHookSettings", function(settings) {
@@ -95113,12 +95675,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
95113
95675
  var rendererID = +rendererIDString;
95114
95676
  var renderer = _this._rendererInterfaces[rendererID];
95115
95677
  if (_this._lastSelectedRendererID === rendererID) {
95116
- var path32 = renderer.getPathForElement(_this._lastSelectedElementID);
95117
- if (path32 !== null) {
95118
- renderer.setTrackedPath(path32);
95678
+ var path33 = renderer.getPathForElement(_this._lastSelectedElementID);
95679
+ if (path33 !== null) {
95680
+ renderer.setTrackedPath(path33);
95119
95681
  _this._persistedSelection = {
95120
95682
  rendererID,
95121
- path: path32
95683
+ path: path33
95122
95684
  };
95123
95685
  }
95124
95686
  }
@@ -95193,11 +95755,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
95193
95755
  var rendererID = _this._lastSelectedRendererID;
95194
95756
  var id = _this._lastSelectedElementID;
95195
95757
  var renderer = _this._rendererInterfaces[rendererID];
95196
- var path32 = renderer != null ? renderer.getPathForElement(id) : null;
95197
- if (path32 !== null) {
95758
+ var path33 = renderer != null ? renderer.getPathForElement(id) : null;
95759
+ if (path33 !== null) {
95198
95760
  storage_sessionStorageSetItem(SESSION_STORAGE_LAST_SELECTION_KEY, JSON.stringify({
95199
95761
  rendererID,
95200
- path: path32
95762
+ path: path33
95201
95763
  }));
95202
95764
  } else {
95203
95765
  storage_sessionStorageRemoveItem(SESSION_STORAGE_LAST_SELECTION_KEY);
@@ -95920,7 +96482,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
95920
96482
  hasElementWithId: function hasElementWithId() {
95921
96483
  return false;
95922
96484
  },
95923
- inspectElement: function inspectElement(requestID, id, path32) {
96485
+ inspectElement: function inspectElement(requestID, id, path33) {
95924
96486
  return {
95925
96487
  id,
95926
96488
  responseID: requestID,
@@ -101190,9 +101752,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
101190
101752
  }
101191
101753
  return null;
101192
101754
  }
101193
- function getElementAttributeByPath(id, path32) {
101755
+ function getElementAttributeByPath(id, path33) {
101194
101756
  if (isMostRecentlyInspectedElement(id)) {
101195
- return utils_getInObject(mostRecentlyInspectedElement, path32);
101757
+ return utils_getInObject(mostRecentlyInspectedElement, path33);
101196
101758
  }
101197
101759
  return;
101198
101760
  }
@@ -101895,9 +102457,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
101895
102457
  function isMostRecentlyInspectedElementCurrent(id) {
101896
102458
  return isMostRecentlyInspectedElement(id) && !hasElementUpdatedSinceLastInspected;
101897
102459
  }
101898
- function mergeInspectedPaths(path32) {
102460
+ function mergeInspectedPaths(path33) {
101899
102461
  var current = currentlyInspectedPaths;
101900
- path32.forEach(function(key) {
102462
+ path33.forEach(function(key) {
101901
102463
  if (!current[key]) {
101902
102464
  current[key] = {};
101903
102465
  }
@@ -101905,21 +102467,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
101905
102467
  });
101906
102468
  }
101907
102469
  function createIsPathAllowed(key, secondaryCategory) {
101908
- return function isPathAllowed(path32) {
102470
+ return function isPathAllowed(path33) {
101909
102471
  switch (secondaryCategory) {
101910
102472
  case "hooks":
101911
- if (path32.length === 1) {
102473
+ if (path33.length === 1) {
101912
102474
  return true;
101913
102475
  }
101914
- if (path32[path32.length - 2] === "hookSource" && path32[path32.length - 1] === "fileName") {
102476
+ if (path33[path33.length - 2] === "hookSource" && path33[path33.length - 1] === "fileName") {
101915
102477
  return true;
101916
102478
  }
101917
- if (path32[path32.length - 1] === "subHooks" || path32[path32.length - 2] === "subHooks") {
102479
+ if (path33[path33.length - 1] === "subHooks" || path33[path33.length - 2] === "subHooks") {
101918
102480
  return true;
101919
102481
  }
101920
102482
  break;
101921
102483
  case "suspendedBy":
101922
- if (path32.length < 5) {
102484
+ if (path33.length < 5) {
101923
102485
  return true;
101924
102486
  }
101925
102487
  break;
@@ -101930,8 +102492,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
101930
102492
  if (!current) {
101931
102493
  return false;
101932
102494
  }
101933
- for (var i = 0;i < path32.length; i++) {
101934
- current = current[path32[i]];
102495
+ for (var i = 0;i < path33.length; i++) {
102496
+ current = current[path33[i]];
101935
102497
  if (!current) {
101936
102498
  return false;
101937
102499
  }
@@ -101985,38 +102547,38 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
101985
102547
  break;
101986
102548
  }
101987
102549
  }
101988
- function storeAsGlobal(id, path32, count) {
102550
+ function storeAsGlobal(id, path33, count) {
101989
102551
  if (isMostRecentlyInspectedElement(id)) {
101990
- var value = utils_getInObject(mostRecentlyInspectedElement, path32);
102552
+ var value = utils_getInObject(mostRecentlyInspectedElement, path33);
101991
102553
  var key = "$reactTemp".concat(count);
101992
102554
  window[key] = value;
101993
102555
  console.log(key);
101994
102556
  console.log(value);
101995
102557
  }
101996
102558
  }
101997
- function getSerializedElementValueByPath(id, path32) {
102559
+ function getSerializedElementValueByPath(id, path33) {
101998
102560
  if (isMostRecentlyInspectedElement(id)) {
101999
- var valueToCopy = utils_getInObject(mostRecentlyInspectedElement, path32);
102561
+ var valueToCopy = utils_getInObject(mostRecentlyInspectedElement, path33);
102000
102562
  return serializeToString(valueToCopy);
102001
102563
  }
102002
102564
  }
102003
- function inspectElement(requestID, id, path32, forceFullData) {
102004
- if (path32 !== null) {
102005
- mergeInspectedPaths(path32);
102565
+ function inspectElement(requestID, id, path33, forceFullData) {
102566
+ if (path33 !== null) {
102567
+ mergeInspectedPaths(path33);
102006
102568
  }
102007
102569
  if (isMostRecentlyInspectedElement(id) && !forceFullData) {
102008
102570
  if (!hasElementUpdatedSinceLastInspected) {
102009
- if (path32 !== null) {
102571
+ if (path33 !== null) {
102010
102572
  var secondaryCategory = null;
102011
- if (path32[0] === "hooks" || path32[0] === "suspendedBy") {
102012
- secondaryCategory = path32[0];
102573
+ if (path33[0] === "hooks" || path33[0] === "suspendedBy") {
102574
+ secondaryCategory = path33[0];
102013
102575
  }
102014
102576
  return {
102015
102577
  id,
102016
102578
  responseID: requestID,
102017
102579
  type: "hydrated-path",
102018
- path: path32,
102019
- value: cleanForBridge(utils_getInObject(mostRecentlyInspectedElement, path32), createIsPathAllowed(null, secondaryCategory), path32)
102580
+ path: path33,
102581
+ value: cleanForBridge(utils_getInObject(mostRecentlyInspectedElement, path33), createIsPathAllowed(null, secondaryCategory), path33)
102020
102582
  };
102021
102583
  } else {
102022
102584
  return {
@@ -102212,7 +102774,7 @@ The error thrown in the component is:
102212
102774
  console.groupEnd();
102213
102775
  }
102214
102776
  }
102215
- function deletePath(type, id, hookID, path32) {
102777
+ function deletePath(type, id, hookID, path33) {
102216
102778
  var devtoolsInstance = idToDevToolsInstanceMap.get(id);
102217
102779
  if (devtoolsInstance === undefined) {
102218
102780
  console.warn('Could not find DevToolsInstance with id "'.concat(id, '"'));
@@ -102226,11 +102788,11 @@ The error thrown in the component is:
102226
102788
  var instance2 = fiber.stateNode;
102227
102789
  switch (type) {
102228
102790
  case "context":
102229
- path32 = path32.slice(1);
102791
+ path33 = path33.slice(1);
102230
102792
  switch (fiber.tag) {
102231
102793
  case ClassComponent:
102232
- if (path32.length === 0) {} else {
102233
- deletePathInObject(instance2.context, path32);
102794
+ if (path33.length === 0) {} else {
102795
+ deletePathInObject(instance2.context, path33);
102234
102796
  }
102235
102797
  instance2.forceUpdate();
102236
102798
  break;
@@ -102240,21 +102802,21 @@ The error thrown in the component is:
102240
102802
  break;
102241
102803
  case "hooks":
102242
102804
  if (typeof overrideHookStateDeletePath === "function") {
102243
- overrideHookStateDeletePath(fiber, hookID, path32);
102805
+ overrideHookStateDeletePath(fiber, hookID, path33);
102244
102806
  }
102245
102807
  break;
102246
102808
  case "props":
102247
102809
  if (instance2 === null) {
102248
102810
  if (typeof overridePropsDeletePath === "function") {
102249
- overridePropsDeletePath(fiber, path32);
102811
+ overridePropsDeletePath(fiber, path33);
102250
102812
  }
102251
102813
  } else {
102252
- fiber.pendingProps = copyWithDelete(instance2.props, path32);
102814
+ fiber.pendingProps = copyWithDelete(instance2.props, path33);
102253
102815
  instance2.forceUpdate();
102254
102816
  }
102255
102817
  break;
102256
102818
  case "state":
102257
- deletePathInObject(instance2.state, path32);
102819
+ deletePathInObject(instance2.state, path33);
102258
102820
  instance2.forceUpdate();
102259
102821
  break;
102260
102822
  }
@@ -102309,7 +102871,7 @@ The error thrown in the component is:
102309
102871
  }
102310
102872
  }
102311
102873
  }
102312
- function overrideValueAtPath(type, id, hookID, path32, value) {
102874
+ function overrideValueAtPath(type, id, hookID, path33, value) {
102313
102875
  var devtoolsInstance = idToDevToolsInstanceMap.get(id);
102314
102876
  if (devtoolsInstance === undefined) {
102315
102877
  console.warn('Could not find DevToolsInstance with id "'.concat(id, '"'));
@@ -102323,13 +102885,13 @@ The error thrown in the component is:
102323
102885
  var instance2 = fiber.stateNode;
102324
102886
  switch (type) {
102325
102887
  case "context":
102326
- path32 = path32.slice(1);
102888
+ path33 = path33.slice(1);
102327
102889
  switch (fiber.tag) {
102328
102890
  case ClassComponent:
102329
- if (path32.length === 0) {
102891
+ if (path33.length === 0) {
102330
102892
  instance2.context = value;
102331
102893
  } else {
102332
- utils_setInObject(instance2.context, path32, value);
102894
+ utils_setInObject(instance2.context, path33, value);
102333
102895
  }
102334
102896
  instance2.forceUpdate();
102335
102897
  break;
@@ -102339,18 +102901,18 @@ The error thrown in the component is:
102339
102901
  break;
102340
102902
  case "hooks":
102341
102903
  if (typeof overrideHookState === "function") {
102342
- overrideHookState(fiber, hookID, path32, value);
102904
+ overrideHookState(fiber, hookID, path33, value);
102343
102905
  }
102344
102906
  break;
102345
102907
  case "props":
102346
102908
  switch (fiber.tag) {
102347
102909
  case ClassComponent:
102348
- fiber.pendingProps = copyWithSet(instance2.props, path32, value);
102910
+ fiber.pendingProps = copyWithSet(instance2.props, path33, value);
102349
102911
  instance2.forceUpdate();
102350
102912
  break;
102351
102913
  default:
102352
102914
  if (typeof overrideProps === "function") {
102353
- overrideProps(fiber, path32, value);
102915
+ overrideProps(fiber, path33, value);
102354
102916
  }
102355
102917
  break;
102356
102918
  }
@@ -102358,7 +102920,7 @@ The error thrown in the component is:
102358
102920
  case "state":
102359
102921
  switch (fiber.tag) {
102360
102922
  case ClassComponent:
102361
- utils_setInObject(instance2.state, path32, value);
102923
+ utils_setInObject(instance2.state, path33, value);
102362
102924
  instance2.forceUpdate();
102363
102925
  break;
102364
102926
  }
@@ -102644,14 +103206,14 @@ The error thrown in the component is:
102644
103206
  var trackedPathMatchInstance = null;
102645
103207
  var trackedPathMatchDepth = -1;
102646
103208
  var mightBeOnTrackedPath = false;
102647
- function setTrackedPath(path32) {
102648
- if (path32 === null) {
103209
+ function setTrackedPath(path33) {
103210
+ if (path33 === null) {
102649
103211
  trackedPathMatchFiber = null;
102650
103212
  trackedPathMatchInstance = null;
102651
103213
  trackedPathMatchDepth = -1;
102652
103214
  mightBeOnTrackedPath = false;
102653
103215
  }
102654
- trackedPath = path32;
103216
+ trackedPath = path33;
102655
103217
  }
102656
103218
  function updateTrackedPathStateBeforeMount(fiber, fiberInstance) {
102657
103219
  if (trackedPath === null || !mightBeOnTrackedPath) {
@@ -103415,9 +103977,9 @@ The error thrown in the component is:
103415
103977
  }
103416
103978
  var currentlyInspectedElementID = null;
103417
103979
  var currentlyInspectedPaths = {};
103418
- function mergeInspectedPaths(path32) {
103980
+ function mergeInspectedPaths(path33) {
103419
103981
  var current = currentlyInspectedPaths;
103420
- path32.forEach(function(key) {
103982
+ path33.forEach(function(key) {
103421
103983
  if (!current[key]) {
103422
103984
  current[key] = {};
103423
103985
  }
@@ -103425,13 +103987,13 @@ The error thrown in the component is:
103425
103987
  });
103426
103988
  }
103427
103989
  function createIsPathAllowed(key) {
103428
- return function isPathAllowed(path32) {
103990
+ return function isPathAllowed(path33) {
103429
103991
  var current = currentlyInspectedPaths[key];
103430
103992
  if (!current) {
103431
103993
  return false;
103432
103994
  }
103433
- for (var i = 0;i < path32.length; i++) {
103434
- current = current[path32[i]];
103995
+ for (var i = 0;i < path33.length; i++) {
103996
+ current = current[path33[i]];
103435
103997
  if (!current) {
103436
103998
  return false;
103437
103999
  }
@@ -103481,24 +104043,24 @@ The error thrown in the component is:
103481
104043
  break;
103482
104044
  }
103483
104045
  }
103484
- function storeAsGlobal(id, path32, count) {
104046
+ function storeAsGlobal(id, path33, count) {
103485
104047
  var inspectedElement = inspectElementRaw(id);
103486
104048
  if (inspectedElement !== null) {
103487
- var value = utils_getInObject(inspectedElement, path32);
104049
+ var value = utils_getInObject(inspectedElement, path33);
103488
104050
  var key = "$reactTemp".concat(count);
103489
104051
  window[key] = value;
103490
104052
  console.log(key);
103491
104053
  console.log(value);
103492
104054
  }
103493
104055
  }
103494
- function getSerializedElementValueByPath(id, path32) {
104056
+ function getSerializedElementValueByPath(id, path33) {
103495
104057
  var inspectedElement = inspectElementRaw(id);
103496
104058
  if (inspectedElement !== null) {
103497
- var valueToCopy = utils_getInObject(inspectedElement, path32);
104059
+ var valueToCopy = utils_getInObject(inspectedElement, path33);
103498
104060
  return serializeToString(valueToCopy);
103499
104061
  }
103500
104062
  }
103501
- function inspectElement(requestID, id, path32, forceFullData) {
104063
+ function inspectElement(requestID, id, path33, forceFullData) {
103502
104064
  if (forceFullData || currentlyInspectedElementID !== id) {
103503
104065
  currentlyInspectedElementID = id;
103504
104066
  currentlyInspectedPaths = {};
@@ -103511,8 +104073,8 @@ The error thrown in the component is:
103511
104073
  type: "not-found"
103512
104074
  };
103513
104075
  }
103514
- if (path32 !== null) {
103515
- mergeInspectedPaths(path32);
104076
+ if (path33 !== null) {
104077
+ mergeInspectedPaths(path33);
103516
104078
  }
103517
104079
  updateSelectedElement(id);
103518
104080
  inspectedElement.context = cleanForBridge(inspectedElement.context, createIsPathAllowed("context"));
@@ -103715,10 +104277,10 @@ The error thrown in the component is:
103715
104277
  console.groupEnd();
103716
104278
  }
103717
104279
  }
103718
- function getElementAttributeByPath(id, path32) {
104280
+ function getElementAttributeByPath(id, path33) {
103719
104281
  var inspectedElement = inspectElementRaw(id);
103720
104282
  if (inspectedElement !== null) {
103721
- return utils_getInObject(inspectedElement, path32);
104283
+ return utils_getInObject(inspectedElement, path33);
103722
104284
  }
103723
104285
  return;
103724
104286
  }
@@ -103735,14 +104297,14 @@ The error thrown in the component is:
103735
104297
  }
103736
104298
  return element.type;
103737
104299
  }
103738
- function deletePath(type, id, hookID, path32) {
104300
+ function deletePath(type, id, hookID, path33) {
103739
104301
  var internalInstance = idToInternalInstanceMap.get(id);
103740
104302
  if (internalInstance != null) {
103741
104303
  var publicInstance = internalInstance._instance;
103742
104304
  if (publicInstance != null) {
103743
104305
  switch (type) {
103744
104306
  case "context":
103745
- deletePathInObject(publicInstance.context, path32);
104307
+ deletePathInObject(publicInstance.context, path33);
103746
104308
  forceUpdate(publicInstance);
103747
104309
  break;
103748
104310
  case "hooks":
@@ -103750,12 +104312,12 @@ The error thrown in the component is:
103750
104312
  case "props":
103751
104313
  var element = internalInstance._currentElement;
103752
104314
  internalInstance._currentElement = legacy_renderer_objectSpread(legacy_renderer_objectSpread({}, element), {}, {
103753
- props: copyWithDelete(element.props, path32)
104315
+ props: copyWithDelete(element.props, path33)
103754
104316
  });
103755
104317
  forceUpdate(publicInstance);
103756
104318
  break;
103757
104319
  case "state":
103758
- deletePathInObject(publicInstance.state, path32);
104320
+ deletePathInObject(publicInstance.state, path33);
103759
104321
  forceUpdate(publicInstance);
103760
104322
  break;
103761
104323
  }
@@ -103789,14 +104351,14 @@ The error thrown in the component is:
103789
104351
  }
103790
104352
  }
103791
104353
  }
103792
- function overrideValueAtPath(type, id, hookID, path32, value) {
104354
+ function overrideValueAtPath(type, id, hookID, path33, value) {
103793
104355
  var internalInstance = idToInternalInstanceMap.get(id);
103794
104356
  if (internalInstance != null) {
103795
104357
  var publicInstance = internalInstance._instance;
103796
104358
  if (publicInstance != null) {
103797
104359
  switch (type) {
103798
104360
  case "context":
103799
- utils_setInObject(publicInstance.context, path32, value);
104361
+ utils_setInObject(publicInstance.context, path33, value);
103800
104362
  forceUpdate(publicInstance);
103801
104363
  break;
103802
104364
  case "hooks":
@@ -103804,12 +104366,12 @@ The error thrown in the component is:
103804
104366
  case "props":
103805
104367
  var element = internalInstance._currentElement;
103806
104368
  internalInstance._currentElement = legacy_renderer_objectSpread(legacy_renderer_objectSpread({}, element), {}, {
103807
- props: copyWithSet(element.props, path32, value)
104369
+ props: copyWithSet(element.props, path33, value)
103808
104370
  });
103809
104371
  forceUpdate(publicInstance);
103810
104372
  break;
103811
104373
  case "state":
103812
- utils_setInObject(publicInstance.state, path32, value);
104374
+ utils_setInObject(publicInstance.state, path33, value);
103813
104375
  forceUpdate(publicInstance);
103814
104376
  break;
103815
104377
  }
@@ -103850,7 +104412,7 @@ The error thrown in the component is:
103850
104412
  return [];
103851
104413
  }
103852
104414
  function setTraceUpdatesEnabled(enabled) {}
103853
- function setTrackedPath(path32) {}
104415
+ function setTrackedPath(path33) {}
103854
104416
  function getOwnersList(id) {
103855
104417
  return null;
103856
104418
  }
@@ -107309,10 +107871,10 @@ init_setup_write();
107309
107871
  // src/cli/plugins.ts
107310
107872
  init_paths();
107311
107873
  init_loader4();
107312
- import * as path23 from "path";
107874
+ import * as path24 from "path";
107313
107875
  async function pluginsListCommand(config2, workdir, overrideGlobalPluginsDir) {
107314
- const globalPluginsDir = overrideGlobalPluginsDir ?? path23.join(globalConfigDir(), "plugins");
107315
- const projectPluginsDir = path23.join(workdir, ".nax", "plugins");
107876
+ const globalPluginsDir = overrideGlobalPluginsDir ?? path24.join(globalConfigDir(), "plugins");
107877
+ const projectPluginsDir = path24.join(workdir, ".nax", "plugins");
107316
107878
  const configPlugins = config2.plugins || [];
107317
107879
  const registry3 = await loadPlugins(globalPluginsDir, projectPluginsDir, configPlugins, workdir, config2.disabledPlugins);
107318
107880
  const plugins = registry3.plugins;
@@ -107362,10 +107924,10 @@ function formatSource(type, sourcePath) {
107362
107924
  return `built-in (${sourcePath})`;
107363
107925
  }
107364
107926
  if (type === "global") {
107365
- return `global (${path23.basename(sourcePath)})`;
107927
+ return `global (${path24.basename(sourcePath)})`;
107366
107928
  }
107367
107929
  if (type === "project") {
107368
- return `project (${path23.basename(sourcePath)})`;
107930
+ return `project (${path24.basename(sourcePath)})`;
107369
107931
  }
107370
107932
  return `config (${sourcePath})`;
107371
107933
  }
@@ -107607,6 +108169,8 @@ var FIELD_DESCRIPTIONS = {
107607
108169
  "execution.rectification.maxFailureSummaryChars": "Max characters in failure summary",
107608
108170
  "execution.rectification.abortOnIncreasingFailures": "Abort if failure count increases",
107609
108171
  "execution.rectification.consecutiveIncreasesToBail": "Consecutive regressing iterations required before abortOnIncreasingFailures bails (default: 2; 1 = legacy behaviour)",
108172
+ "execution.rectification.abortOnNoProgress": "Abort rectification when no progress is made for several consecutive iterations (default: true)",
108173
+ "execution.rectification.consecutiveNoProgressToBail": "Consecutive no-progress iterations required before abortOnNoProgress bails (default: 3; one higher than the count bail's 2 because the no-progress predicate fires on a wider shape)",
107610
108174
  "execution.rectification.escalateOnExhaustion": "Enable model tier escalation when attempts are exhausted with remaining failures",
107611
108175
  "execution.rectification.rethinkAtAttempt": "Attempt number at which 'rethink your approach' language is injected into the prompt (default: 2)",
107612
108176
  "execution.rectification.urgencyAtAttempt": "Attempt number at which 'final chance before escalation' urgency is added (default: 3)",
@@ -107759,10 +108323,10 @@ function deepDiffConfigs(global2, project, currentPath = []) {
107759
108323
  for (const key of Object.keys(project)) {
107760
108324
  const projectValue = project[key];
107761
108325
  const globalValue = global2[key];
107762
- const path24 = [...currentPath, key];
107763
- const pathStr = path24.join(".");
108326
+ const path25 = [...currentPath, key];
108327
+ const pathStr = path25.join(".");
107764
108328
  if (projectValue !== null && typeof projectValue === "object" && !Array.isArray(projectValue) && globalValue !== null && typeof globalValue === "object" && !Array.isArray(globalValue)) {
107765
- const nestedDiffs = deepDiffConfigs(globalValue, projectValue, path24);
108329
+ const nestedDiffs = deepDiffConfigs(globalValue, projectValue, path25);
107766
108330
  diffs.push(...nestedDiffs);
107767
108331
  } else {
107768
108332
  if (!deepEqual(projectValue, globalValue)) {
@@ -107805,11 +108369,11 @@ init_defaults();
107805
108369
  init_loader();
107806
108370
  import { existsSync as existsSync25 } from "fs";
107807
108371
  import { join as join71 } from "path";
107808
- async function loadConfigFile(path24) {
107809
- if (!existsSync25(path24))
108372
+ async function loadConfigFile(path25) {
108373
+ if (!existsSync25(path25))
107810
108374
  return null;
107811
108375
  try {
107812
- return await Bun.file(path24).json();
108376
+ return await Bun.file(path25).json();
107813
108377
  } catch {
107814
108378
  return null;
107815
108379
  }
@@ -107856,10 +108420,10 @@ async function configCommand(config2, options = {}) {
107856
108420
  console.log(`${"Field".padEnd(40)}${"Project Value".padEnd(20)}Global Value`);
107857
108421
  console.log("\u2500".repeat(80));
107858
108422
  for (const diff2 of diffs) {
107859
- const path24 = diff2.path.padEnd(40);
108423
+ const path25 = diff2.path.padEnd(40);
107860
108424
  const projectVal = formatValueForTable(diff2.projectValue);
107861
108425
  const globalVal = formatValueForTable(diff2.globalValue);
107862
- console.log(`${path24}${projectVal.padEnd(20)}${globalVal}`);
108426
+ console.log(`${path25}${projectVal.padEnd(20)}${globalVal}`);
107863
108427
  const description = FIELD_DESCRIPTIONS[diff2.path];
107864
108428
  if (description) {
107865
108429
  console.log(`${"".padEnd(40)}\u21B3 ${description}`);
@@ -107892,26 +108456,26 @@ function determineConfigSources() {
107892
108456
  project: projectPath && fileExists(projectPath) ? projectPath : null
107893
108457
  };
107894
108458
  }
107895
- function fileExists(path24) {
107896
- return existsSync26(path24);
108459
+ function fileExists(path25) {
108460
+ return existsSync26(path25);
107897
108461
  }
107898
- function displayConfigWithDescriptions(obj, path24, sources, indent = 0) {
108462
+ function displayConfigWithDescriptions(obj, path25, sources, indent = 0) {
107899
108463
  const indentStr = " ".repeat(indent);
107900
- const pathStr = path24.join(".");
108464
+ const pathStr = path25.join(".");
107901
108465
  if (obj === null || obj === undefined || typeof obj !== "object" || Array.isArray(obj)) {
107902
108466
  const description = FIELD_DESCRIPTIONS[pathStr];
107903
108467
  const value = formatValue(obj);
107904
108468
  if (description) {
107905
108469
  console.log(`${indentStr}# ${description}`);
107906
108470
  }
107907
- const key = path24[path24.length - 1] || "";
108471
+ const key = path25[path25.length - 1] || "";
107908
108472
  console.log(`${indentStr}${key}: ${value}`);
107909
108473
  console.log();
107910
108474
  return;
107911
108475
  }
107912
108476
  const entries = Object.entries(obj);
107913
108477
  const objAsRecord = obj;
107914
- const isPromptsSection = path24.join(".") === "prompts";
108478
+ const isPromptsSection = path25.join(".") === "prompts";
107915
108479
  if (isPromptsSection && !objAsRecord.overrides) {
107916
108480
  const description = FIELD_DESCRIPTIONS["prompts.overrides"];
107917
108481
  if (description) {
@@ -107934,7 +108498,7 @@ function displayConfigWithDescriptions(obj, path24, sources, indent = 0) {
107934
108498
  }
107935
108499
  for (let i = 0;i < entries.length; i++) {
107936
108500
  const [key, value] = entries[i];
107937
- const currentPath = [...path24, key];
108501
+ const currentPath = [...path25, key];
107938
108502
  const currentPathStr = currentPath.join(".");
107939
108503
  const description = FIELD_DESCRIPTIONS[currentPathStr];
107940
108504
  if (description) {
@@ -108372,11 +108936,11 @@ async function rulesLintCommand(options, deps = _rulesLintDeps) {
108372
108936
  }
108373
108937
  // src/cli/rules.ts
108374
108938
  var _rulesCLIDeps = {
108375
- readFile: async (path24) => Bun.file(path24).text(),
108376
- writeFile: async (path24, content) => {
108377
- await Bun.write(path24, content);
108939
+ readFile: async (path25) => Bun.file(path25).text(),
108940
+ writeFile: async (path25, content) => {
108941
+ await Bun.write(path25, content);
108378
108942
  },
108379
- fileExists: async (path24) => Bun.file(path24).exists(),
108943
+ fileExists: async (path25) => Bun.file(path25).exists(),
108380
108944
  globInDir: (dir) => {
108381
108945
  try {
108382
108946
  return [...new Bun.Glob("*.md").scanSync({ cwd: dir })].sort().map((f) => join75(dir, f));
@@ -108384,8 +108948,8 @@ var _rulesCLIDeps = {
108384
108948
  return [];
108385
108949
  }
108386
108950
  },
108387
- mkdir: async (path24) => {
108388
- await mkdir11(path24, { recursive: true });
108951
+ mkdir: async (path25) => {
108952
+ await mkdir11(path25, { recursive: true });
108389
108953
  },
108390
108954
  globCanonicalRuleFiles: (workdir) => _rulesLintDeps.globCanonicalRuleFiles(workdir),
108391
108955
  globHasMatch: (pattern, cwd) => _rulesLintDeps.globHasMatch(pattern, cwd),
@@ -108411,22 +108975,35 @@ var AGENT_RULE_DIRS = {
108411
108975
  claude: ".claude/rules"
108412
108976
  };
108413
108977
  var SUPPORTED_AGENTS = [...Object.keys(AGENT_RULE_DIRS), ...Object.keys(AGENT_SHIM_FILES)].sort();
108978
+ function packageGlobToFileGlob(pattern) {
108979
+ const base = pattern.replace(/\/+$/, "").replace(/\/+\*{1,2}$/, "").replace(/\/+$/, "");
108980
+ if (base === "" || base === "**")
108981
+ return "**";
108982
+ return `${base}/**`;
108983
+ }
108414
108984
  function claudeFrontmatter(rule) {
108415
- if (rule.paths?.length) {
108416
- _rulesCLIDeps.getLogger().warn("rules-export", "Dropping package scope \u2014 Claude has no equivalent", {
108985
+ const fileGlobs = rule.appliesTo ?? [];
108986
+ const packageGlobs = rule.paths ?? [];
108987
+ if (fileGlobs.length > 0 && packageGlobs.length > 0) {
108988
+ _rulesCLIDeps.getLogger().warn("rules-export", "Dropping package scope \u2014 Claude cannot express both scopes", {
108417
108989
  rule: rule.path ?? rule.fileName,
108418
- droppedPaths: rule.paths
108990
+ description: rule.description,
108991
+ droppedPaths: packageGlobs,
108992
+ keptAppliesTo: fileGlobs
108419
108993
  });
108420
108994
  }
108421
- const globs = rule.appliesTo ?? [];
108422
- if (globs.length === 0)
108995
+ const globs = fileGlobs.length > 0 ? fileGlobs : [...new Set(packageGlobs.map(packageGlobToFileGlob))];
108996
+ const description = rule.description;
108997
+ if (globs.length === 0 && description === undefined)
108423
108998
  return "";
108424
- const lines = globs.map((g) => ` - ${JSON.stringify(g)}`).join(`
108425
- `);
108999
+ const descLine = description !== undefined ? `description: ${JSON.stringify(description)}
109000
+ ` : "";
109001
+ const globLines = globs.length > 0 ? `paths:
109002
+ ${globs.map((g) => ` - ${JSON.stringify(g)}`).join(`
109003
+ `)}
109004
+ ` : "";
108426
109005
  return `---
108427
- paths:
108428
- ${lines}
108429
- ---
109006
+ ${descLine}${globLines}---
108430
109007
  `;
108431
109008
  }
108432
109009
  async function exportRuleDirectory(input) {
@@ -108645,8 +109222,8 @@ async function resolveRunProfileOverride(opts) {
108645
109222
  return cliChain;
108646
109223
  if (opts.envProfile)
108647
109224
  return;
108648
- const readJson = opts._readJson ?? (async (path24) => {
108649
- const file3 = Bun.file(path24);
109225
+ const readJson = opts._readJson ?? (async (path25) => {
109226
+ const file3 = Bun.file(path25);
108650
109227
  if (!await file3.exists())
108651
109228
  return;
108652
109229
  return file3.json();
@@ -109049,14 +109626,14 @@ function resolveEffective(detected, configPatterns) {
109049
109626
  return "detected";
109050
109627
  return "none";
109051
109628
  }
109052
- async function loadRawConfig(path24) {
109053
- const f = Bun.file(path24);
109629
+ async function loadRawConfig(path25) {
109630
+ const f = Bun.file(path25);
109054
109631
  if (!await f.exists())
109055
109632
  return {};
109056
109633
  return JSON.parse(await f.text());
109057
109634
  }
109058
- async function writeRawConfig(path24, data) {
109059
- await Bun.write(path24, `${JSON.stringify(data, null, 2)}
109635
+ async function writeRawConfig(path25, data) {
109636
+ await Bun.write(path25, `${JSON.stringify(data, null, 2)}
109060
109637
  `);
109061
109638
  }
109062
109639
  function deepSet(obj, keyPath, value) {
@@ -109844,10 +110421,10 @@ function renderReport(timeline, options = {}) {
109844
110421
  }
109845
110422
 
109846
110423
  // src/commands/replay.ts
109847
- async function readJsonlLenient(path24) {
109848
- if (!existsSync32(path24))
110424
+ async function readJsonlLenient(path25) {
110425
+ if (!existsSync32(path25))
109849
110426
  return [];
109850
- const content = await Bun.file(path24).text();
110427
+ const content = await Bun.file(path25).text();
109851
110428
  const lines = content.split(`
109852
110429
  `);
109853
110430
  const entries = [];
@@ -109861,11 +110438,11 @@ async function readJsonlLenient(path24) {
109861
110438
  }
109862
110439
  return entries;
109863
110440
  }
109864
- async function readJsonOrUndefined(path24) {
109865
- if (!existsSync32(path24))
110441
+ async function readJsonOrUndefined(path25) {
110442
+ if (!existsSync32(path25))
109866
110443
  return;
109867
110444
  try {
109868
- return await Bun.file(path24).json();
110445
+ return await Bun.file(path25).json();
109869
110446
  } catch {
109870
110447
  return;
109871
110448
  }
@@ -115161,8 +115738,8 @@ function Text({ color, backgroundColor, dimColor = false, bold = false, italic =
115161
115738
  }
115162
115739
 
115163
115740
  // node_modules/ink/build/components/ErrorOverview.js
115164
- var cleanupPath = (path32) => {
115165
- return path32?.replace(`file://${cwd()}/`, "");
115741
+ var cleanupPath = (path33) => {
115742
+ return path33?.replace(`file://${cwd()}/`, "");
115166
115743
  };
115167
115744
  var stackUtils = new import_stack_utils.default({
115168
115745
  cwd: cwd(),
@@ -118966,8 +119543,8 @@ configProfileCmd.command("current").description("Show the currently active profi
118966
119543
  });
118967
119544
  configProfileCmd.command("create <name>").description("Create a new empty profile").option("-d, --dir <path>", "Project directory", process.cwd()).action(async (name, options) => {
118968
119545
  try {
118969
- const path32 = await profileCreateCommand(name, options.dir);
118970
- console.log(`Created profile at: ${path32}`);
119546
+ const path33 = await profileCreateCommand(name, options.dir);
119547
+ console.log(`Created profile at: ${path33}`);
118971
119548
  } catch (err) {
118972
119549
  console.error(source_default.red(`Error: ${err.message}`));
118973
119550
  process.exit(1);
@@ -119267,6 +119844,7 @@ rules.command("export").description("Export canonical rules for an agent (claude
119267
119844
  process.exit(1);
119268
119845
  return;
119269
119846
  }
119847
+ initLogger({ level: "info", useChalk: true });
119270
119848
  try {
119271
119849
  await rulesExportCommand({
119272
119850
  dir: workdir,