token-goat 2.9.30 → 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 (172) hide show
  1. package/README.md +24 -7
  2. package/SECURITY.md +10 -2
  3. package/THIRD_PARTY_NOTICES.md +1 -1
  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/{token-goat-chunk-QSBRTGM2.mjs → token-goat-chunk-25TRAWET.mjs} +17 -7
  9. package/dist/token-goat-chunk-2KXO6V2B.mjs +203 -0
  10. package/dist/{token-goat-chunk-IVKIZWAB.mjs → token-goat-chunk-2M7E4PF7.mjs} +41 -12
  11. package/dist/{token-goat-chunk-SMVRN2HU.mjs → token-goat-chunk-2UPZGKKY.mjs} +2 -2
  12. package/dist/token-goat-chunk-2WLPWKHV.mjs +135 -0
  13. package/dist/token-goat-chunk-2XBMMDBD.mjs +126 -0
  14. package/dist/token-goat-chunk-32ZOY4N5.mjs +23 -0
  15. package/dist/token-goat-chunk-3EZRNKTK.mjs +188 -0
  16. package/dist/token-goat-chunk-4ADZHI7J.mjs +63 -0
  17. package/dist/token-goat-chunk-4GBVPH3D.mjs +242 -0
  18. package/dist/{token-goat-chunk-KWPNJBDH.mjs → token-goat-chunk-4GILLLWY.mjs} +7 -4
  19. package/dist/{token-goat-chunk-67TQJ76B.mjs → token-goat-chunk-4NAPX7BA.mjs} +36 -3
  20. package/dist/{token-goat-chunk-PU7V3FD6.mjs → token-goat-chunk-4SC7UJYV.mjs} +3354 -2553
  21. package/dist/token-goat-chunk-4SMRO4TO.mjs +366 -0
  22. package/dist/{token-goat-chunk-AFLYLHDH.mjs → token-goat-chunk-4ZBFWLXF.mjs} +283 -427
  23. package/dist/{token-goat-chunk-JDWCRD6M.mjs → token-goat-chunk-57BIAXJL.mjs} +73 -40
  24. package/dist/token-goat-chunk-5AC66HNP.mjs +115 -0
  25. package/dist/token-goat-chunk-5IMLKSOP.mjs +145 -0
  26. package/dist/token-goat-chunk-646E6U44.mjs +398 -0
  27. package/dist/token-goat-chunk-65N4RHP4.mjs +33 -0
  28. package/dist/{token-goat-chunk-JN4XMLSD.mjs → token-goat-chunk-6DG6HWP3.mjs} +8 -2
  29. package/dist/token-goat-chunk-6ENQSNRZ.mjs +573 -0
  30. package/dist/token-goat-chunk-6ZY4GNF2.mjs +91 -0
  31. package/dist/{token-goat-chunk-VPBBTSJR.mjs → token-goat-chunk-76FGDLRO.mjs} +262 -255
  32. package/dist/{token-goat-chunk-7IN2MKDS.mjs → token-goat-chunk-7EZTZOMC.mjs} +121 -289
  33. package/dist/{token-goat-chunk-OJBNYTJP.mjs → token-goat-chunk-7MAOA6X4.mjs} +640 -80
  34. package/dist/token-goat-chunk-7R2ZVVAX.mjs +218 -0
  35. package/dist/{token-goat-chunk-PD5VKH46.mjs → token-goat-chunk-AUNGYYQX.mjs} +2 -2
  36. package/dist/{token-goat-chunk-HG45AF2B.mjs → token-goat-chunk-AUQYRMMH.mjs} +794 -37
  37. package/dist/token-goat-chunk-B3PEKBYG.mjs +128 -0
  38. package/dist/{token-goat-chunk-A3CK6N5Z.mjs → token-goat-chunk-BA4HI6BW.mjs} +1309 -110
  39. package/dist/{token-goat-chunk-JB6QN6VF.mjs → token-goat-chunk-BFCWY73P.mjs} +59 -23
  40. package/dist/{token-goat-chunk-B45VMIIH.mjs → token-goat-chunk-BWGFUZZE.mjs} +7 -5
  41. package/dist/{token-goat-chunk-P4QMM4WK.mjs → token-goat-chunk-C75NA7PL.mjs} +50 -23
  42. package/dist/token-goat-chunk-CBIQ7WTD.mjs +87 -0
  43. package/dist/token-goat-chunk-CETM74KC.mjs +307 -0
  44. package/dist/{token-goat-chunk-H2PHHGM5.mjs → token-goat-chunk-CIMQ2BB3.mjs} +57 -12
  45. package/dist/{token-goat-chunk-N2NMER56.mjs → token-goat-chunk-CJLS3CDL.mjs} +46 -4
  46. package/dist/{token-goat-chunk-VES7EL7O.mjs → token-goat-chunk-CO3UYX6G.mjs} +1 -1
  47. package/dist/token-goat-chunk-COPNXRJM.mjs +154 -0
  48. package/dist/token-goat-chunk-CSJ5L3NL.mjs +479 -0
  49. package/dist/{token-goat-chunk-4LCCNRTG.mjs → token-goat-chunk-CVCEVUGK.mjs} +8 -6
  50. package/dist/{token-goat-chunk-B2RZZCSS.mjs → token-goat-chunk-CXHOFN7R.mjs} +37 -20
  51. package/dist/token-goat-chunk-D735C4QM.mjs +603 -0
  52. package/dist/{token-goat-chunk-APGZXSPS.mjs → token-goat-chunk-DGS2LVNA.mjs} +47 -30
  53. package/dist/{token-goat-chunk-54K3EUV3.mjs → token-goat-chunk-DOWRSMWO.mjs} +1 -1
  54. package/dist/token-goat-chunk-E45INMY3.mjs +71 -0
  55. package/dist/token-goat-chunk-EC5F37F4.mjs +244 -0
  56. package/dist/{token-goat-chunk-XTQAOTSO.mjs → token-goat-chunk-EDBDRVH5.mjs} +4 -1
  57. package/dist/{token-goat-chunk-5BCIJXMO.mjs → token-goat-chunk-EELTBKDM.mjs} +14 -10
  58. package/dist/{token-goat-chunk-W3QCJS6G.mjs → token-goat-chunk-F4HYL64R.mjs} +8 -6
  59. package/dist/token-goat-chunk-F6PAUIEK.mjs +624 -0
  60. package/dist/token-goat-chunk-FDSREWLX.mjs +692 -0
  61. package/dist/token-goat-chunk-GGGG7RWB.mjs +236 -0
  62. package/dist/{token-goat-chunk-C63JQV5K.mjs → token-goat-chunk-GL3ETKSC.mjs} +233 -15
  63. package/dist/token-goat-chunk-GVB2MUST.mjs +1298 -0
  64. package/dist/token-goat-chunk-GWFLAUMQ.mjs +307 -0
  65. package/dist/{token-goat-chunk-ZEJVMUQH.mjs → token-goat-chunk-HLPW63A7.mjs} +2 -2
  66. package/dist/{token-goat-chunk-GOLEOXZP.mjs → token-goat-chunk-HU4TORC5.mjs} +44 -26
  67. package/dist/{token-goat-chunk-Z57YODA2.mjs → token-goat-chunk-I7VKZZAW.mjs} +2 -2
  68. package/dist/{token-goat-chunk-NYKZLXMK.mjs → token-goat-chunk-IA6XSPE3.mjs} +6 -6
  69. package/dist/{token-goat-chunk-E3OQX2XT.mjs → token-goat-chunk-IAGXMHIK.mjs} +81 -42
  70. package/dist/{token-goat-chunk-HYBFA5X3.mjs → token-goat-chunk-IK2DRMFX.mjs} +24 -68
  71. package/dist/{token-goat-chunk-COBQGL5S.mjs → token-goat-chunk-INNPTRUX.mjs} +249 -299
  72. package/dist/{token-goat-chunk-7NADEDKJ.mjs → token-goat-chunk-JJ5BX4F4.mjs} +6 -1
  73. package/dist/{token-goat-chunk-PEPTHRFF.mjs → token-goat-chunk-JVFSHVFJ.mjs} +6 -6
  74. package/dist/token-goat-chunk-KGEFFSHD.mjs +50 -0
  75. package/dist/token-goat-chunk-KQBLRPBN.mjs +433 -0
  76. package/dist/{token-goat-chunk-Q5VTGRH7.mjs → token-goat-chunk-LCNQ2CNN.mjs} +55 -319
  77. package/dist/token-goat-chunk-M3LFJDPU.mjs +58 -0
  78. package/dist/token-goat-chunk-M52KPT3C.mjs +87 -0
  79. package/dist/token-goat-chunk-MBEG42H7.mjs +150 -0
  80. package/dist/{token-goat-chunk-EVC4TOLE.mjs → token-goat-chunk-METECDOH.mjs} +3 -12
  81. package/dist/{token-goat-chunk-T4FK7VOV.mjs → token-goat-chunk-MHX7XCC3.mjs} +2 -1
  82. package/dist/token-goat-chunk-N5LSOVSU.mjs +137 -0
  83. package/dist/{token-goat-chunk-LOBGHXPB.mjs → token-goat-chunk-N5MMR2IW.mjs} +1 -1
  84. package/dist/token-goat-chunk-N7B3JQ2C.mjs +160 -0
  85. package/dist/{token-goat-chunk-RHXKCZX3.mjs → token-goat-chunk-NISNMD7T.mjs} +2182 -2959
  86. package/dist/token-goat-chunk-NMD42SFQ.mjs +434 -0
  87. package/dist/token-goat-chunk-NOSS5VWY.mjs +174 -0
  88. package/dist/{token-goat-chunk-KQNZDCBD.mjs → token-goat-chunk-NSNSPPBG.mjs} +25 -3
  89. package/dist/token-goat-chunk-OBOFIHKN.mjs +38 -0
  90. package/dist/token-goat-chunk-OBRFJ5O5.mjs +76 -0
  91. package/dist/{token-goat-chunk-JTQQGXZH.mjs → token-goat-chunk-ODBT2USM.mjs} +124 -57
  92. package/dist/token-goat-chunk-OS5EM5PP.mjs +107 -0
  93. package/dist/token-goat-chunk-OUKDTVNU.mjs +1178 -0
  94. package/dist/token-goat-chunk-OXFMP75N.mjs +566 -0
  95. package/dist/{token-goat-chunk-DZX2YDPT.mjs → token-goat-chunk-OYIYKDDT.mjs} +2 -2
  96. package/dist/{token-goat-chunk-QCLDAQTS.mjs → token-goat-chunk-P6HQSWQ3.mjs} +50 -53
  97. package/dist/token-goat-chunk-P6VGNTQT.mjs +71 -0
  98. package/dist/{token-goat-chunk-7BXSNBY5.mjs → token-goat-chunk-PFWIMH2E.mjs} +23 -15
  99. package/dist/token-goat-chunk-PJZXIS3G.mjs +39 -0
  100. package/dist/token-goat-chunk-PUO5INXP.mjs +606 -0
  101. package/dist/{token-goat-chunk-GFBSN7BD.mjs → token-goat-chunk-PX5PQWTY.mjs} +22 -250
  102. package/dist/token-goat-chunk-Q5QDBC6O.mjs +111 -0
  103. package/dist/token-goat-chunk-QFNQXSDT.mjs +40 -0
  104. package/dist/{token-goat-chunk-FBNQNSJK.mjs → token-goat-chunk-QH7YVYOY.mjs} +2198 -2782
  105. package/dist/{token-goat-chunk-64FBPDTK.mjs → token-goat-chunk-QLMUHEPB.mjs} +12 -9
  106. package/dist/{token-goat-chunk-RZRTDST7.mjs → token-goat-chunk-QQOJIHL3.mjs} +37 -11
  107. package/dist/{token-goat-chunk-XKI4SEMX.mjs → token-goat-chunk-QQTWJY2O.mjs} +19 -0
  108. package/dist/{token-goat-chunk-U4N3BN2W.mjs → token-goat-chunk-QYHO5CPH.mjs} +3 -2
  109. package/dist/token-goat-chunk-RELAVWAD.mjs +27 -0
  110. package/dist/{token-goat-chunk-ETBHVDB6.mjs → token-goat-chunk-RSLPOBKQ.mjs} +22 -11
  111. package/dist/token-goat-chunk-SAMFDIS2.mjs +712 -0
  112. package/dist/token-goat-chunk-SDELXLDM.mjs +48 -0
  113. package/dist/{token-goat-chunk-4JJS54TR.mjs → token-goat-chunk-SOAFZNNZ.mjs} +161 -38
  114. package/dist/{token-goat-chunk-664RTTUV.mjs → token-goat-chunk-SRTHT7KV.mjs} +21 -16
  115. package/dist/{token-goat-chunk-4FVIAHSI.mjs → token-goat-chunk-T5P5ACNQ.mjs} +7 -6
  116. package/dist/token-goat-chunk-T5YGG4V3.mjs +45 -0
  117. package/dist/token-goat-chunk-TAUZ4OFS.mjs +110 -0
  118. package/dist/{token-goat-chunk-COTXZHTS.mjs → token-goat-chunk-TM6MC754.mjs} +4 -3
  119. package/dist/token-goat-chunk-TWUKBOMP.mjs +72 -0
  120. package/dist/{token-goat-chunk-3CHUNJ2O.mjs → token-goat-chunk-U2KSB4SG.mjs} +8 -5
  121. package/dist/{token-goat-chunk-3Z5S4KGM.mjs → token-goat-chunk-U4WHMG6Y.mjs} +29 -49
  122. package/dist/{token-goat-chunk-PY533T7F.mjs → token-goat-chunk-UGJHGR5A.mjs} +21 -15
  123. package/dist/{token-goat-chunk-CYCEYAEO.mjs → token-goat-chunk-UOUDVA5U.mjs} +1 -1
  124. package/dist/{token-goat-chunk-JDHE26RP.mjs → token-goat-chunk-URRJ33GR.mjs} +16 -5
  125. package/dist/{token-goat-chunk-56EIMS3E.mjs → token-goat-chunk-UZOROKIS.mjs} +23 -17
  126. package/dist/{token-goat-chunk-CZ3LUXYZ.mjs → token-goat-chunk-VIHGGGEI.mjs} +427 -308
  127. package/dist/token-goat-chunk-VTJLAA7P.mjs +21 -0
  128. package/dist/token-goat-chunk-VWDXLT4F.mjs +678 -0
  129. package/dist/{token-goat-chunk-YARZFCZS.mjs → token-goat-chunk-VWZA2H4P.mjs} +62 -53
  130. package/dist/{token-goat-chunk-SQSSNQPE.mjs → token-goat-chunk-VXEXMJDL.mjs} +3979 -4745
  131. package/dist/token-goat-chunk-WBA5SKT4.mjs +547 -0
  132. package/dist/{token-goat-chunk-SJHWVNDQ.mjs → token-goat-chunk-WDH44VAU.mjs} +7 -4
  133. package/dist/token-goat-chunk-X2SUP3EI.mjs +107 -0
  134. package/dist/token-goat-chunk-X3BELZSJ.mjs +125 -0
  135. package/dist/{token-goat-chunk-FZ3NEW5O.mjs → token-goat-chunk-XLRBNZCC.mjs} +13 -8
  136. package/dist/{token-goat-chunk-Z44YO3QZ.mjs → token-goat-chunk-XRKUX6CM.mjs} +1 -1
  137. package/dist/token-goat-chunk-XX6O25RN.mjs +82 -0
  138. package/dist/token-goat-chunk-XZSUHBVS.mjs +65 -0
  139. package/dist/{token-goat-chunk-WY3L4DVT.mjs → token-goat-chunk-Y2ZTQOCL.mjs} +13 -8
  140. package/dist/{token-goat-chunk-UQ5UK2T7.mjs → token-goat-chunk-YB4VMGK2.mjs} +1 -1
  141. package/dist/token-goat-chunk-YBIIY3HR.mjs +51 -0
  142. package/dist/{token-goat-chunk-ZQSJMO2R.mjs → token-goat-chunk-YHVDKQBR.mjs} +105 -105
  143. package/dist/{token-goat-chunk-H2K3QP6H.mjs → token-goat-chunk-YJB5XLWI.mjs} +8 -6
  144. package/dist/{token-goat-chunk-ZCDTCVIS.mjs → token-goat-chunk-YKB6AQG3.mjs} +5 -2
  145. package/dist/token-goat-chunk-YMTG2YA5.mjs +35 -0
  146. package/dist/token-goat-chunk-YPBZYQRV.mjs +40 -0
  147. package/dist/{token-goat-chunk-HOJLCGDP.mjs → token-goat-chunk-YY6AVUFL.mjs} +2033 -2251
  148. package/dist/token-goat-chunk-Z7N5OMMP.mjs +98 -0
  149. package/dist/token-goat-chunk-ZNMNUPAZ.mjs +938 -0
  150. package/dist/token-goat-hook-client.cjs +1 -1
  151. package/dist/token-goat-hook-client.mjs +3 -3
  152. package/dist/token-goat-hook.mjs +67 -38
  153. package/dist/token-goat.core.mjs +4 -4
  154. package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
  155. package/docs/cli.md +40 -21
  156. package/docs/install.md +19 -9
  157. package/docs/security.md +5 -3
  158. package/package.json +2 -1
  159. package/dist/token-goat-chunk-5KDMCMF2.mjs +0 -362
  160. package/dist/token-goat-chunk-6QMAS7AB.mjs +0 -42
  161. package/dist/token-goat-chunk-7F2UBPD3.mjs +0 -397
  162. package/dist/token-goat-chunk-ARDNEC2U.mjs +0 -248
  163. package/dist/token-goat-chunk-ATCPY7EQ.mjs +0 -134
  164. package/dist/token-goat-chunk-EFHMMIGP.mjs +0 -68
  165. package/dist/token-goat-chunk-IVALLT3S.mjs +0 -48
  166. package/dist/token-goat-chunk-JDU3EXSU.mjs +0 -65
  167. package/dist/token-goat-chunk-MKPF4CL5.mjs +0 -37
  168. package/dist/token-goat-chunk-RC35RBUL.mjs +0 -312
  169. package/dist/token-goat-chunk-USILZ3T3.mjs +0 -53
  170. package/dist/token-goat-chunk-VL3YIFHZ.mjs +0 -2975
  171. package/dist/token-goat-chunk-XU4P6Z24.mjs +0 -133
  172. package/dist/token-goat-chunk-Y776AENC.mjs +0 -1597
