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
@@ -0,0 +1,33 @@
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/windows_powershell.ts
8
+ init_define_import_meta_env();
9
+
10
+ // src/windows_system32.ts
11
+ init_define_import_meta_env();
12
+ import * as fs from "node:fs";
13
+ import * as path from "node:path";
14
+ var DEFAULT_WINDOWS_DIR = "C:\\Windows";
15
+ function windowsSystem32Exe(...rel) {
16
+ const missing = path.join(DEFAULT_WINDOWS_DIR, "System32", ...rel);
17
+ for (const root of [process.env["SystemRoot"], process.env["windir"], DEFAULT_WINDOWS_DIR]) {
18
+ if (root === void 0 || !path.win32.isAbsolute(root)) continue;
19
+ const exe = path.join(root, "System32", ...rel);
20
+ if (fs.existsSync(exe)) return exe;
21
+ }
22
+ return missing;
23
+ }
24
+
25
+ // src/windows_powershell.ts
26
+ function windowsPowerShellPath() {
27
+ return windowsSystem32Exe("WindowsPowerShell", "v1.0", "powershell.exe");
28
+ }
29
+
30
+ export {
31
+ windowsSystem32Exe,
32
+ windowsPowerShellPath
33
+ };
@@ -3,6 +3,12 @@ const require = __cjsRequire(import.meta.url);
3
3
  import {
4
4
  external_exports
5
5
  } from "./token-goat-chunk-3U6ZYVX5.mjs";
