token-goat 2.9.28 → 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 (134) hide show
  1. package/README.md +36 -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-66LODAUT.mjs → token-goat-chunk-4JJS54TR.mjs} +4 -3
  11. package/dist/token-goat-chunk-4LCCNRTG.mjs +313 -0
  12. package/dist/token-goat-chunk-54K3EUV3.mjs +35 -0
  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-NILVK7XM.mjs → token-goat-chunk-64FBPDTK.mjs} +12 -6
  19. package/dist/{token-goat-chunk-LEG3JNJ6.mjs → token-goat-chunk-664RTTUV.mjs} +31 -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-F7QZRIWM.mjs → token-goat-chunk-7F2UBPD3.mjs} +42 -35
  24. package/dist/{token-goat-chunk-CC2PYJM7.mjs → token-goat-chunk-7IN2MKDS.mjs} +718 -595
  25. package/dist/token-goat-chunk-7NADEDKJ.mjs +124 -0
  26. package/dist/{token-goat-chunk-6SGLIPQB.mjs → token-goat-chunk-A3CK6N5Z.mjs} +621 -72
  27. package/dist/{token-goat-chunk-HXNAC4ZF.mjs → token-goat-chunk-AFLYLHDH.mjs} +48 -33
  28. package/dist/token-goat-chunk-AM5V6GSX.mjs +367 -0
  29. package/dist/{token-goat-chunk-I7CB3X4K.mjs → token-goat-chunk-APGZXSPS.mjs} +44 -148
  30. package/dist/{token-goat-chunk-BJBRGPBX.mjs → token-goat-chunk-ARDNEC2U.mjs} +11 -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-QM76S6YS.mjs → token-goat-chunk-B45VMIIH.mjs} +6 -5
  34. package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
  35. package/dist/{token-goat-chunk-GGLEE35R.mjs → token-goat-chunk-C63JQV5K.mjs} +49 -10
  36. package/dist/{token-goat-chunk-RJH64KQH.mjs → token-goat-chunk-COBQGL5S.mjs} +2661 -2440
  37. package/dist/token-goat-chunk-COTXZHTS.mjs +39 -0
  38. package/dist/token-goat-chunk-CYCEYAEO.mjs +265 -0
  39. package/dist/token-goat-chunk-CZ3LUXYZ.mjs +4115 -0
  40. package/dist/token-goat-chunk-DZX2YDPT.mjs +15 -0
  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-6Z5ULNE5.mjs → token-goat-chunk-FBNQNSJK.mjs} +2490 -4957
  47. package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
  48. package/dist/{token-goat-chunk-XI2VFAV6.mjs → token-goat-chunk-FZ3NEW5O.mjs} +33 -19
  49. package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
  50. package/dist/{token-goat-chunk-VE27HPIF.mjs → token-goat-chunk-GFBSN7BD.mjs} +30 -398
  51. package/dist/{token-goat-chunk-L45ZQRT7.mjs → token-goat-chunk-GOLEOXZP.mjs} +780 -786
  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-CBMY2FGI.mjs → token-goat-chunk-HOJLCGDP.mjs} +17113 -15554
  57. package/dist/{token-goat-chunk-HUDC5GS5.mjs → token-goat-chunk-HYBFA5X3.mjs} +120 -19
  58. package/dist/token-goat-chunk-IVALLT3S.mjs +48 -0
  59. package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
  60. package/dist/{token-goat-chunk-UBUKHVYW.mjs → token-goat-chunk-IVKIZWAB.mjs} +3 -3
  61. package/dist/{token-goat-chunk-4JMWPWCS.mjs → token-goat-chunk-JB6QN6VF.mjs} +6 -4
  62. package/dist/{token-goat-chunk-Q4S3UQGO.mjs → token-goat-chunk-JDHE26RP.mjs} +10 -3
  63. package/dist/{token-goat-chunk-7R2XYKC5.mjs → token-goat-chunk-JDU3EXSU.mjs} +14 -10
  64. package/dist/token-goat-chunk-JDWCRD6M.mjs +253 -0
  65. package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-JN4XMLSD.mjs} +7 -4
  66. package/dist/token-goat-chunk-JTQQGXZH.mjs +733 -0
  67. package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
  68. package/dist/token-goat-chunk-KQNZDCBD.mjs +47 -0
  69. package/dist/{token-goat-chunk-4RN64ZND.mjs → token-goat-chunk-KWPNJBDH.mjs} +28 -3
  70. package/dist/token-goat-chunk-LOBGHXPB.mjs +242 -0
  71. package/dist/token-goat-chunk-MKPF4CL5.mjs +37 -0
  72. package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
  73. package/dist/{token-goat-chunk-YWSP6IU7.mjs → token-goat-chunk-N2NMER56.mjs} +25 -15
  74. package/dist/token-goat-chunk-NYKZLXMK.mjs +218 -0
  75. package/dist/token-goat-chunk-OJBNYTJP.mjs +3087 -0
  76. package/dist/token-goat-chunk-P4QMM4WK.mjs +295 -0
  77. package/dist/token-goat-chunk-PD5VKH46.mjs +184 -0
  78. package/dist/token-goat-chunk-PEPTHRFF.mjs +129 -0
  79. package/dist/{token-goat-chunk-VWZKZPSR.mjs → token-goat-chunk-PU7V3FD6.mjs} +8752 -11098
  80. package/dist/token-goat-chunk-PY533T7F.mjs +46 -0
  81. package/dist/token-goat-chunk-Q5VTGRH7.mjs +761 -0
  82. package/dist/{token-goat-chunk-IHKZ3QNA.mjs → token-goat-chunk-QCLDAQTS.mjs} +33 -19
  83. package/dist/{token-goat-chunk-LKSXAMJB.mjs → token-goat-chunk-QSBRTGM2.mjs} +9 -2
  84. package/dist/{token-goat-chunk-4STDIGYC.mjs → token-goat-chunk-RC35RBUL.mjs} +7 -5
  85. package/dist/{token-goat-chunk-D5ICEPSB.mjs → token-goat-chunk-RHXKCZX3.mjs} +887 -507
  86. package/dist/{token-goat-chunk-RSS3TLXU.mjs → token-goat-chunk-RZRTDST7.mjs} +17 -7
  87. package/dist/{token-goat-chunk-MAMQPC43.mjs → token-goat-chunk-SJHWVNDQ.mjs} +15 -21
  88. package/dist/token-goat-chunk-SMVRN2HU.mjs +188 -0
  89. package/dist/{token-goat-chunk-EL7M26WP.mjs → token-goat-chunk-SQSSNQPE.mjs} +2100 -1442
  90. package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-T4FK7VOV.mjs} +3 -3
  91. package/dist/token-goat-chunk-U4N3BN2W.mjs +92 -0
  92. package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
  93. package/dist/{token-goat-chunk-XKY4VKJ4.mjs → token-goat-chunk-UQ5UK2T7.mjs} +15 -4
  94. package/dist/token-goat-chunk-USILZ3T3.mjs +53 -0
  95. package/dist/token-goat-chunk-VES7EL7O.mjs +205 -0
  96. package/dist/{token-goat-chunk-M56BWPBN.mjs → token-goat-chunk-VL3YIFHZ.mjs} +550 -49
  97. package/dist/{token-goat-chunk-IZXKVT4A.mjs → token-goat-chunk-VPBBTSJR.mjs} +362 -128
  98. package/dist/{token-goat-chunk-F2ARFHLJ.mjs → token-goat-chunk-W3QCJS6G.mjs} +10 -2
  99. package/dist/{token-goat-chunk-FSTWAOW6.mjs → token-goat-chunk-WY3L4DVT.mjs} +11 -5
  100. package/dist/{token-goat-chunk-OSUFN2FV.mjs → token-goat-chunk-XB5KKOCG.mjs} +5 -25
  101. package/dist/token-goat-chunk-XKI4SEMX.mjs +66 -0
  102. package/dist/token-goat-chunk-XU4P6Z24.mjs +133 -0
  103. package/dist/{token-goat-chunk-6CCQDAYY.mjs → token-goat-chunk-Y776AENC.mjs} +138 -33
  104. package/dist/token-goat-chunk-YARZFCZS.mjs +359 -0
  105. package/dist/{token-goat-chunk-EEIDFMEM.mjs → token-goat-chunk-YZAAZU2S.mjs} +12 -3
  106. package/dist/{token-goat-chunk-E3K3BTEQ.mjs → token-goat-chunk-Z44YO3QZ.mjs} +12 -6
  107. package/dist/token-goat-chunk-Z57YODA2.mjs +35 -0
  108. package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-ZCDTCVIS.mjs} +49 -30
  109. package/dist/token-goat-chunk-ZEJVMUQH.mjs +48 -0
  110. package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
  111. package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
  112. package/dist/{token-goat-chunk-SJEKA7Y2.mjs → token-goat-chunk-ZQSJMO2R.mjs} +381 -201
  113. package/dist/token-goat-hook-client.cjs +539 -0
  114. package/dist/token-goat-hook-client.mjs +26 -0
  115. package/dist/token-goat-hook.mjs +48 -28
  116. package/dist/token-goat.core.mjs +10 -45
  117. package/docs/C4_RUNTIME_ARCHITECTURE.md +3 -3
  118. package/docs/cli.md +82 -47
  119. package/docs/install.md +58 -23
  120. package/docs/security.md +7 -7
  121. package/package.json +17 -7
  122. package/scripts/verify-native-dist.mjs +386 -0
  123. package/dist/token-goat-chunk-4JJBFT7V.mjs +0 -20
  124. package/dist/token-goat-chunk-5NNYIUGV.mjs +0 -143
  125. package/dist/token-goat-chunk-6DQNNFJ6.mjs +0 -294
  126. package/dist/token-goat-chunk-7MAFDRVR.mjs +0 -47
  127. package/dist/token-goat-chunk-BCN2YQC6.mjs +0 -32
  128. package/dist/token-goat-chunk-D7GHQKQD.mjs +0 -30
  129. package/dist/token-goat-chunk-GMOUBOX4.mjs +0 -386
  130. package/dist/token-goat-chunk-IFORDBGC.mjs +0 -192
  131. package/dist/token-goat-chunk-JXK2HQXS.mjs +0 -318
  132. package/dist/token-goat-chunk-L7SDVGBT.mjs +0 -430
  133. package/dist/token-goat-chunk-MMLMALWK.mjs +0 -1381
  134. package/dist/token-goat-chunk-MVSWBNMD.mjs +0 -1985