@@ -1,15 +1,22 @@
1
1
  import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
3
  import {
4
- classifyContent,
5
- guardDivisor
6
- } from "./token-goat-chunk-3Z5S4KGM.mjs";
4
+ forClient
5
+ } from "./token-goat-chunk-KGEFFSHD.mjs";
7
6
  import {
8
- safeSlice
9
- } from "./token-goat-chunk-GOLEOXZP.mjs";
7
+ GUARD_UNITS_PER_TOKEN,
8
+ TEXT_GUARD_UNITS,
9
+ classifyContent,
10
+ guardDivisor,
11
+ guardTokens,
12
+ guardUnits
13
+ } from "./token-goat-chunk-XX6O25RN.mjs";
10
14
  import {
11
15
  stripAnsiEscapes
12
16
  } from "./token-goat-chunk-HAVAOB3S.mjs";
17
+ import {
18
+ safeSlice
19
+ } from "./token-goat-chunk-HU4TORC5.mjs";
13
20
  import {
14
21
  init_define_import_meta_env
15
22
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -21,50 +28,77 @@ function estimateTokensFromLength(length, cls = "text") {
21
28
  }
22
29
  function estimateTokens(text) {
23
30
  const stripped = stripAnsiEscapes(text);
24
- return estimateTokensFromLength(stripped.length, classifyContent(stripped));
31
+ return Math.max(1, Math.floor(guardTokens(stripped, classifyContent(stripped) === "dense")) + 1);
25
32
  }
26
- function trimToBudget(text, budgetTokens, command) {
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);
42
+ }
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 = {}) {
27
60
  const markerMarginTokens = 64;
61
+ const reserve = Math.max(0, opts.reserveTokens ?? 0);
28
62
  const strippedAll = stripAnsiEscapes(text);
29
- const contentClass = classifyContent(strippedAll);
30
- const totalTokens = estimateTokensFromLength(strippedAll.length, contentClass);
31
- 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) {
32
66
  return text;
33
67
  }