6
+ import {
7
+ answeringMcpToolCall
8
+ } from "./token-goat-chunk-KGEFFSHD.mjs";
9
+ import {
10
+ displaySafeText
11
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
6
12
  import {
7
13
  init_define_import_meta_env
8
14
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -91,6 +97,10 @@ var McpServer = class {
91
97
  }
92
98
  }
93
99
  async handleMessage(message) {
100
+ if (message === null || typeof message !== "object" || Array.isArray(message)) {
101
+ await this.sendError(void 0, JSONRPC_INVALID_REQUEST, "Invalid Request: a JSON-RPC message must be a JSON object");
102
+ return;
103
+ }
94
104
  if (!isRequest(message)) return;
95
105
  const { id, method } = message;
96
106
  const params = message.params ?? {};
@@ -109,7 +119,7 @@ var McpServer = class {
109
119
  await this.send({ jsonrpc: "2.0", id, result: await this.callTool(params) });
110
120
  return;
111
121
  default:
112
- await this.sendError(id, JSONRPC_METHOD_NOT_FOUND, `Method not found: ${method}`);
122
+ await this.sendError(id, JSONRPC_METHOD_NOT_FOUND, `Method not found: ${displaySafeText(method)}`);
113
123
  return;
114
124
  }
115
125
  } catch (err) {
@@ -117,7 +127,7 @@ var McpServer = class {
117
127
  }
118
128
  }
119
129
  async sendError(id, code, message) {
120
- await this.send({ jsonrpc: "2.0", id, error: { code, message } });
130
+ await this.send(id === void 0 ? { jsonrpc: "2.0", error: { code, message } } : { jsonrpc: "2.0", id, error: { code, message } });
121
131
  }
122
132
  initializeResult(params) {
123
133
  const requested = params["protocolVersion"];
@@ -153,7 +163,7 @@ var McpServer = class {
153
163
  );
154
164
  }
155
165
  try {
156
- return await handler(parsed.data);
166
+ return await answeringMcpToolCall(() => handler(parsed.data), new Set(this.tools.keys()));
157
167
  } catch (err) {
158
168
  return errorText(err instanceof Error ? err.message : String(err));
159
169
  }
@@ -0,0 +1,573 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ diagnoseSqlFailure
5
+ } from "./token-goat-chunk-PX5PQWTY.mjs";
6
+ import {
7
+ SEARCH_COMMAND_RE,
8
+ classifyToolError
9
+ } from "./token-goat-chunk-JVFSHVFJ.mjs";
10
+ import {
11
+ PIPELINE_PASSTHROUGH_HEADS,
12
+ extractCommand,
13
+ pureFileReadPath,
14
+ stripCommandPrefix,
15
+ unwrapCompressCommand
16
+ } from "./token-goat-chunk-ODBT2USM.mjs";
17
+ import {
18
+ splitShellSegments,
19
+ stripLeadingAssignments
20
+ } from "./token-goat-chunk-DGS2LVNA.mjs";
21
+ import {
22
+ applyHintTracking,
23
+ settleSelfScoredHints,
24
+ uncorrelatedHint
25
+ } from "./token-goat-chunk-4SMRO4TO.mjs";
26
+ import {
27
+ sessionSidecarPath
28
+ } from "./token-goat-chunk-WBA5SKT4.mjs";
29
+ import {
30
+ registerHook,
31
+ sessionStateKey
32
+ } from "./token-goat-chunk-C75NA7PL.mjs";
33
+ import {
34
+ OUTPUT_FIRST_TOOL_RESPONSE_KEYS,
35
+ contextOutput,
36
+ estimateResultCount,
37
+ extractToolResponseField,
38
+ getFilePath,
39
+ getToolInput,
40
+ getToolName,
41
+ passOutput,
42
+ resolveEventPath,
43
+ structuredResultCount
44
+ } from "./token-goat-chunk-76FGDLRO.mjs";
45
+ import {
46
+ recordStat
47
+ } from "./token-goat-chunk-U4WHMG6Y.mjs";
48
+ import {
49
+ buildLineIndex,
50
+ offsetToLine
51
+ } from "./token-goat-chunk-OUKDTVNU.mjs";
52
+ import {
53
+ redactSecrets
54
+ } from "./token-goat-chunk-T5P5ACNQ.mjs";
55
+ import {
56
+ ensureDirSync
57
+ } from "./token-goat-chunk-HU4TORC5.mjs";
58
+ import {
59
+ displaySafeText,
60
+ hostPathOfIndexKey,
61
+ normalizePath
62
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
63
+ import {
64
+ init_define_import_meta_env
65
+ } from "./token-goat-chunk-A37V4PBF.mjs";
66
+
67
+ // src/hooks_tool_failure.ts
68
+ init_define_import_meta_env();
69
+ import { createHash } from "node:crypto";
70
+ import { existsSync, readFileSync as readFileSync2, statSync, writeFileSync as writeFileSync2 } from "node:fs";
71
+ import { dirname as dirname2, relative } from "node:path";
72
+
73
+ // src/call_streak.ts
74
+ init_define_import_meta_env();
75
+ import { readFileSync, writeFileSync } from "node:fs";
76
+ import { dirname } from "node:path";
77
+ var SERIAL_GAP_MS = 1e3;
78
+ var SERIAL_READS_BEFORE_HINT = 3;
79
+ var ZERO_HIT_SEARCHES_BEFORE_BRAKE = 3;
80
+ var MAX_BATCH_HINTS_PER_SESSION = 2;
81
+ var MAX_SEARCH_BRAKES_PER_SESSION = 2;
82
+ var STREAK_SUFFIX = ".call-streak";
83
+ var TG_SEARCH_RE = /^(?:token-goat|tg)\s+(?:answer|semantic|symbol|refs|locate)\b/;
84
+ var TG_MEANING_SEARCH_RE = /^(?:token-goat|tg)\s+(?:answer|semantic)\b/;
85
+ var TG_READ_RE = /^(?:token-goat|tg)\s+(?:read|section|outline|skeleton|brief)\b/;
86
+ var WRITE_REDIRECT_RE = /\d?>>?(?!\s*(?:&\d|\/dev\/null\b))/;
87
+ function freshState() {
88
+ return { promptId: "", lastReadPostAt: 0, inFlight: false, serialRun: 0, batchShownInRun: false, batchShown: 0, batchVerdict: "none", zeroHits: 0, brakeShownInRun: false, brakeShown: 0, brakeVerdict: false };
89
+ }
90
+ function readState(target) {
91
+ const state = freshState();
92
+ try {
93
+ const parsed = JSON.parse(readFileSync(target, "utf8"));
94
+ if (parsed === null || typeof parsed !== "object") return state;
95
+ const p = parsed;
96
+ for (const key of Object.keys(state)) {
97
+ if (typeof p[key] === typeof state[key]) state[key] = p[key];
98
+ }
99
+ if (!["none", "next_turn", "second_call"].includes(state.batchVerdict)) state.batchVerdict = "none";
100
+ } catch {
101
+ }
102
+ return state;
103
+ }
104
+ function writeState(target, state) {
105
+ try {
106
+ ensureDirSync(dirname(target));
107
+ writeFileSync(target, JSON.stringify(state), "utf8");
108
+ } catch {
109
+ }
110
+ }
111
+ var MUTATING = { readOnly: false, search: false, meaningSearch: false };
112
+ function isPassThroughStage(stage) {
113
+ const head = (stage.split(/\s/, 1)[0] ?? "").replace(/^.*[/\\]/, "");
114
+ return head !== "tee" && PIPELINE_PASSTHROUGH_HEADS.has(head);
115
+ }
116
+ function bashCallKind(event) {
117
+ const raw = extractCommand(event);
118
+ if (raw === void 0) return MUTATING;
119
+ const cmd = stripCommandPrefix(unwrapCompressCommand(raw) ?? raw);
120
+ const stages = splitShellSegments(cmd).map((s) => stripLeadingAssignments(s.trim())).filter((s) => s !== "");
121
+ if (stages.length === 0 || stages.some((s) => WRITE_REDIRECT_RE.test(s))) return MUTATING;
122
+ const searches = stages.filter((s) => SEARCH_COMMAND_RE.test(s) || TG_SEARCH_RE.test(s));
123
+ const readOnly = pureFileReadPath(cmd) !== null || stages.every((s) => SEARCH_COMMAND_RE.test(s) || TG_SEARCH_RE.test(s) || TG_READ_RE.test(s) || isPassThroughStage(s));
124
+ if (!readOnly) return MUTATING;
125
+ return { readOnly, search: searches.length > 0, meaningSearch: TG_MEANING_SEARCH_RE.test(stages[0] ?? "") };
126
+ }
127
+ function callKind(event) {
128
+ switch (event.toolName) {
129
+ case "Read":
130
+ return { readOnly: true, search: false, meaningSearch: false };
131
+ case "Grep":
132
+ case "Glob":
133
+ return { readOnly: true, search: true, meaningSearch: false };
134
+ case "Bash":
135
+ return bashCallKind(event);
136
+ default:
137
+ return MUTATING;
138
+ }
139
+ }
140
+ function searchResultCount(event) {
141
+ const structured = structuredResultCount(event.raw);
142
+ if (structured !== null) return structured;
143
+ const text = extractToolResponseField(event.raw, OUTPUT_FIRST_TOOL_RESPONSE_KEYS);
144
+ if (event.toolName === "Bash") return text.trim() === "" ? 0 : 1;
145
+ return text === "" ? null : estimateResultCount(text);
146
+ }
147
+ function batchHintText(run) {
148
+ return `[token-goat] ${run} reads/searches in a row each waited a full turn. Issue independent reads and searches together in one message.`;
149
+ }
150
+ function searchBrakeText(misses) {
151
+ return `[token-goat] ${misses} searches in a row found nothing. Search by meaning instead of guessing literals: \`token-goat answer "<question>"\` or \`token-goat semantic "<description>"\`.`;
152
+ }
153
+ function trackedLine(event, category, text) {
154
+ const out = applyHintTracking(event, contextOutput(text, [sessionStateKey(event)]), uncorrelatedHint(category));
155
+ if (out.hookType !== "context") return null;
156
+ recordStat("session_hint", 0, 0);
157
+ return out.context;
158
+ }
159
+ function breakStreaks(event, state) {
160
+ if (state.batchVerdict === "second_call") {
161
+ settleSelfScoredHints("read_batch", event, false);
162
+ state.batchVerdict = "none";
163
+ }
164
+ Object.assign(state, { lastReadPostAt: 0, inFlight: false, serialRun: 0, batchShownInRun: false, zeroHits: 0, brakeShownInRun: false });
165
+ }
166
+ function onReadOnlyPre(event, state, kind, now, canSpeak) {
167
+ const serial = !state.inFlight && (state.lastReadPostAt === 0 || now - state.lastReadPostAt > SERIAL_GAP_MS);
168
+ state.inFlight = true;
169
+ if (state.batchVerdict === "second_call") {
170
+ settleSelfScoredHints("read_batch", event, !serial);
171
+ state.batchVerdict = "none";
172
+ } else if (state.batchVerdict === "next_turn" && serial) {
173
+ state.batchVerdict = "second_call";
174
+ }
175
+ if (state.brakeVerdict && kind.search && serial) {
176
+ settleSelfScoredHints("search_brake", event, kind.meaningSearch);
177
+ state.brakeVerdict = false;
178
+ }
179
+ if (!serial) {
180
+ state.serialRun = 0;
181
+ state.batchShownInRun = false;
182
+ return null;
183
+ }
184
+ state.serialRun += 1;
185
+ if (state.serialRun < SERIAL_READS_BEFORE_HINT || state.batchShownInRun || state.batchShown >= MAX_BATCH_HINTS_PER_SESSION || !canSpeak) return null;
186
+ state.batchShownInRun = true;
187
+ const line = trackedLine(event, "read_batch", batchHintText(state.serialRun));
188
+ if (line === null) return null;
189
+ state.batchShown += 1;
190
+ state.batchVerdict = "next_turn";
191
+ return line;
192
+ }
193
+ function onSearchMiss(event, state, canSpeak) {
194
+ state.zeroHits += 1;
195
+ if (state.zeroHits < ZERO_HIT_SEARCHES_BEFORE_BRAKE || state.brakeShownInRun || state.brakeShown >= MAX_SEARCH_BRAKES_PER_SESSION || !canSpeak) return null;
196
+ state.brakeShownInRun = true;
197
+ const line = trackedLine(event, "search_brake", searchBrakeText(state.zeroHits));
198
+ if (line === null) return null;
199
+ state.brakeShown += 1;
200
+ state.brakeVerdict = true;
201
+ return line;
202
+ }
203
+ function onReadOnlyPost(event, state, kind, now, canSpeak) {
204
+ state.inFlight = false;
205
+ state.lastReadPostAt = now;
206
+ if (!kind.search) return null;
207
+ const count = searchResultCount(event);
208
+ if (count === null) return null;
209
+ if (count === 0) return onSearchMiss(event, state, canSpeak);
210
+ state.zeroHits = 0;
211
+ state.brakeShownInRun = false;
212
+ return null;
213
+ }
214
+ function withStreakState(event, update) {
215
+ if (!event.sessionId) return null;
216
+ const target = sessionSidecarPath(sessionStateKey(event), STREAK_SUFFIX);
217
+ if (target === null) return null;
218
+ const state = readState(target);
219
+ const before = JSON.stringify(state);
220
+ const promptId = event.raw["prompt_id"];
221
+ if (typeof promptId === "string" && promptId !== state.promptId) {
222
+ breakStreaks(event, state);
223
+ if (state.batchVerdict !== "none") settleSelfScoredHints("read_batch", event, null);
224
+ if (state.brakeVerdict) settleSelfScoredHints("search_brake", event, null);
225
+ state.batchVerdict = "none";
226
+ state.brakeVerdict = false;
227
+ state.promptId = promptId;
228
+ }
229
+ const line = update(state);
230
+ if (JSON.stringify(state) !== before) writeState(target, state);
231
+ return line;
232
+ }
233
+ function applyCallStreak(event, output, now) {
234
+ if (event.eventName !== "pre_tool_use" && event.eventName !== "post_tool_use") return output;
235
+ if (output.hookType === "deny") return output;
236
+ try {
237
+ const canSpeak = output.hookType === "pass" || output.hookType === "context";
238
+ const kind = callKind(event);
239
+ const line = withStreakState(event, (state) => {
240
+ if (!kind.readOnly) {
241
+ breakStreaks(event, state);
242
+ return null;
243
+ }
244
+ return event.eventName === "pre_tool_use" ? onReadOnlyPre(event, state, kind, now, canSpeak) : onReadOnlyPost(event, state, kind, now, canSpeak);
245
+ });
246
+ if (line === null) return output;
247
+ return output.hookType === "context" ? { ...output, context: `${output.context}
248
+ ${line}` } : contextOutput(line);
249
+ } catch {
250
+ return output;
251
+ }
252
+ }
253
+ function callStreakAfterFailure(event, reason) {
254
+ try {
255
+ const kind = callKind(event);
256
+ const line = withStreakState(event, (state) => {
257
+ if (!kind.readOnly) {
258
+ breakStreaks(event, state);
259
+ return null;
260
+ }
261
+ state.inFlight = false;
262
+ state.lastReadPostAt = Date.now();
263
+ return reason === "search_no_match" ? onSearchMiss(event, state, true) : null;
264
+ });
265
+ return line === null ? null : contextOutput(line);
266
+ } catch {
267
+ return null;
268
+ }
269
+ }
270
+
271
+ // src/hooks_verification.ts
272
+ init_define_import_meta_env();
273
+ var VERIFICATION_WORD = /test|jest|lint|check|build|compile|verify|tsc|ruff|clippy|mypy|pyright|\bvet\b/i;
274
+ function mayBeVerificationCommand(command) {
275
+ return VERIFICATION_WORD.test(command);
276
+ }
277
+ registerHook("stop", async (event) => (await import("./token-goat-chunk-OS5EM5PP.mjs")).stopHandler(event), { advisory: true });
278
+ async function noteFailedVerificationHandler(event) {
279
+ const executed = getToolInput(event)["command"];
280
+ const command = typeof executed === "string" ? unwrapCompressCommand(executed) ?? executed : null;
281
+ if (getToolName(event)?.toLowerCase() === "bash" && command !== null && mayBeVerificationCommand(command)) {
282
+ const [failure, verification] = await Promise.all([import("./token-goat-chunk-XZSUHBVS.mjs"), import("./token-goat-chunk-QFNQXSDT.mjs")]);
283
+ const errorText = failure.extractFailureText(event.raw);
284
+ if (errorText !== "") verification.noteFailedVerificationRun(command, errorText, event.raw["is_interrupt"] === true);
285
+ }
286
+ return passOutput();
287
+ }
288
+
289
+ // src/hooks_tool_failure.ts
290
+ var FAILURE_SUFFIX = ".tool-failures";
291
+ var MAX_TRACKED_FAILURES = 64;
292
+ var SIGNATURE_ERROR_CHARS = 200;
293
+ var LEDGER_VERSION = 2;
294
+ function failureSignature(toolName, errorText) {
295
+ const tool = toolName === void 0 || toolName === "" ? "unknown" : toolName;
296
+ const normalized = errorText.replace(/\s+/g, " ").trim().slice(0, SIGNATURE_ERROR_CHARS);
297
+ return `${tool} :: ${normalized}`;
298
+ }
299
+ function extractFailureText(raw) {
300
+ for (const key of ["error", "errorMessage", "tool_error", "toolError", "message", "reason"]) {
301
+ const value = raw[key];
302
+ if (typeof value === "string" && value.trim() !== "") return value;
303
+ }
304
+ const response = raw["tool_response"] ?? raw["toolResponse"];
305
+ if (typeof response === "string" && response.trim() !== "") return response;
306
+ if (response !== null && typeof response === "object") {
307
+ const nested = response["error"];
308
+ if (typeof nested === "string" && nested.trim() !== "") return nested;
309
+ }
310
+ return "";
311
+ }
312
+ function ledgerPath(sessionId) {
313
+ return sessionSidecarPath(sessionId, FAILURE_SUFFIX);
314
+ }
315
+ function readLedger(target) {
316
+ try {
317
+ const parsed = JSON.parse(readFileSync2(target, "utf8"));
318
+ if (parsed !== null && typeof parsed === "object") {
319
+ if (parsed.version !== LEDGER_VERSION) return { seen: {}, order: [] };
320
+ const seen = parsed.seen;
321
+ const order = parsed.order;
322
+ if (seen !== null && typeof seen === "object" && Array.isArray(order)) {
323
+ return { seen, order: order.filter((k) => typeof k === "string") };
324
+ }
325
+ }
326
+ } catch {
327
+ }
328
+ return { seen: {}, order: [] };
329
+ }
330
+ function writeLedger(target, ledger) {
331
+ try {
332
+ ensureDirSync(dirname2(target));
333
+ writeFileSync2(target, JSON.stringify({ version: LEDGER_VERSION, ...ledger }), "utf8");
334
+ } catch {
335
+ }
336
+ }
337
+ var REPEAT_NOTICE_EXEMPT = /* @__PURE__ */ new Set([
338
+ // Refusals and stops. Claude Code never delivers a refused call to this event (a PreToolUse deny fired no PostToolUseFailure in a 2.1.281 capture), so these guard the other harnesses that route failures here.
339
+ "interrupted",
340
+ // the payload's is_interrupt flag; the census has 0 rows because an interrupt never surfaces as an is_error result
341
+ "tg_deny",
342
+ // 2,762 rows, 283 repeats, 13 with the same input: the deny names the command to run instead
343
+ "tg_content_delivered",
344
+ // a deny whose text is the content (a Skill's compact slice or heading tree, a served Read sidecar): the call did its job, so there is nothing to retry
345
+ "hook_deny",
346
+ // 5 rows: another hook's refusal, with its own instruction
347
+ "user_rejected",
348
+ // 73 rows, 21 repeats, 1 with the same input
349
+ "auto_mode_blocked",
350
+ // 1 row
351
+ // Generic wording: a repeat was a different call that failed the same way.
352
+ "search_no_match",
353
+ // 99 repeats, 0 with the same input: every empty grep prints the same bare `Exit code 1`
354
+ "command_timeout",
355
+ // 41 repeats, 0 with the same input
356
+ "subagent_limit",
357
+ // 27 repeats, 1 with the same input; the harness's own text already says not to retry
358
+ "input_validation"
359
+ // 23 repeats, 0 with the same input
360
+ ]);
361
+ function repeatFailureNotice(toolName) {
362
+ const tool = toolName === void 0 || toolName === "" ? "This tool" : displaySafeText(toolName);
363
+ return `[token-goat] ${tool} just failed with the same error as an earlier call this session. Retrying it unchanged will fail the same way -- change the arguments, the tool, or the approach.`;
364
+ }
365
+ var nearMissLib;
366
+ async function loadNearMiss() {
367
+ try {
368
+ nearMissLib ??= await import("./token-goat-chunk-5IMLKSOP.mjs");
369
+ } catch {
370
+ }
371
+ }
372
+ var MAX_EDIT_DIAGNOSE_BYTES = 10 * 1024 * 1024;
373
+ function editOldStrings(event) {
374
+ const input = event.toolInput;
375
+ const out = [];
376
+ for (const key of ["old_string", "old_str", "target", "TargetContent"]) {
377
+ const value = input[key];
378
+ if (typeof value === "string" && value !== "") {
379
+ out.push(value);
380
+ break;
381
+ }
382
+ }
383
+ const edits = input["edits"];
384
+ if (Array.isArray(edits)) {
385
+ for (const entry of edits) {
386
+ const value = entry !== null && typeof entry === "object" ? entry["old_string"] : void 0;
387
+ if (typeof value === "string" && value !== "") out.push(value);
388
+ }
389
+ }
390
+ return out;
391
+ }
392
+ function diagnoseEditFailure(event, errorText) {
393
+ const toolName = getToolName(event);
394
+ if (!toolName || !/^(edit|multiedit|str_replace_editor)$/i.test(toolName)) {
395
+ return null;
396
+ }
397
+ const isMultiple = /multiple matches|not unique|found \d+ matches|matches \d+ times|more than one match/i.test(errorText);
398
+ const isNotFound = /no match|not found|could not find|zero matches|string to replace.*not found/i.test(errorText);
399
+ if (!isMultiple && !isNotFound) {
400
+ return null;
401
+ }
402
+ const fallbackPath = ["path", "TargetFile"].map((key) => event.toolInput[key]).find((value) => typeof value === "string" && value !== "");
403
+ const filePath = getFilePath(event) ?? (fallbackPath === void 0 ? void 0 : resolveEventPath(event, fallbackPath));
404
+ if (!filePath) return null;
405
+ const oldStrings = editOldStrings(event);
406
+ if (oldStrings.length === 0) return null;
407
+ const absPath = hostPathOfIndexKey(normalizePath(filePath));
408
+ if (!existsSync(absPath)) return null;
409
+ try {
410
+ const stat = statSync(absPath);
411
+ if (stat.size > MAX_EDIT_DIAGNOSE_BYTES) return null;
412
+ const fileContent = readFileSync2(absPath, "utf8");
413
+ const oldString = oldStrings.length === 1 ? oldStrings[0] : oldStrings.find((candidate) => isNotFound ? !fileContent.includes(candidate) : fileContent.indexOf(candidate) !== fileContent.lastIndexOf(candidate));
414
+ if (oldString === void 0) return null;
415
+ const relDisplay = displaySafeText(relative(process.cwd(), absPath).replace(/\\/g, "/") || absPath);
416
+ if (isMultiple) {
417
+ const matchLines = [];
418
+ const lineIndex = buildLineIndex(fileContent);
419
+ let pos = 0;
420
+ while (pos < fileContent.length) {
421
+ const idx = fileContent.indexOf(oldString, pos);
422
+ if (idx === -1) break;
423
+ matchLines.push(offsetToLine(lineIndex, idx));
424
+ pos = idx + Math.max(1, oldString.length);
425
+ }
426
+ if (matchLines.length > 1) {
427
+ const lineList = matchLines.slice(0, 5).join(", ");
428
+ const overflow = matchLines.length > 5 ? ` (+${matchLines.length - 5} more)` : "";
429
+ return `[token-goat] Edit failed: string matched ${matchLines.length} times in ${relDisplay} on lines ${lineList}${overflow}. Include 2-3 lines of surrounding context to make old_str unique.`;
430
+ }
431
+ }
432
+ if (isNotFound) {
433
+ const normOld = oldString.replace(/\r\n/g, "\n");
434
+ const normFile = fileContent.replace(/\r\n/g, "\n");
435
+ if (normFile.includes(normOld)) {
436
+ return `[token-goat] Edit failed: string not found in ${relDisplay}, but matches with normalized line endings. Check CRLF vs LF line endings or whitespace.`;
437
+ }
438
+ const nearMiss = nearMissLib?.findNearMiss(fileContent, oldString) ?? null;
439
+ const nearAdvice = nearMiss === null ? null : nearMissLib?.describeNearMiss(fileContent, relDisplay, nearMiss) ?? null;
440
+ if (nearAdvice !== null) return nearAdvice;
441
+ const firstLine = oldString.split(/\r?\n/)[0]?.trim() ?? "";
442
+ if (firstLine.length >= 10) {
443
+ const fileLines = fileContent.split("\n");
444
+ const similarLines = [];
445
+ for (let i = 0; i < fileLines.length; i++) {
446
+ const lineText = fileLines[i];
447
+ if (lineText !== void 0 && lineText.includes(firstLine)) {
448
+ similarLines.push(i + 1);
449
+ if (similarLines.length >= 3) break;
450
+ }
451
+ }
452
+ if (similarLines.length > 0) {
453
+ return `[token-goat] Edit failed: string not found in ${relDisplay}. A similar line was found on line ${similarLines.join(", ")} \u2014 view that range to copy exact text.`;
454
+ }
455
+ }
456
+ return `[token-goat] Edit failed: string not found in ${relDisplay}. View the target lines to copy the exact current content and indentation.`;
457
+ }
458
+ } catch {
459
+ }
460
+ return null;
461
+ }
462
+ function editAdviceOutput(event, text) {
463
+ const out = contextOutput(text);
464
+ return nearMissLib?.isNearMissAdvice(text) === true ? applyHintTracking(event, out, uncorrelatedHint("edit_near_miss")) : out;
465
+ }
466
+ var RECOVERY_SKIPPED = /* @__PURE__ */ new Set(["shell_syntax_error", "sleep_blocked"]);
467
+ function newSlot() {
468
+ return { lines: [], recovery: null, pathMiss: null };
469
+ }
470
+ function withExtraLines(base, lines) {
471
+ if (lines.length === 0) return base;
472
+ const extra = lines.join("\n");
473
+ if (base.hookType === "context") return contextOutput([base.context, extra].join("\n"), base.correlators);
474
+ return base.hookType === "pass" ? contextOutput(extra) : base;
475
+ }
476
+ function postToolUseFailureHandler(event) {
477
+ return adviseOnFailure(event, newSlot());
478
+ }
479
+ async function postToolUseFailureWithExtras(event) {
480
+ const slot = newSlot();
481
+ const toolName = getToolName(event);
482
+ if (toolName !== void 0 && /^(edit|multiedit|str_replace_editor)$/i.test(toolName)) await loadNearMiss();
483
+ const base = adviseOnFailure(event, slot);
484
+ try {
485
+ if (slot.recovery !== null) {
486
+ const { recoveryAfterFailure } = await import("./token-goat-chunk-FDSREWLX.mjs");
487
+ const recovery = recoveryAfterFailure(event, { command: slot.recovery.command, errorText: slot.recovery.errorText });
488
+ if (recovery !== null) slot.lines.push(recovery);
489
+ }
490
+ if (slot.pathMiss !== null) {
491
+ const { pathMissAfterFailure } = await import("./token-goat-chunk-3EZRNKTK.mjs");
492
+ const pathMiss = pathMissAfterFailure(event, slot.pathMiss);
493
+ if (pathMiss !== null) slot.lines.push(pathMiss);
494
+ }
495
+ } catch {
496
+ }
497
+ return withExtraLines(base, slot.lines);
498
+ }
499
+ function adviseOnFailure(event, slot) {
500
+ try {
501
+ const errorText = extractFailureText(event.raw);
502
+ if (errorText === "") return passOutput();
503
+ const toolName = getToolName(event);
504
+ const executed = getToolInput(event)["command"];
505
+ const command = typeof executed === "string" ? unwrapCompressCommand(executed) ?? executed : executed;
506
+ const verdict = classifyToolError(toolName, errorText, { isInterrupt: event.raw["is_interrupt"] === true, ...typeof command === "string" ? { command } : {} });
507
+ recordStat("tool_failure", 0, 0, void 0, `tool=${(toolName ?? "unknown").replace(/\s+/g, "_")} class=${verdict.kind} reason=${verdict.reason}`);
508
+ const streakLine = callStreakAfterFailure(event, verdict.reason);
509
+ if (toolName === "Bash" && typeof command === "string" && event.raw["is_interrupt"] !== true && !REPEAT_NOTICE_EXEMPT.has(verdict.reason) && !RECOVERY_SKIPPED.has(verdict.reason)) {
510
+ slot.recovery = { toolName, errorText, command };
511
+ }
512
+ if (verdict.reason === "path_not_found" && event.raw["is_interrupt"] !== true) {
513
+ slot.pathMiss = { toolName, errorText };
514
+ }
515
+ if (REPEAT_NOTICE_EXEMPT.has(verdict.reason)) return streakLine ?? passOutput();
516
+ if (!event.sessionId) return passOutput();
517
+ const target = ledgerPath(event.sessionId);
518
+ if (target === null) return passOutput();
519
+ const signature = createHash("sha256").update(failureSignature(toolName, redactSecrets(errorText).text)).digest("hex");
520
+ const ledger = readLedger(target);
521
+ const priorState = ledger.seen[signature];
522
+ const editDiagnostic = diagnoseEditFailure(event, errorText);
523
+ const sqlDiagnostic = diagnoseSqlFailure(event, errorText);
524
+ if (priorState === void 0) {
525
+ ledger.seen[signature] = false;
526
+ ledger.order.push(signature);
527
+ while (ledger.order.length > MAX_TRACKED_FAILURES) {
528
+ const evicted = ledger.order.shift();
529
+ if (evicted !== void 0) delete ledger.seen[evicted];
530
+ }
531
+ writeLedger(target, ledger);
532
+ if (editDiagnostic !== null) {
533
+ ledger.seen[signature] = true;
534
+ writeLedger(target, ledger);
535
+ return editAdviceOutput(event, editDiagnostic);
536
+ }
537
+ if (sqlDiagnostic !== null) {
538
+ ledger.seen[signature] = true;
539
+ writeLedger(target, ledger);
540
+ return contextOutput(sqlDiagnostic);
541
+ }
542
+ return passOutput();
543
+ }
544
+ if (priorState) return passOutput();
545
+ ledger.seen[signature] = true;
546
+ writeLedger(target, ledger);
547
+ if (editDiagnostic !== null) {
548
+ return editAdviceOutput(event, editDiagnostic);
549
+ }
550
+ if (sqlDiagnostic !== null) {
551
+ return contextOutput(sqlDiagnostic);
552
+ }
553
+ return contextOutput(repeatFailureNotice(toolName));
554
+ } catch {
555
+ return passOutput();
556
+ }
557
+ }
558
+ registerHook("post_tool_use_failure", noteFailedVerificationHandler, { advisory: true });
559
+ registerHook("post_tool_use_failure", postToolUseFailureWithExtras);
560
+
561
+ export {
562
+ applyCallStreak,
563
+ MAX_TRACKED_FAILURES,
564
+ failureSignature,
565
+ extractFailureText,
566
+ REPEAT_NOTICE_EXEMPT,
567
+ repeatFailureNotice,
568
+ loadNearMiss,
569
+ diagnoseEditFailure,
570
+ postToolUseFailureHandler,
571
+ postToolUseFailureWithExtras,
572
+ mayBeVerificationCommand
573
+ };