typebulb 0.43.1 → 0.44.1

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.
@@ -5,7 +5,7 @@ import { existsSync, readFileSync, writeFileSync } from "node:fs";
5
5
  import { resolve } from "node:path";
6
6
  import { Type } from "typebox";
7
7
 
8
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/utils/textUtils.js
8
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/utils/textUtils.js
9
9
  var TextUtils = class _TextUtils {
10
10
  static NormalizeToLf(text) {
11
11
  return (text ?? "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
@@ -133,7 +133,7 @@ var TextUtils = class _TextUtils {
133
133
  }
134
134
  };
135
135
 
136
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/utils/arrayUtils.js
136
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/utils/arrayUtils.js
137
137
  var ArrayUtils = class {
138
138
  /// <summary>
139
139
  /// Groups items by key, preserving first-seen key order (like LINQ's GroupBy).
@@ -171,7 +171,7 @@ var ArrayUtils = class {
171
171
  }
172
172
  };
173
173
 
174
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/models.js
174
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/models.js
175
175
  var PatchInputFile = class {
176
176
  Key;
177
177
  InputFullText;
@@ -358,8 +358,18 @@ var Chunk = class _Chunk {
358
358
  InsertLinesWithContext() {
359
359
  return [...this.ContextBefore, ...this.InsertLines, ...this.ContextAfter];
360
360
  }
361
+ // The FULL context runs the diff supplied adjacent to this chunk's block, bounded
362
+ // by sibling blocks and hunk edges, in file order. A fact about the diff rather
363
+ // than the match — ContextBefore/After hold only the window the progressive-growth
364
+ // search consumed — so the dropped-context audit can see every supplied line, and
365
+ // `with` rewrites (fallback anchor, tiebreak, splice) carry the stamps forward.
366
+ SuppliedContextBefore = [];
367
+ SuppliedContextAfter = [];
361
368
  with(values) {
362
- return new _Chunk(values.ContextBefore ?? this.ContextBefore, values.DeleteLines ?? this.DeleteLines, values.InsertLines ?? this.InsertLines, values.ContextAfter ?? this.ContextAfter, values.Match ?? this.Match, values.DiffLocation ?? this.DiffLocation);
369
+ const chunk = new _Chunk(values.ContextBefore ?? this.ContextBefore, values.DeleteLines ?? this.DeleteLines, values.InsertLines ?? this.InsertLines, values.ContextAfter ?? this.ContextAfter, values.Match ?? this.Match, values.DiffLocation ?? this.DiffLocation);
370
+ chunk.SuppliedContextBefore = values.SuppliedContextBefore ?? this.SuppliedContextBefore;
371
+ chunk.SuppliedContextAfter = values.SuppliedContextAfter ?? this.SuppliedContextAfter;
372
+ return chunk;
363
373
  }
364
374
  };
365
375
  var MatchState;
@@ -397,7 +407,7 @@ var UniqueMatch = class _UniqueMatch {
397
407
  }
398
408
  };
399
409
 
400
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/utils/yaml.js
410
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/utils/yaml.js
401
411
  var Yaml = class _Yaml {
402
412
  _sb = [];
403
413
  // -------- Public API --------
@@ -454,7 +464,7 @@ var Yaml = class _Yaml {
454
464
  }
455
465
  };
456
466
 
457
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/exceptions.js
467
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/exceptions.js
458
468
  var PatchException = class extends Error {
459
469
  Error;
460
470
  constructor(error) {
@@ -516,7 +526,7 @@ ${this.SuggestedFixYaml}`;
516
526
  }
517
527
  };
518
528
 
519
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/applier/guards.js
529
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/applier/guards.js
520
530
  var DuplicateGuard = class _DuplicateGuard {
521
531
  // Two chunks that resolve to the same anchor with the same deletes and inserts are
522
532
  // provably the same edit (an LLM re-emitting a hunk). Applying it once is
@@ -566,7 +576,7 @@ var OverlapGuard = class {
566
576
  }
567
577
  };
568
578
 
569
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/applier/editMinimizer.js
579
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/applier/editMinimizer.js
570
580
  var EditMinimizer = class _EditMinimizer {
571
581
  static Same(a, b) {
572
582
  return a === b;
@@ -600,7 +610,7 @@ var EditMinimizer = class _EditMinimizer {
600
610
  }
601
611
  };
602
612
 
603
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/applier/indenter.js
613
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/applier/indenter.js
604
614
  var Anchor = class {
605
615
  BaseIndent;
606
616
  Shift;
@@ -691,7 +701,7 @@ var Indenter = class _Indenter {
691
701
  }
692
702
  };
693
703
 
694
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/applier/matchHint.js
704
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/applier/matchHint.js
695
705
  var MatchHint = class _MatchHint {
696
706
  // A quoted line inside exactly one longer file line is the prose line-model
697
707
  // mistake: the author's "line" (a sentence of an unwrapped paragraph, or a
@@ -724,7 +734,7 @@ var MatchHint = class _MatchHint {
724
734
  static MinHintLineContent = 12;
725
735
  };
726
736
 
727
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/applier/chunkApplier.js
737
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/applier/chunkApplier.js
728
738
  var InputChunks = class {
729
739
  InputFullText;
730
740
  Chunks;
@@ -793,7 +803,7 @@ var ChunkApplier = class _ChunkApplier {
793
803
  }
794
804
  };
795
805
 
796
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/heuristics.js
806
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/heuristics.js
797
807
  var DiffContentHeuristics = class _DiffContentHeuristics {
798
808
  /**
799
809
  * Checks if a line starts with a doubled marker (++ or --)
@@ -1018,7 +1028,7 @@ var DiffContentHeuristics = class _DiffContentHeuristics {
1018
1028
  }
1019
1029
  };
1020
1030
 
1021
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/hunkBuilder.js
1031
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/hunkBuilder.js
1022
1032
  var Header = class _Header {
1023
1033
  Path;
1024
1034
  OldStart;
@@ -1239,7 +1249,7 @@ ${h.NewText}`;
1239
1249
  }
1240
1250
  };
1241
1251
 
1242
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/unifiedDiffParser.js
1252
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/unifiedDiffParser.js
1243
1253
  var UnifiedDiffParser = class _UnifiedDiffParser {
1244
1254
  /**
1245
1255
  * Parse a unified diff into structured hunks.
@@ -1483,7 +1493,7 @@ var UnifiedDiffParser = class _UnifiedDiffParser {
1483
1493
  }
1484
1494
  };
1485
1495
 
1486
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/anchorer/hunkSlicer.js
1496
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/anchorer/hunkSlicer.js
1487
1497
  var Block = class {
1488
1498
  StartIndex;
1489
1499
  EndIndex;
@@ -1536,7 +1546,7 @@ var HunkSlicer = class _HunkSlicer {
1536
1546
  }
1537
1547
  };
1538
1548
 
1539
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/anchorer/search.js
1549
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/anchorer/search.js
1540
1550
  var Match = class {
1541
1551
  LineIndex;
1542
1552
  Fuzz;
@@ -1674,7 +1684,7 @@ var Search = class _Search {
1674
1684
  }
1675
1685
  };
1676
1686
 
1677
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/anchorer/blockAnchorer.js
1687
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/anchorer/blockAnchorer.js
1678
1688
  var BlockAnchorer = class _BlockAnchorer {
1679
1689
  static AnchorBlocks(hunk, blocks, lines, options) {
1680
1690
  return blocks.map((focus, index) => {
@@ -1683,6 +1693,8 @@ var BlockAnchorer = class _BlockAnchorer {
1683
1693
  let aboveBlockIdx = index - 1;
1684
1694
  let belowBlockIdx = index + 1;
1685
1695
  let chunk = null;
1696
+ const suppliedAbove = _BlockAnchorer.ContextLines(hunk, focus.StartIndex - 1, index > 0 ? blocks[index - 1].EndIndex + 1 : 0, Number.MAX_SAFE_INTEGER, true);
1697
+ const suppliedBelow = _BlockAnchorer.ContextLines(hunk, focus.EndIndex + 1, index < blocks.length - 1 ? blocks[index + 1].StartIndex - 1 : hunk.Lines.length - 1, Number.MAX_SAFE_INTEGER, false);
1686
1698
  while (true) {
1687
1699
  const aboveBound = aboveBlockIdx >= 0 ? blocks[aboveBlockIdx].EndIndex + 1 : 0;
1688
1700
  const belowBound = belowBlockIdx < blocks.length ? blocks[belowBlockIdx].StartIndex - 1 : hunk.Lines.length - 1;
@@ -1692,6 +1704,8 @@ var BlockAnchorer = class _BlockAnchorer {
1692
1704
  const needle = _BlockAnchorer.BuildNeedle(hunk, aboveEdge, belowEdge);
1693
1705
  const match = _BlockAnchorer.Anchor(lines, ctxAbove, needle, ctxBelow);
1694
1706
  chunk = new Chunk(aboveEdge == focus.StartIndex ? ctxAbove : _BlockAnchorer.ContextLines(hunk, focus.StartIndex - 1, 0, k, true), focus.DeleteLines, focus.InsertLines, belowEdge == focus.EndIndex ? ctxBelow : _BlockAnchorer.ContextLines(hunk, focus.EndIndex + 1, hunk.Lines.length - 1, k, false), _BlockAnchorer.AlignMatchToFocus(match, hunk, aboveEdge, focus.StartIndex), new DiffLocation(hunk, focus.StartIndex, focus.EndIndex));
1707
+ chunk.SuppliedContextBefore = suppliedAbove;
1708
+ chunk.SuppliedContextAfter = suppliedBelow;
1695
1709
  if (!chunk.Match.IsAmbiguous)
1696
1710
  return chunk;
1697
1711
  if (ctxAbove.length < k && ctxBelow.length < k)
@@ -1792,7 +1806,7 @@ var BlockAnchorer = class _BlockAnchorer {
1792
1806
  }
1793
1807
  };
1794
1808
 
1795
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/anchorer/hunkAnchorer.js
1809
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/anchorer/hunkAnchorer.js
1796
1810
  var AnchorOutcome = class {
1797
1811
  Chunks;
1798
1812
  AlreadyAppliedCount;
@@ -1802,13 +1816,16 @@ var AnchorOutcome = class {
1802
1816
  }
1803
1817
  };
1804
1818
  var HunkAnchorer = class _HunkAnchorer {
1805
- static Anchor(originalText, hunks, options) {
1819
+ /// <param name="hunkWasSkipped">A hunk of this diff stated no change and was dropped at
1820
+ /// parse time — so an unpositioned insert here may be the orphaned half of a split hunk
1821
+ /// whose anchor went with it. See UseFallbackAnchorIfNecessary.</param>
1822
+ static Anchor(originalText, hunks, options, hunkWasSkipped = false) {
1806
1823
  const lines = TextUtils.ToLines(originalText);
1807
1824
  const slicedHunks = HunkSlicer.Slice(hunks);
1808
1825
  const chunks = [];
1809
1826
  for (const sliced of slicedHunks)
1810
1827
  for (const chunk of BlockAnchorer.AnchorBlocks(sliced.Hunk, sliced.Blocks, lines, options))
1811
- chunks.push(_HunkAnchorer.UseFallbackAnchorIfNecessary(sliced.Hunk, chunk, lines, slicedHunks.length == 1));
1828
+ chunks.push(_HunkAnchorer.UseFallbackAnchorIfNecessary(sliced.Hunk, chunk, lines, hunkWasSkipped));
1812
1829
  const deleteCounts = /* @__PURE__ */ new Map();
1813
1830
  for (const l of chunks.flatMap((c) => c.DeleteLines))
1814
1831
  if (l.trim().length > 0)
@@ -1817,16 +1834,16 @@ var HunkAnchorer = class _HunkAnchorer {
1817
1834
  const kept = chunks.filter((c) => !_HunkAnchorer.AppliedAtAnchor(lines, c) && (c.InsertLines.some((l) => movedFromElsewhere(c, l)) || !_HunkAnchorer.AlreadyApplied(lines, c))).map((c) => _HunkAnchorer.TrySubLineSplice(c, lines));
1818
1835
  return new AnchorOutcome(kept, chunks.length - kept.length);
1819
1836
  }
1820
- static UseFallbackAnchorIfNecessary(hunk, chunk, lines, soleHunk) {
1837
+ static UseFallbackAnchorIfNecessary(hunk, chunk, lines, hunkWasSkipped) {
1821
1838
  const lineCount = lines.length;
1822
1839
  if (chunk.Match.IsNotFound && hunk.Lines.length == chunk.InsertLines.length) {
1823
1840
  const targetIsEmpty = lineCount == 0 || lineCount == 1 && lines[0].length == 0;
1824
- if (hunk.OldStart < 0 && !soleHunk && !targetIsEmpty)
1841
+ if (hunk.OldStart < 0 && hunkWasSkipped && !targetIsEmpty)
1825
1842
  return chunk;
1826
1843
  const anchorLine = hunk.OldStart <= 1 ? 0 : hunk.OldStart;
1827
1844
  if (anchorLine > lineCount)
1828
1845
  return chunk;
1829
- return new Chunk(chunk.ContextBefore, chunk.DeleteLines, chunk.InsertLines, chunk.ContextAfter, new UniqueMatch(MatchState.Success, anchorLine), chunk.DiffLocation);
1846
+ return chunk.with({ Match: new UniqueMatch(MatchState.Success, anchorLine) });
1830
1847
  }
1831
1848
  return chunk;
1832
1849
  }
@@ -1872,7 +1889,13 @@ var HunkAnchorer = class _HunkAnchorer {
1872
1889
  const echoes = (r) => r.length > 0 && insert.includes(r.trim());
1873
1890
  if (!remnantOk(prefix) || !remnantOk(suffix) || echoes(prefix) || echoes(suffix) || insert.length > frag.length * 2 + 8 && _HunkAnchorer.SharedStem(frag, insert) < _HunkAnchorer.MinSpliceStemContent)
1874
1891
  return chunk;
1875
- return new Chunk([], [target], [prefix + insert + suffix], [], new UniqueMatch(MatchState.Success, lineIndex, _HunkAnchorer.SubLineSpliceFuzz), chunk.DiffLocation);
1892
+ return chunk.with({
1893
+ ContextBefore: [],
1894
+ DeleteLines: [target],
1895
+ InsertLines: [prefix + insert + suffix],
1896
+ ContextAfter: [],
1897
+ Match: new UniqueMatch(MatchState.Success, lineIndex, _HunkAnchorer.SubLineSpliceFuzz)
1898
+ });
1876
1899
  }
1877
1900
  // Trimmed length a fragment must reach before substring evidence counts.
1878
1901
  static MinSpliceFragmentContent = 8;
@@ -1964,7 +1987,49 @@ var HunkAnchorer = class _HunkAnchorer {
1964
1987
  }
1965
1988
  };
1966
1989
 
1967
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/selectionTarget.js
1990
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/anchorer/contextAuditor.js
1991
+ var ContextDivergence = class _ContextDivergence {
1992
+ ContextText;
1993
+ FileText;
1994
+ DiffLine;
1995
+ FileLine;
1996
+ constructor(ContextText, FileText, DiffLine2, FileLine) {
1997
+ this.ContextText = ContextText;
1998
+ this.FileText = FileText;
1999
+ this.DiffLine = DiffLine2;
2000
+ this.FileLine = FileLine;
2001
+ }
2002
+ // Mirrors Edit.Shift: selection-scoped callers see true file coordinates.
2003
+ Shift(lineDelta) {
2004
+ return new _ContextDivergence(this.ContextText, this.FileText, this.DiffLine, this.FileLine + lineDelta);
2005
+ }
2006
+ };
2007
+ var ContextAuditor = class _ContextAuditor {
2008
+ static Audit(appliedChunks, lines) {
2009
+ const divergences = appliedChunks.filter((c) => c.Match.IsSuccess).flatMap((c) => [
2010
+ ..._ContextAuditor.AuditRun(c.SuppliedContextBefore, c.Match.LineIndex - c.SuppliedContextBefore.length, lines, c),
2011
+ ..._ContextAuditor.AuditRun(c.SuppliedContextAfter, c.Match.LineIndex + c.DeleteLines.length, lines, c)
2012
+ ]);
2013
+ const seen = /* @__PURE__ */ new Set();
2014
+ return divergences.filter((d) => seen.has(d.ContextText) ? false : (seen.add(d.ContextText), true));
2015
+ }
2016
+ // `run` is in file order; `startIndex` is the claimed position of its first line.
2017
+ static AuditRun(run, startIndex, lines, chunk) {
2018
+ return run.map((ctx, i) => _ContextAuditor.AuditLine(ctx, startIndex + i, lines, chunk)).filter((d) => d != null);
2019
+ }
2020
+ static AuditLine(ctx, at, lines, chunk) {
2021
+ if (ctx.trim().length == 0)
2022
+ return null;
2023
+ const inRange = at >= 0 && at < lines.length;
2024
+ if (inRange && Search.LinesEquivalent(lines[at], ctx))
2025
+ return null;
2026
+ if (lines.some((l) => Search.LinesEquivalent(l, ctx)))
2027
+ return null;
2028
+ return new ContextDivergence(ctx, inRange ? lines[at] : null, chunk.DiffLocation?.StartLine ?? -1, inRange ? at + 1 : chunk.Match.LineIndex + 1);
2029
+ }
2030
+ };
2031
+
2032
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/selectionTarget.js
1968
2033
  var SelectionTarget = class {
1969
2034
  FullText;
1970
2035
  SelectedText;
@@ -1996,7 +2061,7 @@ var SelectionTarget = class {
1996
2061
  }
1997
2062
  };
1998
2063
 
1999
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/sanitizers/shared.js
2064
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/sanitizers/shared.js
2000
2065
  function isDiffMarker(line) {
2001
2066
  return line.startsWith("--- ") || line.startsWith("+++ ") || line.startsWith("@@") || line.startsWith("diff --git");
2002
2067
  }
@@ -2053,7 +2118,7 @@ function isLikelyFileHeader(trimmed) {
2053
2118
  return trimmed.startsWith("diff --git") || (trimmed.startsWith("--- ") || trimmed.startsWith("+++ ")) && (trimmed.includes(".") || trimmed.includes("/") || trimmed.includes("\\"));
2054
2119
  }
2055
2120
 
2056
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/sanitizers/customFormatSanitizer.js
2121
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/sanitizers/customFormatSanitizer.js
2057
2122
  var CustomFormatSanitizer = class _CustomFormatSanitizer {
2058
2123
  static OPERATIONS = [
2059
2124
  { header: /^\s*\*\*\* Update File: (.+)$/i, fromPath: (p) => `a/${p}`, toPath: (p) => `b/${p}` },
@@ -2078,7 +2143,7 @@ var CustomFormatSanitizer = class _CustomFormatSanitizer {
2078
2143
  }
2079
2144
  };
2080
2145
 
2081
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/sanitizers/decoratedHeaderSanitizer.js
2146
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/sanitizers/decoratedHeaderSanitizer.js
2082
2147
  var DecoratedHeaderSanitizer = class _DecoratedHeaderSanitizer {
2083
2148
  static DECORATED_HEADER_REGEX = /^(---|\+\+\+)\s+(.+?)\s+(---|\+\+\+)+\s*$/;
2084
2149
  static process(text) {
@@ -2091,7 +2156,7 @@ var DecoratedHeaderSanitizer = class _DecoratedHeaderSanitizer {
2091
2156
  }
2092
2157
  };
2093
2158
 
2094
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/sanitizers/decorativeMarkerSanitizer.js
2159
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/sanitizers/decorativeMarkerSanitizer.js
2095
2160
  var DecorativeMarkerSanitizer = class _DecorativeMarkerSanitizer {
2096
2161
  static process(text) {
2097
2162
  return transformOutsideHunkBodies(text, (line) => _DecorativeMarkerSanitizer.isDecorativeMarker(line.trim()) ? null : line);
@@ -2112,14 +2177,14 @@ var DecorativeMarkerSanitizer = class _DecorativeMarkerSanitizer {
2112
2177
  }
2113
2178
  };
2114
2179
 
2115
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/sanitizers/backtickSanitizer.js
2180
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/sanitizers/backtickSanitizer.js
2116
2181
  var BacktickSanitizer = class {
2117
2182
  static process(text) {
2118
2183
  return text.replace(/^```+\s*diff\b/gmi, "```diff").replace(/^```+$/gm, "```");
2119
2184
  }
2120
2185
  };
2121
2186
 
2122
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/sanitizers/diffBlockReunifier.js
2187
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/sanitizers/diffBlockReunifier.js
2123
2188
  var DiffBlockReunifier = class {
2124
2189
  static process(text) {
2125
2190
  const lines = text.split("\n");
@@ -2155,7 +2220,7 @@ var DiffBlockReunifier = class {
2155
2220
  }
2156
2221
  };
2157
2222
 
2158
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/sanitizers/devNullSanitizer.js
2223
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/sanitizers/devNullSanitizer.js
2159
2224
  var DevNullSanitizer = class {
2160
2225
  static process(text, fileKeys) {
2161
2226
  if (!fileKeys?.length)
@@ -2198,7 +2263,7 @@ var DevNullSanitizer = class {
2198
2263
  }
2199
2264
  };
2200
2265
 
2201
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/sanitizers/prefixInjector.js
2266
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/sanitizers/prefixInjector.js
2202
2267
  var PrefixInjector = class {
2203
2268
  static process(text) {
2204
2269
  const lines = text.split("\n");
@@ -2257,7 +2322,7 @@ var PrefixInjector = class {
2257
2322
  }
2258
2323
  };
2259
2324
 
2260
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/parser/diffSanitizer.js
2325
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/parser/diffSanitizer.js
2261
2326
  var DiffSanitizer = class {
2262
2327
  static Process(diff, fileKeys) {
2263
2328
  if (!diff?.trim())
@@ -2273,7 +2338,7 @@ var DiffSanitizer = class {
2273
2338
  }
2274
2339
  };
2275
2340
 
2276
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/headerlessRouter.js
2341
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/headerlessRouter.js
2277
2342
  var HeaderlessRouter = class {
2278
2343
  static Route(fileHunks, files, options) {
2279
2344
  const group = fileHunks.find((g) => g.Key == "");
@@ -2298,9 +2363,9 @@ var HeaderlessRouter = class {
2298
2363
  }
2299
2364
  };
2300
2365
 
2301
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/patchNotices.js
2302
- var PatchNotices = class {
2303
- static For(hunks, file, contextOnlyHunkLines) {
2366
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/patchNotices.js
2367
+ var PatchNotices = class _PatchNotices {
2368
+ static For(hunks, file, contextOnlyHunkLines, contextDivergences) {
2304
2369
  const notices = [];
2305
2370
  if (file.Edits.length === 0)
2306
2371
  notices.push(file.AlreadyAppliedCount > 0 ? `Note: no edits were applied because the file already contains this change (${file.AlreadyAppliedCount} chunk(s) detected as already applied).` : "Note: no edits were applied \u2014 the diff parsed but expressed no change for this file.");
@@ -2318,11 +2383,27 @@ var PatchNotices = class {
2318
2383
  notices.push("Note: insert lines contained raw control characters and were written verbatim. That is usually transport damage rather than intended content; verify the written bytes.");
2319
2384
  if (contextOnlyHunkLines.length > 0)
2320
2385
  notices.push(`Note: the hunk${contextOnlyHunkLines.length === 1 ? "" : "s"} at diff line ${contextOnlyHunkLines.join(", ")} stated no change (context only), so nothing was applied there while the other edits landed. If an edit was intended, its '+'/'-' lines were lost \u2014 re-send that hunk and verify.`);
2386
+ if (file.Edits.length > 0)
2387
+ for (const d of contextDivergences)
2388
+ notices.push((d.DiffLine > 0 ? `Note: the edit at diff line ${d.DiffLine} supplied a context line that appears nowhere in the file \u2014 ` : "Note: a supplied context line appears nowhere in the file \u2014 ") + (d.FileText != null ? `the diff said "${_PatchNotices.DivergenceQuote(d.ContextText, d.FileText)}", and at the spot the edit landed (file line ${d.FileLine}) the file reads "${_PatchNotices.DivergenceQuote(d.FileText, d.ContextText)}". ` : `the diff said "${_PatchNotices.DivergenceQuote(d.ContextText, null)}" beside an edit landing at the file's boundary (file line ${d.FileLine}), where the file has no adjacent line. `) + "The edit applied via its '-'/'+' lines alone; context lines only locate an edit. If that difference was an intended change, it was NOT applied \u2014 express it as a '-'/'+' pair.");
2321
2389
  return notices;
2322
2390
  }
2391
+ // A quote window around the first character where the two lines diverge, so long
2392
+ // prose lines that share a long head still display their difference.
2393
+ static DivergenceQuote(line, other) {
2394
+ const window = 72;
2395
+ if (line.length <= window)
2396
+ return line;
2397
+ let p = 0;
2398
+ if (other != null)
2399
+ while (p < line.length && p < other.length && line[p] == other[p])
2400
+ p++;
2401
+ const start = Math.min(Math.max(p - Math.floor(window / 3), 0), line.length - window);
2402
+ return (start > 0 ? "\u2026" : "") + line.slice(start, start + window) + (start + window < line.length ? "\u2026" : "");
2403
+ }
2323
2404
  };
2324
2405
 
2325
- // ../node_modules/.pnpm/matchu-patchu@0.3.3/node_modules/matchu-patchu/dist/patcher.js
2406
+ // ../node_modules/.pnpm/matchu-patchu@0.3.5/node_modules/matchu-patchu/dist/patcher.js
2326
2407
  var Patcher = class {
2327
2408
  static Apply(diff, files, options) {
2328
2409
  options = options ?? new PatchOptions();
@@ -2345,10 +2426,12 @@ var Patcher = class {
2345
2426
  const targetText = targetSelection.TargetText;
2346
2427
  const group = fileHunks.find((h) => h.Key == f.Key);
2347
2428
  const hunks = group?.Hunks ?? [];
2348
- const anchored = HunkAnchorer.Anchor(targetText, hunks, options);
2429
+ const contextOnly = group?.ContextOnlyHunkLines ?? [];
2430
+ const anchored = HunkAnchorer.Anchor(targetText, hunks, options, contextOnly.length > 0);
2349
2431
  const outputEdits = ChunkApplier.Apply(targetText, anchored.Chunks, options);
2432
+ const contextDivergences = ContextAuditor.Audit(anchored.Chunks, TextUtils.ToLines(targetText)).map((d) => d.Shift(targetSelection.LineOffset));
2350
2433
  const file = new PatchOutputFile(f.Key, outputEdits.Edits.map((h) => h.Fuzz).reduce((a, b) => a + b, 0), outputEdits.Edits.map((e) => e.Shift(targetSelection.LineOffset)), f.InputSelectedText, f.InputFullText, targetSelection.Replace(outputEdits.OutputText), [...outputEdits.Errors], anchored.AlreadyAppliedCount);
2351
- file.Notices = PatchNotices.For(hunks, file, group?.ContextOnlyHunkLines ?? []);
2434
+ file.Notices = PatchNotices.For(hunks, file, contextOnly, contextDivergences);
2352
2435
  return file;
2353
2436
  });
2354
2437
  return new PatchOutput([...patchOutputFiles, ...reportFiles]);
@@ -2357,7 +2440,7 @@ var Patcher = class {
2357
2440
 
2358
2441
  // cli/agents/pi/server/piPatcherExtension.ts
2359
2442
  var DESCRIPTION = true ? "Apply unified diffs to files \u2014 tolerant of form, strict about intent. Repairs sloppy AI-generated diffs (mangled headers, whitespace drift, missing prefixes; line numbers can be wrong or absent \u2014 hunks anchor by fuzzy-matched context lines) and applies all hunks atomically when the intent is unambiguous; fails with a precise, typed error when it isn't. Use for multi-hunk edits in one step, or when exact string-replacement editing fails on whitespace or invisible characters." : "Apply unified diffs to files.";
2360
- var BUILD_TAG = true ? "matchu-patchu-pi 0.3.3, built 2026-07-29 13:16:50" : "matchu-patchu-pi dev";
2443
+ var BUILD_TAG = true ? "matchu-patchu-pi 0.3.5, built 2026-07-30 11:31:49" : "matchu-patchu-pi dev";
2361
2444
  var errorBlocks = (errors) => {
2362
2445
  const parts = [`Patch failed with ${errors.length} error(s):`];
2363
2446
  for (const e of errors) parts.push("", e.toString());