34
68
  const lines = text.split("\n");
35
69
  if (lines.length > 1 && lines[lines.length - 1] === "") lines.pop();
36
70
  const totalLines = lines.length;
37
- const bodyBudget = Math.max(1, budgetTokens - markerMarginTokens);
38
- const charBudget = bodyBudget * guardDivisor(contentClass);
71
+ const bodyBudget = Math.max(1, budgetTokens - markerMarginTokens - reserve);
39
72
  const kept = [];
40
- let used = 0;
73
+ let usedTokens = 0;
41
74
  for (const ln of lines) {
42
75
  const stripped = stripAnsiEscapes(ln);
43
- const cost = ln.length + 1;
44
- if (kept.length === 0 && cost > charBudget) {
45
- 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);
46
80
  kept.push(truncated);
47
81
  break;
48
82
  }
49
- if (kept.length > 0 && used + cost > charBudget) {
83
+ if (kept.length > 0 && usedTokens + costTokens > bodyBudget) {
50
84
  break;
51
85
  }
52
86
  kept.push(ln);
53
- used += cost;
87
+ usedTokens += costTokens;
54
88
  }
55
89
  const shown = kept.length;
56
90
  const hint = getHintFor(command);
57
- const marker = `[token-goat: output capped at ~${budgetTokens} tokens to protect context \u2014 showing ${shown} of ${totalLines} lines. ${hint}]`;
58
- 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);
59
93
  }
