token-goat 2.9.29 → 2.9.31

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 (197) hide show
  1. package/README.md +53 -42
  2. package/SECURITY.md +37 -11
  3. package/THIRD_PARTY_NOTICES.md +41 -4
  4. package/dist/native/linux-arm64/tg-hook +0 -0
  5. package/dist/native/linux-x64/tg-hook +0 -0
  6. package/dist/native/win32-arm64/tg-hook.exe +0 -0
  7. package/dist/native/win32-x64/tg-hook.exe +0 -0
  8. package/dist/ort-wasm-simd-threaded.mjs +59 -0
  9. package/dist/{token-goat-chunk-SE6E4BKJ.mjs → token-goat-chunk-25TRAWET.mjs} +23 -6
  10. package/dist/token-goat-chunk-2KXO6V2B.mjs +203 -0
  11. package/dist/{token-goat-chunk-UXSXQQIY.mjs → token-goat-chunk-2M7E4PF7.mjs} +43 -14
  12. package/dist/token-goat-chunk-2UPZGKKY.mjs +188 -0
  13. package/dist/token-goat-chunk-2WLPWKHV.mjs +135 -0
  14. package/dist/token-goat-chunk-2XBMMDBD.mjs +126 -0
  15. package/dist/token-goat-chunk-32ZOY4N5.mjs +23 -0
  16. package/dist/token-goat-chunk-3EZRNKTK.mjs +188 -0
  17. package/dist/token-goat-chunk-4ADZHI7J.mjs +63 -0
  18. package/dist/token-goat-chunk-4GBVPH3D.mjs +242 -0
  19. package/dist/{token-goat-chunk-2WOUYWLM.mjs → token-goat-chunk-4GILLLWY.mjs} +34 -7
  20. package/dist/token-goat-chunk-4NAPX7BA.mjs +90 -0
  21. package/dist/{token-goat-chunk-NMBWLRHW.mjs → token-goat-chunk-4SC7UJYV.mjs} +9981 -11563
  22. package/dist/token-goat-chunk-4SMRO4TO.mjs +366 -0
  23. package/dist/{token-goat-chunk-O6I2XU4P.mjs → token-goat-chunk-4ZBFWLXF.mjs} +310 -441
  24. package/dist/token-goat-chunk-57BIAXJL.mjs +286 -0
  25. package/dist/token-goat-chunk-5AC66HNP.mjs +115 -0
  26. package/dist/token-goat-chunk-5IMLKSOP.mjs +145 -0
  27. package/dist/token-goat-chunk-5RG5SBL6.mjs +221 -0
  28. package/dist/{token-goat-chunk-RRNZMM3A.mjs → token-goat-chunk-5Y6ZYL6U.mjs} +21 -2
  29. package/dist/token-goat-chunk-646E6U44.mjs +398 -0
  30. package/dist/token-goat-chunk-65N4RHP4.mjs +33 -0
  31. package/dist/{token-goat-chunk-6AK46ZT7.mjs → token-goat-chunk-6DG6HWP3.mjs} +13 -3
  32. package/dist/token-goat-chunk-6ENQSNRZ.mjs +573 -0
  33. package/dist/token-goat-chunk-6ZY4GNF2.mjs +91 -0
  34. package/dist/{token-goat-chunk-E5TK5DNO.mjs → token-goat-chunk-76FGDLRO.mjs} +574 -340
  35. package/dist/{token-goat-chunk-TGOXNAHW.mjs → token-goat-chunk-7EZTZOMC.mjs} +780 -767
  36. package/dist/token-goat-chunk-7MAOA6X4.mjs +3647 -0
  37. package/dist/token-goat-chunk-7R2ZVVAX.mjs +218 -0
  38. package/dist/{token-goat-chunk-TCQANXYC.mjs → token-goat-chunk-AM5V6GSX.mjs} +18 -2
  39. package/dist/token-goat-chunk-AUNGYYQX.mjs +184 -0
  40. package/dist/token-goat-chunk-AUQYRMMH.mjs +2985 -0
  41. package/dist/token-goat-chunk-B3PEKBYG.mjs +128 -0
  42. package/dist/{token-goat-chunk-KOPIR3KZ.mjs → token-goat-chunk-BA4HI6BW.mjs} +1910 -165
  43. package/dist/{token-goat-chunk-52NSDWYY.mjs → token-goat-chunk-BFCWY73P.mjs} +58 -20
  44. package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
  45. package/dist/token-goat-chunk-BWGFUZZE.mjs +25 -0
  46. package/dist/token-goat-chunk-C75NA7PL.mjs +322 -0
  47. package/dist/token-goat-chunk-CBIQ7WTD.mjs +87 -0
  48. package/dist/token-goat-chunk-CETM74KC.mjs +307 -0
  49. package/dist/token-goat-chunk-CIMQ2BB3.mjs +233 -0
  50. package/dist/{token-goat-chunk-DNSPXQXQ.mjs → token-goat-chunk-CJLS3CDL.mjs} +70 -18
  51. package/dist/{token-goat-chunk-MELOKFDJ.mjs → token-goat-chunk-CO3UYX6G.mjs} +7 -1
  52. package/dist/token-goat-chunk-COPNXRJM.mjs +154 -0
  53. package/dist/token-goat-chunk-CSJ5L3NL.mjs +479 -0
  54. package/dist/token-goat-chunk-CVCEVUGK.mjs +315 -0
  55. package/dist/token-goat-chunk-CXHOFN7R.mjs +371 -0
  56. package/dist/token-goat-chunk-D735C4QM.mjs +603 -0
  57. package/dist/{token-goat-chunk-E4ZOJIZK.mjs → token-goat-chunk-DGS2LVNA.mjs} +70 -160
  58. package/dist/{token-goat-chunk-L7H3U27L.mjs → token-goat-chunk-DOWRSMWO.mjs} +1 -1
  59. package/dist/token-goat-chunk-E45INMY3.mjs +71 -0
  60. package/dist/token-goat-chunk-EC5F37F4.mjs +244 -0
  61. package/dist/{token-goat-chunk-XTQAOTSO.mjs → token-goat-chunk-EDBDRVH5.mjs} +4 -1
  62. package/dist/token-goat-chunk-EELTBKDM.mjs +613 -0
  63. package/dist/token-goat-chunk-EVMZJ27Z.mjs +147 -0
  64. package/dist/token-goat-chunk-EXKGNHEG.mjs +2096 -0
  65. package/dist/{token-goat-chunk-YOOVFPTP.mjs → token-goat-chunk-F4HYL64R.mjs} +12 -2
  66. package/dist/token-goat-chunk-F6PAUIEK.mjs +624 -0
  67. package/dist/token-goat-chunk-FDSREWLX.mjs +692 -0
  68. package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
  69. package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
  70. package/dist/token-goat-chunk-GGGG7RWB.mjs +236 -0
  71. package/dist/{token-goat-chunk-TDUT2CL6.mjs → token-goat-chunk-GL3ETKSC.mjs} +276 -19
  72. package/dist/{token-goat-chunk-7CPMDFGB.mjs → token-goat-chunk-GVB2MUST.mjs} +265 -1567
  73. package/dist/token-goat-chunk-GWFLAUMQ.mjs +307 -0
  74. package/dist/token-goat-chunk-HAVAOB3S.mjs +87 -0
  75. package/dist/token-goat-chunk-HLPW63A7.mjs +48 -0
  76. package/dist/token-goat-chunk-HU4TORC5.mjs +1377 -0
  77. package/dist/token-goat-chunk-I7VKZZAW.mjs +35 -0
  78. package/dist/token-goat-chunk-IA6XSPE3.mjs +218 -0
  79. package/dist/token-goat-chunk-IAGXMHIK.mjs +863 -0
  80. package/dist/{token-goat-chunk-435UQTKD.mjs → token-goat-chunk-IK2DRMFX.mjs} +129 -74
  81. package/dist/{token-goat-chunk-ZER6EAXZ.mjs → token-goat-chunk-INNPTRUX.mjs} +2954 -2783
  82. package/dist/token-goat-chunk-JJ5BX4F4.mjs +129 -0
  83. package/dist/token-goat-chunk-JVFSHVFJ.mjs +129 -0
  84. package/dist/token-goat-chunk-KGEFFSHD.mjs +50 -0
  85. package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
  86. package/dist/token-goat-chunk-KQBLRPBN.mjs +433 -0
  87. package/dist/token-goat-chunk-LCNQ2CNN.mjs +497 -0
  88. package/dist/token-goat-chunk-M3LFJDPU.mjs +58 -0
  89. package/dist/token-goat-chunk-M52KPT3C.mjs +87 -0
  90. package/dist/token-goat-chunk-MBEG42H7.mjs +150 -0
  91. package/dist/{token-goat-chunk-EVC4TOLE.mjs → token-goat-chunk-METECDOH.mjs} +3 -12
  92. package/dist/{token-goat-chunk-2AWQ2R5X.mjs → token-goat-chunk-MHX7XCC3.mjs} +3 -2
  93. package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
  94. package/dist/token-goat-chunk-N5LSOVSU.mjs +137 -0
  95. package/dist/{token-goat-chunk-DPNLUJWB.mjs → token-goat-chunk-N5MMR2IW.mjs} +30 -8
  96. package/dist/token-goat-chunk-N7B3JQ2C.mjs +160 -0
  97. package/dist/{token-goat-chunk-VMFWNHGR.mjs → token-goat-chunk-NISNMD7T.mjs} +2545 -2953
  98. package/dist/token-goat-chunk-NMD42SFQ.mjs +434 -0
  99. package/dist/token-goat-chunk-NOSS5VWY.mjs +174 -0
  100. package/dist/token-goat-chunk-NSNSPPBG.mjs +69 -0
  101. package/dist/token-goat-chunk-OBOFIHKN.mjs +38 -0
  102. package/dist/token-goat-chunk-OBRFJ5O5.mjs +76 -0
  103. package/dist/token-goat-chunk-ODBT2USM.mjs +800 -0
  104. package/dist/token-goat-chunk-OS5EM5PP.mjs +107 -0
  105. package/dist/token-goat-chunk-OUKDTVNU.mjs +1178 -0
  106. package/dist/token-goat-chunk-OXFMP75N.mjs +566 -0
  107. package/dist/{token-goat-chunk-ASLWOQ3I.mjs → token-goat-chunk-OYIYKDDT.mjs} +2 -1
  108. package/dist/{token-goat-chunk-67BNIKKO.mjs → token-goat-chunk-P6HQSWQ3.mjs} +55 -47
  109. package/dist/token-goat-chunk-P6VGNTQT.mjs +71 -0
  110. package/dist/token-goat-chunk-PFWIMH2E.mjs +261 -0
  111. package/dist/token-goat-chunk-PJZXIS3G.mjs +39 -0
  112. package/dist/token-goat-chunk-PUO5INXP.mjs +606 -0
  113. package/dist/token-goat-chunk-PX5PQWTY.mjs +462 -0
  114. package/dist/token-goat-chunk-Q5QDBC6O.mjs +111 -0
  115. package/dist/token-goat-chunk-QFNQXSDT.mjs +40 -0
  116. package/dist/token-goat-chunk-QH7YVYOY.mjs +3957 -0
  117. package/dist/token-goat-chunk-QLMUHEPB.mjs +43 -0
  118. package/dist/{token-goat-chunk-PYSUADX4.mjs → token-goat-chunk-QQOJIHL3.mjs} +50 -14
  119. package/dist/token-goat-chunk-QQTWJY2O.mjs +85 -0
  120. package/dist/token-goat-chunk-QYHO5CPH.mjs +93 -0
  121. package/dist/token-goat-chunk-RELAVWAD.mjs +27 -0
  122. package/dist/token-goat-chunk-RSLPOBKQ.mjs +339 -0
  123. package/dist/token-goat-chunk-SAMFDIS2.mjs +712 -0
  124. package/dist/token-goat-chunk-SDELXLDM.mjs +48 -0
  125. package/dist/{token-goat-chunk-PGTH2U4C.mjs → token-goat-chunk-SOAFZNNZ.mjs} +164 -40
  126. package/dist/{token-goat-chunk-G23DWHV4.mjs → token-goat-chunk-SRTHT7KV.mjs} +33 -15
  127. package/dist/token-goat-chunk-T5P5ACNQ.mjs +212 -0
  128. package/dist/token-goat-chunk-T5YGG4V3.mjs +45 -0
  129. package/dist/token-goat-chunk-TAUZ4OFS.mjs +110 -0
  130. package/dist/token-goat-chunk-TM6MC754.mjs +40 -0
  131. package/dist/token-goat-chunk-TWUKBOMP.mjs +72 -0
  132. package/dist/token-goat-chunk-U2KSB4SG.mjs +56 -0
  133. package/dist/token-goat-chunk-U4WHMG6Y.mjs +898 -0
  134. package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
  135. package/dist/token-goat-chunk-UGJHGR5A.mjs +52 -0
  136. package/dist/{token-goat-chunk-RQGGMPCR.mjs → token-goat-chunk-UOUDVA5U.mjs} +76 -16
  137. package/dist/{token-goat-chunk-HNFZZHFW.mjs → token-goat-chunk-URRJ33GR.mjs} +22 -4
  138. package/dist/token-goat-chunk-UZOROKIS.mjs +165 -0
  139. package/dist/token-goat-chunk-VIHGGGEI.mjs +4234 -0
  140. package/dist/token-goat-chunk-VTJLAA7P.mjs +21 -0
  141. package/dist/token-goat-chunk-VWDXLT4F.mjs +678 -0
  142. package/dist/token-goat-chunk-VWZA2H4P.mjs +368 -0
  143. package/dist/{token-goat-chunk-QO3LXVVR.mjs → token-goat-chunk-VXEXMJDL.mjs} +2964 -3153
  144. package/dist/token-goat-chunk-WBA5SKT4.mjs +547 -0
  145. package/dist/{token-goat-chunk-ONXH6NZ5.mjs → token-goat-chunk-WDH44VAU.mjs} +19 -22
  146. package/dist/token-goat-chunk-X2SUP3EI.mjs +107 -0
  147. package/dist/token-goat-chunk-X3BELZSJ.mjs +125 -0
  148. package/dist/{token-goat-chunk-RLP6J7WR.mjs → token-goat-chunk-XLRBNZCC.mjs} +40 -21
  149. package/dist/{token-goat-chunk-S4VSXURL.mjs → token-goat-chunk-XRKUX6CM.mjs} +4 -0
  150. package/dist/token-goat-chunk-XX6O25RN.mjs +82 -0
  151. package/dist/token-goat-chunk-XZSUHBVS.mjs +65 -0
  152. package/dist/token-goat-chunk-Y2ZTQOCL.mjs +35 -0
  153. package/dist/{token-goat-chunk-UA5BKWWQ.mjs → token-goat-chunk-YB4VMGK2.mjs} +15 -4
  154. package/dist/token-goat-chunk-YBIIY3HR.mjs +51 -0
  155. package/dist/{token-goat-chunk-PKRWMHVP.mjs → token-goat-chunk-YHVDKQBR.mjs} +389 -221
  156. package/dist/token-goat-chunk-YJB5XLWI.mjs +26 -0
  157. package/dist/{token-goat-chunk-PQ53BSCF.mjs → token-goat-chunk-YKB6AQG3.mjs} +53 -31
  158. package/dist/token-goat-chunk-YMTG2YA5.mjs +35 -0
  159. package/dist/token-goat-chunk-YPBZYQRV.mjs +40 -0
  160. package/dist/{token-goat-chunk-HUYUHODZ.mjs → token-goat-chunk-YY6AVUFL.mjs} +13246 -12247
  161. package/dist/token-goat-chunk-Z7N5OMMP.mjs +98 -0
  162. package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
  163. package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
  164. package/dist/token-goat-chunk-ZNMNUPAZ.mjs +938 -0
  165. package/dist/token-goat-hook-client.cjs +87 -23
  166. package/dist/token-goat-hook-client.mjs +3 -3
  167. package/dist/token-goat-hook.mjs +76 -31
  168. package/dist/token-goat.core.mjs +6 -6
  169. package/docs/C4_RUNTIME_ARCHITECTURE.md +2 -2
  170. package/docs/cli.md +113 -60
  171. package/docs/install.md +63 -20
  172. package/docs/security.md +10 -8
  173. package/package.json +18 -7
  174. package/scripts/verify-native-dist.mjs +386 -0
  175. package/dist/token-goat-chunk-2NNUA2LR.mjs +0 -143
  176. package/dist/token-goat-chunk-44BM7DDQ.mjs +0 -294
  177. package/dist/token-goat-chunk-BGYOZ6DO.mjs +0 -24
  178. package/dist/token-goat-chunk-C5YPNZKQ.mjs +0 -318
  179. package/dist/token-goat-chunk-CIQ2FTY3.mjs +0 -1990
  180. package/dist/token-goat-chunk-D4ETHJD6.mjs +0 -246
  181. package/dist/token-goat-chunk-DNRPXHYH.mjs +0 -1062
  182. package/dist/token-goat-chunk-EUSDXRXU.mjs +0 -1429
  183. package/dist/token-goat-chunk-FTP4U4QA.mjs +0 -64
  184. package/dist/token-goat-chunk-G7IWXCFF.mjs +0 -456
  185. package/dist/token-goat-chunk-GLXRTTLE.mjs +0 -36
  186. package/dist/token-goat-chunk-H5J3C56Q.mjs +0 -1511
  187. package/dist/token-goat-chunk-IVWI2OCK.mjs +0 -368
  188. package/dist/token-goat-chunk-JTKCQMQA.mjs +0 -418
  189. package/dist/token-goat-chunk-LZNBQTDK.mjs +0 -26
  190. package/dist/token-goat-chunk-ORNFMIER.mjs +0 -295
  191. package/dist/token-goat-chunk-RTMVLHWX.mjs +0 -7113
  192. package/dist/token-goat-chunk-VQ6F6T7X.mjs +0 -36
  193. package/dist/token-goat-chunk-VZQEWRVH.mjs +0 -312
  194. package/dist/token-goat-chunk-XYWPOSCN.mjs +0 -807
  195. package/dist/token-goat-chunk-YAGLESS3.mjs +0 -23
  196. package/dist/token-goat-chunk-YKSRAWUU.mjs +0 -33
  197. package/dist/token-goat-chunk-Z6KBMOBI.mjs +0 -53
