token-goat 2.9.29 → 2.9.30

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 (131) hide show
  1. package/README.md +34 -40
  2. package/SECURITY.md +28 -10
  3. package/THIRD_PARTY_NOTICES.md +40 -3
  4. package/dist/native/linux-arm64/tg-hook +0 -0
  5. package/dist/native/linux-x64/tg-hook +0 -0
  6. package/dist/ort-wasm-simd-threaded.mjs +59 -0
  7. package/dist/token-goat-chunk-3CHUNJ2O.mjs +53 -0
  8. package/dist/token-goat-chunk-3Z5S4KGM.mjs +918 -0
  9. package/dist/token-goat-chunk-4FVIAHSI.mjs +211 -0
  10. package/dist/{token-goat-chunk-PGTH2U4C.mjs → token-goat-chunk-4JJS54TR.mjs} +4 -3
  11. package/dist/token-goat-chunk-4LCCNRTG.mjs +313 -0
  12. package/dist/{token-goat-chunk-L7H3U27L.mjs → token-goat-chunk-54K3EUV3.mjs} +1 -1
  13. package/dist/token-goat-chunk-56EIMS3E.mjs +159 -0
  14. package/dist/token-goat-chunk-5BCIJXMO.mjs +609 -0
  15. package/dist/token-goat-chunk-5KDMCMF2.mjs +362 -0
  16. package/dist/token-goat-chunk-5RG5SBL6.mjs +221 -0
  17. package/dist/{token-goat-chunk-RRNZMM3A.mjs → token-goat-chunk-5Y6ZYL6U.mjs} +21 -2
  18. package/dist/{token-goat-chunk-GLXRTTLE.mjs → token-goat-chunk-64FBPDTK.mjs} +12 -8
  19. package/dist/{token-goat-chunk-G23DWHV4.mjs → token-goat-chunk-664RTTUV.mjs} +28 -15
  20. package/dist/token-goat-chunk-67TQJ76B.mjs +57 -0
  21. package/dist/token-goat-chunk-6QMAS7AB.mjs +42 -0
  22. package/dist/token-goat-chunk-7BXSNBY5.mjs +253 -0
  23. package/dist/{token-goat-chunk-IVWI2OCK.mjs → token-goat-chunk-7F2UBPD3.mjs} +40 -11
  24. package/dist/{token-goat-chunk-TGOXNAHW.mjs → token-goat-chunk-7IN2MKDS.mjs} +682 -501
  25. package/dist/token-goat-chunk-7NADEDKJ.mjs +124 -0
  26. package/dist/{token-goat-chunk-KOPIR3KZ.mjs → token-goat-chunk-A3CK6N5Z.mjs} +618 -72
  27. package/dist/{token-goat-chunk-O6I2XU4P.mjs → token-goat-chunk-AFLYLHDH.mjs} +44 -31
  28. package/dist/{token-goat-chunk-TCQANXYC.mjs → token-goat-chunk-AM5V6GSX.mjs} +18 -2
  29. package/dist/{token-goat-chunk-E4ZOJIZK.mjs → token-goat-chunk-APGZXSPS.mjs} +39 -146
  30. package/dist/{token-goat-chunk-D4ETHJD6.mjs → token-goat-chunk-ARDNEC2U.mjs} +9 -7
  31. package/dist/token-goat-chunk-ATCPY7EQ.mjs +134 -0
  32. package/dist/token-goat-chunk-B2RZZCSS.mjs +354 -0
  33. package/dist/{token-goat-chunk-BGYOZ6DO.mjs → token-goat-chunk-B45VMIIH.mjs} +6 -7
  34. package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
  35. package/dist/{token-goat-chunk-TDUT2CL6.mjs → token-goat-chunk-C63JQV5K.mjs} +45 -6
  36. package/dist/{token-goat-chunk-ZER6EAXZ.mjs → token-goat-chunk-COBQGL5S.mjs} +2661 -2440
  37. package/dist/token-goat-chunk-COTXZHTS.mjs +39 -0
  38. package/dist/{token-goat-chunk-RQGGMPCR.mjs → token-goat-chunk-CYCEYAEO.mjs} +76 -16
  39. package/dist/token-goat-chunk-CZ3LUXYZ.mjs +4115 -0
  40. package/dist/{token-goat-chunk-ASLWOQ3I.mjs → token-goat-chunk-DZX2YDPT.mjs} +2 -1
  41. package/dist/token-goat-chunk-E3OQX2XT.mjs +824 -0
  42. package/dist/token-goat-chunk-EFHMMIGP.mjs +68 -0
  43. package/dist/token-goat-chunk-ETBHVDB6.mjs +328 -0
  44. package/dist/token-goat-chunk-EVMZJ27Z.mjs +147 -0
  45. package/dist/token-goat-chunk-EXKGNHEG.mjs +2096 -0
  46. package/dist/{token-goat-chunk-RTMVLHWX.mjs → token-goat-chunk-FBNQNSJK.mjs} +2555 -5127
  47. package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
  48. package/dist/{token-goat-chunk-RLP6J7WR.mjs → token-goat-chunk-FZ3NEW5O.mjs} +33 -19
  49. package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
  50. package/dist/{token-goat-chunk-DNRPXHYH.mjs → token-goat-chunk-GFBSN7BD.mjs} +29 -401
  51. package/dist/{token-goat-chunk-XYWPOSCN.mjs → token-goat-chunk-GOLEOXZP.mjs} +763 -211
  52. package/dist/token-goat-chunk-H2K3QP6H.mjs +24 -0
  53. package/dist/token-goat-chunk-H2PHHGM5.mjs +188 -0
  54. package/dist/token-goat-chunk-HAVAOB3S.mjs +87 -0
  55. package/dist/token-goat-chunk-HG45AF2B.mjs +2228 -0
  56. package/dist/{token-goat-chunk-HUYUHODZ.mjs → token-goat-chunk-HOJLCGDP.mjs} +12965 -11748
  57. package/dist/{token-goat-chunk-435UQTKD.mjs → token-goat-chunk-HYBFA5X3.mjs} +118 -19
  58. package/dist/token-goat-chunk-IVALLT3S.mjs +48 -0
  59. package/dist/{token-goat-chunk-UXSXQQIY.mjs → token-goat-chunk-IVKIZWAB.mjs} +3 -3
  60. package/dist/{token-goat-chunk-52NSDWYY.mjs → token-goat-chunk-JB6QN6VF.mjs} +6 -4
  61. package/dist/{token-goat-chunk-HNFZZHFW.mjs → token-goat-chunk-JDHE26RP.mjs} +10 -3
  62. package/dist/{token-goat-chunk-FTP4U4QA.mjs → token-goat-chunk-JDU3EXSU.mjs} +12 -11
  63. package/dist/token-goat-chunk-JDWCRD6M.mjs +253 -0
  64. package/dist/{token-goat-chunk-6AK46ZT7.mjs → token-goat-chunk-JN4XMLSD.mjs} +5 -1
  65. package/dist/token-goat-chunk-JTQQGXZH.mjs +733 -0
  66. package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
  67. package/dist/token-goat-chunk-KQNZDCBD.mjs +47 -0
  68. package/dist/{token-goat-chunk-2WOUYWLM.mjs → token-goat-chunk-KWPNJBDH.mjs} +27 -3
  69. package/dist/{token-goat-chunk-DPNLUJWB.mjs → token-goat-chunk-LOBGHXPB.mjs} +30 -8
  70. package/dist/token-goat-chunk-MKPF4CL5.mjs +37 -0
  71. package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
  72. package/dist/{token-goat-chunk-DNSPXQXQ.mjs → token-goat-chunk-N2NMER56.mjs} +25 -15
  73. package/dist/token-goat-chunk-NYKZLXMK.mjs +218 -0
  74. package/dist/token-goat-chunk-OJBNYTJP.mjs +3087 -0
  75. package/dist/token-goat-chunk-P4QMM4WK.mjs +295 -0
  76. package/dist/token-goat-chunk-PD5VKH46.mjs +184 -0
  77. package/dist/token-goat-chunk-PEPTHRFF.mjs +129 -0
  78. package/dist/{token-goat-chunk-NMBWLRHW.mjs → token-goat-chunk-PU7V3FD6.mjs} +8721 -11104
  79. package/dist/token-goat-chunk-PY533T7F.mjs +46 -0
  80. package/dist/token-goat-chunk-Q5VTGRH7.mjs +761 -0
  81. package/dist/{token-goat-chunk-67BNIKKO.mjs → token-goat-chunk-QCLDAQTS.mjs} +31 -20
  82. package/dist/{token-goat-chunk-SE6E4BKJ.mjs → token-goat-chunk-QSBRTGM2.mjs} +9 -2
  83. package/dist/{token-goat-chunk-VZQEWRVH.mjs → token-goat-chunk-RC35RBUL.mjs} +4 -4
  84. package/dist/{token-goat-chunk-VMFWNHGR.mjs → token-goat-chunk-RHXKCZX3.mjs} +873 -504
  85. package/dist/{token-goat-chunk-PYSUADX4.mjs → token-goat-chunk-RZRTDST7.mjs} +17 -7
  86. package/dist/{token-goat-chunk-ONXH6NZ5.mjs → token-goat-chunk-SJHWVNDQ.mjs} +15 -21
  87. package/dist/token-goat-chunk-SMVRN2HU.mjs +188 -0
  88. package/dist/{token-goat-chunk-QO3LXVVR.mjs → token-goat-chunk-SQSSNQPE.mjs} +2295 -1718
  89. package/dist/{token-goat-chunk-2AWQ2R5X.mjs → token-goat-chunk-T4FK7VOV.mjs} +2 -2
  90. package/dist/token-goat-chunk-U4N3BN2W.mjs +92 -0
  91. package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
  92. package/dist/{token-goat-chunk-UA5BKWWQ.mjs → token-goat-chunk-UQ5UK2T7.mjs} +15 -4
  93. package/dist/token-goat-chunk-USILZ3T3.mjs +53 -0
  94. package/dist/{token-goat-chunk-MELOKFDJ.mjs → token-goat-chunk-VES7EL7O.mjs} +7 -1
  95. package/dist/{token-goat-chunk-7CPMDFGB.mjs → token-goat-chunk-VL3YIFHZ.mjs} +389 -14
  96. package/dist/{token-goat-chunk-E5TK5DNO.mjs → token-goat-chunk-VPBBTSJR.mjs} +356 -129
  97. package/dist/{token-goat-chunk-YOOVFPTP.mjs → token-goat-chunk-W3QCJS6G.mjs} +10 -2
  98. package/dist/{token-goat-chunk-LZNBQTDK.mjs → token-goat-chunk-WY3L4DVT.mjs} +11 -7
  99. package/dist/token-goat-chunk-XKI4SEMX.mjs +66 -0
  100. package/dist/token-goat-chunk-XU4P6Z24.mjs +133 -0
  101. package/dist/{token-goat-chunk-H5J3C56Q.mjs → token-goat-chunk-Y776AENC.mjs} +112 -26
  102. package/dist/token-goat-chunk-YARZFCZS.mjs +359 -0
  103. package/dist/{token-goat-chunk-S4VSXURL.mjs → token-goat-chunk-Z44YO3QZ.mjs} +4 -0
  104. package/dist/token-goat-chunk-Z57YODA2.mjs +35 -0
  105. package/dist/{token-goat-chunk-PQ53BSCF.mjs → token-goat-chunk-ZCDTCVIS.mjs} +48 -29
  106. package/dist/token-goat-chunk-ZEJVMUQH.mjs +48 -0
  107. package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
  108. package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
  109. package/dist/{token-goat-chunk-PKRWMHVP.mjs → token-goat-chunk-ZQSJMO2R.mjs} +338 -170
  110. package/dist/token-goat-hook-client.cjs +87 -23
  111. package/dist/token-goat-hook-client.mjs +3 -3
  112. package/dist/token-goat-hook.mjs +46 -30
  113. package/dist/token-goat.core.mjs +6 -6
  114. package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
  115. package/docs/cli.md +80 -46
  116. package/docs/install.md +47 -14
  117. package/docs/security.md +7 -7
  118. package/package.json +17 -7
  119. package/scripts/verify-native-dist.mjs +386 -0
  120. package/dist/token-goat-chunk-2NNUA2LR.mjs +0 -143
  121. package/dist/token-goat-chunk-44BM7DDQ.mjs +0 -294
  122. package/dist/token-goat-chunk-C5YPNZKQ.mjs +0 -318
  123. package/dist/token-goat-chunk-CIQ2FTY3.mjs +0 -1990
  124. package/dist/token-goat-chunk-EUSDXRXU.mjs +0 -1429
  125. package/dist/token-goat-chunk-G7IWXCFF.mjs +0 -456
  126. package/dist/token-goat-chunk-JTKCQMQA.mjs +0 -418
  127. package/dist/token-goat-chunk-ORNFMIER.mjs +0 -295
  128. package/dist/token-goat-chunk-VQ6F6T7X.mjs +0 -36
  129. package/dist/token-goat-chunk-YAGLESS3.mjs +0 -23
  130. package/dist/token-goat-chunk-YKSRAWUU.mjs +0 -33
  131. package/dist/token-goat-chunk-Z6KBMOBI.mjs +0 -53
