@oh-my-pi/pi-coding-agent 14.2.1 → 14.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/CHANGELOG.md +143 -1
  2. package/package.json +19 -19
  3. package/src/autoresearch/prompt.md +1 -1
  4. package/src/cli/args.ts +10 -1
  5. package/src/cli/shell-cli.ts +15 -3
  6. package/src/commit/agentic/prompts/analyze-file.md +1 -1
  7. package/src/config/model-registry.ts +67 -15
  8. package/src/config/prompt-templates.ts +5 -5
  9. package/src/config/settings-schema.ts +63 -4
  10. package/src/cursor.ts +3 -8
  11. package/src/debug/system-info.ts +6 -2
  12. package/src/discovery/claude.ts +58 -36
  13. package/src/discovery/helpers.ts +3 -3
  14. package/src/discovery/opencode.ts +20 -2
  15. package/src/edit/diff.ts +50 -47
  16. package/src/edit/index.ts +87 -57
  17. package/src/edit/line-hash.ts +735 -19
  18. package/src/edit/modes/apply-patch.ts +0 -9
  19. package/src/edit/modes/atom.ts +658 -0
  20. package/src/edit/modes/chunk.ts +144 -78
  21. package/src/edit/modes/hashline.ts +223 -146
  22. package/src/edit/modes/patch.ts +5 -9
  23. package/src/edit/modes/replace.ts +6 -11
  24. package/src/edit/renderer.ts +112 -143
  25. package/src/edit/streaming.ts +385 -0
  26. package/src/exec/bash-executor.ts +58 -5
  27. package/src/export/html/template.generated.ts +1 -1
  28. package/src/export/html/template.js +4 -12
  29. package/src/extensibility/custom-tools/types.ts +2 -0
  30. package/src/extensibility/custom-tools/wrapper.ts +2 -1
  31. package/src/internal-urls/docs-index.generated.ts +7 -7
  32. package/src/internal-urls/pi-protocol.ts +0 -2
  33. package/src/lsp/client.ts +8 -1
  34. package/src/lsp/defaults.json +2 -1
  35. package/src/lsp/index.ts +1 -1
  36. package/src/mcp/render.ts +1 -8
  37. package/src/modes/acp/acp-agent.ts +76 -2
  38. package/src/modes/components/assistant-message.ts +5 -34
  39. package/src/modes/components/diff.ts +23 -14
  40. package/src/modes/components/footer.ts +21 -16
  41. package/src/modes/components/hook-editor.ts +1 -1
  42. package/src/modes/components/settings-defs.ts +6 -1
  43. package/src/modes/components/todo-reminder.ts +1 -8
  44. package/src/modes/components/tool-execution.ts +112 -105
  45. package/src/modes/controllers/input-controller.ts +1 -1
  46. package/src/modes/controllers/selector-controller.ts +1 -1
  47. package/src/modes/interactive-mode.ts +0 -2
  48. package/src/modes/print-mode.ts +8 -0
  49. package/src/modes/theme/mermaid-cache.ts +13 -52
  50. package/src/modes/theme/theme.ts +2 -2
  51. package/src/prompts/agents/librarian.md +1 -1
  52. package/src/prompts/agents/reviewer.md +4 -4
  53. package/src/prompts/ci-green-request.md +1 -1
  54. package/src/prompts/review-request.md +1 -1
  55. package/src/prompts/system/subagent-system-prompt.md +3 -3
  56. package/src/prompts/system/subagent-yield-reminder.md +11 -0
  57. package/src/prompts/system/system-prompt.md +4 -1
  58. package/src/prompts/tools/ask.md +3 -2
  59. package/src/prompts/tools/ast-edit.md +15 -19
  60. package/src/prompts/tools/ast-grep.md +18 -24
  61. package/src/prompts/tools/atom.md +96 -0
  62. package/src/prompts/tools/browser.md +1 -0
  63. package/src/prompts/tools/chunk-edit.md +58 -179
  64. package/src/prompts/tools/debug.md +4 -5
  65. package/src/prompts/tools/exit-plan-mode.md +4 -5
  66. package/src/prompts/tools/find.md +4 -8
  67. package/src/prompts/tools/github.md +18 -0
  68. package/src/prompts/tools/grep.md +8 -8
  69. package/src/prompts/tools/hashline.md +22 -89
  70. package/src/prompts/tools/{gemini-image.md → image-gen.md} +1 -1
  71. package/src/prompts/tools/inspect-image.md +6 -6
  72. package/src/prompts/tools/lsp.md +6 -0
  73. package/src/prompts/tools/patch.md +12 -19
  74. package/src/prompts/tools/python.md +3 -2
  75. package/src/prompts/tools/read-chunk.md +46 -8
  76. package/src/prompts/tools/read.md +9 -6
  77. package/src/prompts/tools/ssh.md +8 -17
  78. package/src/prompts/tools/todo-write.md +54 -41
  79. package/src/sdk.ts +22 -14
  80. package/src/session/agent-session.ts +61 -22
  81. package/src/session/session-manager.ts +228 -57
  82. package/src/session/streaming-output.ts +11 -0
  83. package/src/system-prompt.ts +7 -2
  84. package/src/task/executor.ts +44 -48
  85. package/src/task/render.ts +11 -13
  86. package/src/tools/ask.ts +7 -7
  87. package/src/tools/ast-edit.ts +45 -41
  88. package/src/tools/ast-grep.ts +77 -85
  89. package/src/tools/bash.ts +21 -9
  90. package/src/tools/browser.ts +32 -30
  91. package/src/tools/calculator.ts +4 -4
  92. package/src/tools/cancel-job.ts +1 -1
  93. package/src/tools/checkpoint.ts +2 -2
  94. package/src/tools/debug.ts +41 -37
  95. package/src/tools/exit-plan-mode.ts +1 -1
  96. package/src/tools/find.ts +4 -4
  97. package/src/tools/gh-renderer.ts +12 -4
  98. package/src/tools/gh.ts +514 -712
  99. package/src/tools/grep.ts +115 -130
  100. package/src/tools/{gemini-image.ts → image-gen.ts} +459 -60
  101. package/src/tools/index.ts +14 -32
  102. package/src/tools/inspect-image.ts +3 -3
  103. package/src/tools/json-tree.ts +114 -114
  104. package/src/tools/match-line-format.ts +9 -8
  105. package/src/tools/notebook.ts +8 -7
  106. package/src/tools/poll-tool.ts +2 -1
  107. package/src/tools/python.ts +9 -23
  108. package/src/tools/read.ts +32 -21
  109. package/src/tools/render-mermaid.ts +1 -1
  110. package/src/tools/render-utils.ts +18 -0
  111. package/src/tools/renderers.ts +2 -2
  112. package/src/tools/report-tool-issue.ts +3 -2
  113. package/src/tools/resolve.ts +1 -1
  114. package/src/tools/review.ts +12 -10
  115. package/src/tools/search-tool-bm25.ts +2 -4
  116. package/src/tools/sqlite-reader.ts +116 -3
  117. package/src/tools/ssh.ts +4 -4
  118. package/src/tools/todo-write.ts +172 -147
  119. package/src/tools/vim.ts +14 -15
  120. package/src/tools/write.ts +4 -4
  121. package/src/tools/{submit-result.ts → yield.ts} +11 -13
  122. package/src/utils/edit-mode.ts +2 -1
  123. package/src/utils/file-display-mode.ts +10 -5
  124. package/src/utils/git.ts +9 -5
  125. package/src/utils/shell-snapshot.ts +2 -3
  126. package/src/vim/render.ts +4 -4
  127. package/src/web/search/providers/codex.ts +129 -6
  128. package/src/prompts/system/subagent-submit-reminder.md +0 -11
  129. package/src/prompts/tools/gh-issue-view.md +0 -11
  130. package/src/prompts/tools/gh-pr-checkout.md +0 -12
  131. package/src/prompts/tools/gh-pr-diff.md +0 -12
  132. package/src/prompts/tools/gh-pr-push.md +0 -11
  133. package/src/prompts/tools/gh-pr-view.md +0 -11
  134. package/src/prompts/tools/gh-repo-view.md +0 -11
  135. package/src/prompts/tools/gh-run-watch.md +0 -12
  136. package/src/prompts/tools/gh-search-issues.md +0 -11
  137. package/src/prompts/tools/gh-search-prs.md +0 -11