60
94
  function capJsonRows(items, budgetTokens) {
61
95
  const totalCount = items.length;
62
- const charBudget = Math.max(1, budgetTokens * guardDivisor());
96
+ const budget = Math.max(TEXT_GUARD_UNITS, budgetTokens * GUARD_UNITS_PER_TOKEN);
63
97
  const kept = [];
64
98
  let used = 0;
65
99
  for (const item of items) {
66
- const cost = JSON.stringify(item).length + 2;
67
- 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;
68
102
  kept.push(item);
69
103
  used += cost;
70
104
  }
@@ -93,6 +127,8 @@ function getHintFor(command) {
93
127
  export {
94
128
  estimateTokensFromLength,
95
129
  estimateTokens,
130
+ sliceToEstimatedTokens,
131
+ isCappedOutput,
96
132
  trimToBudget,
97
133
  capJsonRows
98
134
  };
@@ -5,15 +5,17 @@ import {
5
5
  docxTables,
6
6
  docxText,
7
7
  formatDocxTables
8
- } from "./token-goat-chunk-UQ5UK2T7.mjs";
9
- import "./token-goat-chunk-IVKIZWAB.mjs";
10
- import "./token-goat-chunk-XTQAOTSO.mjs";
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";
11
12
  import "./token-goat-chunk-AH6QILZM.mjs";
12
13
  import "./token-goat-chunk-Y4AFKTHK.mjs";
13
- import "./token-goat-chunk-GOLEOXZP.mjs";
14
+ import "./token-goat-chunk-HU4TORC5.mjs";
15
+ import "./token-goat-chunk-GGGG7RWB.mjs";
14
16
  import "./token-goat-chunk-AM5V6GSX.mjs";
15
17
  import "./token-goat-chunk-FNFBKLRD.mjs";
16
- import "./token-goat-chunk-VES7EL7O.mjs";
18
+ import "./token-goat-chunk-CO3UYX6G.mjs";
17
19
  import "./token-goat-chunk-A37V4PBF.mjs";
18
20
  export {
19
21
  docxOutline,
@@ -9,10 +9,10 @@ import {
9
9
  foldToolName,
10
10
  replaceToolResponseField,
11
11
  vscodeNativeToolInput
12
- } from "./token-goat-chunk-VPBBTSJR.mjs";
12
+ } from "./token-goat-chunk-76FGDLRO.mjs";
13
13
  import {
14
14
  recordUnmappedTool
15
- } from "./token-goat-chunk-3Z5S4KGM.mjs";
15
+ } from "./token-goat-chunk-U4WHMG6Y.mjs";
16
16
  import {
17
17
  registerReset
18
18
  } from "./token-goat-chunk-YZAAZU2S.mjs";
@@ -26,33 +26,51 @@ init_define_import_meta_env();
26
26
  // src/bridges/vscode_hooks.ts
27
27
  init_define_import_meta_env();
28
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();
29
35
  import * as fs from "node:fs";
30
36
  import * as os from "node:os";
31
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
32
64
  function vscodeToolName(event) {
33
65
  const name = event?.raw[VSCODE_TOOL_NAME_KEY];
34
66
  return typeof name === "string" ? name : void 0;
35
67
  }
36
- var SHRINK_PREFIX = "token-goat-shrink-";
37
- var MATERIALIZED_MAX_AGE_MS = 60 * 60 * 1e3;
38
68
  var lastMaterializedSweepAtMs = 0;
39
69
  function pruneMaterialized() {
40
70
  const now = Date.now();
41
- if (now - lastMaterializedSweepAtMs < MATERIALIZED_MAX_AGE_MS) return;
71
+ if (now - lastMaterializedSweepAtMs < SHRINK_COPY_MAX_AGE_MS) return;
42
72
  lastMaterializedSweepAtMs = now;
43
- try {
44
- const dir = os.tmpdir();
45
- for (const file of fs.readdirSync(dir)) {
46
- if (!file.startsWith(SHRINK_PREFIX)) continue;
47
- const full = path.join(dir, file);
48
- try {
49
- const st = fs.statSync(full);
50
- if (st.isFile() && now - st.mtimeMs > MATERIALIZED_MAX_AGE_MS) fs.unlinkSync(full);
51
- } catch {
52
- }
53
- }
54
- } catch {
55
- }
73
+ sweepStaleShrinkCopies(now);
56
74
  }
57
75
  function materializeShrunkImageFile(context) {
58
76
  const idx = context.indexOf("data:image/");
@@ -61,13 +79,16 @@ function materializeShrunkImageFile(context) {
61
79
  if (!match) return void 0;
62
80
  try {
63
81
  pruneMaterialized();
64
- const file = path.join(os.tmpdir(), `${SHRINK_PREFIX}${process.pid}-${Date.now()}-${crypto.randomUUID()}.${match[1]}`);
65
- fs.writeFileSync(file, Buffer.from(match[2], "base64"), { mode: 384 });
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 });
66
84
  return file;
67
85
  } catch {
68
86
  return void 0;
69
87
  }
70
88
  }