@@ -1,13 +1,22 @@
1
1
  import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
3
  import {
4
+ forClient
5
+ } from "./token-goat-chunk-KGEFFSHD.mjs";
6
+ import {
7
+ GUARD_UNITS_PER_TOKEN,
8
+ TEXT_GUARD_UNITS,
4
9
  classifyContent,
5
10
  guardDivisor,
11
+ guardTokens,
12
+ guardUnits
13
+ } from "./token-goat-chunk-XX6O25RN.mjs";
14
+ import {
6
15
  stripAnsiEscapes
7
- } from "./token-goat-chunk-CIQ2FTY3.mjs";
16
+ } from "./token-goat-chunk-HAVAOB3S.mjs";
8
17
  import {
9
18
  safeSlice
10
- } from "./token-goat-chunk-XYWPOSCN.mjs";
19
+ } from "./token-goat-chunk-HU4TORC5.mjs";
11
20
  import {
12
21
  init_define_import_meta_env
13
22
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -19,50 +28,77 @@ function estimateTokensFromLength(length, cls = "text") {
19
28
  }
20
29
  function estimateTokens(text) {
21
30
  const stripped = stripAnsiEscapes(text);
22
- return estimateTokensFromLength(stripped.length, classifyContent(stripped));
31
+ return Math.max(1, Math.floor(guardTokens(stripped, classifyContent(stripped) === "dense")) + 1);
32
+ }
33
+ function sliceToGuardTokens(text, tokens, dense) {
34
+ let used = 0;
35
+ let end = 0;
36
+ for (const ch of text) {
37
+ used += guardTokens(ch, dense);
38
+ if (used > tokens) break;
39
+ end += ch.length;
40
+ }
41
+ return safeSlice(text, end);
23
42
  }
24
- function trimToBudget(text, budgetTokens, command) {
43
+ function sliceToEstimatedTokens(text, maxTokens) {
44
+ if (estimateTokens(text) <= maxTokens) return text;
45
+ let lo = 0;
46
+ let hi = text.length;
47
+ while (lo < hi) {
48
+ const mid = Math.ceil((lo + hi) / 2);
49
+ if (estimateTokens(safeSlice(text, mid)) <= maxTokens) lo = mid;
50
+ else hi = mid - 1;
51
+ }
52
+ return safeSlice(text, lo);
53
+ }
54
+ var CAP_MARKER_PREFIX = "[token-goat: output capped at ~";
55
+ var JSON_CUT_FLAG = /"truncated"\s*:\s*true\b/;
56
+ function isCappedOutput(text) {
57
+ return text.includes(CAP_MARKER_PREFIX) || JSON_CUT_FLAG.test(text);
58
+ }
59
+ function trimToBudget(text, budgetTokens, command, opts = {}) {
25
60
  const markerMarginTokens = 64;
61
+ const reserve = Math.max(0, opts.reserveTokens ?? 0);
26
62
  const strippedAll = stripAnsiEscapes(text);
27
- const contentClass = classifyContent(strippedAll);
28
- const totalTokens = estimateTokensFromLength(strippedAll.length, contentClass);
29
- if (totalTokens <= budgetTokens) {
63
+ const dense = classifyContent(strippedAll) === "dense";
64
+ const totalTokens = Math.max(1, Math.floor(guardTokens(strippedAll, dense)) + 1);
65
+ if (totalTokens <= budgetTokens - reserve) {
30
66
  return text;
31
67
  }
32
68
  const lines = text.split("\n");
33
69
  if (lines.length > 1 && lines[lines.length - 1] === "") lines.pop();
34
70
  const totalLines = lines.length;
35
- const bodyBudget = Math.max(1, budgetTokens - markerMarginTokens);
36
- const charBudget = bodyBudget * guardDivisor(contentClass);
71
+ const bodyBudget = Math.max(1, budgetTokens - markerMarginTokens - reserve);
37
72
  const kept = [];
38
- let used = 0;
73
+ let usedTokens = 0;
39
74
  for (const ln of lines) {
40
75
  const stripped = stripAnsiEscapes(ln);
41
- const cost = ln.length + 1;
42
- if (kept.length === 0 && cost > charBudget) {
43
- const truncated = safeSlice(stripped, charBudget);
76
+ const costTokens = guardTokens(`${ln}
77
+ `, dense);
78
+ if (kept.length === 0 && costTokens > bodyBudget) {
79
+ const truncated = sliceToGuardTokens(stripped, bodyBudget, dense);
44
80
  kept.push(truncated);
45
81
  break;
46
82
  }
47
- if (kept.length > 0 && used + cost > charBudget) {
83
+ if (kept.length > 0 && usedTokens + costTokens > bodyBudget) {
48
84
  break;
49
85
  }
50
86
  kept.push(ln);
51
- used += cost;
87
+ usedTokens += costTokens;
52
88
  }
53
89
  const shown = kept.length;
54
90
  const hint = getHintFor(command);
55
- const marker = `[token-goat: output capped at ~${budgetTokens} tokens to protect context \u2014 showing ${shown} of ${totalLines} lines. ${hint}]`;
56
- return kept.join("\n") + "\n" + marker;
91
+ const marker = `${CAP_MARKER_PREFIX}${budgetTokens} tokens to protect context \u2014 showing ${shown} of ${totalLines} lines. ${hint}]`;
92
+ return kept.join("\n") + "\n" + forClient(marker);
57
93
  }
58
94
  function capJsonRows(items, budgetTokens) {
59
95
  const totalCount = items.length;
60
- const charBudget = Math.max(1, budgetTokens * guardDivisor());
96
+ const budget = Math.max(TEXT_GUARD_UNITS, budgetTokens * GUARD_UNITS_PER_TOKEN);
61
97
  const kept = [];
62
98
  let used = 0;
63
99
  for (const item of items) {
64
- const cost = JSON.stringify(item).length + 2;
65
- if (kept.length > 0 && used + cost > charBudget) break;
100
+ const cost = guardUnits(JSON.stringify(item)) + 2 * TEXT_GUARD_UNITS;
101
+ if (kept.length > 0 && used + cost > budget) break;
66
102
  kept.push(item);
67
103
  used += cost;
68
104
  }
@@ -91,6 +127,8 @@ function getHintFor(command) {
91
127
  export {
92
128
  estimateTokensFromLength,
93
129
  estimateTokens,
130
+ sliceToEstimatedTokens,
131
+ isCappedOutput,
94
132
  trimToBudget,
95
133
  capJsonRows
96
134
  };
@@ -0,0 +1,30 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ init_define_import_meta_env
5
+ } from "./token-goat-chunk-A37V4PBF.mjs";
6
+
7
+ // src/claude_config_dir.ts
8
+ init_define_import_meta_env();
9
+ import * as os from "node:os";
10
+ import * as path from "node:path";
11
+ function claudeConfigDir(homeDir = os.homedir()) {
12
+ const override = process.env["CLAUDE_CONFIG_DIR"];
13
+ if (override !== void 0 && override !== "") return override;
14
+ return path.join(homeDir, ".claude");
15
+ }
16
+ function claudeGlobalJsonPath(homeDir = os.homedir()) {
17
+ const override = process.env["CLAUDE_CONFIG_DIR"];
18
+ return path.join(override !== void 0 && override !== "" ? override : homeDir, ".claude.json");
19
+ }
20
+ function projectTranscriptsDir(projectRoot) {
21
+ const rootStr = path.resolve(projectRoot);
22
+ const slug = rootStr.replace(/[^A-Za-z0-9]/g, "-");
23
+ return path.join(claudeConfigDir(), "projects", slug);
24
+ }
25
+
26
+ export {
27
+ claudeConfigDir,
28
+ claudeGlobalJsonPath,
29
+ projectTranscriptsDir
30
+ };
@@ -0,0 +1,25 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ docxOutline,
5
+ docxTables,
6
+ docxText,
7
+ formatDocxTables
8
+ } from "./token-goat-chunk-YB4VMGK2.mjs";
9
+ import "./token-goat-chunk-2M7E4PF7.mjs";
10
+ import "./token-goat-chunk-E45INMY3.mjs";
11
+ import "./token-goat-chunk-EDBDRVH5.mjs";
12
+ import "./token-goat-chunk-AH6QILZM.mjs";
13
+ import "./token-goat-chunk-Y4AFKTHK.mjs";
14
+ import "./token-goat-chunk-HU4TORC5.mjs";
15
+ import "./token-goat-chunk-GGGG7RWB.mjs";
16
+ import "./token-goat-chunk-AM5V6GSX.mjs";
17
+ import "./token-goat-chunk-FNFBKLRD.mjs";
18
+ import "./token-goat-chunk-CO3UYX6G.mjs";
19
+ import "./token-goat-chunk-A37V4PBF.mjs";
20
+ export {
21
+ docxOutline,
22
+ docxTables,
23
+ docxText,
24
+ formatDocxTables
25
+ };
@@ -0,0 +1,322 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ ANTIGRAVITY_TOOL_NAME_KEY,
5
+ BODY_FIRST_TOOL_RESPONSE_KEYS,
6
+ OUTPUT_FIRST_TOOL_RESPONSE_KEYS,
7
+ VSCODE_TOOL_NAME_KEY,
8
+ antigravityNativeToolInput,
9
+ foldToolName,
10
+ replaceToolResponseField,
11
+ vscodeNativeToolInput
12
+ } from "./token-goat-chunk-76FGDLRO.mjs";
13
+ import {
14
+ recordUnmappedTool
15
+ } from "./token-goat-chunk-U4WHMG6Y.mjs";
16
+ import {
17
+ registerReset
18
+ } from "./token-goat-chunk-YZAAZU2S.mjs";
19
+ import {
20
+ init_define_import_meta_env
21
+ } from "./token-goat-chunk-A37V4PBF.mjs";
22
+
23
+ // src/hook_registry.ts
24
+ init_define_import_meta_env();
25
+
26
+ // src/bridges/vscode_hooks.ts
27
+ init_define_import_meta_env();
28
+ import * as crypto from "node:crypto";
29
+ import * as fs2 from "node:fs";
30
+ import * as os2 from "node:os";
31
+ import * as path2 from "node:path";
32
+
33
+ // src/shrink_temp_copies.ts
34
+ init_define_import_meta_env();
35
+ import * as fs from "node:fs";
36
+ import * as os from "node:os";
37
+ import * as path from "node:path";
38
+ var SHRINK_COPY_PREFIX = "token-goat-shrink-";
39
+ var SHRINK_COPY_MAX_AGE_MS = 60 * 60 * 1e3;
40
+ function sweepStaleShrinkCopies(now = Date.now(), dir = os.tmpdir()) {
41
+ let removed = 0;
42
+ let names;
43
+ try {
44
+ names = fs.readdirSync(dir);
45
+ } catch {
46
+ return 0;
47
+ }
48
+ for (const name of names) {
49
+ if (!name.startsWith(SHRINK_COPY_PREFIX)) continue;
50
+ const full = path.join(dir, name);
51
+ try {
52
+ const st = fs.statSync(full);
53
+ if (st.isFile() && now - st.mtimeMs > SHRINK_COPY_MAX_AGE_MS) {
54
+ fs.unlinkSync(full);
55
+ removed++;
56
+ }
57
+ } catch {
58
+ }
59
+ }
60
+ return removed;
61
+ }
62
+
63
+ // src/bridges/vscode_hooks.ts
64
+ function vscodeToolName(event) {
65
+ const name = event?.raw[VSCODE_TOOL_NAME_KEY];
66
+ return typeof name === "string" ? name : void 0;
67
+ }
68
+ var lastMaterializedSweepAtMs = 0;
69
+ function pruneMaterialized() {
70
+ const now = Date.now();
71
+ if (now - lastMaterializedSweepAtMs < SHRINK_COPY_MAX_AGE_MS) return;
72
+ lastMaterializedSweepAtMs = now;
73
+ sweepStaleShrinkCopies(now);
74
+ }
75
+ function materializeShrunkImageFile(context) {
76
+ const idx = context.indexOf("data:image/");
77
+ if (idx === -1) return void 0;
78
+ const match = /^data:image\/([a-zA-Z0-9.+-]+);base64,([A-Za-z0-9+/=]+)$/.exec(context.slice(idx).trim());
79
+ if (!match) return void 0;
80
+ try {
81
+ pruneMaterialized();
82
+ const file = path2.join(os2.tmpdir(), `${SHRINK_COPY_PREFIX}${process.pid}-${Date.now()}-${crypto.randomUUID()}.${match[1]}`);
83
+ fs2.writeFileSync(file, Buffer.from(match[2], "base64"), { mode: 384 });
84
+ return file;
85
+ } catch {
86
+ return void 0;
87
+ }
88
+ }
89
+ function isShrunkImagePayload(eventName, context) {
90
+ return eventName === "pre_tool_use" && context.includes("data:image/");
91
+ }
92
+ var NESTED_DECISION_EVENTS = /* @__PURE__ */ new Set(["stop", "subagent_stop"]);
93
+ function serializeVscodeOutput(output, eventName, hookEventName, event) {
94
+ switch (output.hookType) {
95
+ case "deny":
96
+ if (eventName === "pre_tool_use") {
97
+ return JSON.stringify({
98
+ hookSpecificOutput: { hookEventName, permissionDecision: "deny", permissionDecisionReason: output.message }
99
+ });
100
+ }
101
+ if (NESTED_DECISION_EVENTS.has(eventName)) {
102
+ return JSON.stringify({ hookSpecificOutput: { hookEventName, decision: "block", reason: output.message } });
103
+ }
104
+ return JSON.stringify({ decision: "block", reason: output.message });
105
+ case "context": {
106
+ if (NESTED_DECISION_EVENTS.has(eventName)) return "{}";
107
+ if (eventName === "pre_compact" || eventName === "notification") return JSON.stringify({ systemMessage: output.context });
108
+ if (isShrunkImagePayload(eventName, output.context)) return "{}";
109
+ return JSON.stringify({ hookSpecificOutput: { hookEventName, additionalContext: output.context } });
110
+ }
111
+ case "rewriteInput": {
112
+ const tool = vscodeToolName(event);
113
+ const updatedInput = tool === void 0 ? output.updatedInput : vscodeNativeToolInput(tool, output.updatedInput);
114
+ return JSON.stringify({ hookSpecificOutput: { hookEventName: "PreToolUse", updatedInput } });
115
+ }
116
+ case "rewriteOutput":
117
+ return "{}";
118
+ case "pass":
119
+ return "{}";
120
+ }
121
+ }
122
+
123
+ // src/bridges/antigravity_hooks.ts
124
+ init_define_import_meta_env();
125
+ function antigravityToolName(event) {
126
+ const name = event?.raw[ANTIGRAVITY_TOOL_NAME_KEY];
127
+ return typeof name === "string" ? name : void 0;
128
+ }
129
+ function serializeAntigravityOutput(output, eventName, event) {
130
+ if (eventName === "pre_tool_use") {
131
+ switch (output.hookType) {
132
+ case "deny":
133
+ return JSON.stringify({ decision: "deny", reason: output.message });
134
+ case "context":
135
+ if (output.context.includes("data:image/")) return "{}";
136
+ return JSON.stringify({ reason: output.context });
137
+ case "rewriteInput": {
138
+ const tool = antigravityToolName(event);
139
+ const overwrite = tool === void 0 ? output.updatedInput : antigravityNativeToolInput(tool, output.updatedInput);
140
+ return JSON.stringify({ overwrite });
141
+ }
142
+ default:
143
+ return "{}";
144
+ }
145
+ }
146
+ if (eventName === "post_tool_use" && output.hookType === "rewriteOutput" && typeof event?.raw["result"] === "string") {
147
+ return JSON.stringify({ overwriteResult: output.updatedOutput });
148
+ }
149
+ return "{}";
150
+ }
151
+
152
+ // src/hook_registry.ts
153
+ function sessionStateKey(event) {
154
+ return event.agentId !== void 0 ? `${event.sessionId}:agent:${event.agentId}` : event.sessionId;
155
+ }
156
+ var _handlers = /* @__PURE__ */ new Map();
157
+ function registerHook(eventName, handler, opts) {
158
+ let list = _handlers.get(eventName);
159
+ if (list === void 0) {
160
+ list = [];
161
+ _handlers.set(eventName, list);
162
+ }
163
+ list.push({
164
+ handler,
165
+ toolName: opts?.toolName,
166
+ toolPattern: opts?.toolPattern,
167
+ advisory: opts?.advisory === true,
168
+ followsMatcher: opts?.followsMatcher === true
169
+ });
170
+ }
171
+ function toolMatcherFor(eventName) {
172
+ const list = _handlers.get(eventName);
173
+ if (list === void 0 || list.length === 0) return null;
174
+ const parts = [];
175
+ for (const { toolName, toolPattern, followsMatcher } of list) {
176
+ if (followsMatcher) continue;
177
+ if (toolName === void 0 && toolPattern === void 0) return null;
178
+ for (const part of [toolName === void 0 ? void 0 : `^${toolName}$`, toolPattern]) {
179
+ if (part !== void 0 && part !== "" && !parts.includes(part)) parts.push(part);
180
+ }
181
+ }
182
+ if (parts.length === 0) return null;
183
+ return parts.join("|");
184
+ }
185
+ function noteUnrecognizedTool(event, list) {
186
+ const toolName = event.toolName;
187
+ if (typeof toolName !== "string" || toolName === "") return;
188
+ const named = [];
189
+ for (const { toolName: want, toolPattern } of list) {
190
+ if (toolPattern !== void 0) {
191
+ let matches = false;
192
+ try {
193
+ matches = new RegExp(toolPattern).test(toolName);
194
+ } catch {
195
+ }
196
+ if (matches) return;
197
+ }
198
+ if (want === void 0) continue;
199
+ if (want === toolName) return;
200
+ named.push(want);
201
+ }
202
+ if (named.length === 0) return;
203
+ const folded = foldToolName(toolName);
204
+ const nearMiss = named.find((n) => foldToolName(n) === folded) ?? null;
205
+ recordUnmappedTool(toolName, event.eventName, nearMiss);
206
+ }
207
+ async function runHook(event) {
208
+ const list = _handlers.get(event.eventName);
209
+ if (list === void 0) return { hookType: "pass" };
210
+ noteUnrecognizedTool(event, list);
211
+ let advisoryResult;
212
+ let noticeResult;
213
+ for (const { handler, toolName, advisory } of list) {
214
+ if (toolName !== void 0 && toolName !== event.toolName) continue;
215
+ let result;
216
+ try {
217
+ result = await handler(event);
218
+ } catch {
219
+ continue;
220
+ }
221
+ if (result.hookType !== "pass") {
222
+ if (advisory) {
223
+ advisoryResult = result;
224
+ continue;
225
+ }
226
+ return result;
227
+ }
228
+ if (result.notice !== void 0) noticeResult ??= result;
229
+ }
230
+ return advisoryResult ?? noticeResult ?? { hookType: "pass" };
231
+ }
232
+ function clearHooks() {
233
+ _handlers.clear();
234
+ }
235
+ registerReset(clearHooks);
236
+ var CLAUDE_CODE_EVENT_NAMES = {
237
+ pre_tool_use: "PreToolUse",
238
+ post_tool_use: "PostToolUse",
239
+ notification: "Notification",
240
+ stop: "Stop",
241
+ pre_compact: "PreCompact",
242
+ post_compact: "PostCompact",
243
+ user_prompt_submit: "UserPromptSubmit",
244
+ subagent_stop: "SubagentStop",
245
+ // Wired for Copilot CLI (`subagentStart`) and VS Code (`SubagentStart`) only; hooks_agent_spawn.ts's subagentStartHandler answers it with the spawn briefing as additionalContext, which both harnesses read.
246
+ subagent_start: "SubagentStart",
247
+ session_start: "SessionStart",
248
+ // Claude Code sends a failed tool call here rather than to PostToolUse, and its PostToolUseFailure output schema accepts hookSpecificOutput.additionalContext (captured and read from claude.exe 2.1.281); install.ts HOOK_EVENT_MAP registers it.
249
+ post_tool_use_failure: "PostToolUseFailure"
250
+ };
251
+ var EVENTS_WITHOUT_ADDITIONAL_CONTEXT = /* @__PURE__ */ new Set([
252
+ "notification",
253
+ "pre_compact",
254
+ "stop"
255
+ ]);
256
+ var EVENTS_WITH_RAW_STDOUT_CONTEXT = /* @__PURE__ */ new Set(["pre_compact"]);
257
+ var BODY_FIRST_REWRITE_TOOLS = /* @__PURE__ */ new Set(["WebFetch", "Skill"]);
258
+ function shapedUpdatedToolOutput(updatedOutput, harness, event) {
259
+ if (harness !== "claudecode") return updatedOutput;
260
+ const resp = event?.raw["tool_response"];
261
+ if (resp === null || resp === void 0 || typeof resp !== "object") return updatedOutput;
262
+ const keys = BODY_FIRST_REWRITE_TOOLS.has(event?.toolName ?? "") ? BODY_FIRST_TOOL_RESPONSE_KEYS : OUTPUT_FIRST_TOOL_RESPONSE_KEYS;
263
+ return replaceToolResponseField(resp, keys, updatedOutput) ?? updatedOutput;
264
+ }
265
+ function serializeOutput(output, eventName, harness, event) {
266
+ if (harness === "vscode") return serializeVscodeOutput(output, eventName, CLAUDE_CODE_EVENT_NAMES[eventName], event);
267
+ if (harness === "antigravity") return serializeAntigravityOutput(output, eventName, event);
268
+ switch (output.hookType) {
269
+ case "deny":
270
+ return JSON.stringify({ decision: "block", reason: output.message });
271
+ case "context":
272
+ if (EVENTS_WITH_RAW_STDOUT_CONTEXT.has(eventName) && harness === "claudecode") {
273
+ return output.context;
274
+ }
275
+ if (EVENTS_WITHOUT_ADDITIONAL_CONTEXT.has(eventName)) {
276
+ return JSON.stringify({ systemMessage: output.context });
277
+ }
278
+ if (harness === "claudecode" && isShrunkImagePayload(eventName, output.context)) {
279
+ return JSON.stringify(noticeField(output.notice, harness));
280
+ }
281
+ return JSON.stringify({
282
+ ...noticeField(output.notice, harness),
283
+ hookSpecificOutput: {
284
+ hookEventName: CLAUDE_CODE_EVENT_NAMES[eventName],
285
+ additionalContext: output.context
286
+ }
287
+ });
288
+ case "rewriteInput":
289
+ return JSON.stringify({
290
+ hookSpecificOutput: {
291
+ hookEventName: "PreToolUse",
292
+ // Claude Code matches its permission rules against updatedInput and skips the prompt on "allow", so it gets one only for a call rewrite_permission.ts proved auto-allowed. Codex applies updatedInput only beside "allow" ("Return updatedInput only with permissionDecision: allow", https://developers.openai.com/codex/hooks) and documents approval prompts as a separate PermissionRequest event, so there the field is the rewrite's required carrier. Every other harness gets none.
293
+ ...output.approve && harness === "claudecode" || harness === "codex" ? { permissionDecision: "allow" } : {},
294
+ updatedInput: output.updatedInput
295
+ }
296
+ });
297
+ case "rewriteOutput":
298
+ return JSON.stringify({
299
+ hookSpecificOutput: {
300
+ hookEventName: "PostToolUse",
301
+ // A block array is emitted only when the handler built one, and only for Claude Code: every other harness token-goat bridges to reads this field as a plain string into a text block of its own, so handing it an array there is the same mistake in the other direction. See HookOutput's `updatedBlocks` for the capture that proves Claude Code takes the array.
302
+ updatedToolOutput: output.updatedBlocks !== void 0 && harness === "claudecode" ? output.updatedBlocks : shapedUpdatedToolOutput(output.updatedOutput, harness, event),
303
+ ...output.context !== void 0 ? { additionalContext: output.context } : {}
304
+ }
305
+ });
306
+ case "pass":
307
+ return JSON.stringify(noticeField(output.notice, harness));
308
+ }
309
+ }
310
+ function noticeField(notice, harness) {
311
+ return notice !== void 0 && harness === "claudecode" ? { systemMessage: notice } : {};
312
+ }
313
+
314
+ export {
315
+ sweepStaleShrinkCopies,
316
+ materializeShrunkImageFile,
317
+ sessionStateKey,
318
+ registerHook,
319
+ toolMatcherFor,
320
+ runHook,
321
+ serializeOutput
322
+ };
@@ -0,0 +1,87 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ extractErrorMessage
5
+ } from "./token-goat-chunk-HU4TORC5.mjs";
6
+ import {
7
+ displaySafeJson,
8
+ displaySafeText
9
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
10
+ import {
11
+ init_define_import_meta_env
12
+ } from "./token-goat-chunk-A37V4PBF.mjs";
13
+
14
+ // src/command_error.ts
15
+ init_define_import_meta_env();
16
+ var CliError = class extends Error {
17
+ lines;
18
+ constructor(message) {
19
+ super(typeof message === "string" ? message : message.join("\n"));
20
+ this.lines = typeof message === "string" ? void 0 : message;
21
+ }
22
+ };
23
+ var invocation = null;
24
+ function setCliInvocation(argv) {
25
+ invocation = argv.slice(2);
26
+ }
27
+ function clearCliInvocation() {
28
+ invocation = null;
29
+ }
30
+ function cliInvocation() {
31
+ return invocation ?? process.argv.slice(2);
32
+ }
33
+ function formatCommandError(e) {
34
+ if (e instanceof CliError && e.lines !== void 0) return "token-goat: " + e.lines.map(displaySafeText).join("\n");
35
+ return "token-goat: " + displaySafeText(extractErrorMessage(e));
36
+ }
37
+ function formatGitFailure(command, stderr) {
38
+ if (/not a git repository/i.test(stderr)) return formatCommandError(new CliError(`git ${command} failed: not a git repository`));
39
+ const lines = [];
40
+ for (const line of stderr.trim().split(/\r?\n/)) {
41
+ if (/^usage:/i.test(line.trimStart())) break;
42
+ lines.push(line.trimEnd());
43
+ }
44
+ while (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
45
+ const [first, ...rest] = lines;
46
+ return formatCommandError(new CliError([`git ${command} failed: ${first ?? "git printed no error message"}`, ...rest]));
47
+ }
48
+ function formatParseError(str) {
49
+ const lines = (str.endsWith("\n") ? str.slice(0, -1) : str).split("\n");
50
+ if (lines[0].startsWith("error: ")) lines[0] = lines[0].slice("error: ".length);
51
+ return formatCommandError(new CliError(lines)) + "\n";
52
+ }
53
+ function formatFailedResultText(text) {
54
+ return isJsonBody(text) ? text : formatCommandError(new CliError(text.split("\n")));
55
+ }
56
+ function displaySafeFailureText(text) {
57
+ return isJsonBody(text) ? text : text.split("\n").map(displaySafeText).join("\n");
58
+ }
59
+ function isJsonBody(text) {
60
+ const head = text.trimStart()[0];
61
+ if (head !== "{" && head !== "[") return false;
62
+ try {
63
+ JSON.parse(text);
64
+ return true;
65
+ } catch {
66
+ return false;
67
+ }
68
+ }
69
+ function writeCommandFailure(json, body, message) {
70
+ if (json) process.stdout.write(`${displaySafeJson(body, 0)}
71
+ `);
72
+ else process.stderr.write(formatCommandError(new CliError(message)) + "\n");
73
+ process.exitCode = 1;
74
+ }
75
+
76
+ export {
77
+ CliError,
78
+ setCliInvocation,
79
+ clearCliInvocation,
80
+ cliInvocation,
81
+ formatCommandError,
82
+ formatGitFailure,
83
+ formatParseError,
84
+ formatFailedResultText,
85
+ displaySafeFailureText,
86
+ writeCommandFailure
87
+ };