@@ -3,26 +3,740 @@
3
3
  * circular dependencies (prompt-templates → hashline → tools → edit).
4
4
  */
5
5
 
6
- /** 16-char nibble alphabet (no digits); shared with chunk checksum suffixes. */
7
- export const HASHLINE_NIBBLE_ALPHABET = "ZPMQVRWSNKTXJBYH";
6
+ /**
7
+ * 647 single-token BPE bigrams for hashline anchors. Every entry tokenizes as
8
+ * exactly one token in modern BPE vocabularies (cl100k / o200k / Claude family),
9
+ * so a hashline anchor built from one bigram is exactly 1 token.
10
+ *
11
+ * This is the complete set of 2-letter lowercase combinations that are single
12
+ * tokens — the 29 missing combinations are rare-letter pairs (q/x/z heavy)
13
+ * that no major BPE vocabulary merges into a single token.
14
+ *
15
+ * Order is stable forever — changing it would invalidate every saved
16
+ * `LINE+ID` reference in transcripts and prompts.
17
+ */
18
+ export const HASHLINE_BIGRAMS = [
19
+ "aa",
20
+ "ab",
21
+ "ac",
22
+ "ad",
23
+ "ae",
24
+ "af",
25
+ "ag",
26
+ "ah",
27
+ "ai",
28
+ "aj",
29
+ "ak",
30
+ "al",
31
+ "am",
32
+ "an",
33
+ "ao",
34
+ "ap",
35
+ "aq",
36
+ "ar",
37
+ "as",
38
+ "at",
39
+ "au",
40
+ "av",
41
+ "aw",
42
+ "ax",
43
+ "ay",
44
+ "az",
45
+ "ba",
46
+ "bb",
47
+ "bc",
48
+ "bd",
49
+ "be",
50
+ "bf",
51
+ "bg",
52
+ "bh",
53
+ "bi",
54
+ "bj",
55
+ "bk",
56
+ "bl",
57
+ "bm",
58
+ "bn",
59
+ "bo",
60
+ "bp",
61
+ "br",
62
+ "bs",
63
+ "bt",
64
+ "bu",
65
+ "bv",
66
+ "bw",
67
+ "bx",
68
+ "by",
69
+ "bz",
70
+ "ca",
71
+ "cb",
72
+ "cc",
73
+ "cd",
74
+ "ce",
75
+ "cf",
76
+ "cg",
77
+ "ch",
78
+ "ci",
79
+ "cj",
80
+ "ck",
81
+ "cl",
82
+ "cm",
83
+ "cn",
84
+ "co",
85
+ "cp",
86
+ "cq",
87
+ "cr",
88
+ "cs",
89
+ "ct",
90
+ "cu",
91
+ "cv",
92
+ "cw",
93
+ "cx",
94
+ "cy",
95
+ "cz",
96
+ "da",
97
+ "db",
98
+ "dc",
99
+ "dd",
100
+ "de",
101
+ "df",
102
+ "dg",
103
+ "dh",
104
+ "di",
105
+ "dj",
106
+ "dk",
107
+ "dl",
108
+ "dm",
109
+ "dn",
110
+ "do",
111
+ "dp",
112
+ "dq",
113
+ "dr",
114
+ "ds",
115
+ "dt",
116
+ "du",
117
+ "dv",
118
+ "dw",
119
+ "dx",
120
+ "dy",
121
+ "dz",
122
+ "ea",
123
+ "eb",
124
+ "ec",
125
+ "ed",
126
+ "ee",
127
+ "ef",
128
+ "eg",
129
+ "eh",
130
+ "ei",
131
+ "ej",
132
+ "ek",
133
+ "el",
134
+ "em",
135
+ "en",
136
+ "eo",
137
+ "ep",
138
+ "eq",
139
+ "er",
140
+ "es",
141
+ "et",
142
+ "eu",
143
+ "ev",
144
+ "ew",
145
+ "ex",
146
+ "ey",
147
+ "ez",
148
+ "fa",
149
+ "fb",
150
+ "fc",
151
+ "fd",
152
+ "fe",
153
+ "ff",
154
+ "fg",
155
+ "fh",
156
+ "fi",
157
+ "fj",
158
+ "fk",
159
+ "fl",
160
+ "fm",
161
+ "fn",
162
+ "fo",
163
+ "fp",
164
+ "fq",
165
+ "fr",
166
+ "fs",
167
+ "ft",
168
+ "fu",
169
+ "fv",
170
+ "fw",
171
+ "fx",
172
+ "fy",
173
+ "fz",
174
+ "ga",
175
+ "gb",
176
+ "gc",
177
+ "gd",
178
+ "ge",
179
+ "gf",
180
+ "gg",
181
+ "gh",
182
+ "gi",
183
+ "gj",
184
+ "gl",
185
+ "gm",
186
+ "gn",
187
+ "go",
188
+ "gp",
189
+ "gr",
190
+ "gs",
191
+ "gt",
192
+ "gu",
193
+ "gv",
194
+ "gw",
195
+ "gx",
196
+ "gy",
197
+ "gz",
198
+ "ha",
199
+ "hb",
200
+ "hc",
201
+ "hd",
202
+ "he",
203
+ "hf",
204
+ "hg",
205
+ "hh",
206
+ "hi",
207
+ "hj",
208
+ "hk",
209
+ "hl",
210
+ "hm",
211
+ "hn",
212
+ "ho",
213
+ "hp",
214
+ "hq",
215
+ "hr",
216
+ "hs",
217
+ "ht",
218
+ "hu",
219
+ "hv",
220
+ "hw",
221
+ "hx",
222
+ "hy",
223
+ "hz",
224
+ "ia",
225
+ "ib",
226
+ "ic",
227
+ "id",
228
+ "ie",
229
+ "if",
230
+ "ig",
231
+ "ih",
232
+ "ii",
233
+ "ij",
234
+ "ik",
235
+ "il",
236
+ "im",
237
+ "in",
238
+ "io",
239
+ "ip",
240
+ "iq",
241
+ "ir",
242
+ "is",
243
+ "it",
244
+ "iu",
245
+ "iv",
246
+ "iw",
247
+ "ix",
248
+ "iy",
249
+ "iz",
250
+ "ja",
251
+ "jb",
252
+ "jc",
253
+ "jd",
254
+ "je",
255
+ "jf",
256
+ "jg",
257
+ "jh",
258
+ "ji",
259
+ "jj",
260
+ "jk",
261
+ "jl",
262
+ "jm",
263
+ "jn",
264
+ "jo",
265
+ "jp",
266
+ "jq",
267
+ "jr",
268
+ "js",
269
+ "jt",
270
+ "ju",
271
+ "jw",
272
+ "jx",
273
+ "jy",
274
+ "ka",
275
+ "kb",
276
+ "kc",
277
+ "kd",
278
+ "ke",
279
+ "kf",
280
+ "kg",
281
+ "kh",
282
+ "ki",
283
+ "kj",
284
+ "kk",
285
+ "kl",
286
+ "km",
287
+ "kn",
288
+ "ko",
289
+ "kp",
290
+ "kr",
291
+ "ks",
292
+ "kt",
293
+ "ku",
294
+ "kv",
295
+ "kw",
296
+ "kx",
297
+ "ky",
298
+ "la",
299
+ "lb",
300
+ "lc",
301
+ "ld",
302
+ "le",
303
+ "lf",
304
+ "lg",
305
+ "lh",
306
+ "li",
307
+ "lj",
308
+ "lk",
309
+ "ll",
310
+ "lm",
311
+ "ln",
312
+ "lo",
313
+ "lp",
314
+ "lr",
315
+ "ls",
316
+ "lt",
317
+ "lu",
318
+ "lv",
319
+ "lw",
320
+ "lx",
321
+ "ly",
322
+ "lz",
323
+ "ma",
324
+ "mb",
325
+ "mc",
326
+ "md",
327
+ "me",
328
+ "mf",
329
+ "mg",
330
+ "mh",
331
+ "mi",
332
+ "mj",
333
+ "mk",
334
+ "ml",
335
+ "mm",
336
+ "mn",
337
+ "mo",
338
+ "mp",
339
+ "mq",
340
+ "mr",
341
+ "ms",
342
+ "mt",
343
+ "mu",
344
+ "mv",
345
+ "mw",
346
+ "mx",
347
+ "my",
348
+ "mz",
349
+ "na",
350
+ "nb",
351
+ "nc",
352
+ "nd",
353
+ "ne",
354
+ "nf",
355
+ "ng",
356
+ "nh",
357
+ "ni",
358
+ "nj",
359
+ "nk",
360
+ "nl",
361
+ "nm",
362
+ "nn",
363
+ "no",
364
+ "np",
365
+ "nr",
366
+ "ns",
367
+ "nt",
368
+ "nu",
369
+ "nv",
370
+ "nw",
371
+ "nx",
372
+ "ny",
373
+ "nz",
374
+ "oa",
375
+ "ob",
376
+ "oc",
377
+ "od",
378
+ "oe",
379
+ "of",
380
+ "og",
381
+ "oh",
382
+ "oi",
383
+ "oj",
384
+ "ok",
385
+ "ol",
386
+ "om",
387
+ "on",
388
+ "oo",
389
+ "op",
390
+ "oq",
391
+ "or",
392
+ "os",
393
+ "ot",
394
+ "ou",
395
+ "ov",
396
+ "ow",
397
+ "ox",
398
+ "oy",
399
+ "oz",
400
+ "pa",
401
+ "pb",
402
+ "pc",
403
+ "pd",
404
+ "pe",
405
+ "pf",
406
+ "pg",
407
+ "ph",
408
+ "pi",
409
+ "pj",
410
+ "pk",
411
+ "pl",
412
+ "pm",
413
+ "pn",
414
+ "po",
415
+ "pp",
416
+ "pq",
417
+ "pr",
418
+ "ps",
419
+ "pt",
420
+ "pu",
421
+ "pv",
422
+ "pw",
423
+ "px",
424
+ "py",
425
+ "pz",
426
+ "qa",
427
+ "qb",
428
+ "qc",
429
+ "qd",
430
+ "qe",
431
+ "qh",
432
+ "qi",
433
+ "ql",
434
+ "qm",
435
+ "qn",
436
+ "qo",
437
+ "qp",
438
+ "qq",
439
+ "qr",
440
+ "qs",
441
+ "qt",
442
+ "qu",
443
+ "qw",
444
+ "qx",
445
+ "qy",
446
+ "ra",
447
+ "rb",
448
+ "rc",
449
+ "rd",
450
+ "re",
451
+ "rf",
452
+ "rg",
453
+ "rh",
454
+ "ri",
455
+ "rk",
456
+ "rl",
457
+ "rm",
458
+ "rn",
459
+ "ro",
460
+ "rp",
461
+ "rq",
462
+ "rr",
463
+ "rs",
464
+ "rt",
465
+ "ru",
466
+ "rv",
467
+ "rw",
468
+ "rx",
469
+ "ry",
470
+ "rz",
471
+ "sa",
472
+ "sb",
473
+ "sc",
474
+ "sd",
475
+ "se",
476
+ "sf",
477
+ "sg",
478
+ "sh",
479
+ "si",
480
+ "sj",
481
+ "sk",
482
+ "sl",
483
+ "sm",
484
+ "sn",
485
+ "so",
486
+ "sp",
487
+ "sq",
488
+ "sr",
489
+ "ss",
490
+ "st",
491
+ "su",
492
+ "sv",
493
+ "sw",
494
+ "sx",
495
+ "sy",
496
+ "sz",
497
+ "ta",
498
+ "tb",
499
+ "tc",
500
+ "td",
501
+ "te",
502
+ "tf",
503
+ "tg",
504
+ "th",
505
+ "ti",
506
+ "tj",
507
+ "tk",
508
+ "tl",
509
+ "tm",
510
+ "tn",
511
+ "to",
512
+ "tp",
513
+ "tr",
514
+ "ts",
515
+ "tt",
516
+ "tu",
517
+ "tv",
518
+ "tw",
519
+ "tx",
520
+ "ty",
521
+ "tz",
522
+ "ua",
523
+ "ub",
524
+ "uc",
525
+ "ud",
526
+ "ue",
527
+ "uf",
528
+ "ug",
529
+ "uh",
530
+ "ui",
531
+ "uj",
532
+ "uk",
533
+ "ul",
534
+ "um",
535
+ "un",
536
+ "uo",
537
+ "up",
538
+ "uq",
539
+ "ur",
540
+ "us",
541
+ "ut",
542
+ "uu",
543
+ "uv",
544
+ "uw",
545
+ "ux",
546
+ "uy",
547
+ "uz",
548
+ "va",
549
+ "vb",
550
+ "vc",
551
+ "vd",
552
+ "ve",
553
+ "vf",
554
+ "vg",
555
+ "vh",
556
+ "vi",
557
+ "vj",
558
+ "vk",
559
+ "vl",
560
+ "vm",
561
+ "vn",
562
+ "vo",
563
+ "vp",
564
+ "vq",
565
+ "vr",
566
+ "vs",
567
+ "vt",
568
+ "vu",
569
+ "vv",
570
+ "vw",
571
+ "vx",
572
+ "vy",
573
+ "vz",
574
+ "wa",
575
+ "wb",
576
+ "wc",
577
+ "wd",
578
+ "we",
579
+ "wf",
580
+ "wg",
581
+ "wh",
582
+ "wi",
583
+ "wj",
584
+ "wk",
585
+ "wl",
586
+ "wm",
587
+ "wn",
588
+ "wo",
589
+ "wp",
590
+ "wr",
591
+ "ws",
592
+ "wt",
593
+ "wu",
594
+ "wv",
595
+ "ww",
596
+ "wx",
597
+ "wy",
598
+ "xa",
599
+ "xb",
600
+ "xc",
601
+ "xd",
602
+ "xe",
603
+ "xf",
604
+ "xh",
605
+ "xi",
606
+ "xl",
607
+ "xm",
608
+ "xn",
609
+ "xo",
610
+ "xp",
611
+ "xr",
612
+ "xs",
613
+ "xt",
614
+ "xu",
615
+ "xx",
616
+ "xy",
617
+ "xz",
618
+ "ya",
619
+ "yb",
620
+ "yc",
621
+ "yd",
622
+ "ye",
623
+ "yf",
624
+ "yg",
625
+ "yh",
626
+ "yi",
627
+ "yj",
628
+ "yk",
629
+ "yl",
630
+ "ym",
631
+ "yn",
632
+ "yo",
633
+ "yp",
634
+ "yr",
635
+ "ys",
636
+ "yt",
637
+ "yu",
638
+ "yv",
639
+ "yw",
640
+ "yx",
641
+ "yy",
642
+ "yz",
643
+ "za",
644
+ "zb",
645
+ "zc",
646
+ "zd",
647
+ "ze",
648
+ "zf",
649
+ "zg",
650
+ "zh",
651
+ "zi",
652
+ "zk",
653
+ "zl",
654
+ "zm",
655
+ "zn",
656
+ "zo",
657
+ "zp",
658
+ "zr",
659
+ "zs",
660
+ "zt",
661
+ "zu",
662
+ "zw",
663
+ "zx",
664
+ "zy",
665
+ "zz",
666
+ ] as const;
667
+
668
+ export const HASHLINE_BIGRAMS_COUNT = HASHLINE_BIGRAMS.length;
669
+
670
+ /**
671
+ * 40 common English BPE bigrams used by chunk checksums (`path#checksum`).
672
+ * Kept separate from {@link HASHLINE_BIGRAMS} because the chunk checksum
673
+ * format is `path#bigram1bigram2` (4 chars from a 1600-code namespace) and
674
+ * is independent of the line-anchor format.
675
+ *
676
+ * Order is stable forever — changing it invalidates every saved chunk path.
677
+ */
678
+ export const CHUNK_BIGRAMS = [
679
+ "th",
680
+ "he",
681
+ "in",
682
+ "er",
683
+ "an",
684
+ "re",
685
+ "on",
686
+ "at",
687
+ "en",
688
+ "nd",
689
+ "ti",
690
+ "es",
691
+ "or",
692
+ "te",
693
+ "of",
694
+ "ed",
695
+ "is",
696
+ "it",
697
+ "al",
698
+ "ar",
699
+ "st",
700
+ "to",
701
+ "nt",
702
+ "ng",
703
+ "se",
704
+ "ha",
705
+ "as",
706
+ "ou",
707
+ "io",
708
+ "le",
709
+ "ve",
710
+ "co",
711
+ "me",
712
+ "de",
713
+ "hi",
714
+ "ri",
715
+ "ro",
716
+ "ic",
717
+ "ne",
718
+ "ea",
719
+ ] as const;
8
720
 