@@ -1,37 +1,42 @@
1
1
  import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ sanitizeFtsQuery
5
+ } from "./token-goat-chunk-HYBFA5X3.mjs";
3
6
  import {
4
7
  DEFAULT_MAX_AGE_MS,
5
8
  blobPath,
6
9
  isBlobStale,
7
10
  loadBlob,
8
11
  storeBlob
9
- } from "./token-goat-chunk-BJBRGPBX.mjs";
12
+ } from "./token-goat-chunk-ARDNEC2U.mjs";
10
13
  import {
11
- hasUnquotedOperator
12
- } from "./token-goat-chunk-4RN64ZND.mjs";
14
+ getDb
15
+ } from "./token-goat-chunk-VL3YIFHZ.mjs";
13
16
  import {
14
17
  redactSecrets
15
- } from "./token-goat-chunk-MVSWBNMD.mjs";
16
- import {
17
- sanitizeFtsQuery
18
- } from "./token-goat-chunk-HUDC5GS5.mjs";
19
- import {
20
- getDb
21
- } from "./token-goat-chunk-M56BWPBN.mjs";
18
+ } from "./token-goat-chunk-4FVIAHSI.mjs";
22
19
  import {
23
20
  shortFingerprint
24
- } from "./token-goat-chunk-CC2PYJM7.mjs";
21
+ } from "./token-goat-chunk-7IN2MKDS.mjs";
25
22
  import {
26
23
  registerReset
27
- } from "./token-goat-chunk-EEIDFMEM.mjs";
24
+ } from "./token-goat-chunk-YZAAZU2S.mjs";
28
25
  import {
29
- globalDbPath,
30
26
  runGit
31
- } from "./token-goat-chunk-L45ZQRT7.mjs";
27
+ } from "./token-goat-chunk-GOLEOXZP.mjs";
32
28
  import {
33
29
  normalizePath
34
- } from "./token-goat-chunk-NMTKNYGF.mjs";
30
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
31
+ import {
32
+ globalDbPath
33
+ } from "./token-goat-chunk-VES7EL7O.mjs";
34
+ import {
35
+ hasUnquotedOperator
36
+ } from "./token-goat-chunk-KWPNJBDH.mjs";
37
+ import {
38
+ stripAnsiEscapes
39
+ } from "./token-goat-chunk-HAVAOB3S.mjs";
35
40
  import {
36
41
  init_define_import_meta_env
37
42
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -138,7 +143,7 @@ var BUILD_COMMAND_PATTERNS = [
138
143
  /^\s*(?:gradle|\.\/gradlew|gradlew)\b/i,
139
144
  // Python / pip
140
145
  /^\s*pip\s+(install|freeze)\b/i,
141
- // npm audit / npm outdated — read-only reporting commands with no side effects, safe to cache/recall. Each resolves a `lockfile`-scoped fingerprint via bash_output_cache.ts's isNpmAuditCommand/isNpmOutdatedCommand, but that fingerprinting never actually ran outside their own unit tests until this entry, since neither subcommand was recognized by isBuildCommand (the generic cache-reachability gate in hooks_bash.ts). `npm install`/`npm ci`/`npm list`/`npm ls` are deliberately left out — see the negative-case test in lang_patterns.test.ts.
146
+ // npm audit / npm outdated — read-only reporting commands with no side effects, safe to cache/recall. Each resolves a `lockfile`-scoped fingerprint via bash_output_cache.ts's isNpmAuditCommand/isNpmOutdatedCommand, but that fingerprinting never actually ran outside their own unit tests until this entry, since neither subcommand was recognized by isBuildCommand (the generic cache-reachability gate in hooks_bash.ts and hooks_bash_post.ts). `npm install`/`npm ci`/`npm list`/`npm ls` are deliberately left out — see the negative-case test in lang_patterns.test.ts.
142
147
  /^\s*npm\s+(audit|outdated)\b/i,
143
148
  // Poetry
144
149
  /^\s*poetry\s+(install|update)\b/i,
@@ -223,6 +228,8 @@ var TEST_RUNNER_COMMAND_PATTERNS = [
223
228
  /^go test(?:\s|$)/i,
224
229
  // Rust / Cargo
225
230
  /^cargo test(?:\s|$)/i,
231
+ // dotnet test
232
+ /^\s*dotnet\s+test(?:\s|$)/i,
226
233
  // npm test / npm run test
227
234
  /^npm (?:test|run test)(?:\s|$)/i,
228
235
  // yarn test / yarn run test / pnpm test / pnpm run test
@@ -231,6 +238,20 @@ var TEST_RUNNER_COMMAND_PATTERNS = [
231
238
  function isTestRunnerCommand(cmd) {
232
239
  return TEST_RUNNER_COMMAND_PATTERNS.some((re) => re.test(cmd));
233
240
  }
241
+ var DEV_SERVER_COMMAND_PATTERNS = [
242
+ { pattern: /^(?:npx\s+)?next dev/, recallHint: '--tail 30 --grep "error|warn|ready|compiled"' },
243
+ { pattern: /^(?:npx\s+)?next build/, recallHint: '--grep "error|warn|Failed|\u2713"' },
244
+ // vite ends at whitespace or the end of the command, not at a word boundary, which a hyphen satisfies: vite-node is another tool, so it is neither recalled nor fingerprinted as a dev server.
245
+ { pattern: /^(?:npx\s+)?vite(?:\s|$)/, recallHint: '--tail 20 --grep "error|warn|ready"' },
246
+ // nuxt dev ends the same way: `nuxt devtools enable` is another nuxt command.
247
+ { pattern: /^(?:npx\s+)?nuxt dev(?:\s|$)/, recallHint: '--tail 30 --grep "error|warn|ready"' },
248
+ { pattern: /^(?:npx\s+)?remix dev/, recallHint: '--tail 20 --grep "error|warn|ready"' },
249
+ { pattern: /^(?:npx\s+)?astro dev/, recallHint: '--tail 20 --grep "error|warn|ready"' }
250
+ ];
251
+ function isDevServerCommand(cmd) {
252
+ const trimmed = cmd.trim();
253
+ return DEV_SERVER_COMMAND_PATTERNS.some(({ pattern }) => pattern.test(trimmed));
254
+ }
234
255
  var MONITORING_COMMAND_PATTERNS = [
235
256
  // GitHub CI
236
257
  { pattern: /^gh run (?:watch|view|list)/, recallHint: '--grep "fail|error|pass|\u2713|\u2717|conclusion"' },
@@ -240,16 +261,10 @@ var MONITORING_COMMAND_PATTERNS = [
240
261
  { pattern: /^gh pr list/, recallHint: '--grep "OPEN|DRAFT|MERGED|#"' },
241
262
  { pattern: /^gh issue view/, recallHint: '--grep "state|title|label|OPEN|CLOSED"' },
242
263
  { pattern: /^gh workflow (?:run|list|view)/, recallHint: '--grep "completed|failed|in_progress"' },
243
- // Dev servers (Next, Vite, Nuxt, Remix, Astro)
244
- { pattern: /^(?:npx\s+)?next dev/, recallHint: '--tail 30 --grep "error|warn|ready|compiled"' },
245
- { pattern: /^(?:npx\s+)?next build/, recallHint: '--grep "error|warn|Failed|\u2713"' },
246
- { pattern: /^(?:npx\s+)?vite\b(?:\s+dev|\s+build|\s+preview)?/, recallHint: '--tail 20 --grep "error|warn|ready"' },
247
- { pattern: /^(?:npx\s+)?nuxt dev/, recallHint: '--tail 30 --grep "error|warn|ready"' },
248
- { pattern: /^(?:npx\s+)?remix dev/, recallHint: '--tail 20 --grep "error|warn|ready"' },
249
- { pattern: /^(?:npx\s+)?astro dev/, recallHint: '--tail 20 --grep "error|warn|ready"' },
250
- // Test watchers
251
- { pattern: /^(?:npx\s+)?vitest(?:\s+run|\s+watch)?/, recallHint: '--grep "FAIL|PASS|Error|\u2713|\u2717"' },
252
- { pattern: /^(?:npx\s+)?jest(?:\s+--watch)?/, recallHint: '--grep "FAIL|PASS|Error|Tests:"' },
264
+ ...DEV_SERVER_COMMAND_PATTERNS,
265
+ // Test watchers. jest and vitest must be followed by whitespace or the end of the command, as in TEST_RUNNER_COMMAND_PATTERNS, not merely by a word boundary: a cached run goes stale only through the git fingerprint isTestRunnerCommand grants, and a longer name (jest-codemods, vitest-preview) is another tool that predicate rejects.
266
+ { pattern: /^(?:npx\s+)?vitest(?:\s|$)/, recallHint: '--grep "FAIL|PASS|Error|\u2713|\u2717"' },
267
+ { pattern: /^(?:npx\s+)?jest(?:\s|$)/, recallHint: '--grep "FAIL|PASS|Error|Tests:"' },
253
268
  { pattern: /^pytest(?:\s|$)/, recallHint: '--grep "FAILED|PASSED|ERROR|passed|failed"' },
254
269
  { pattern: /^(?:cargo\s+test|cargo\s+watch)/, recallHint: '--grep "FAILED|ok|error\\["' },
255
270
  { pattern: /^go test/, recallHint: '--grep "FAIL|ok|---"' },
@@ -266,7 +281,8 @@ var MONITORING_COMMAND_PATTERNS = [
266
281
  { pattern: /^(?:npx\s+)?prettier(?:\s|$)/, recallHint: '--grep "unchanged|reformatted|error"' },
267
282
  { pattern: /^npx\s+tsc(?:\s|$)/, recallHint: '--grep "error TS|Cannot find|Type "' },
268
283
  { pattern: /^ruff(?:\s|$)/, recallHint: '--grep "error|warning|Found"' },
269
- { pattern: /^(?:cargo\s+)?clippy/, recallHint: '--grep "error\\[|warning\\["' },
284
+ // Ends the same way: clippy-driver is clippy's rustc wrapper, run without cargo, so isBuildCommand gives it no fingerprint to go stale by.
285
+ { pattern: /^(?:cargo\s+)?clippy(?:\s|$)/, recallHint: '--grep "error\\[|warning\\["' },
270
286
  // git diff (full diff output — can be very large; excludes --stat which is small)
271
287
  { pattern: /^git diff(?!\s+--stat)(?:\s+HEAD)?(?:\s|$)/, recallHint: '--grep "@@|\\+\\+\\+|---|diff --git"' },
272
288
  { pattern: /^git diff\s+--cached(?!\s+--stat)/, recallHint: '--grep "@@|\\+\\+\\+|---|diff --git"' },
@@ -345,7 +361,8 @@ function indexRecallEntry(cacheType, id, label, content, storedAt) {
345
361
  label = excluded.label,
346
362
  content = excluded.content,
347
363
  stored_at = excluded.stored_at`
348
- ).run({ cacheType, id, label, content, storedAt });
364
+ // Stripped so a query spanning a colour boundary matches the text a reader sees; the cached blob itself stays raw.
365
+ ).run({ cacheType, id, label: stripAnsiEscapes(label), content: stripAnsiEscapes(content), storedAt });
349
366
  } catch {
350
367
  }
351
368
  pruneCacheRecallRows();
@@ -371,7 +388,7 @@ function hasFtsTable() {
371
388
  return _ftsAvailable;
372
389
  }
373
390
  function buildSnippet(content, query, maxLen = 160) {
374
- const flat = content.replace(/\s+/g, " ").trim();
391
+ const flat = stripAnsiEscapes(content).replace(/\s+/g, " ").trim();
375
392
  const tokens = query.split(/\s+/).filter(Boolean);
376
393
  let idx = -1;
377
394
  const lowerFlat = flat.toLowerCase();
@@ -489,7 +506,6 @@ var COMMAND_PATTERNS = {
489
506
  envProbe: /^\s*(?:node\s+(?:-v|--version)|npm\s+(?:-v|--version)|python3?\s+(?:(?:-V)\b|--?version)|git\s+--version|uv\s+--version|go\s+version|rustc\s+--version|cargo\s+--version|java\s+--version|ruby\s+--version|gem\s+--version|php\s+--version|which\b|where\b)/i,
490
507
  npx: /^(?!.*\b(?:install|add|remove|uninstall|i|rm|update|upgrade|set|get|publish|link|ci|audit|shrinkwrap|dedupe|prune|rebuild)\b)\s*npx\s+(?:--?yes\s+)?/i,
491
508
  gitPush: /^\s*git\s+push\b/i,
492
- testRunner: /^\s*(?:npx\s+)?(?:pytest|vitest|jest|go\s+test)\b/i,
493
509
  lintCommand: /^\s*(?:(?:npx\s+)?eslint|(?:uv\s+run\s+)?ruff)\b/i,
494
510
  npmRunScript: /^\s*npm\s+run(?:-script)?\b/i,
495
511
  catCommand: /^\s*cat\b/i
@@ -515,7 +531,6 @@ var isNpmInstallCommand = (cmd) => isCommandOfType(cmd, "npmInstall");
515
531
  var isNpmAuditCommand = (cmd) => isCommandOfType(cmd, "npmAudit");
516
532
  var isNpmOutdatedCommand = (cmd) => isCommandOfType(cmd, "npmOutdated");
517
533
  var isGitPushCommand = (cmd) => isCommandOfType(cmd, "gitPush");
518
- var isTestRunnerCommand2 = (cmd) => isCommandOfType(cmd, "testRunner");
519
534
  var isLintCommand = (cmd) => isCommandOfType(cmd, "lintCommand");
520
535
  var isNpmRunScriptCommand = (cmd) => isCommandOfType(cmd, "npmRunScript");
521
536
  var isCatCommand = (cmd) => isCommandOfType(cmd, "catCommand");
@@ -661,7 +676,7 @@ function bashOutputIdSync(command, output, cwd = null) {
661
676
  }
662
677
  function computeBashFingerprints(command, cwd) {
663
678
  const fingerprints = {};
664
- if (cwd && (isGitMutableCommand(command) || isGitPushCommand(command) || isTestRunnerCommand2(command) || isLintCommand(command) || isBuildCommand(command) || isNpmRunScriptCommand(command))) {
679
+ if (cwd && (isGitMutableCommand(command) || isGitPushCommand(command) || isTestRunnerCommand(command) || isLintCommand(command) || isBuildCommand(command) || isDevServerCommand(command) || isNpmRunScriptCommand(command))) {
665
680
  const fp = gitStateFingerprintSync(cwd);
666
681
  if (fp) fingerprints.git = fp;
667
682
  }
@@ -846,7 +861,7 @@ function getBashOutput(id) {
846
861
  }
847
862
  registerReset(() => {
848
863
  _byId = /* @__PURE__ */ new Map();
849
- });
864
+ }, { perRequest: true });
850
865
 
851
866
  export {
852
867
  isLockFile,
@@ -0,0 +1,367 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ MSYS_PATH_RE,
5
+ WSL_PATH_RE,
6
+ expandShortPath,
7
+ isUncOrDevicePath,
8
+ lowercaseDriveLetter,
9
+ normalizeDarwinSystemAlias
10
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
11
+ import {
12
+ init_define_import_meta_env
13
+ } from "./token-goat-chunk-A37V4PBF.mjs";
14
+
15
+ // src/path_containment.ts
16
+ init_define_import_meta_env();
17
+ import * as fs from "node:fs";
18
+ import * as path from "node:path";
19
+ function isCaseInsensitiveFs() {
20
+ const o = process.env["TOKEN_GOAT_CASE_INSENSITIVE_FS"];
21
+ if (o === "1") return true;
22
+ if (o === "0") return false;
23
+ return process.platform === "win32" || process.platform === "darwin";
24
+ }
25
+ function foldPath(p) {
26
+ return isCaseInsensitiveFs() ? foldCase(p) : p;
27
+ }
28
+ function isNodeModulesPath(p) {
29
+ const check = foldPath(p);
30
+ return check.includes("/node_modules/") || check.includes("\\node_modules\\");
31
+ }
32
+ function foldCase(s) {
33
+ return s.toLowerCase();
34
+ }
35
+ function foldCaseForContainment(s) {
36
+ return s.replace(/[A-Z]/g, (c) => c.toLowerCase());
37
+ }
38
+ function foldPathForContainment(p) {
39
+ return isCaseInsensitiveFs() ? foldCaseForContainment(p) : p;
40
+ }
41
+ var CYGWIN_PREFIX_RE = /^\/cygdrive\/([a-zA-Z])\/(.*)$/s;
42
+ function normalizeShellDrivePrefix(posixStr) {
43
+ let m = WSL_PATH_RE.exec(posixStr);
44
+ if (m) {
45
+ return `${m[1].toLowerCase()}:/${m[2]}`;
46
+ }
47
+ m = CYGWIN_PREFIX_RE.exec(posixStr);
48
+ if (m) {
49
+ return `${m[1].toLowerCase()}:/${m[2]}`;
50
+ }
51
+ m = MSYS_PATH_RE.exec(posixStr);
52
+ if (m) {
53
+ return `${m[1].toLowerCase()}:${m[2] ?? "/"}`;
54
+ }
55
+ return posixStr;
56
+ }
57
+ function canonicalize(inputPath, baseDir) {
58
+ const pathStr = typeof inputPath === "string" ? inputPath : inputPath.pathname;
59
+ const isWin32 = process.platform === "win32";
60
+ const base = baseDir ?? process.cwd();
61
+ const slashed = pathStr.replace(/\\/g, "/");
62
+ let pre = isWin32 ? normalizeShellDrivePrefix(slashed) : slashed;
63
+ if (pre !== slashed) {
64
+ pre = (isWin32 ? path.win32.resolve : path.resolve)(base, pre);
65
+ } else {
66
+ pre = (isWin32 ? path.win32.resolve : path.resolve)(base, pathStr);
67
+ }
68
+ let normalized = pre.replace(/\\/g, "/");
69
+ if (isWin32) {
70
+ normalized = normalizeShellDrivePrefix(normalized);
71
+ }
72
+ normalized = expandShortPath(normalized);
73
+ normalized = normalizeDarwinSystemAlias(normalized);
74
+ normalized = lowercaseDriveLetter(normalized);
75
+ return normalized;
76
+ }
77
+ var UNRESOLVABLE_PATH = "unresolvable-link-chain";
78
+ var MAX_LINK_HOPS = 40;
79
+ var MAX_RESOLVE_PATH_BYTES = 4096;
80
+ var MAX_WALK_SEGMENTS = MAX_RESOLVE_PATH_BYTES * (MAX_LINK_HOPS + 1);
81
+ function rootAndSegments(p) {
82
+ const parts = p.replace(/\\/g, "/").split("/");
83
+ const up = parts.indexOf("..");
84
+ const head = up === -1 ? parts.join("/") : parts.slice(0, up).join("/");
85
+ const canon = canonicalize(head === "" ? "." : head);
86
+ const m = /^(\/\/[^/]+\/[^/]+|[a-z]:\/|\/)/i.exec(canon);
87
+ const root = m === null ? "/" : m[1];
88
+ const rest = canon.slice(root.length).split("/");
89
+ return { root, segs: up === -1 ? rest : [...rest, ...parts.slice(up)] };
90
+ }
91
+ function joinSegment(base, seg) {
92
+ return base.endsWith("/") ? base + seg : `${base}/${seg}`;
93
+ }
94
+ function parentSegment(base, root) {
95
+ const cut = base.lastIndexOf("/");
96
+ return cut < root.length ? root : base.slice(0, cut);
97
+ }
98
+ var DRIVE_RELATIVE_PATH = /^[a-z]:(?![\\/])/i;
99
+ function linkTarget(link) {
100
+ const raw = link.replace(/\\/g, "/").replace(/^\/\/\?\/(UNC\/)?/i, (_m, unc) => unc === void 0 ? "" : "//");
101
+ if (!/^(\/\/[^/]+\/|[a-z]:\/|\/)/i.test(raw)) return { root: null, segs: raw.split("/") };
102
+ const abs = rootAndSegments(raw);
103
+ return { root: abs.root, segs: abs.segs };
104
+ }
105
+ function resolveThroughLinks(p) {
106
+ if (Buffer.byteLength(p, "utf8") > MAX_RESOLVE_PATH_BYTES) return UNRESOLVABLE_PATH;
107
+ const start = rootAndSegments(p);
108
+ let root = start.root;
109
+ let base = root;
110
+ const stack = start.segs.slice().reverse();
111
+ let hops = 0;
112
+ let walked = 0;
113
+ while (stack.length > 0) {
114
+ if (++walked > MAX_WALK_SEGMENTS) return UNRESOLVABLE_PATH;
115
+ const seg = stack.pop();
116
+ if (seg === "" || seg === ".") continue;
117
+ if (seg === "..") {
118
+ base = parentSegment(base, root);
119
+ continue;
120
+ }
121
+ const candidate = joinSegment(base, seg);
122
+ if (Buffer.byteLength(candidate, "utf8") > MAX_RESOLVE_PATH_BYTES) return UNRESOLVABLE_PATH;
123
+ let link = null;
124
+ try {
125
+ if (fs.lstatSync(candidate).isSymbolicLink()) link = fs.readlinkSync(candidate);
126
+ } catch (err) {
127
+ const code = err.code;
128
+ if (code !== "ENOENT" && code !== "ENOTDIR") return UNRESOLVABLE_PATH;
129
+ link = null;
130
+ }
131
+ if (link === null) {
132
+ base = candidate;
133
+ continue;
134
+ }
135
+ if (++hops > MAX_LINK_HOPS) return UNRESOLVABLE_PATH;
136
+ if (DRIVE_RELATIVE_PATH.test(link)) return UNRESOLVABLE_PATH;
137
+ const target = linkTarget(link);
138
+ if (target.root !== null) {
139
+ if (!isUncOrDevicePath(root) && isUncOrDevicePath(target.root)) return UNRESOLVABLE_PATH;
140
+ root = target.root;
141
+ base = target.root;
142
+ }
143
+ for (let i = target.segs.length - 1; i >= 0; i--) stack.push(target.segs[i]);
144
+ }
145
+ return base;
146
+ }
147
+ function normalizeForFs(p) {
148
+ return process.platform === "darwin" ? p.normalize("NFC") : p;
149
+ }
150
+ function escapesOntoNetworkThroughLinks(target, cwd) {
151
+ if (isUncOrDevicePath(target)) return true;
152
+ let absolute;
153
+ try {
154
+ absolute = path.resolve(cwd ?? process.cwd(), target);
155
+ } catch {
156
+ return true;
157
+ }
158
+ if (isUncOrDevicePath(absolute)) return true;
159
+ const resolved = resolveThroughLinks(absolute);
160
+ return resolved === UNRESOLVABLE_PATH || isUncOrDevicePath(resolved);
161
+ }
162
+ function isInsideRoot(target, root) {
163
+ if (reachesForeignShare(target, root)) return false;
164
+ const rt = resolveThroughLinks(target);
165
+ const rr = resolveThroughLinks(root);
166
+ if (rt === UNRESOLVABLE_PATH || rr === UNRESOLVABLE_PATH) return false;
167
+ const nt = normalizeForFs(rt);
168
+ const nr = normalizeForFs(rr);
169
+ const t = foldPathForContainment(nt);
170
+ const r = foldPathForContainment(nr);
171
+ if (t !== r && !t.startsWith(r.endsWith("/") ? r : r + "/")) return false;
172
+ if (nt.slice(0, nr.length) === nr) return true;
173
+ return sameDirectory(nt.slice(0, nr.length), nr);
174
+ }
175
+ function isNetworkPath(p, platform = process.platform) {
176
+ return networkShareRoot(p, platform) !== null;
177
+ }
178
+ function networkShareRoot(p, platform = process.platform) {
179
+ if (platform !== "win32") return null;
180
+ const device = /^[\\/]{2}([?.][\\/])?/.exec(p);
181
+ if (device === null) return null;
182
+ let rest = p.slice(device[0].length);
183
+ if (device[1] !== void 0) {
184
+ const unc = /^UNC[\\/]/i.exec(rest);
185
+ if (unc === null) return null;
186
+ rest = rest.slice(unc[0].length);
187
+ }
188
+ const [host = "", share = ""] = rest.split(/[\\/]/);
189
+ return `//${foldCase(host)}/${foldCase(share)}`;
190
+ }
191
+ function reachesForeignShare(target, root, platform = process.platform) {
192
+ const share = networkShareRoot(target, platform);
193
+ return share !== null && share !== networkShareRoot(root, platform);
194
+ }
195
+ function sameDirectory(a, b, platform = process.platform) {
196
+ if (isNetworkPath(a, platform) || isNetworkPath(b, platform)) return false;
197
+ let canonicalRoot;
198
+ try {
199
+ canonicalRoot = fs.realpathSync.native(b);
200
+ } catch {
201
+ return true;
202
+ }
203
+ try {
204
+ return fs.realpathSync.native(a) === canonicalRoot;
205
+ } catch {
206
+ return false;
207
+ }
208
+ }
209
+
210
+ // src/process_util.ts
211
+ init_define_import_meta_env();
212
+ import { spawnSync } from "node:child_process";
213
+ import { existsSync, realpathSync as realpathSync2, statSync } from "node:fs";
214
+ import * as path2 from "node:path";
215
+ function sleepSync(ms) {
216
+ if (ms <= 0) return;
217
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
218
+ }
219
+ function isWindows() {
220
+ return process.platform === "win32";
221
+ }
222
+ function windowsCmdQuoteArg(arg) {
223
+ if (arg === "") return '""';
224
+ if (arg[0] === '"' && arg[arg.length - 1] === '"') {
225
+ throw new Error(`windowsCmdQuoteArg: cannot faithfully encode an argument that both starts and ends with a literal double quote for cmd.exe: ${JSON.stringify(arg)}`);
226
+ }
227
+ let out = "";
228
+ let inQuote = false;
229
+ let backslashes = 0;
230
+ const flushBackslashesPlain = () => {
231
+ if (backslashes > 0) {
232
+ out += "\\".repeat(backslashes);
233
+ backslashes = 0;
234
+ }
235
+ };
236
+ const flushBackslashesDoubled = () => {
237
+ out += "\\".repeat(backslashes * 2);
238
+ backslashes = 0;
239
+ };
240
+ const ensureQuoteOpen = () => {
241
+ if (!inQuote) {
242
+ flushBackslashesDoubled();
243
+ out += '"';
244
+ inQuote = true;
245
+ } else {
246
+ flushBackslashesPlain();
247
+ }
248
+ };
249
+ const ensureQuoteClosed = () => {
250
+ if (inQuote) {
251
+ flushBackslashesDoubled();
252
+ out += '"';
253
+ inQuote = false;
254
+ } else {
255
+ flushBackslashesPlain();
256
+ }
257
+ };
258
+ for (const ch of arg) {
259
+ if (ch === "\\") {
260
+ backslashes++;
261
+ continue;
262
+ }
263
+ if (ch === '"') {
264
+ flushBackslashesDoubled();
265
+ if (inQuote) {
266
+ out += '"';
267
+ inQuote = false;
268
+ }
269
+ out += '\\^"';
270
+ continue;
271
+ }
272
+ if (ch === "%" || ch === "!") {
273
+ ensureQuoteClosed();
274
+ out += `^${ch}`;
275
+ continue;
276
+ }
277
+ ensureQuoteOpen();
278
+ out += ch;
279
+ }
280
+ ensureQuoteClosed();
281
+ return out;
282
+ }
283
+ function quoteShellPath(value) {
284
+ if (process.platform === "win32") return `"${value}"`;
285
+ return `"${value.replace(/[\\$`"]/g, "\\$&")}"`;
286
+ }
287
+ function quotePosixShellWord(value) {
288
+ return `'${value.replace(/'/g, "'\\''")}'`;
289
+ }
290
+ function quotePowershellPath(value) {
291
+ return `'${value.replace(/'/g, "''")}'`;
292
+ }
293
+ var POWERSHELL_EXIT_SUFFIX = "; if (Get-Variable LASTEXITCODE -ErrorAction Ignore) { exit (Get-Variable LASTEXITCODE -ValueOnly) }; exit 1";
294
+ function powershellHookLine(call) {
295
+ return `& ${call}${POWERSHELL_EXIT_SUFFIX}`;
296
+ }
297
+ function resolveOnPath(label) {
298
+ if (path2.isAbsolute(label)) return existsSync(label) ? label : null;
299
+ if (label.includes("/") || label.includes("\\")) return null;
300
+ const onWindows = process.platform === "win32";
301
+ const exts = onWindows ? (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").split(";").filter((e) => e.trim() !== "") : [""];
302
+ let cwd;
303
+ try {
304
+ cwd = realpathSync2(process.cwd());
305
+ } catch {
306
+ cwd = path2.resolve(process.cwd());
307
+ }
308
+ for (const rawDir of (process.env["PATH"] ?? "").split(path2.delimiter)) {
309
+ const dir = rawDir.trim().replace(/^"|"$/g, "");
310
+ if (dir === "" || dir === ".") continue;
311
+ let resolvedDir;
312
+ try {
313
+ resolvedDir = realpathSync2(path2.resolve(dir));
314
+ } catch {
315
+ continue;
316
+ }
317
+ if (foldPath(resolvedDir) === foldPath(cwd)) continue;
318
+ for (const ext of exts) {
319
+ const candidate = path2.join(resolvedDir, label + ext);
320
+ try {
321
+ if (statSync(candidate).isFile()) return candidate;
322
+ } catch {
323
+ }
324
+ }
325
+ }
326
+ return null;
327
+ }
328
+ function spawnResolvedSync(resolved, args, options) {
329
+ if (!isWindows() || !/\.(?:cmd|bat)$/i.test(resolved)) return spawnSync(resolved, args, options);
330
+ const comspec = path2.join(process.env["SystemRoot"] ?? process.env["windir"] ?? "C:\\Windows", "System32", "cmd.exe");
331
+ const line = [resolved, ...args].map(windowsCmdQuoteArg).join(" ");
332
+ return spawnSync(existsSync(comspec) ? comspec : "cmd.exe", ["/d", "/s", "/c", `"${line}"`], { ...options, windowsVerbatimArguments: true });
333
+ }
334
+ function installEpipeGuard(streams) {
335
+ const targets = (streams ?? [process.stdout, process.stderr]).filter((s) => s !== void 0);
336
+ for (const stream of targets) {
337
+ stream.on("error", (err) => {
338
+ if (err.code === "EPIPE") {
339
+ process.exitCode = 0;
340
+ return;
341
+ }
342
+ throw err;
343
+ });
344
+ }
345
+ return targets;
346
+ }
347
+
348
+ export {
349
+ isCaseInsensitiveFs,
350
+ foldPath,
351
+ isNodeModulesPath,
352
+ foldCase,
353
+ foldCaseForContainment,
354
+ foldPathForContainment,
355
+ canonicalize,
356
+ escapesOntoNetworkThroughLinks,
357
+ isInsideRoot,
358
+ sleepSync,
359
+ isWindows,
360
+ quoteShellPath,
361
+ quotePosixShellWord,
362
+ quotePowershellPath,
363
+ powershellHookLine,
364
+ resolveOnPath,
365
+ spawnResolvedSync,
366
+ installEpipeGuard
367
+ };