@@ -10,19 +10,19 @@ import {
10
10
  countContentLines,
11
11
  ensureDirSync,
12
12
  escapeRegExp
13
- } from "./token-goat-chunk-XYWPOSCN.mjs";
13
+ } from "./token-goat-chunk-GOLEOXZP.mjs";
14
14
  import {
15
15
  foldCase,
16
16
  foldPath,
17
17
  sleepSync
18
- } from "./token-goat-chunk-TCQANXYC.mjs";
18
+ } from "./token-goat-chunk-AM5V6GSX.mjs";
19
19
  import {
20
20
  safeJoin
21
- } from "./token-goat-chunk-NMTKNYGF.mjs";
21
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
22
22
  import {
23
23
  SYMBOL_BODY_CHAR_CAP,
24
24
  dataDir
25
- } from "./token-goat-chunk-MELOKFDJ.mjs";
25
+ } from "./token-goat-chunk-VES7EL7O.mjs";
26
26
  import {
27
27
  init_define_import_meta_env
28
28
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -393,6 +393,13 @@ function scalaCharLiteralLength(line, index) {
393
393
  return line[index + 1] !== void 0 && line[index + 1] !== "'" && line[index + 2] === "'" ? 3 : 0;
394
394
  }
395
395
  function stripStringLiterals(line, opts = {}) {
396
+ const stringFrame = (idx, delim) => {
397
+ const quote = line[idx];
398
+ const prev = line[idx - 1] ?? "";
399
+ const bareBraceHole = quote === '"' && (idx > 0 && prev === "$" || idx > 1 && prev === "@" && line[idx - 2] === "$" || idx > 1 && prev === "$" && line[idx - 2] === "@");
400
+ const plain = opts.interpolatorPrefix === true && !/[A-Za-z0-9_]/.test(prev) || opts.singleQuoteHoles === true && prev === "r" && !/[A-Za-z0-9_$]/.test(line[idx - 2] ?? "");
401
+ return { kind: "string", quote: delim, bareBraceHole, plain };
402
+ };
396
403
  const openDelim = (idx) => {
397
404
  const q = line[idx];
398
405
  if (opts.tripleQuotes && line[idx + 1] === q && line[idx + 2] === q) return q + q + q;
@@ -417,9 +424,8 @@ function stripStringLiterals(line, opts = {}) {
417
424
  continue;
418
425
  }
419
426
  if (ch === '"' || ch === "'") {
420
- const bareBraceHole = ch === '"' && i > 0 && line[i - 1] === "$";
421
427
  const delim = openDelim(i);
422
- stack.push({ kind: "string", quote: delim, bareBraceHole });
428
+ stack.push(stringFrame(i, delim));
423
429
  out += delim;
424
430
  i += delim.length;
425
431
  continue;
@@ -429,15 +435,35 @@ function stripStringLiterals(line, opts = {}) {
429
435
  continue;
430
436
  }
431
437
  if (top.kind === "hole") {
438
+ if (top.paren === true && (ch === "(" || ch === ")")) {
439
+ if (ch === "(") {
440
+ top.depth++;
441
+ out += ch;
442
+ } else {
443
+ if (top.depth > 0) {
444
+ top.depth--;
445
+ out += ch;
446
+ } else {
447
+ stack.pop();
448
+ out += " ";
449
+ }
450
+ }
451
+ i++;
452
+ continue;
453
+ }
454
+ if (top.paren === true && (ch === "{" || ch === "}")) {
455
+ out += ch;
456
+ i++;
457
+ continue;
458
+ }
432
459
  if (opts.symbolLiterals === true && ch === "'" && scalaCharLiteralLength(line, i) === 0) {
433
460
  out += ch;
434
461
  i++;
435
462
  continue;
436
463
  }
437
464
  if (ch === '"' || ch === "'") {
438
- const bareBraceHole = ch === '"' && i > 0 && line[i - 1] === "$";
439
465
  const delim = openDelim(i);
440
- stack.push({ kind: "string", quote: delim, bareBraceHole });
466
+ stack.push(stringFrame(i, delim));
441
467
  out += delim;
442
468
  i += delim.length;
443
469
  continue;
@@ -462,6 +488,12 @@ function stripStringLiterals(line, opts = {}) {
462
488
  i++;
463
489
  continue;
464
490
  }
491
+ if (opts.swiftInterpolation === true && top.quote === '"' && ch === "\\" && line[i + 1] === "(") {
492
+ stack.push({ kind: "hole", depth: 0, paren: true });
493
+ out += " ";
494
+ i += 2;
495
+ continue;
496
+ }
465
497
  if (ch === "\\" && i + 1 < line.length && line[i + 1] !== "\n") {
466
498
  out += " ";
467
499
  i += 2;
@@ -473,7 +505,7 @@ function stripStringLiterals(line, opts = {}) {
473
505
  i += top.quote.length;
474
506
  continue;
475
507
  }
476
- if (top.quote === '"') {
508
+ if (!top.plain && (top.quote === '"' || opts.singleQuoteHoles === true && top.quote[0] === "'")) {
477
509
  if (top.bareBraceHole && ch === "{") {
478
510
  if (line[i + 1] === "{") {
479
511
  out += " ";
@@ -1184,12 +1216,21 @@ function findMatchingBraceEndLine(content, openBraceIndex, totalLines, lineIndex
1184
1216
  const rRaw = opts?.rRawStrings === true;
1185
1217
  const tripleDelims = tripleQuoteDelimiters(opts);
1186
1218
  const lineString = opts?.lineStringPrefix;
1219
+ const interpolation = opts?.interpolation;
1220
+ let interpolated = false;
1187
1221
  let depth = 0;
1188
1222
  let quote = null;
1189
1223
  let verbatim = false;
1190
1224
  for (let i = openBraceIndex; i < content.length; i++) {
1191
1225
  const ch = content[i];
1192
1226
  if (quote !== null) {
1227
+ if (interpolated && interpolation !== void 0) {
1228
+ const past = skipInterpolationAt(content, i, content.length, interpolation);
1229
+ if (past !== null) {
1230
+ i = past - 1;
1231
+ continue;
1232
+ }
1233
+ }
1193
1234
  if (verbatim) {
1194
1235
  if (ch === quote) {
1195
1236
  if (content[i + 1] === quote) {
@@ -1252,6 +1293,7 @@ function findMatchingBraceEndLine(content, openBraceIndex, totalLines, lineIndex
1252
1293
  if (ch === '"' || ch === "'" || backtick && ch === "`") {
1253
1294
  quote = ch;
1254
1295
  verbatim = escapes === "csharp" && ch === '"' && opensCsharpVerbatimString(content, i);
1296
+ interpolated = interpolation !== void 0 && opensInterpolatedString(content, i, interpolation);
1255
1297
  continue;
1256
1298
  }
1257
1299
  if (ch === "{") depth++;
@@ -1285,6 +1327,7 @@ function assignBraceBlockSpans(symbols, content, opts = {}) {
1285
1327
  rawStringQuotes: opts.rawStringQuotes ?? false,
1286
1328
  tripleSingleQuote: opts.tripleSingleQuote ?? false,
1287
1329
  tripleQuoteRunClose: opts.tripleQuoteRunClose ?? "last",
1330
+ ...opts.interpolation === void 0 ? {} : { interpolation: opts.interpolation },
1288
1331
  ...blockComment === void 0 ? {} : { blockComment, nestedBlockComments },
1289
1332
  ...lineStringPrefix === void 0 ? {} : { lineStringPrefix },
1290
1333
  ...opts.lineCommentExceptions === void 0 ? {} : { lineCommentExceptions: opts.lineCommentExceptions }
@@ -1292,6 +1335,18 @@ function assignBraceBlockSpans(symbols, content, opts = {}) {
1292
1335
  return symbols.map((sym) => {
1293
1336
  if (sym.lineEnd !== sym.lineStart) return sym;
1294
1337
  const nextStart = starts.find((s) => s > sym.lineStart);
1338
+ if (opts.expressionBodies === true) {
1339
+ const arrowLast = Math.min(nextStart !== void 0 ? nextStart - 1 : totalLines, sym.lineStart + BRACE_SEARCH_MAX_LINES);
1340
+ const arrowEnd = findArrowBodyEndLine(scanContent, lineIndex, sym.lineStart, arrowLast);
1341
+ if (arrowEnd !== null) {
1342
+ return arrowEnd <= sym.lineStart ? withWholeLineBody(sym, lines) : { ...sym, lineEnd: arrowEnd, body: lines.slice(sym.lineStart - 1, arrowEnd).join("\n") };
1343
+ }
1344
+ } else if (opts.expressionBodies === "kotlin") {
1345
+ const eqEnd = findKotlinEqualsBodyEndLine(scanContent, lineIndex, sym.lineStart, nextStart !== void 0 ? nextStart - 1 : totalLines);
1346
+ if (eqEnd !== null) {
1347
+ return eqEnd <= sym.lineStart ? withWholeLineBody(sym, lines) : { ...sym, lineEnd: eqEnd, body: lines.slice(sym.lineStart - 1, eqEnd).join("\n") };
1348
+ }
1349
+ }
1295
1350
  const lastSearchLine = Math.min(nextStart !== void 0 ? nextStart - 1 : totalLines, sym.lineStart + BRACE_SEARCH_MAX_LINES);
1296
1351
  const openIndex = findBlockOpenBrace(scanContent, lineIndex, sym.lineStart, lastSearchLine, lineCommentPrefix, scanOpts);
1297
1352
  if (openIndex === null) return sym;
@@ -1303,11 +1358,304 @@ function assignBraceBlockSpans(symbols, content, opts = {}) {
1303
1358
  lineCommentPrefix,
1304
1359
  scanOpts
1305
1360
  );
1306
- if (endLine <= sym.lineStart) return sym;
1361
+ if (endLine === sym.lineStart) return withWholeLineBody(sym, lines);
1362
+ if (endLine < sym.lineStart) return sym;
1307
1363
  return { ...sym, lineEnd: endLine, body: lines.slice(sym.lineStart - 1, endLine).join("\n") };
1308
1364
  });
1309
1365
  }
1366
+ function withWholeLineBody(sym, lines) {
1367
+ const line = lines[sym.lineStart - 1];
1368
+ if (line === void 0 || sym.body.includes("{") || !line.includes("{")) return sym;
1369
+ return { ...sym, body: line.trimEnd() };
1370
+ }
1310
1371
  var BRACE_SEARCH_MAX_LINES = 10;
1372
+ function skipCsharpInterpolationHole(content, i, to) {
1373
+ let depth = 0;
1374
+ for (let k = i; k < to; k++) {
1375
+ const lit = skipCsharpLiteral(content, k, to);
1376
+ if (lit !== null) {
1377
+ k = lit - 1;
1378
+ continue;
1379
+ }
1380
+ const ch = content[k];
1381
+ if (ch === "{") depth++;
1382
+ else if (ch === "}" && --depth === 0) return k + 1;
1383
+ }
1384
+ return to;
1385
+ }
1386
+ function skipCsharpLiteral(content, i, to) {
1387
+ const first = content[i];
1388
+ if (first === "'") {
1389
+ if (content[i + 1] === "\\") {
1390
+ const close = content.indexOf("'", i + 3);
1391
+ return close === -1 || close >= to ? null : close + 1;
1392
+ }
1393
+ return content[i + 2] === "'" ? i + 3 : null;
1394
+ }
1395
+ let j = i;
1396
+ while ((content[j] === "$" || content[j] === "@") && j - i < 3) j++;
1397
+ if (content[j] !== '"') return null;
1398
+ const prefix = content.slice(i, j);
1399
+ if (j > i && /[A-Za-z0-9_]/.test(content[i - 1] ?? "")) return null;
1400
+ const interpolated = prefix.includes("$");
1401
+ const verbatim = prefix.includes("@");
1402
+ const run = quoteRunLength(content, j);
1403
+ if (run >= 3) {
1404
+ const end = skipRawStringQuotes(content, j + run, run);
1405
+ return end === -1 ? to : end;
1406
+ }
1407
+ for (let k = j + 1; k < to; k++) {
1408
+ const ch = content[k];
1409
+ if (ch === void 0) break;
1410
+ if (verbatim) {
1411
+ if (ch === '"') {
1412
+ if (content[k + 1] === '"') {
1413
+ k++;
1414
+ continue;
1415
+ }
1416
+ return k + 1;
1417
+ }
1418
+ } else if (ch === "\\") {
1419
+ k++;
1420
+ continue;
1421
+ } else if (ch === '"') return k + 1;
1422
+ if (interpolated) {
1423
+ if (ch === "{") {
1424
+ if (content[k + 1] === "{") {
1425
+ k++;
1426
+ continue;
1427
+ }
1428
+ k = skipCsharpInterpolationHole(content, k, to) - 1;
1429
+ }
1430
+ }
1431
+ }
1432
+ return to;
1433
+ }
1434
+ function findArrowBodyEndLine(content, lineIndex, startLine, lastSearchLine) {
1435
+ const from = lineIndex[startLine - 1];
1436
+ if (from === void 0) return null;
1437
+ const to = lineIndex[lastSearchLine] ?? content.length;
1438
+ let depth = 0;
1439
+ let seenArrow = false;
1440
+ for (let i = from; i < to; i++) {
1441
+ const ch = content[i];
1442
+ if (ch === void 0) break;
1443
+ if (ch === "/" && content[i + 1] === "/") {
1444
+ while (i + 1 < to && content[i + 1] !== "\n") i++;
1445
+ continue;
1446
+ }
1447
+ if (ch === "/" && content[i + 1] === "*") {
1448
+ const end = content.indexOf("*/", i + 2);
1449
+ if (end === -1) return null;
1450
+ i = end + 1;
1451
+ continue;
1452
+ }
1453
+ const lit = skipCsharpLiteral(content, i, to);
1454
+ if (lit !== null) {
1455
+ i = lit - 1;
1456
+ continue;
1457
+ }
1458
+ if (ch === "(" || ch === "[") depth++;
1459
+ else if (ch === ")" || ch === "]") {
1460
+ if (depth > 0) depth--;
1461
+ } else if (ch === "=" && content[i + 1] === ">" && depth === 0) {
1462
+ seenArrow = true;
1463
+ i++;
1464
+ } else if (ch === "{") {
1465
+ if (!seenArrow && depth === 0) return null;
1466
+ depth++;
1467
+ } else if (ch === "}") {
1468
+ if (depth === 0) return null;
1469
+ depth--;
1470
+ } else if (ch === ";" && depth === 0) {
1471
+ if (!seenArrow) return null;
1472
+ let line = startLine;
1473
+ for (let k = from; k < i; k++) if (content[k] === "\n") line++;
1474
+ return line;
1475
+ }
1476
+ }
1477
+ return null;
1478
+ }
1479
+ function skipKotlinTemplateHole(content, i, to) {
1480
+ let depth = 0;
1481
+ for (let k = i; k < to; k++) {
1482
+ const lit = skipKotlinLiteral(content, k, to);
1483
+ if (lit !== null) {
1484
+ k = lit - 1;
1485
+ continue;
1486
+ }
1487
+ const ch = content[k];
1488
+ if (ch === "{") depth++;
1489
+ else if (ch === "}" && --depth === 0) return k + 1;
1490
+ }
1491
+ return to;
1492
+ }
1493
+ function skipKotlinLiteral(content, i, to) {
1494
+ const first = content[i];
1495
+ if (first === "'") {
1496
+ for (let k = i + 1; k < to && content[k] !== "\n"; k++) {
1497
+ if (content[k] === "\\") {
1498
+ k++;
1499
+ continue;
1500
+ }
1501
+ if (content[k] === "'") return k + 1;
1502
+ }
1503
+ return null;
1504
+ }
1505
+ if (first !== '"') return null;
1506
+ const triple = content.startsWith('"""', i);
1507
+ for (let k = i + (triple ? 3 : 1); k < to; k++) {
1508
+ const ch = content[k];
1509
+ if (triple) {
1510
+ if (ch === '"' && content.startsWith('"""', k)) {
1511
+ k += 3;
1512
+ while (content[k] === '"') k++;
1513
+ return k;
1514
+ }
1515
+ } else if (ch === "\\") {
1516
+ k++;
1517
+ continue;
1518
+ } else if (ch === '"') return k + 1;
1519
+ else if (ch === "\n") return k;
1520
+ if (ch === "$" && content[k + 1] === "{") k = skipKotlinTemplateHole(content, k + 1, to) - 1;
1521
+ }
1522
+ return to;
1523
+ }
1524
+ function opensInterpolatedString(content, i, lang) {
1525
+ const q = content[i];
1526
+ const prev = content[i - 1] ?? "";
1527
+ if (lang === "csharp") return q === '"' && (prev === "$" || prev === "@" && content[i - 2] === "$");
1528
+ if (lang === "scala") return q === '"' && /[A-Za-z0-9_]/.test(prev);
1529
+ if (lang === "dart") return !(prev === "r" && !/[A-Za-z0-9_$]/.test(content[i - 2] ?? ""));
1530
+ return q === '"';
1531
+ }
1532
+ function skipInterpolationAt(content, i, to, lang) {
1533
+ const ch = content[i];
1534
+ if (lang === "swift") return ch === "\\" && content[i + 1] === "(" ? skipInterpolationHole(content, i + 1, to, lang) : null;
1535
+ if (lang === "csharp") {
1536
+ if (ch !== "{") return null;
1537
+ return content[i + 1] === "{" ? i + 2 : skipInterpolationHole(content, i, to, lang);
1538
+ }
1539
+ return ch === "$" && content[i + 1] === "{" ? skipInterpolationHole(content, i + 1, to, lang) : null;
1540
+ }
1541
+ function skipInterpolationHole(content, i, to, lang) {
1542
+ const open = content[i];
1543
+ const close = open === "(" ? ")" : "}";
1544
+ let depth = 0;
1545
+ for (let k = i; k < to; k++) {
1546
+ const lit = skipNestedLiteral(content, k, to, lang);
1547
+ if (lit !== null) {
1548
+ k = lit - 1;
1549
+ continue;
1550
+ }
1551
+ const ch = content[k];
1552
+ if (ch === open) depth++;
1553
+ else if (ch === close && --depth === 0) return k + 1;
1554
+ }
1555
+ return to;
1556
+ }
1557
+ function skipNestedLiteral(content, i, to, lang) {
1558
+ const ch = content[i];
1559
+ if (lang === "csharp") return skipCsharpLiteral(content, i, to);
1560
+ if (lang === "kotlin") return skipKotlinLiteral(content, i, to);
1561
+ if (ch === "'" && lang === "scala") {
1562
+ const len = scalaCharLiteralLength(content, i);
1563
+ return len > 0 ? i + len : null;
1564
+ }
1565
+ if (ch !== '"' && !(ch === "'" && lang === "dart")) return null;
1566
+ return skipInterpolatedString(content, i, to, lang, opensInterpolatedString(content, i, lang));
1567
+ }
1568
+ function skipInterpolatedString(content, i, to, lang, interpolated) {
1569
+ const q = content[i];
1570
+ if (content.startsWith(q + q + q, i)) {
1571
+ const end = content.indexOf(q + q + q, i + 3);
1572
+ return end === -1 || end >= to ? to : end + 3;
1573
+ }
1574
+ for (let k = i + 1; k < to; k++) {
1575
+ const ch = content[k];
1576
+ if (ch === "\n") return k;
1577
+ if (interpolated) {
1578
+ const past = skipInterpolationAt(content, k, to, lang);
1579
+ if (past !== null) {
1580
+ k = past - 1;
1581
+ continue;
1582
+ }
1583
+ }
1584
+ if (ch === "\\") {
1585
+ k++;
1586
+ continue;
1587
+ }
1588
+ if (ch === q) return k + 1;
1589
+ }
1590
+ return to;
1591
+ }
1592
+ function kotlinBodyContinues(content, lastSig, ifParenClosedAt, nextLineFrom) {
1593
+ const c = content[lastSig];
1594
+ const prev = content[lastSig - 1];
1595
+ if (lastSig === ifParenClosedAt) return true;
1596
+ if (c !== void 0 && "=*/%&|,.:".includes(c)) return true;
1597
+ if ((c === "+" || c === "-") && prev !== c) return true;
1598
+ if (c === ">" && prev === "-") return true;
1599
+ if (/(?:^|[^A-Za-z0-9_])else$/.test(content.slice(Math.max(0, lastSig - 4), lastSig + 1))) return true;
1600
+ const rest = content.slice(nextLineFrom);
1601
+ const next = /^(?:[ \t\r]*(?:\/\/[^\n]*)?\n)*[ \t]*(\.|\?\.|\?:|&&|\|\||else\b|as\b|catch\b|finally\b)/.exec(rest);
1602
+ return next !== null;
1603
+ }
1604
+ function findKotlinEqualsBodyEndLine(content, lineIndex, startLine, lastLine) {
1605
+ const from = lineIndex[startLine - 1];
1606
+ if (from === void 0) return null;
1607
+ const to = lineIndex[lastLine] ?? content.length;
1608
+ let depth = 0;
1609
+ let seenEq = false;
1610
+ let line = startLine;
1611
+ let lastSig = -1;
1612
+ let ifParenClosedAt = -1;
1613
+ const ifParens = [];
1614
+ for (let i = from; i < to; i++) {
1615
+ const ch = content[i];
1616
+ if (ch === void 0) break;
1617
+ if (ch === "\n") {
1618
+ if (depth === 0) {
1619
+ if (!seenEq) return null;
1620
+ if (!kotlinBodyContinues(content, lastSig, ifParenClosedAt, i + 1)) return line;
1621
+ }
1622
+ line++;
1623
+ continue;
1624
+ }
1625
+ if (ch === " " || ch === " " || ch === "\r") continue;
1626
+ if (ch === "/" && content[i + 1] === "/") {
1627
+ while (i + 1 < to && content[i + 1] !== "\n") i++;
1628
+ continue;
1629
+ }
1630
+ if (ch === "/" && content[i + 1] === "*") {
1631
+ const end = content.indexOf("*/", i + 2);
1632
+ if (end === -1) return null;
1633
+ for (let k = i; k < end; k++) if (content[k] === "\n") line++;
1634
+ i = end + 1;
1635
+ continue;
1636
+ }
1637
+ const lit = skipKotlinLiteral(content, i, to);
1638
+ if (lit !== null) {
1639
+ for (let k = i; k < lit; k++) if (content[k] === "\n") line++;
1640
+ lastSig = lit - 1;
1641
+ i = lit - 1;
1642
+ continue;
1643
+ }
1644
+ lastSig = i;
1645
+ if (ch === "(" || ch === "[" || ch === "{") {
1646
+ if (ch === "{" && !seenEq && depth === 0) return null;
1647
+ ifParens.push(ch === "(" && /\bif\s*$/.test(content.slice(Math.max(from, i - 8), i)));
1648
+ depth++;
1649
+ } else if (ch === ")" || ch === "]" || ch === "}") {
1650
+ if (depth === 0) return null;
1651
+ depth--;
1652
+ if (ifParens.pop() === true) ifParenClosedAt = i;
1653
+ } else if (ch === "=" && !seenEq && depth === 0 && !"=!<>".includes(content[i - 1] ?? " ") && content[i + 1] !== "=") {
1654
+ seenEq = true;
1655
+ }
1656
+ }
1657
+ return seenEq && depth === 0 ? line : null;
1658
+ }
1311
1659
  function maskMultilineStrings(content, lang) {
1312
1660
  let state = null;
1313
1661
  const parts = [];
@@ -1337,6 +1685,8 @@ function findBlockOpenBrace(content, lineIndex, startLine, lastSearchLine, lineC
1337
1685
  const from = lineIndex[startLine - 1];
1338
1686
  if (from === void 0) return null;
1339
1687
  const to = lineIndex[lastSearchLine] ?? content.length;
1688
+ const interpolation = opts?.interpolation;
1689
+ let interpolated = false;
1340
1690
  let quote = null;
1341
1691
  let parenDepth = 0;
1342
1692
  let linesSeen = 0;
@@ -1346,6 +1696,13 @@ function findBlockOpenBrace(content, lineIndex, startLine, lastSearchLine, lineC
1346
1696
  const ch = content[i];
1347
1697
  if (ch === void 0) break;
1348
1698
  if (quote !== null) {
1699
+ if (interpolated && interpolation !== void 0) {
1700
+ const past = skipInterpolationAt(content, i, to, interpolation);
1701
+ if (past !== null) {
1702
+ i = past - 1;
1703
+ continue;
1704
+ }
1705
+ }
1349
1706
  if (verbatim) {
1350
1707
  if (ch === quote) {
1351
1708
  if (content[i + 1] === quote) {
@@ -1412,6 +1769,7 @@ function findBlockOpenBrace(content, lineIndex, startLine, lastSearchLine, lineC
1412
1769
  if (ch === '"' || ch === "'") {
1413
1770
  quote = ch;
1414
1771
  verbatim = stringEscapes === "csharp" && ch === '"' && opensCsharpVerbatimString(content, i);
1772
+ interpolated = interpolation !== void 0 && opensInterpolatedString(content, i, interpolation);
1415
1773
  continue;
1416
1774
  }
1417
1775
  if (ch === "(" || ch === "[") parenDepth++;
@@ -1976,7 +2334,7 @@ CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_path);
1976
2334
  CREATE INDEX IF NOT EXISTS idx_symbols_name_kind ON symbols(name, kind);
1977
2335
  CREATE INDEX IF NOT EXISTS idx_symbols_file_folded ON symbols(TG_LOWER(file_path));
1978
2336
  CREATE INDEX IF NOT EXISTS idx_symbols_file_name_folded ON symbols(TG_LOWER(file_path), name);
1979
- -- Partial index backing checkSymbolBodySize (cli_doctor.ts), which every SessionStart hook runs.
2337
+ -- Partial index backing checkSymbolBodySize (symbol_body_probe.ts), which every SessionStart hook runs.
1980
2338
  -- Its predicate cannot be served by any index above, so the check had to read the whole symbols
1981
2339
  -- table -- 226 MB / 231324 rows here, 229 ms per session start, and the early-exit LIMIT 1 never
1982
2340
  -- fires on a healthy index because there is nothing to find. Indexing the *violating* rows only
@@ -1984,7 +2342,7 @@ CREATE INDEX IF NOT EXISTS idx_symbols_file_name_folded ON symbols(TG_LOWER(file
1984
2342
  -- ms, 4 KB on disk, and no measurable insert cost (-0.2%, within noise, over 40000 real rows),
1985
2343
  -- because SQLite evaluates the predicate and skips the b-tree write for every row under the cap.
1986
2344
  -- SQLite uses a partial index only where the query's WHERE implies the index's, so the probe in
1987
- -- cli_doctor.ts spells its comparison the same way and against the same constant. That makes the
2345
+ -- symbol_body_probe.ts spells its comparison the same way and against the same constant. That makes the
1988
2346
  -- threshold part of the stored schema -- see SYMBOL_BODY_CHAR_CAP in constants.ts for what
1989
2347
  -- changing it requires. A query with a lower threshold correctly gets a full scan instead, so no
1990
2348
  -- other reader can be served stale rows by this index.
@@ -2080,7 +2438,11 @@ CREATE INDEX IF NOT EXISTS idx_cache_recall_type ON cache_recall(cache_type);
2080
2438
  -- picked and averaging fabrications into a measured rate is how 174 of bash_redirect's 698 rows
2081
2439
  -- came to hold its efficacy down to 0.86% when the observed figure was 1.15%. calls_remaining is
2082
2440
  -- the countdown of subsequent tool-use events still eligible to resolve this row before it is
2083
- -- considered timed out. displayed=0 marks a detection that never reached the agent -- auto-
2441
+ -- considered timed out. A displayed, observable row with resolved=0 is pending: nothing has
2442
+ -- scored it yet. Nothing sweeps these on a clock, so a session that ends mid-window leaves its
2443
+ -- rows pending for good, and efficacy and suppression count only resolved rows -- counting a
2444
+ -- pending one as not acted on is what muted bash_redirect at 1 in 11 when its scored rows stood
2445
+ -- at 1 in 6. displayed=0 marks a detection that never reached the agent -- auto-
2084
2446
  -- suppressed, or declined by a hint's own net-benefit gate -- recorded so the ledger can answer
2085
2447
  -- how often a hint fired at all, which it previously could not: a suppressed detection left no
2086
2448
  -- trace, so a fully-muted category was indistinguishable from one that had stopped triggering.
@@ -2523,6 +2885,18 @@ function openReadOnlyFallback(resolved, key, fallback, writeError) {
2523
2885
  }
2524
2886
  return conn;
2525
2887
  }
2888
+ function closeDb(dbPath) {
2889
+ const { key } = connectionKey(dbPath);
2890
+ for (const cache of [_connections, _readOnlyConnections]) {
2891
+ const conn = cache.get(key);
2892
+ if (conn === void 0) continue;
2893
+ try {
2894
+ conn.close();
2895
+ } catch {
2896
+ }
2897
+ cache.delete(key);
2898
+ }
2899
+ }
2526
2900
  function closeAllDbs() {
2527
2901
  for (const cache of [_connections, _readOnlyConnections]) {
2528
2902
  for (const conn of cache.values()) {
@@ -2596,5 +2970,6 @@ export {
2596
2970
  redactIfDotenv,
2597
2971
  allowReadOnlyIndex,
2598
2972
  isReadOnlyDb,
2599
- getDb
2973
+ getDb,
2974
+ closeDb
2600
2975
  };