9
- const NIBBLE_STR = HASHLINE_NIBBLE_ALPHABET;
721
+ export const CHUNK_BIGRAMS_COUNT = CHUNK_BIGRAMS.length;
722
+
723
+ /**
724
+ * Regex source matching exactly one bigram from {@link HASHLINE_BIGRAMS}.
725
+ * Used by hashline parsers — keep in sync with the alphabet array above.
726
+ */
727
+ export const HASHLINE_BIGRAM_RE_SRC = `(?:${HASHLINE_BIGRAMS.join("|")})`;
10
728
 
11
- const DICT = Array.from({ length: 256 }, (_, i) => {
12
- const h = i >>> 4;
13
- const l = i & 0x0f;
14
- return `${NIBBLE_STR[h]}${NIBBLE_STR[l]}`;
15
- });
729
+ export const HASHLINE_CONTENT_SEPARATOR = ":";
16
730
 
17
731
  const RE_SIGNIFICANT = /[\p{L}\p{N}]/u;
18
732
 
19
733
  /**
20
- * Compute a short hexadecimal hash of a single line.
734
+ * Compute a short BPE-bigram hash of a single line.
21
735
  *
22
- * Uses xxHash32 on a trailing-whitespace-trimmed, CR-stripped line, truncated to 2 chars from
23
- * {@link NIBBLE_STR}. For lines containing no alphanumeric characters (only
24
- * punctuation/symbols/whitespace), the line number is mixed in to reduce hash collisions.
25
- * The line input should not include a trailing newline.
736
+ * Uses xxHash32 on a trailing-whitespace-trimmed, CR-stripped line, mapped into
737
+ * {@link HASHLINE_BIGRAMS} via modulo. For lines containing no alphanumeric
738
+ * characters (only punctuation/symbols/whitespace), the line number is mixed in
739
+ * to reduce hash collisions. The line input should not include a trailing newline.
26
740
  */