89
+ function isShrunkImagePayload(eventName, context) {
90
+ return eventName === "pre_tool_use" && context.includes("data:image/");
91
+ }
71
92
  var NESTED_DECISION_EVENTS = /* @__PURE__ */ new Set(["stop", "subagent_stop"]);
72
93
  function serializeVscodeOutput(output, eventName, hookEventName, event) {
73
94
  switch (output.hookType) {
@@ -84,7 +105,7 @@ function serializeVscodeOutput(output, eventName, hookEventName, event) {
84
105
  case "context": {
85
106
  if (NESTED_DECISION_EVENTS.has(eventName)) return "{}";
86
107
  if (eventName === "pre_compact" || eventName === "notification") return JSON.stringify({ systemMessage: output.context });
87
- if (eventName === "pre_tool_use" && output.context.includes("data:image/")) return "{}";
108
+ if (isShrunkImagePayload(eventName, output.context)) return "{}";
88
109
  return JSON.stringify({ hookSpecificOutput: { hookEventName, additionalContext: output.context } });
89
110
  }
90
111
  case "rewriteInput": {
@@ -229,7 +250,8 @@ var CLAUDE_CODE_EVENT_NAMES = {
229
250
  };
230
251
  var EVENTS_WITHOUT_ADDITIONAL_CONTEXT = /* @__PURE__ */ new Set([
231
252
  "notification",
232
- "pre_compact"
253
+ "pre_compact",
254
+ "stop"
233
255
  ]);
234
256
  var EVENTS_WITH_RAW_STDOUT_CONTEXT = /* @__PURE__ */ new Set(["pre_compact"]);
235
257
  var BODY_FIRST_REWRITE_TOOLS = /* @__PURE__ */ new Set(["WebFetch", "Skill"]);
@@ -253,6 +275,9 @@ function serializeOutput(output, eventName, harness, event) {
253
275
  if (EVENTS_WITHOUT_ADDITIONAL_CONTEXT.has(eventName)) {
254
276
  return JSON.stringify({ systemMessage: output.context });
255
277
  }
278
+ if (harness === "claudecode" && isShrunkImagePayload(eventName, output.context)) {
279
+ return JSON.stringify(noticeField(output.notice, harness));
280
+ }
256
281
  return JSON.stringify({
257
282
  ...noticeField(output.notice, harness),
258
283
  hookSpecificOutput: {
@@ -264,7 +289,8 @@ function serializeOutput(output, eventName, harness, event) {
264
289
  return JSON.stringify({
265
290
  hookSpecificOutput: {
266
291
  hookEventName: "PreToolUse",
267
- permissionDecision: "allow",
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" } : {},
268
294
  updatedInput: output.updatedInput
269
295
  }
270
296
  });
@@ -286,6 +312,7 @@ function noticeField(notice, harness) {
286
312
  }
287
313
 
288
314
  export {
315
+ sweepStaleShrinkCopies,
289
316
  materializeShrunkImageFile,
290
317
  sessionStateKey,
291
318
  registerHook,
@@ -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
+ };