27
741
  export function computeLineHash(idx: number, line: string): string {
28
742
  line = line.replace(/\r/g, "").trimEnd();
@@ -31,20 +745,22 @@ export function computeLineHash(idx: number, line: string): string {
31
745
  if (!RE_SIGNIFICANT.test(line)) {
32
746
  seed = idx;
33
747
  }
34
- return DICT[Bun.hash.xxHash32(line, seed) & 0xff];
748
+ return HASHLINE_BIGRAMS[Bun.hash.xxHash32(line, seed) % HASHLINE_BIGRAMS_COUNT];
35
749
  }
36
750
 
37
751
  /**
38
- * Formats a hash given the line number and text.
752
+ * Formats an anchor reference given a line number and its text.
753
+ * Returns `LINE+ID` (e.g., `42nd`) — no separator between number and bigram.
39
754
  */
40
755
  export function formatLineHash(line: number, lines: string): string {
41
- return `${line}#${computeLineHash(line, lines)}`;
756
+ return `${line}${computeLineHash(line, lines)}`;
42
757
  }
43
758
 
44
759
  /**
45
760
  * Format file text with hashline prefixes for display.
46
761
  *
47
- * Each line becomes `LINENUM#HASH:TEXT` where LINENUM is 1-indexed.
762
+ * Each line becomes `LINE+ID:TEXT` where LINENUM is 1-indexed.
763
+ * No padding on line numbers; colon separator between anchor and content.
48
764
  *
49
765
  * @param text - Raw file text string
50
766
  * @param startLine - First line number (1-indexed, defaults to 1)
@@ -53,7 +769,7 @@ export function formatLineHash(line: number, lines: string): string {
53
769
  * @example
54
770
  * ```
55
771
  * formatHashLines("function hi() {\n return;\n}")
56
- * // "1#HH:function hi() {\n2#HH: return;\n3#HH:}"
772
+ * // "1th:function hi() {\n2er: return;\n3in:}"
57
773
  * ```
58
774
  */
59
775
  export function formatHashLines(text: string, startLine = 1): string {
@@ -61,7 +777,7 @@ export function formatHashLines(text: string, startLine = 1): string {
61
777
  return lines
62
778
  .map((line, i) => {
63
779
  const num = startLine + i;
64
- return `${formatLineHash(num, line)}:${line}`;
780
+ return `${formatLineHash(num, line)}${HASHLINE_CONTENT_SEPARATOR}${line}`;
65
781
  })
66
782
  .join("\n");
67
783
  }