@smeltjs/core 0.2.0 → 0.4.0

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 (348) hide show
  1. package/README.md +3 -3
  2. package/dist/agents/guide.d.ts +68 -0
  3. package/dist/agents/guide.d.ts.map +1 -0
  4. package/dist/agents/guide.js +72 -0
  5. package/dist/agents/guide.js.map +1 -0
  6. package/dist/agents/instructions.d.ts +133 -0
  7. package/dist/agents/instructions.d.ts.map +1 -0
  8. package/dist/agents/instructions.js +212 -0
  9. package/dist/agents/instructions.js.map +1 -0
  10. package/dist/agents/lint.d.ts +154 -0
  11. package/dist/agents/lint.d.ts.map +1 -0
  12. package/dist/agents/lint.js +761 -0
  13. package/dist/agents/lint.js.map +1 -0
  14. package/dist/agents/split.d.ts +113 -0
  15. package/dist/agents/split.d.ts.map +1 -0
  16. package/dist/agents/split.js +234 -0
  17. package/dist/agents/split.js.map +1 -0
  18. package/dist/apply.d.ts.map +1 -1
  19. package/dist/apply.js.map +1 -1
  20. package/dist/cache/prefix.d.ts.map +1 -1
  21. package/dist/cache/prefix.js.map +1 -1
  22. package/dist/cli/agents.d.ts +39 -0
  23. package/dist/cli/agents.d.ts.map +1 -0
  24. package/dist/cli/agents.js +121 -0
  25. package/dist/cli/agents.js.map +1 -0
  26. package/dist/cli/args.d.ts +17 -70
  27. package/dist/cli/args.d.ts.map +1 -1
  28. package/dist/cli/args.js +18 -338
  29. package/dist/cli/args.js.map +1 -1
  30. package/dist/cli/bin.d.ts.map +1 -1
  31. package/dist/cli/bin.js.map +1 -1
  32. package/dist/cli/config.d.ts +60 -0
  33. package/dist/cli/config.d.ts.map +1 -1
  34. package/dist/cli/config.js +89 -2
  35. package/dist/cli/config.js.map +1 -1
  36. package/dist/cli/hooks.d.ts +55 -51
  37. package/dist/cli/hooks.d.ts.map +1 -1
  38. package/dist/cli/hooks.js +206 -658
  39. package/dist/cli/hooks.js.map +1 -1
  40. package/dist/cli/init.d.ts +30 -15
  41. package/dist/cli/init.d.ts.map +1 -1
  42. package/dist/cli/init.js +167 -38
  43. package/dist/cli/init.js.map +1 -1
  44. package/dist/cli/report.d.ts +23 -0
  45. package/dist/cli/report.d.ts.map +1 -1
  46. package/dist/cli/report.js +142 -4
  47. package/dist/cli/report.js.map +1 -1
  48. package/dist/cli/run.d.ts +29 -90
  49. package/dist/cli/run.d.ts.map +1 -1
  50. package/dist/cli/run.js +34 -342
  51. package/dist/cli/run.js.map +1 -1
  52. package/dist/cli/shell.d.ts +106 -0
  53. package/dist/cli/shell.d.ts.map +1 -0
  54. package/dist/cli/shell.js +100 -0
  55. package/dist/cli/shell.js.map +1 -0
  56. package/dist/cli/subcommands/agents.d.ts +72 -0
  57. package/dist/cli/subcommands/agents.d.ts.map +1 -0
  58. package/dist/cli/subcommands/agents.js +162 -0
  59. package/dist/cli/subcommands/agents.js.map +1 -0
  60. package/dist/cli/subcommands/flags.d.ts +144 -0
  61. package/dist/cli/subcommands/flags.d.ts.map +1 -0
  62. package/dist/cli/subcommands/flags.js +220 -0
  63. package/dist/cli/subcommands/flags.js.map +1 -0
  64. package/dist/cli/subcommands/hooks.d.ts +18 -0
  65. package/dist/cli/subcommands/hooks.d.ts.map +1 -0
  66. package/dist/cli/subcommands/hooks.js +80 -0
  67. package/dist/cli/subcommands/hooks.js.map +1 -0
  68. package/dist/cli/subcommands/init.d.ts +19 -0
  69. package/dist/cli/subcommands/init.d.ts.map +1 -0
  70. package/dist/cli/subcommands/init.js +44 -0
  71. package/dist/cli/subcommands/init.js.map +1 -0
  72. package/dist/cli/subcommands/map.d.ts +75 -0
  73. package/dist/cli/subcommands/map.d.ts.map +1 -0
  74. package/dist/cli/subcommands/map.js +132 -0
  75. package/dist/cli/subcommands/map.js.map +1 -0
  76. package/dist/cli/subcommands/registry.d.ts +81 -0
  77. package/dist/cli/subcommands/registry.d.ts.map +1 -0
  78. package/dist/cli/subcommands/registry.js +141 -0
  79. package/dist/cli/subcommands/registry.js.map +1 -0
  80. package/dist/cli/subcommands/retrieve.d.ts +74 -0
  81. package/dist/cli/subcommands/retrieve.d.ts.map +1 -0
  82. package/dist/cli/subcommands/retrieve.js +84 -0
  83. package/dist/cli/subcommands/retrieve.js.map +1 -0
  84. package/dist/cli/subcommands/smelt.d.ts +107 -0
  85. package/dist/cli/subcommands/smelt.d.ts.map +1 -0
  86. package/dist/cli/subcommands/smelt.js +304 -0
  87. package/dist/cli/subcommands/smelt.js.map +1 -0
  88. package/dist/cli/subcommands/stats.d.ts +43 -0
  89. package/dist/cli/subcommands/stats.d.ts.map +1 -0
  90. package/dist/cli/subcommands/stats.js +62 -0
  91. package/dist/cli/subcommands/stats.js.map +1 -0
  92. package/dist/cli/subcommands/subcommand.d.ts +113 -0
  93. package/dist/cli/subcommands/subcommand.d.ts.map +1 -0
  94. package/dist/cli/subcommands/subcommand.js +3 -0
  95. package/dist/cli/subcommands/subcommand.js.map +1 -0
  96. package/dist/cli/usage.d.ts +3 -0
  97. package/dist/cli/usage.d.ts.map +1 -0
  98. package/dist/cli/usage.js +95 -0
  99. package/dist/cli/usage.js.map +1 -0
  100. package/dist/detect.d.ts.map +1 -1
  101. package/dist/detect.js.map +1 -1
  102. package/dist/errors.d.ts +21 -1
  103. package/dist/errors.d.ts.map +1 -1
  104. package/dist/errors.js +33 -1
  105. package/dist/errors.js.map +1 -1
  106. package/dist/harness/aider.d.ts +10 -0
  107. package/dist/harness/aider.d.ts.map +1 -0
  108. package/dist/harness/aider.js +21 -0
  109. package/dist/harness/aider.js.map +1 -0
  110. package/dist/harness/claude-code.d.ts +3 -0
  111. package/dist/harness/claude-code.d.ts.map +1 -0
  112. package/dist/harness/claude-code.js +68 -0
  113. package/dist/harness/claude-code.js.map +1 -0
  114. package/dist/harness/cline.d.ts +3 -0
  115. package/dist/harness/cline.d.ts.map +1 -0
  116. package/dist/harness/cline.js +54 -0
  117. package/dist/harness/cline.js.map +1 -0
  118. package/dist/harness/codex.d.ts +3 -0
  119. package/dist/harness/codex.d.ts.map +1 -0
  120. package/dist/harness/codex.js +92 -0
  121. package/dist/harness/codex.js.map +1 -0
  122. package/dist/harness/cursor.d.ts +3 -0
  123. package/dist/harness/cursor.d.ts.map +1 -0
  124. package/dist/harness/cursor.js +54 -0
  125. package/dist/harness/cursor.js.map +1 -0
  126. package/dist/harness/gemini.d.ts +3 -0
  127. package/dist/harness/gemini.d.ts.map +1 -0
  128. package/dist/harness/gemini.js +60 -0
  129. package/dist/harness/gemini.js.map +1 -0
  130. package/dist/harness/grok.d.ts +3 -0
  131. package/dist/harness/grok.d.ts.map +1 -0
  132. package/dist/harness/grok.js +47 -0
  133. package/dist/harness/grok.js.map +1 -0
  134. package/dist/harness/hermes.d.ts +3 -0
  135. package/dist/harness/hermes.d.ts.map +1 -0
  136. package/dist/harness/hermes.js +72 -0
  137. package/dist/harness/hermes.js.map +1 -0
  138. package/dist/harness/kilocode.d.ts +3 -0
  139. package/dist/harness/kilocode.d.ts.map +1 -0
  140. package/dist/harness/kilocode.js +35 -0
  141. package/dist/harness/kilocode.js.map +1 -0
  142. package/dist/harness/opencode.d.ts +3 -0
  143. package/dist/harness/opencode.d.ts.map +1 -0
  144. package/dist/harness/opencode.js +97 -0
  145. package/dist/harness/opencode.js.map +1 -0
  146. package/dist/harness/paths.d.ts +17 -0
  147. package/dist/harness/paths.d.ts.map +1 -0
  148. package/dist/harness/paths.js +45 -0
  149. package/dist/harness/paths.js.map +1 -0
  150. package/dist/harness/profile.d.ts +209 -0
  151. package/dist/harness/profile.d.ts.map +1 -0
  152. package/dist/harness/profile.js +41 -0
  153. package/dist/harness/profile.js.map +1 -0
  154. package/dist/harness/registry.d.ts +100 -0
  155. package/dist/harness/registry.d.ts.map +1 -0
  156. package/dist/harness/registry.js +144 -0
  157. package/dist/harness/registry.js.map +1 -0
  158. package/dist/harness/snippet.d.ts +19 -0
  159. package/dist/harness/snippet.d.ts.map +1 -0
  160. package/dist/harness/snippet.js +41 -0
  161. package/dist/harness/snippet.js.map +1 -0
  162. package/dist/hash.d.ts.map +1 -1
  163. package/dist/hash.js.map +1 -1
  164. package/dist/hooks/guard-core.d.ts +14 -14
  165. package/dist/hooks/guard-core.d.ts.map +1 -1
  166. package/dist/hooks/guard-core.js +15 -37
  167. package/dist/hooks/guard-core.js.map +1 -1
  168. package/dist/hooks/shim.d.ts +95 -4
  169. package/dist/hooks/shim.d.ts.map +1 -1
  170. package/dist/hooks/shim.js +87 -2
  171. package/dist/hooks/shim.js.map +1 -1
  172. package/dist/hooks/shims/claude-code.d.ts +5 -18
  173. package/dist/hooks/shims/claude-code.d.ts.map +1 -1
  174. package/dist/hooks/shims/claude-code.js +9 -56
  175. package/dist/hooks/shims/claude-code.js.map +1 -1
  176. package/dist/hooks/shims/cline.d.ts +5 -12
  177. package/dist/hooks/shims/cline.d.ts.map +1 -1
  178. package/dist/hooks/shims/cline.js +9 -34
  179. package/dist/hooks/shims/cline.js.map +1 -1
  180. package/dist/hooks/shims/codex.d.ts +5 -18
  181. package/dist/hooks/shims/codex.d.ts.map +1 -1
  182. package/dist/hooks/shims/codex.js +9 -51
  183. package/dist/hooks/shims/codex.js.map +1 -1
  184. package/dist/hooks/shims/cursor.d.ts +5 -14
  185. package/dist/hooks/shims/cursor.d.ts.map +1 -1
  186. package/dist/hooks/shims/cursor.js +9 -42
  187. package/dist/hooks/shims/cursor.js.map +1 -1
  188. package/dist/hooks/shims/gemini.d.ts +5 -18
  189. package/dist/hooks/shims/gemini.d.ts.map +1 -1
  190. package/dist/hooks/shims/gemini.js +9 -48
  191. package/dist/hooks/shims/gemini.js.map +1 -1
  192. package/dist/hooks/shims/grok.d.ts +5 -13
  193. package/dist/hooks/shims/grok.d.ts.map +1 -1
  194. package/dist/hooks/shims/grok.js +9 -32
  195. package/dist/hooks/shims/grok.js.map +1 -1
  196. package/dist/hooks/shims/hermes.d.ts +5 -17
  197. package/dist/hooks/shims/hermes.d.ts.map +1 -1
  198. package/dist/hooks/shims/hermes.js +9 -45
  199. package/dist/hooks/shims/hermes.js.map +1 -1
  200. package/dist/index.d.ts +43 -76
  201. package/dist/index.d.ts.map +1 -1
  202. package/dist/index.js +21 -67
  203. package/dist/index.js.map +1 -1
  204. package/dist/lang/bash.d.ts.map +1 -1
  205. package/dist/lang/bash.js.map +1 -1
  206. package/dist/lang/c.d.ts.map +1 -1
  207. package/dist/lang/c.js.map +1 -1
  208. package/dist/lang/c_sharp.d.ts.map +1 -1
  209. package/dist/lang/c_sharp.js.map +1 -1
  210. package/dist/lang/cpp.d.ts.map +1 -1
  211. package/dist/lang/cpp.js.map +1 -1
  212. package/dist/lang/go.d.ts.map +1 -1
  213. package/dist/lang/go.js.map +1 -1
  214. package/dist/lang/java.d.ts.map +1 -1
  215. package/dist/lang/java.js.map +1 -1
  216. package/dist/lang/javascript.d.ts.map +1 -1
  217. package/dist/lang/javascript.js.map +1 -1
  218. package/dist/lang/kotlin.d.ts.map +1 -1
  219. package/dist/lang/kotlin.js.map +1 -1
  220. package/dist/lang/php.d.ts.map +1 -1
  221. package/dist/lang/php.js.map +1 -1
  222. package/dist/lang/profile.d.ts.map +1 -1
  223. package/dist/lang/profile.js.map +1 -1
  224. package/dist/lang/python.d.ts.map +1 -1
  225. package/dist/lang/python.js.map +1 -1
  226. package/dist/lang/registry.d.ts.map +1 -1
  227. package/dist/lang/registry.js.map +1 -1
  228. package/dist/lang/ruby.d.ts.map +1 -1
  229. package/dist/lang/ruby.js.map +1 -1
  230. package/dist/lang/rust.d.ts.map +1 -1
  231. package/dist/lang/rust.js.map +1 -1
  232. package/dist/lang/swift.d.ts.map +1 -1
  233. package/dist/lang/swift.js.map +1 -1
  234. package/dist/lang/tsx.d.ts.map +1 -1
  235. package/dist/lang/tsx.js.map +1 -1
  236. package/dist/lang/typescript.d.ts.map +1 -1
  237. package/dist/lang/typescript.js.map +1 -1
  238. package/dist/net/policy.d.ts +18 -1
  239. package/dist/net/policy.d.ts.map +1 -1
  240. package/dist/net/policy.js +6 -4
  241. package/dist/net/policy.js.map +1 -1
  242. package/dist/ops/index.d.ts +39 -0
  243. package/dist/ops/index.d.ts.map +1 -0
  244. package/dist/ops/index.js +37 -0
  245. package/dist/ops/index.js.map +1 -0
  246. package/dist/ops/inputs.d.ts +170 -0
  247. package/dist/ops/inputs.d.ts.map +1 -0
  248. package/dist/ops/inputs.js +142 -0
  249. package/dist/ops/inputs.js.map +1 -0
  250. package/dist/ops/verbs.d.ts +136 -0
  251. package/dist/ops/verbs.d.ts.map +1 -0
  252. package/dist/ops/verbs.js +76 -0
  253. package/dist/ops/verbs.js.map +1 -0
  254. package/dist/plan/auto.d.ts +69 -0
  255. package/dist/plan/auto.d.ts.map +1 -0
  256. package/dist/plan/auto.js +70 -0
  257. package/dist/plan/auto.js.map +1 -0
  258. package/dist/plan/budget.d.ts +21 -0
  259. package/dist/plan/budget.d.ts.map +1 -0
  260. package/dist/plan/budget.js +26 -0
  261. package/dist/plan/budget.js.map +1 -0
  262. package/dist/plan/grammar.d.ts +14 -0
  263. package/dist/plan/grammar.d.ts.map +1 -1
  264. package/dist/plan/grammar.js +47 -6
  265. package/dist/plan/grammar.js.map +1 -1
  266. package/dist/plan/lexical.d.ts.map +1 -1
  267. package/dist/plan/lexical.js +1 -7
  268. package/dist/plan/lexical.js.map +1 -1
  269. package/dist/plan/planners.d.ts +35 -2
  270. package/dist/plan/planners.d.ts.map +1 -1
  271. package/dist/plan/planners.js +35 -2
  272. package/dist/plan/planners.js.map +1 -1
  273. package/dist/plan/structural.d.ts +19 -5
  274. package/dist/plan/structural.d.ts.map +1 -1
  275. package/dist/plan/structural.js +180 -33
  276. package/dist/plan/structural.js.map +1 -1
  277. package/dist/repomap/cache.d.ts +48 -0
  278. package/dist/repomap/cache.d.ts.map +1 -1
  279. package/dist/repomap/cache.js +112 -13
  280. package/dist/repomap/cache.js.map +1 -1
  281. package/dist/repomap/io.d.ts +24 -0
  282. package/dist/repomap/io.d.ts.map +1 -0
  283. package/dist/repomap/io.js +34 -0
  284. package/dist/repomap/io.js.map +1 -0
  285. package/dist/repomap/map.d.ts +69 -6
  286. package/dist/repomap/map.d.ts.map +1 -1
  287. package/dist/repomap/map.js +104 -22
  288. package/dist/repomap/map.js.map +1 -1
  289. package/dist/repomap/rank.d.ts +26 -2
  290. package/dist/repomap/rank.d.ts.map +1 -1
  291. package/dist/repomap/rank.js +20 -0
  292. package/dist/repomap/rank.js.map +1 -1
  293. package/dist/repomap/reader.d.ts +73 -0
  294. package/dist/repomap/reader.d.ts.map +1 -0
  295. package/dist/repomap/reader.js +30 -0
  296. package/dist/repomap/reader.js.map +1 -0
  297. package/dist/repomap/tags.d.ts.map +1 -1
  298. package/dist/repomap/tags.js.map +1 -1
  299. package/dist/retrieve.d.ts +8 -0
  300. package/dist/retrieve.d.ts.map +1 -1
  301. package/dist/retrieve.js +12 -1
  302. package/dist/retrieve.js.map +1 -1
  303. package/dist/smelter.d.ts +79 -0
  304. package/dist/smelter.d.ts.map +1 -0
  305. package/dist/smelter.js +65 -0
  306. package/dist/smelter.js.map +1 -0
  307. package/dist/stages.d.ts.map +1 -1
  308. package/dist/stages.js +2 -2
  309. package/dist/stages.js.map +1 -1
  310. package/dist/stats.d.ts +2 -1
  311. package/dist/stats.d.ts.map +1 -1
  312. package/dist/stats.js +2 -1
  313. package/dist/stats.js.map +1 -1
  314. package/dist/store-dir.d.ts +43 -4
  315. package/dist/store-dir.d.ts.map +1 -1
  316. package/dist/store-dir.js +48 -5
  317. package/dist/store-dir.js.map +1 -1
  318. package/dist/store.d.ts +6 -0
  319. package/dist/store.d.ts.map +1 -1
  320. package/dist/store.js +6 -0
  321. package/dist/store.js.map +1 -1
  322. package/dist/text/json-edit.d.ts +71 -0
  323. package/dist/text/json-edit.d.ts.map +1 -0
  324. package/dist/text/json-edit.js +219 -0
  325. package/dist/text/json-edit.js.map +1 -0
  326. package/dist/types.d.ts +35 -14
  327. package/dist/types.d.ts.map +1 -1
  328. package/dist/types.js.map +1 -1
  329. package/grammars/tree-sitter-bash.wasm +0 -0
  330. package/grammars/tree-sitter-c.wasm +0 -0
  331. package/grammars/tree-sitter-c_sharp.wasm +0 -0
  332. package/grammars/tree-sitter-cpp.wasm +0 -0
  333. package/grammars/tree-sitter-go.wasm +0 -0
  334. package/grammars/tree-sitter-java.wasm +0 -0
  335. package/grammars/tree-sitter-javascript.wasm +0 -0
  336. package/grammars/tree-sitter-kotlin.wasm +0 -0
  337. package/grammars/tree-sitter-php.wasm +0 -0
  338. package/grammars/tree-sitter-python.wasm +0 -0
  339. package/grammars/tree-sitter-ruby.wasm +0 -0
  340. package/grammars/tree-sitter-rust.wasm +0 -0
  341. package/grammars/tree-sitter-swift.wasm +0 -0
  342. package/grammars/tree-sitter-tsx.wasm +0 -0
  343. package/grammars/tree-sitter-typescript.wasm +0 -0
  344. package/package.json +11 -11
  345. package/dist/cli/resolve.d.ts +0 -103
  346. package/dist/cli/resolve.d.ts.map +0 -1
  347. package/dist/cli/resolve.js +0 -106
  348. package/dist/cli/resolve.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"guard-core.js","sourceRoot":"","sources":["../../src/hooks/guard-core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"guard-core.js","sourceRoot":"","sources":["../../src/hooks/guard-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,2FAA2F;AAC3F,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAE5C;;;;GAIG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,IAAI,CAAC;AAEpD,yFAAyF;AACzF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,SAAS,CAAU,CAAC;AAG9D,2EAA2E;AAC3E,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAE1D;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACjF,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,QAAQ,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,gCAAgC;IAClC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;AAiDpC,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,cAAc,EAAE,uBAAuB;IACvC,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,+BAA+B;IAC5C,eAAe,EAAE,KAAK;CACvB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,IAA4B;IACzE,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,sBAAsB,CAAC;IAEtD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CACF,gBAAgB,IAAI,wBAAwB;YAC1C,IAAI,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM;YAChE,2EAA2E,CAC9E,CAAC;QACF,OAAO,sBAAsB,CAAC;IAChC,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC,gBAAgB,IAAI,yDAAyD,CAAC,CAAC;QACpF,OAAO,sBAAsB,CAAC;IAChC,CAAC;IACD,MAAM,MAAM,GAAG,MAAiC,CAAC;IACjD,MAAM,KAAK,GACT,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,QAAQ;QACnC,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI;QACxB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC,CAAE,MAAM,CAAC,OAAO,CAA6B;QAC9C,CAAC,CAAC,EAAE,CAAC;IAET,OAAO;QACL,cAAc,EAAE,eAAe,CAC7B,KAAK,CAAC,gBAAgB,CAAC,EACvB,uBAAuB,EACvB,GAAG,IAAI,wBAAwB,EAC/B,IAAI,CACL;QACD,WAAW,EAAE,eAAe,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,GAAG,IAAI,qBAAqB,EAAE,IAAI,CAAC;QACtF,WAAW,EAAE,eAAe,CAC1B,MAAM,CAAC,oBAAoB,CAAC,EAC5B,+BAA+B,EAC/B,GAAG,IAAI,sBAAsB,EAC7B,IAAI,CACL;QACD,eAAe,EAAE,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;KACnD,CAAC;AACJ,CAAC;AAED;oFACoF;AACpF,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtF,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC;AAC9E,CAAC;AAED,SAAS,eAAe,CACtB,KAAc,EACd,QAAgB,EAChB,IAAY,EACZ,IAA4B;IAE5B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACpF,IAAI,CACF,gBAAgB,IAAI,oCAAoC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK;QAChF,SAAS,MAAM,CAAC,QAAQ,CAAC,GAAG,CAC/B,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CACtB,KAAc,EACd,IAAY,EACZ,IAA4B;IAE5B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACvC,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC1D,IAAI,CACF,gBAAgB,IAAI,qCAAqC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK;QACjF,eAAe,CAClB,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACvB,SAAS,CAAC;QACR,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;QACpD,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,SAAS,CAAC;QACrC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7F,MAAM,MAAM,GAAG,MAAiC,CAAC;IACjD,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACzD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1F,MAAM,WAAW,GAAG,KAAgC,CAAC;IACrD,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,aAAa,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC;IACnD,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACrE,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC3E,IAAI,aAAa,KAAK,SAAS,IAAI,OAAO,aAAa,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxF,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC;QACpB,KAAK,EAAE;YACL,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;YACvC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;YAC7C,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC;SAC1D;KACF,CAAC;AACJ,CAAC;AAED,MAAM,KAAK,GAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAEjD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,MAAM,CACpB,OAAqB,EACrB,QAAuB,EACvB,GAAW,EACX,QAAQ,GAAoE,YAAY;IAExF,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CACjB,KAA4B,EAC5B,QAAuB,EACvB,GAAW,EACX,QAAyE;IAEzE,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,KAAK,CAAC,aAAa,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC,CAAC,qCAAqC;IACrF,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5E,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC,CAAC,qCAAqC;IAC3F,IAAI,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,cAAc;QAAE,OAAO,KAAK,CAAC;IACvD,OAAO,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,UAAU,CACjB,KAA4B,EAC5B,QAAuB,EACvB,GAAW,EACX,QAAyE;IAEzE,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC9C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACrC,mFAAmF;IACnF,oFAAoF;IACpF,mCAAmC;IACnC,IAAI,6BAA6B,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAE9D,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,kCAAkC;IAE/F,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC;IAE7C,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QACtF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC1D,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC5B,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,SAAS;YACjD,IAAI,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,cAAc,EAAE,CAAC;gBACxC,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,OAAO,IAAI,CAAC,CAAC;gBAC5E,8EAA8E;gBAC9E,0EAA0E;gBAC1E,6EAA6E;gBAC7E,qEAAqE;gBACrE,4EAA4E;gBAC5E,8CAA8C;gBAC9C,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;oBACvB,CAAC,CAAC,QAAQ;oBACV,CAAC,CAAC;wBACE,MAAM,EAAE,MAAM;wBACd,MAAM,EACJ,GAAG,QAAQ,CAAC,MAAM,IAAI,EAAE,YAAY,OAAO,WAAW;4BACtD,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,+CAA+C;4BACtE,GAAG,IAAI,iEAAiE;4BACxE,uBAAuB;qBAC1B,CAAC;YACR,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,IAAI,CAAC,IAAI,QAAQ,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACnF,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACxC,mFAAmF;QACnF,iFAAiF;QACjF,gFAAgF;QAChF,8EAA8E;QAC9E,oCAAoC;QACpC,MAAM,OAAO,GAAG,GAAG,OAAO,MAAM,SAAS,aAAa,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACrF,OAAO;YACL,MAAM,EAAE,MAAM;YACd,MAAM,EACJ,iCAAiC,OAAO,+CAA+C;gBACvF,kDAAkD,OAAO,uBAAuB;gBAChF,gFAAgF;gBAChF,YAAY,gBAAgB,CAAC,QAAQ,CAAC,EAAE;YAC1C,UAAU,EAAE,OAAO;SACpB,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,QAAuB;IAC/C,OAAO,QAAQ,CAAC,eAAe;QAC7B,CAAC,CAAC,KAAK,SAAS,mEAAmE;QACnF,CAAC,CAAC,KAAK,SAAS,uEAAuE;YACnF,sFAAsF;YACtF,gFAAgF;YAChF,gBAAgB,CAAC;AACzB,CAAC;AAED,0FAA0F;AAC1F,SAAS,aAAa,CACpB,IAAY,EACZ,IAAY,EACZ,QAAuB,EACvB,IAAY;IAEZ,MAAM,WAAW,GAAG,GAAG,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,aAAa,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;IAChG,OAAO;QACL,MAAM,EAAE,MAAM;QACd,MAAM,EACJ,gBAAgB,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ;YACnG,uDAAuD,IAAI,gCAAgC;YAC3F,uCAAuC,WAAW,sCAAsC;YACxF,oFAAoF;YACpF,4BAA4B,gBAAgB,CAAC,QAAQ,CAAC,kCAAkC;YACxF,0CAA0C;QAC5C,UAAU,EAAE,WAAW;KACxB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,IAAI,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,GAAG,KAAK,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;QACvB,IAAI,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;YAAE,OAAO,SAAS,CAAC,CAAC,2BAA2B;QACrF,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,EAAE,CAAC;YACjB,CAAC,IAAI,CAAC,CAAC;YACP,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;gBAClD,IAAI,KAAK,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;oBACvF,OAAO,SAAS,CAAC,CAAC,+CAA+C;gBACnE,CAAC;gBACD,OAAO,IAAI,OAAO,CAAC,CAAC,CAAE,CAAC;gBACvB,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;YACD,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM;gBAAE,OAAO,SAAS,CAAC,CAAC,qBAAqB;YAChE,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAC9B,IAAI,EAAE,CAAC;YACP,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;QACd,OAAO,GAAG,IAAI,CAAC;QACf,CAAC,IAAI,CAAC,CAAC;IACT,CAAC;IACD,IAAI,EAAE,CAAC;IACP,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAwB;IACpD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;QACzB,IAAI;QACJ,UAAU;QACV,IAAI;QACJ,QAAQ;QACR,IAAI;QACJ,aAAa;QACb,IAAI;QACJ,iBAAiB;QACjB,IAAI;QACJ,kBAAkB;QAClB,IAAI;QACJ,WAAW;QACX,IAAI;QACJ,eAAe;QACf,IAAI;QACJ,WAAW;QACX,WAAW;QACX,WAAW;QACX,eAAe;QACf,IAAI;QACJ,QAAQ;QACR,IAAI;QACJ,YAAY;QACZ,IAAI;QACJ,QAAQ;QACR,SAAS;QACT,IAAI;QACJ,WAAW;QACX,SAAS;QACT,UAAU;KACX,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACvC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,UAAU;YAAE,OAAO,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9D,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAChD,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,SAAS;QACX,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrD,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;AAC/C,CAAC;AAED;;wFAEwF;AAExF,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,CAAC;QACH,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,cAAc;IAC5B,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,SAAS,CAAC;QACR,IAAI,SAAiB,CAAC;QACtB,IAAI,CAAC;YACH,SAAS,GAAG,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAI,KAA2B,CAAC,IAAI,CAAC;YAC/C,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBAChC,SAAS;YACX,CAAC;YACD,IAAI,IAAI,KAAK,KAAK;gBAAE,MAAM;YAC1B,MAAM,KAAK,CAAC;QACd,CAAC;QACD,IAAI,SAAS,KAAK,CAAC;YAAE,MAAM;QAC3B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC","sourcesContent":["import { readSync, statSync, existsSync, readFileSync } from 'node:fs';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport process from 'node:process';\n\n/**\n * The guard core — one zero-dependency node module, shared by every harness shim.\n *\n * Contract: a caller hands `decide` a {@link GuardRequest}\n * (`{ tool, input: { path?, command?, offsetLimited? } }`) with the settings\n * {@link readGuardSettings} read, and gets one {@link GuardDecision} back —\n * `{ action: \"allow\" | \"deny\", reason?, suggestion? }`. Each shim translates that into\n * its harness's own schema (exit 2, `permissionDecision`, `cancel:true`, …), and the\n * opencode plugin — the one harness whose hook API is JavaScript — imports this module\n * at hook time and calls the same two functions.\n *\n * Two properties are load-bearing and guarded:\n *\n * - **Fail open, loudly.** Malformed stdin, a malformed config, an unstatable path —\n * every degenerate input produces `{\"action\":\"allow\"}` plus a warning on stderr.\n * A guard that can brick a session on bad input is worse than no guard; the agent\n * loses nothing but the optimization, and the warning says so.\n * - **No library import on any path.** This module imports node builtins only —\n * never `../index.ts`, never a planner, never web-tree-sitter. The allow case is\n * a stat and an exit; the research note\n * (docs/research/2026-09-02-agent-enforcement.md § 5) budgets the always-on guard\n * at tens of milliseconds, and loading grammar machinery here would spend that\n * budget before deciding anything. The smelt run itself is only ever paid by the\n * *replacement* command the model runs after a deny (or the rewritten command).\n *\n * Config: the nearest `smelt.config.json` (walking up from the cwd, same discovery\n * as the CLI) may carry a `hooks` block — `thresholdBytes` and `enforcement` — plus\n * the `defaultBudgetBytes` the suggested command quotes. This file reads that config\n * with its own tolerant reader instead of importing `cli/config.ts`: the CLI's strict\n * parser sits on the planner import graph, and a *guard* must fail open where the CLI\n * correctly refuses. `test/hooks-guard-core.test.ts` pins the two readers to the same\n * key names and defaults, so they cannot drift apart silently.\n */\n\n/** Deny threshold when no config says otherwise: reads at or under this pass untouched. */\nexport const DEFAULT_THRESHOLD_BYTES = 8192;\n\n/**\n * The `--budget` the suggested replacement command quotes when no config carries\n * `defaultBudgetBytes`. A suggestion default, not a smelt default: the CLI itself\n * still refuses to run without an explicit budget from a flag or the config.\n */\nexport const DEFAULT_SUGGESTION_BUDGET_BYTES = 8000;\n\n/** The `hooks.enforcement` values `smelt.config.json` may carry. Deny is the default. */\nexport const ENFORCEMENT_MODES = ['deny', 'rewrite'] as const;\nexport type EnforcementMode = (typeof ENFORCEMENT_MODES)[number];\n\n/** The config file this guard discovers, by the same name the CLI uses. */\nexport const GUARD_CONFIG_FILE_NAME = 'smelt.config.json';\n\n/**\n * The runnable CLI name every reason and suggestion quotes. A local (non-global)\n * `npm install @smeltjs/core` puts no `smelt` on anyone's PATH — the installer wires\n * every shim as `node \"<dist path>\"` for exactly that reason — so a suggestion\n * saying bare `smelt` would exit 127 the moment the model (or a rewrite-mode\n * harness) ran it. When this module's sibling `cli/bin.js` exists — the shipped\n * `dist/` layout every real run executes from — the command names it through `node`\n * explicitly; the bare name is only the fallback for layouts where the sibling is\n * absent (the source tree under the test runner).\n */\nexport function smeltCliCommand(): string {\n try {\n const bin = join(dirname(fileURLToPath(import.meta.url)), '..', 'cli', 'bin.js');\n if (existsSync(bin)) return `node ${shellQuote(bin)}`;\n } catch {\n // fall through to the PATH name\n }\n return 'smelt';\n}\n\nconst SMELT_CLI = smeltCliCommand();\n\n/** What a shim hands the guard core: the harness schema already mapped away. */\nexport interface GuardRequest {\n /** `'Read'` for a file-read tool, `'Bash'` for a shell tool; anything else passes. */\n readonly tool: string;\n readonly input: {\n /** The file a Read-shaped tool targets. Relative paths resolve against the cwd. */\n readonly path?: string;\n /** The command a Bash-shaped tool would run, verbatim. */\n readonly command?: string;\n /**\n * True when the read is already windowed (offset/limit given). A windowed read\n * of a huge file is an economy move — it is always allowed, whatever the size.\n */\n readonly offsetLimited?: boolean;\n };\n}\n\n/** The guard's whole answer. `suggestion`, when present, is an executable command. */\nexport interface GuardDecision {\n readonly action: 'allow' | 'deny';\n /** Why, written to steer: names the exact replacement command and `smelt retrieve`. */\n readonly reason?: string;\n /**\n * A command that faithfully replaces the denied one — `smelt <path> --budget <n>`\n * for a raw read, the original pipeline with ` | smelt …` appended for a search.\n * Only emitted when running it preserves the intent of the original call, which is\n * exactly the condition under which a rewrite-mode shim may substitute it via\n * `updatedInput`. Absent on decisions that need the model's judgement instead.\n */\n readonly suggestion?: string;\n}\n\n/** The guard's merged settings: config values where sane, defaults where not. */\nexport interface GuardSettings {\n readonly thresholdBytes: number;\n readonly enforcement: EnforcementMode;\n /** Quoted in every suggested command, so the model runs a complete line. */\n readonly budgetBytes: number;\n /**\n * True when the config carries a directory store. `smelt retrieve <hash>` only\n * works across processes with a persistent store (the CLI's default is memory,\n * which dies with the process that elided), so a deny reason may only *promise*\n * retrieval when this is true — otherwise it says what to configure instead.\n */\n readonly persistentStore: boolean;\n}\n\nexport const DEFAULT_GUARD_SETTINGS: GuardSettings = {\n thresholdBytes: DEFAULT_THRESHOLD_BYTES,\n enforcement: 'deny',\n budgetBytes: DEFAULT_SUGGESTION_BUDGET_BYTES,\n persistentStore: false,\n};\n\n/**\n * Read the nearest `smelt.config.json`'s guard-relevant fields, tolerantly.\n *\n * Tolerant is a deliberate divergence from the CLI: `smelt` refuses a malformed\n * config because a silently skipped setting is a setting the user believed was in\n * force — but this code runs inside somebody's *session*, before every Read, and a\n * guard that turns a config typo into a hard-down harness has failed worse than the\n * typo. So: any unreadable or ill-typed field falls back to its default, and `warn`\n * receives one line saying which file and why — visible in the harness's hook debug\n * output, never fatal.\n */\nexport function readGuardSettings(cwd: string, warn: (text: string) => void): GuardSettings {\n const path = findGuardConfigFile(cwd);\n if (path === undefined) return DEFAULT_GUARD_SETTINGS;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(readFileSync(path, 'utf8'));\n } catch (cause) {\n warn(\n `smelt guard: ${path} is not readable JSON ` +\n `(${cause instanceof Error ? cause.message : String(cause)}) — ` +\n `guarding with defaults instead. \\`smelt\\` itself will refuse this config.`,\n );\n return DEFAULT_GUARD_SETTINGS;\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n warn(`smelt guard: ${path} is not a JSON object — guarding with defaults instead.`);\n return DEFAULT_GUARD_SETTINGS;\n }\n const fields = parsed as Record<string, unknown>;\n const hooks =\n typeof fields['hooks'] === 'object' &&\n fields['hooks'] !== null &&\n !Array.isArray(fields['hooks'])\n ? (fields['hooks'] as Record<string, unknown>)\n : {};\n\n return {\n thresholdBytes: positiveInteger(\n hooks['thresholdBytes'],\n DEFAULT_THRESHOLD_BYTES,\n `${path}: hooks.thresholdBytes`,\n warn,\n ),\n enforcement: enforcementMode(hooks['enforcement'], `${path}: hooks.enforcement`, warn),\n budgetBytes: positiveInteger(\n fields['defaultBudgetBytes'],\n DEFAULT_SUGGESTION_BUDGET_BYTES,\n `${path}: defaultBudgetBytes`,\n warn,\n ),\n persistentStore: isDirectoryStore(fields['store']),\n };\n}\n\n/** True for a well-formed `{\"kind\":\"directory\",\"path\":…}` store block; no warning\n * otherwise — an absent or memory store is a valid (just non-persistent) choice. */\nfunction isDirectoryStore(value: unknown): boolean {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const fields = value as Record<string, unknown>;\n return fields['kind'] === 'directory' && typeof fields['path'] === 'string';\n}\n\nfunction positiveInteger(\n value: unknown,\n fallback: number,\n what: string,\n warn: (text: string) => void,\n): number {\n if (value === undefined) return fallback;\n if (typeof value === 'number' && Number.isInteger(value) && value > 0) return value;\n warn(\n `smelt guard: ${what} must be a positive integer, got ${JSON.stringify(value)} — ` +\n `using ${String(fallback)}.`,\n );\n return fallback;\n}\n\nfunction enforcementMode(\n value: unknown,\n what: string,\n warn: (text: string) => void,\n): EnforcementMode {\n if (value === undefined) return 'deny';\n if (value === 'deny' || value === 'rewrite') return value;\n warn(\n `smelt guard: ${what} must be \"deny\" or \"rewrite\", got ${JSON.stringify(value)} — ` +\n `using \"deny\".`,\n );\n return 'deny';\n}\n\n/** The same upward walk `cli/config.ts` does, re-implemented to keep this module tiny. */\nexport function findGuardConfigFile(cwd: string): string | undefined {\n let dir = resolve(cwd);\n for (;;) {\n const candidate = join(dir, GUARD_CONFIG_FILE_NAME);\n if (existsSync(candidate)) return candidate;\n const parent = dirname(dir);\n if (parent === dir) return undefined;\n dir = parent;\n }\n}\n\n/**\n * Parse one {@link GuardRequest} *document* — the request shape as JSON, for an\n * adapter that receives it over a pipe rather than building it in-process.\n * `undefined` means malformed, and a caller that gets it allows and warns: the same\n * fail-open rule the rest of this module lives under.\n */\nexport function parseGuardRequest(text: string): GuardRequest | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return undefined;\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) return undefined;\n const fields = parsed as Record<string, unknown>;\n if (typeof fields['tool'] !== 'string') return undefined;\n const input = fields['input'];\n if (typeof input !== 'object' || input === null || Array.isArray(input)) return undefined;\n const inputFields = input as Record<string, unknown>;\n const path = inputFields['path'];\n const command = inputFields['command'];\n const offsetLimited = inputFields['offsetLimited'];\n if (path !== undefined && typeof path !== 'string') return undefined;\n if (command !== undefined && typeof command !== 'string') return undefined;\n if (offsetLimited !== undefined && typeof offsetLimited !== 'boolean') return undefined;\n return {\n tool: fields['tool'],\n input: {\n ...(path === undefined ? {} : { path }),\n ...(command === undefined ? {} : { command }),\n ...(offsetLimited === undefined ? {} : { offsetLimited }),\n },\n };\n}\n\nconst ALLOW: GuardDecision = { action: 'allow' };\n\n/**\n * The decision, pure given a stat function — so tests exercise every branch without\n * a filesystem, and the script wires `statSync` in.\n *\n * The shape of the rules, from the research note (§ 5, \"the ~8 KB threshold,\n * validated\", with both amendments):\n *\n * - **Read**: stat the exact target; deny only above the threshold, and never when\n * the read is already windowed (`offsetLimited`) — a windowed read of a huge file\n * is an economy move.\n * - **Bash**: only a *simple* command whose subject is a statable named file can be\n * judged pre-run. `cat <file>` above the threshold is denied with the faithful\n * replacement; `grep`/`rg` output is unknowable pre-run, so it passes in deny\n * mode and is wrapped (` | smelt --budget … --focus <pattern>`) only under\n * `hooks.enforcement: \"rewrite\"`. Pipelines, redirects, substitutions — anything\n * this parser cannot be sure about — pass untouched. Fail open, always.\n */\nexport function decide(\n request: GuardRequest,\n settings: GuardSettings,\n cwd: string,\n statFile: (path: string) => { size: number; isFile: boolean } | undefined = statFileReal,\n): GuardDecision {\n if (request.tool === 'Read') {\n return decideRead(request.input, settings, cwd, statFile);\n }\n if (request.tool === 'Bash') {\n return decideBash(request.input, settings, cwd, statFile);\n }\n return ALLOW;\n}\n\nfunction statFileReal(path: string): { size: number; isFile: boolean } | undefined {\n try {\n const stat = statSync(path);\n return { size: stat.size, isFile: stat.isFile() };\n } catch {\n return undefined;\n }\n}\n\nfunction decideRead(\n input: GuardRequest['input'],\n settings: GuardSettings,\n cwd: string,\n statFile: (path: string) => { size: number; isFile: boolean } | undefined,\n): GuardDecision {\n if (input.path === undefined) return ALLOW;\n if (input.offsetLimited === true) return ALLOW; // already windowed — an economy move\n const path = isAbsolute(input.path) ? input.path : resolve(cwd, input.path);\n const stat = statFile(path);\n if (stat === undefined || !stat.isFile) return ALLOW; // let the tool surface its own error\n if (stat.size <= settings.thresholdBytes) return ALLOW;\n return denyOversized(path, stat.size, settings, 'Reading it raw');\n}\n\nfunction decideBash(\n input: GuardRequest['input'],\n settings: GuardSettings,\n cwd: string,\n statFile: (path: string) => { size: number; isFile: boolean } | undefined,\n): GuardDecision {\n if (input.command === undefined) return ALLOW;\n const command = input.command.trim();\n // A command already using smelt is the model doing the right thing — including the\n // exact replacement a previous deny suggested. Never intercept it (and never wrap a\n // wrapped pipeline a second time).\n if (/(^|[\\s/\"'=])smelt($|[\\s\"'])/.test(command)) return ALLOW;\n\n const words = simpleCommandWords(command);\n if (words === undefined || words.length === 0) return ALLOW; // not simple — unknowable pre-run\n\n const program = words[0]!.split('/').at(-1)!;\n\n if (program === 'cat') {\n const files = words.slice(1).filter((word) => word !== '--' && !word.startsWith('-'));\n for (const file of files) {\n const path = isAbsolute(file) ? file : resolve(cwd, file);\n const stat = statFile(path);\n if (stat === undefined || !stat.isFile) continue;\n if (stat.size > settings.thresholdBytes) {\n const decision = denyOversized(path, stat.size, settings, `\\`${command}\\``);\n // The suggestion is only a *faithful* replacement when cat named exactly this\n // one file; `cat a b` replaced by `smelt a` would silently drop b, so the\n // multi-file case keeps the reason (the model decides), drops the suggestion\n // (nothing may auto-substitute it), and says out loud that the named\n // replacement covers only the oversized file — a model following the reason\n // verbatim must not silently drop the others.\n return files.length === 1\n ? decision\n : {\n action: 'deny',\n reason:\n `${decision.reason ?? ''} Note: \\`${command}\\` names ` +\n `${String(files.length)} files and the replacement above covers only ` +\n `${path} — read the other file(s) separately (cat is fine for the ones ` +\n `under the threshold).`,\n };\n }\n }\n return ALLOW;\n }\n\n if ((program === 'grep' || program === 'rg') && settings.enforcement === 'rewrite') {\n const pattern = searchPattern(words);\n if (pattern === undefined) return ALLOW;\n // Deliberately no `--focus` on the wrap: a plain grep's every output line contains\n // the searched pattern, so focusing on it would protect the entire output — zero\n // elisions exactly when the output is large, plus an over-budget exit. The wrap\n // lets smelt's lexical planner keep the head and tail and collapse the middle\n // into retrievable markers instead.\n const wrapped = `${command} | ${SMELT_CLI} --budget ${String(settings.budgetBytes)}`;\n return {\n action: 'deny',\n reason:\n `smelt guard (rewrite mode): \\`${program}\\` output size is unknowable before it runs, ` +\n `so pipe it through smelt instead. Run exactly: ${wrapped} — output within the ` +\n `budget passes through untouched; past it, elided regions leave <<smelt/v1 …>> ` +\n `markers. ${retrieveSentence(settings)}`,\n suggestion: wrapped,\n };\n }\n\n return ALLOW;\n}\n\n/**\n * The one sentence about getting elided bytes back — honest about the store: the\n * retrieval promise is only made when a persistent store is configured, because a\n * memory store dies with the process and `retrieve` then refuses (`resolveStoreRun`).\n */\nfunction retrieveSentence(settings: GuardSettings): string {\n return settings.persistentStore\n ? `\\`${SMELT_CLI} retrieve <hash>\\` prints any marker's bytes back, byte for byte.`\n : `\\`${SMELT_CLI} retrieve <hash>\\` can print a marker's bytes back once a persistent ` +\n `store is configured ({\"store\":{\"kind\":\"directory\",\"path\":…}} in smelt.config.json — ` +\n `\\`smelt hooks install\\` writes one); without it the elided bytes die with the ` +\n `smelt process.`;\n}\n\n/** The deny everything above the threshold gets: steering text plus the exact command. */\nfunction denyOversized(\n path: string,\n size: number,\n settings: GuardSettings,\n what: string,\n): GuardDecision {\n const replacement = `${SMELT_CLI} ${shellQuote(path)} --budget ${String(settings.budgetBytes)}`;\n return {\n action: 'deny',\n reason:\n `smelt guard: ${path} is ${String(size)} bytes — over the ${String(settings.thresholdBytes)}-byte ` +\n `threshold (smelt.config.json hooks.thresholdBytes). ${what} would spend context on bytes ` +\n `the task may not need. Run instead: ${replacement} --focus <what you are looking for> ` +\n `(repeat --focus per term; focused regions survive verbatim). Elided regions leave ` +\n `<<smelt/v1 …>> markers — ${retrieveSentence(settings)} A windowed read (offset/limit) ` +\n `of just the lines you need is also fine.`,\n suggestion: replacement,\n };\n}\n\n/**\n * Split a command into words IF it is one simple command: no pipes, no logic, no\n * redirects, no substitutions, no expansions this code would have to model. Anything\n * else returns `undefined` and the caller allows — the guard judges only what it can\n * see whole.\n */\nexport function simpleCommandWords(command: string): readonly string[] | undefined {\n const words: string[] = [];\n let current = '';\n let started = false;\n let i = 0;\n const push = (): void => {\n if (started) words.push(current);\n current = '';\n started = false;\n };\n while (i < command.length) {\n const ch = command[i]!;\n if ('|&;<>()`$\\\\\\n*?~{}!'.includes(ch)) return undefined; // shell would interpret it\n if (ch === \"'\" || ch === '\"') {\n const quote = ch;\n i += 1;\n started = true;\n while (i < command.length && command[i] !== quote) {\n if (quote === '\"' && (command[i] === '$' || command[i] === '`' || command[i] === '\\\\')) {\n return undefined; // expansions inside double quotes — not simple\n }\n current += command[i]!;\n i += 1;\n }\n if (i >= command.length) return undefined; // unterminated quote\n i += 1;\n continue;\n }\n if (ch === ' ' || ch === '\\t') {\n push();\n i += 1;\n continue;\n }\n current += ch;\n started = true;\n i += 1;\n }\n push();\n return words;\n}\n\n/**\n * The pattern a grep/rg invocation searches for: an explicit `-e`/`--regexp` value if\n * given, else the first word that is not a flag or a flag's value. `undefined` when\n * the parse is not sure — and unsure means allow, like everything else here.\n */\nexport function searchPattern(words: readonly string[]): string | undefined {\n const takesValue = new Set([\n '-e',\n '--regexp',\n '-f',\n '--file',\n '-m',\n '--max-count',\n '-A',\n '--after-context',\n '-B',\n '--before-context',\n '-C',\n '--context',\n '-d',\n '--directories',\n '-D',\n '--devices',\n '--include',\n '--exclude',\n '--exclude-dir',\n '-t',\n '--type',\n '-T',\n '--type-not',\n '-g',\n '--glob',\n '--iglob',\n '-j',\n '--threads',\n '--color',\n '--colour',\n ]);\n let i = 1;\n while (i < words.length) {\n const word = words[i]!;\n if (word === '--') return words[i + 1];\n if (word === '-e' || word === '--regexp') return words[i + 1];\n if (word.startsWith('--') && word.includes('=')) {\n i += 1;\n continue;\n }\n if (word.startsWith('-') && word.length > 1) {\n i += takesValue.has(word) ? 2 : 1;\n continue;\n }\n return word;\n }\n return undefined;\n}\n\n/** Single-quote a value for `sh` unless it is plainly safe bare. */\nexport function shellQuote(value: string): string {\n if (/^[A-Za-z0-9_./:=-]+$/.test(value)) return value;\n return `'${value.replaceAll(\"'\", `'\"'\"'`)}'`;\n}\n\n/* ------------------------------------------------------------------------------------\n * Process plumbing, for the shims that run as one\n * ---------------------------------------------------------------------------------- */\n\n/** True when this module is the file node was asked to run, not an import. */\nexport function isMainModule(moduleUrl: string): boolean {\n const entry = process.argv[1];\n if (entry === undefined) return false;\n try {\n return pathToFileURL(entry).href === moduleUrl;\n } catch {\n return false;\n }\n}\n\n/** Every byte of fd 0 to EOF, retrying EAGAIN — the same shape `cli/bin.ts` uses. */\nexport function readAllOfStdin(): string {\n const sleeper = new Int32Array(new SharedArrayBuffer(4));\n const chunks: Buffer[] = [];\n const chunk = Buffer.alloc(1 << 16);\n for (;;) {\n let bytesRead: number;\n try {\n bytesRead = readSync(0, chunk, 0, chunk.length, null);\n } catch (error) {\n const code = (error as { code?: string }).code;\n if (code === 'EAGAIN') {\n Atomics.wait(sleeper, 0, 0, 10);\n continue;\n }\n if (code === 'EOF') break;\n throw error;\n }\n if (bytesRead === 0) break;\n chunks.push(Buffer.from(chunk.subarray(0, bytesRead)));\n }\n return Buffer.concat(chunks).toString('utf8');\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { decide, isMainModule, parseGuardRequest } from './guard-core.ts';
1
+ import { decide, isMainModule } from './guard-core.ts';
2
2
  import type { GuardDecision, GuardRequest, GuardSettings } from './guard-core.ts';
3
3
  /**
4
4
  * The shim runtime — the one loop every per-harness shim runs.
@@ -10,6 +10,13 @@ import type { GuardDecision, GuardRequest, GuardSettings } from './guard-core.ts
10
10
  * `guard-core.ts`; a shim that grew an opinion of its own would be a second guard
11
11
  * that drifts from the first.
12
12
  *
13
+ * Most of a shim is a *table*, not code: which tool names mean read and shell, which
14
+ * payload keys carry them, and the two documents the harness's schema wants back. That
15
+ * table is a {@link HarnessHookSchema}, `shimFromSchema` turns one into a
16
+ * {@link ShimAdapter}, and every harness's schema lives in its profile
17
+ * (`src/harness/<id>.ts`). {@link ShimAdapter} stays public as the escape hatch for a
18
+ * harness a table cannot express.
19
+ *
13
20
  * The enforcement gate lives here, once, because it is the same for every harness:
14
21
  *
15
22
  * - **deny mode (the default)**: a deny is rendered as the harness's deny, with the
@@ -27,8 +34,7 @@ import type { GuardDecision, GuardRequest, GuardSettings } from './guard-core.ts
27
34
  * plugin) — a rewrite nobody can see would change what the model asked for
28
35
  * without telling anyone. And a shim never rewrites in deny mode: a silent
29
36
  * rewrite changes what the model asked for without telling it, which is this
30
- * project's signature failure shape applied to the harness (founder ruling,
31
- * KOT-212).
37
+ * project's signature failure shape applied to the harness.
32
38
  */
33
39
  /** What one harness shim supplies. Everything else is {@link runShim}'s. */
34
40
  export interface ShimAdapter {
@@ -81,5 +87,90 @@ export declare function toolCallRequest(toolName: unknown, toolInput: unknown, n
81
87
  }): GuardRequest | undefined;
82
88
  /** The raw stdin as a keyed record, or an empty record when it is not object-shaped. */
83
89
  export declare function asRecord(raw: unknown): Record<string, unknown>;
84
- export { isMainModule, parseGuardRequest };
90
+ /**
91
+ * One harness's pre-tool hook schema — everything that varies between shims, as a
92
+ * table. Everything that does not vary (the tool mapping, the rewrite-input splice,
93
+ * the announcement, the deny fallback) belongs to {@link shimFromSchema} and exists
94
+ * exactly once.
95
+ *
96
+ * A schema states capability, never invents it: a harness whose hook cannot modify
97
+ * tool input simply omits {@link rewrite}, and `renderShimDecision` then falls back to
98
+ * the deny — whose reason still carries the exact replacement command.
99
+ */
100
+ export interface HarnessHookSchema {
101
+ /** Tool names this harness spells a file read with. */
102
+ readonly readTools: readonly string[];
103
+ /** Tool names this harness spells a shell command with. */
104
+ readonly bashTools: readonly string[];
105
+ /**
106
+ * Where the tool name lives in the raw payload, in priority order — harnesses
107
+ * disagree about the spelling (`tool_name`, `toolName`), and some nest the call.
108
+ * A dotted key reads through one level of nesting (`preToolUse.toolName`).
109
+ */
110
+ readonly toolNameKeys: readonly string[];
111
+ /** Where the tool's input object lives, same rules as {@link toolNameKeys}. */
112
+ readonly toolInputKeys: readonly string[];
113
+ /**
114
+ * The payload key carrying the working directory relative paths resolve against,
115
+ * for the harnesses that send one (Claude Code's hook stdin carries the *session's*
116
+ * cwd, which after a `cd` differs from the hook process's own). Absent = the shim
117
+ * process's cwd.
118
+ */
119
+ readonly cwdKey?: string;
120
+ /** The harness's deny document, with the guard's steering reason in its one slot. */
121
+ readonly deny: (reason: string) => unknown;
122
+ /** The harness's input-rewrite document. Absent on a deny-only harness. */
123
+ readonly rewrite?: HarnessRewriteSchema;
124
+ }
125
+ /** What a rewrite renders, and where the substitution is announced. */
126
+ export interface HarnessRewriteSchema {
127
+ /** The rewrite document this harness's schema wants back. */
128
+ readonly document: (rewrite: RewriteSlots) => unknown;
129
+ /**
130
+ * Where the substitution is announced. `'reason'` when the document carries a
131
+ * reason channel the model reads (the template puts {@link RewriteSlots.announcement}
132
+ * there); `'stderr'` when it does not — a rewrite nobody can see would change what
133
+ * the model asked for without telling anyone.
134
+ */
135
+ readonly announce: 'reason' | 'stderr';
136
+ }
137
+ /** What a rewrite document is built from. Filled in by {@link shimFromSchema}. */
138
+ export interface RewriteSlots {
139
+ /**
140
+ * The tool's own input with `command` replaced by the suggestion — the splice every
141
+ * rewriting harness needs, and which four shims used to carry verbatim. Harnesses
142
+ * whose rewrite is a shallow merge send only the changed key instead.
143
+ */
144
+ readonly input: Record<string, unknown>;
145
+ /** The replacement command itself. */
146
+ readonly suggestion: string;
147
+ /** The announcement, for a document with a reason channel. */
148
+ readonly announcement: string;
149
+ }
150
+ /** What a deny says when the decision carries no reason — never an empty message. */
151
+ export declare const DENIED_WITHOUT_REASON = "denied by the smelt guard";
152
+ /**
153
+ * The announcement for a rewrite whose document carries a reason channel the model
154
+ * reads (Claude Code, Codex): the model is told, in its own transcript, that the
155
+ * command it asked for is not the command that ran.
156
+ */
157
+ export declare function rewroteReason(suggestion: string): string;
158
+ /**
159
+ * The stderr announcement, in two halves so a *generated* consumer can splice values
160
+ * between them: the opencode plugin this installer writes is JavaScript source, and
161
+ * its copy of this sentence used to be hand-typed inside a string template where
162
+ * nothing could see it drift from the shims'. Both halves are pinned by
163
+ * `test/guards/harness-registry.test.ts`.
164
+ */
165
+ export declare const REWRITE_ANNOUNCEMENT_OPENING = "smelt guard (rewrite mode): substituted the command in-flight with `";
166
+ export declare const REWRITE_ANNOUNCEMENT_JOIN = "`. ";
167
+ /** The one stderr announcement, for a rewrite schema with no reason channel. */
168
+ export declare function rewriteAnnouncement(suggestion: string, reason: string): string;
169
+ /**
170
+ * The adapter a {@link HarnessHookSchema} describes. Everything shared lives here
171
+ * once: the tool mapping, the rewrite-input splice, both announcements, the deny
172
+ * fallback, and the rule that a schema with no `rewrite` renders a deny instead.
173
+ */
174
+ export declare function shimFromSchema(schema: HarnessHookSchema): ShimAdapter;
175
+ export { isMainModule };
85
176
  //# sourceMappingURL=shim.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shim.d.ts","sourceRoot":"","sources":["../../src/hooks/shim.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,MAAM,EACN,YAAY,EACZ,iBAAiB,EAGlB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAElF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,uFAAuF;IACvF,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,YAAY,GAAG,SAAS,CAAC;IAC/D;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;IACpD,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,UAAU,CAAC;IAChC,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,KAAK,UAAU,CAAC;IAC5F;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,KAAK,UAAU,CAAC;CACjG;AAED,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;+EAC2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,sFAAsF;AACtF,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,WAAW,EACpB,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,GACtC,UAAU,CAkBZ;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CA+BtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAE,OAAO,EAClB,KAAK,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC5E,YAAY,GAAG,SAAS,CAoB1B;AAiBD,wFAAwF;AACxF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAI9D;AAED,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"shim.d.ts","sourceRoot":"","sources":["../../src/hooks/shim.ts"],"names":[],"mappings":"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","sourcesContent":["import process from 'node:process';\n\nimport { decide, isMainModule, readAllOfStdin, readGuardSettings } from './guard-core.ts';\nimport type { GuardDecision, GuardRequest, GuardSettings } from './guard-core.ts';\n\n/**\n * The shim runtime — the one loop every per-harness shim runs.\n *\n * A shim is a thin adapter: it maps its harness's native PreToolUse stdin schema\n * onto a {@link GuardRequest}, hands that to the guard core, and renders the\n * {@link GuardDecision} back in the harness's native output schema. All policy —\n * threshold, windows, suggestion rendering, enforcement mode — lives in\n * `guard-core.ts`; a shim that grew an opinion of its own would be a second guard\n * that drifts from the first.\n *\n * Most of a shim is a *table*, not code: which tool names mean read and shell, which\n * payload keys carry them, and the two documents the harness's schema wants back. That\n * table is a {@link HarnessHookSchema}, `shimFromSchema` turns one into a\n * {@link ShimAdapter}, and every harness's schema lives in its profile\n * (`src/harness/<id>.ts`). {@link ShimAdapter} stays public as the escape hatch for a\n * harness a table cannot express.\n *\n * The enforcement gate lives here, once, because it is the same for every harness:\n *\n * - **deny mode (the default)**: a deny is rendered as the harness's deny, with the\n * guard's steering reason. The transcript stays truthful — the model sees what it\n * asked for refused and why, and learns to run the replacement (and\n * `smelt retrieve`) itself.\n * - **rewrite mode (`hooks.enforcement: \"rewrite\"` in smelt.config.json)**: when the\n * denied call is a Bash command, the guard produced a faithful executable\n * `suggestion`, and this harness can modify tool input, the shim substitutes the\n * suggestion instead of denying. A harness that cannot rewrite falls back to the\n * deny — with the exact command in the reason — so rewrite mode never silently\n * weakens into nothing. A substitution is always announced: in the decision\n * reason where the harness's rewrite schema carries one (Claude Code, Codex),\n * and on stderr where it does not (Gemini, Cursor, Hermes, the opencode\n * plugin) — a rewrite nobody can see would change what the model asked for\n * without telling anyone. And a shim never rewrites in deny mode: a silent\n * rewrite changes what the model asked for without telling it, which is this\n * project's signature failure shape applied to the harness.\n */\n\n/** What one harness shim supplies. Everything else is {@link runShim}'s. */\nexport interface ShimAdapter {\n /** Map the harness's raw stdin JSON to a guard request; `undefined` = pass through. */\n readonly toRequest: (raw: unknown) => GuardRequest | undefined;\n /**\n * The working directory tool-relative paths resolve against, read from the raw\n * payload when the harness sends one (Claude Code's hook stdin carries `cwd`: the\n * *session's* Bash cwd, which after a `cd` differs from this hook process's own).\n * `undefined` falls back to the shim process's cwd.\n */\n readonly cwd?: (raw: unknown) => string | undefined;\n /** Render an allow. Most harnesses: empty stdout, exit 0. */\n readonly pass: () => ShimOutput;\n /** Render a deny, in the harness's schema. */\n readonly deny: (raw: unknown, request: GuardRequest, decision: GuardDecision) => ShimOutput;\n /**\n * Render an input rewrite (only ever called for a Bash-shaped request whose\n * decision carries a faithful `suggestion`, and only in rewrite mode). Omit on\n * harnesses whose hook schema cannot modify tool input — they deny instead. A\n * schema with no reason channel must announce the substitution via `stderr`.\n */\n readonly rewrite?: (raw: unknown, request: GuardRequest, decision: GuardDecision) => ShimOutput;\n}\n\n/** What a shim writes and how it exits. `stdout` is a complete JSON line or ''. */\nexport interface ShimOutput {\n readonly stdout: string;\n /** Written to the shim process's stderr — the announcement channel for harnesses\n * whose rewrite schema has no reason field. Never a decision by itself. */\n readonly stderr?: string;\n readonly exitCode: number;\n}\n\n/** The pure half of the shim loop, for tests: raw harness input → rendered output. */\nexport function renderShimDecision(\n adapter: ShimAdapter,\n raw: unknown,\n settings: GuardSettings,\n cwd: string,\n statFile?: Parameters<typeof decide>[3],\n): ShimOutput {\n const request = adapter.toRequest(raw);\n if (request === undefined) return adapter.pass();\n const effectiveCwd = adapter.cwd?.(raw) ?? cwd;\n const decision =\n statFile === undefined\n ? decide(request, settings, effectiveCwd)\n : decide(request, settings, effectiveCwd, statFile);\n if (decision.action === 'allow') return adapter.pass();\n if (\n settings.enforcement === 'rewrite' &&\n adapter.rewrite !== undefined &&\n request.tool === 'Bash' &&\n decision.suggestion !== undefined\n ) {\n return adapter.rewrite(raw, request, decision);\n }\n return adapter.deny(raw, request, decision);\n}\n\n/**\n * The whole shim as a process: read the harness's stdin, decide, render, exit.\n * Fail open exactly like the guard core — unparseable stdin passes with a stderr\n * warning, and an unexpected error passes too. A shim crash must never read as a\n * policy decision.\n */\nexport function runShimMain(adapter: ShimAdapter): void {\n let output: ShimOutput;\n try {\n const text = readAllOfStdin();\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch {\n process.stderr.write(\n `smelt shim: stdin was not JSON — allowing the call. Fix the hook wiring.\\n`,\n );\n raw = undefined;\n }\n if (raw === undefined) {\n output = adapter.pass();\n } else {\n const settings = readGuardSettings(process.cwd(), (text_) =>\n process.stderr.write(`${text_}\\n`),\n );\n output = renderShimDecision(adapter, raw, settings, process.cwd());\n }\n } catch (error) {\n process.stderr.write(\n `smelt shim: unexpected error — allowing the call. ` +\n `${error instanceof Error ? (error.stack ?? error.message) : String(error)}\\n`,\n );\n output = adapter.pass();\n }\n if (output.stderr !== undefined && output.stderr !== '') process.stderr.write(output.stderr);\n if (output.stdout !== '') process.stdout.write(output.stdout);\n process.exitCode = output.exitCode;\n}\n\n/**\n * Map one `{tool name, tool input}` pair — the shape every surveyed harness feeds its\n * pre-tool hook, under varying key spellings — onto a {@link GuardRequest}.\n * `undefined` for tools the guard has no opinion on: pass through.\n */\nexport function toolCallRequest(\n toolName: unknown,\n toolInput: unknown,\n names: { readonly read: readonly string[]; readonly bash: readonly string[] },\n): GuardRequest | undefined {\n if (typeof toolName !== 'string') return undefined;\n const input =\n typeof toolInput === 'object' && toolInput !== null && !Array.isArray(toolInput)\n ? (toolInput as Record<string, unknown>)\n : {};\n\n if (names.read.includes(toolName)) {\n const path = firstString(input, ['file_path', 'path', 'absolute_path', 'filePath']);\n if (path === undefined) return undefined;\n const offsetLimited =\n firstDefined(input, ['offset', 'limit', 'start_line', 'end_line']) !== undefined;\n return { tool: 'Read', input: { path, offsetLimited } };\n }\n if (names.bash.includes(toolName)) {\n const command = firstString(input, ['command']);\n if (command === undefined) return undefined;\n return { tool: 'Bash', input: { command } };\n }\n return undefined;\n}\n\nfunction firstString(input: Record<string, unknown>, keys: readonly string[]): string | undefined {\n for (const key of keys) {\n const value = input[key];\n if (typeof value === 'string' && value !== '') return value;\n }\n return undefined;\n}\n\nfunction firstDefined(input: Record<string, unknown>, keys: readonly string[]): unknown {\n for (const key of keys) {\n if (input[key] !== undefined && input[key] !== null) return input[key];\n }\n return undefined;\n}\n\n/** The raw stdin as a keyed record, or an empty record when it is not object-shaped. */\nexport function asRecord(raw: unknown): Record<string, unknown> {\n return typeof raw === 'object' && raw !== null && !Array.isArray(raw)\n ? (raw as Record<string, unknown>)\n : {};\n}\n\n/* ------------------------------------------------------------------------------------\n * The hook schema, as data\n * ---------------------------------------------------------------------------------- */\n\n/**\n * One harness's pre-tool hook schema — everything that varies between shims, as a\n * table. Everything that does not vary (the tool mapping, the rewrite-input splice,\n * the announcement, the deny fallback) belongs to {@link shimFromSchema} and exists\n * exactly once.\n *\n * A schema states capability, never invents it: a harness whose hook cannot modify\n * tool input simply omits {@link rewrite}, and `renderShimDecision` then falls back to\n * the deny — whose reason still carries the exact replacement command.\n */\nexport interface HarnessHookSchema {\n /** Tool names this harness spells a file read with. */\n readonly readTools: readonly string[];\n /** Tool names this harness spells a shell command with. */\n readonly bashTools: readonly string[];\n /**\n * Where the tool name lives in the raw payload, in priority order — harnesses\n * disagree about the spelling (`tool_name`, `toolName`), and some nest the call.\n * A dotted key reads through one level of nesting (`preToolUse.toolName`).\n */\n readonly toolNameKeys: readonly string[];\n /** Where the tool's input object lives, same rules as {@link toolNameKeys}. */\n readonly toolInputKeys: readonly string[];\n /**\n * The payload key carrying the working directory relative paths resolve against,\n * for the harnesses that send one (Claude Code's hook stdin carries the *session's*\n * cwd, which after a `cd` differs from the hook process's own). Absent = the shim\n * process's cwd.\n */\n readonly cwdKey?: string;\n /** The harness's deny document, with the guard's steering reason in its one slot. */\n readonly deny: (reason: string) => unknown;\n /** The harness's input-rewrite document. Absent on a deny-only harness. */\n readonly rewrite?: HarnessRewriteSchema;\n}\n\n/** What a rewrite renders, and where the substitution is announced. */\nexport interface HarnessRewriteSchema {\n /** The rewrite document this harness's schema wants back. */\n readonly document: (rewrite: RewriteSlots) => unknown;\n /**\n * Where the substitution is announced. `'reason'` when the document carries a\n * reason channel the model reads (the template puts {@link RewriteSlots.announcement}\n * there); `'stderr'` when it does not — a rewrite nobody can see would change what\n * the model asked for without telling anyone.\n */\n readonly announce: 'reason' | 'stderr';\n}\n\n/** What a rewrite document is built from. Filled in by {@link shimFromSchema}. */\nexport interface RewriteSlots {\n /**\n * The tool's own input with `command` replaced by the suggestion — the splice every\n * rewriting harness needs, and which four shims used to carry verbatim. Harnesses\n * whose rewrite is a shallow merge send only the changed key instead.\n */\n readonly input: Record<string, unknown>;\n /** The replacement command itself. */\n readonly suggestion: string;\n /** The announcement, for a document with a reason channel. */\n readonly announcement: string;\n}\n\n/** What a deny says when the decision carries no reason — never an empty message. */\nexport const DENIED_WITHOUT_REASON = 'denied by the smelt guard';\n\n/**\n * The announcement for a rewrite whose document carries a reason channel the model\n * reads (Claude Code, Codex): the model is told, in its own transcript, that the\n * command it asked for is not the command that ran.\n */\nexport function rewroteReason(suggestion: string): string {\n return `smelt rewrote this command (hooks.enforcement: \"rewrite\"): ${suggestion}`;\n}\n\n/**\n * The stderr announcement, in two halves so a *generated* consumer can splice values\n * between them: the opencode plugin this installer writes is JavaScript source, and\n * its copy of this sentence used to be hand-typed inside a string template where\n * nothing could see it drift from the shims'. Both halves are pinned by\n * `test/guards/harness-registry.test.ts`.\n */\nexport const REWRITE_ANNOUNCEMENT_OPENING =\n 'smelt guard (rewrite mode): substituted the command in-flight with `';\nexport const REWRITE_ANNOUNCEMENT_JOIN = '`. ';\n\n/** The one stderr announcement, for a rewrite schema with no reason channel. */\nexport function rewriteAnnouncement(suggestion: string, reason: string): string {\n return `${REWRITE_ANNOUNCEMENT_OPENING}${suggestion}${REWRITE_ANNOUNCEMENT_JOIN}${reason}`;\n}\n\n/**\n * The first of `keys` the raw payload carries, `undefined` when it carries none — the\n * `a ?? b ?? c` every shim used to spell by hand, with dotted keys for the harnesses\n * that nest the tool call one level down.\n */\nfunction payloadValue(raw: unknown, keys: readonly string[]): unknown {\n const fields = asRecord(raw);\n for (const key of keys) {\n const dot = key.indexOf('.');\n const value =\n dot === -1 ? fields[key] : asRecord(fields[key.slice(0, dot)])[key.slice(dot + 1)];\n if (value !== undefined && value !== null) return value;\n }\n return undefined;\n}\n\n/**\n * The adapter a {@link HarnessHookSchema} describes. Everything shared lives here\n * once: the tool mapping, the rewrite-input splice, both announcements, the deny\n * fallback, and the rule that a schema with no `rewrite` renders a deny instead.\n */\nexport function shimFromSchema(schema: HarnessHookSchema): ShimAdapter {\n const { cwdKey, rewrite } = schema;\n return {\n toRequest: (raw) =>\n toolCallRequest(\n payloadValue(raw, schema.toolNameKeys),\n payloadValue(raw, schema.toolInputKeys),\n { read: schema.readTools, bash: schema.bashTools },\n ),\n ...(cwdKey === undefined\n ? {}\n : {\n cwd: (raw: unknown): string | undefined => {\n const cwd = asRecord(raw)[cwdKey];\n return typeof cwd === 'string' && cwd !== '' ? cwd : undefined;\n },\n }),\n pass: () => ({ stdout: '', exitCode: 0 }),\n deny: (_raw, _request, decision) => ({\n stdout: `${JSON.stringify(schema.deny(decision.reason ?? DENIED_WITHOUT_REASON))}\\n`,\n exitCode: 0,\n }),\n ...(rewrite === undefined\n ? {}\n : {\n rewrite: (raw: unknown, _request: GuardRequest, decision: GuardDecision): ShimOutput => {\n const suggestion = decision.suggestion ?? '';\n const input = {\n ...asRecord(payloadValue(raw, schema.toolInputKeys)),\n command: decision.suggestion,\n };\n const document = rewrite.document({\n input,\n suggestion,\n announcement: rewroteReason(suggestion),\n });\n return {\n stdout: `${JSON.stringify(document)}\\n`,\n ...(rewrite.announce === 'stderr'\n ? { stderr: `${rewriteAnnouncement(suggestion, decision.reason ?? '')}\\n` }\n : {}),\n exitCode: 0,\n };\n },\n }),\n };\n}\n\nexport { isMainModule };\n"]}
@@ -1,5 +1,5 @@
1
1
  import process from 'node:process';
2
- import { decide, isMainModule, parseGuardRequest, readAllOfStdin, readGuardSettings, } from './guard-core.js';
2
+ import { decide, isMainModule, readAllOfStdin, readGuardSettings } from './guard-core.js';
3
3
  /** The pure half of the shim loop, for tests: raw harness input → rendered output. */
4
4
  export function renderShimDecision(adapter, raw, settings, cwd, statFile) {
5
5
  const request = adapter.toRequest(raw);
@@ -103,5 +103,90 @@ export function asRecord(raw) {
103
103
  ? raw
104
104
  : {};
105
105
  }
106
- export { isMainModule, parseGuardRequest };
106
+ /** What a deny says when the decision carries no reason — never an empty message. */
107
+ export const DENIED_WITHOUT_REASON = 'denied by the smelt guard';
108
+ /**
109
+ * The announcement for a rewrite whose document carries a reason channel the model
110
+ * reads (Claude Code, Codex): the model is told, in its own transcript, that the
111
+ * command it asked for is not the command that ran.
112
+ */
113
+ export function rewroteReason(suggestion) {
114
+ return `smelt rewrote this command (hooks.enforcement: "rewrite"): ${suggestion}`;
115
+ }
116
+ /**
117
+ * The stderr announcement, in two halves so a *generated* consumer can splice values
118
+ * between them: the opencode plugin this installer writes is JavaScript source, and
119
+ * its copy of this sentence used to be hand-typed inside a string template where
120
+ * nothing could see it drift from the shims'. Both halves are pinned by
121
+ * `test/guards/harness-registry.test.ts`.
122
+ */
123
+ export const REWRITE_ANNOUNCEMENT_OPENING = 'smelt guard (rewrite mode): substituted the command in-flight with `';
124
+ export const REWRITE_ANNOUNCEMENT_JOIN = '`. ';
125
+ /** The one stderr announcement, for a rewrite schema with no reason channel. */
126
+ export function rewriteAnnouncement(suggestion, reason) {
127
+ return `${REWRITE_ANNOUNCEMENT_OPENING}${suggestion}${REWRITE_ANNOUNCEMENT_JOIN}${reason}`;
128
+ }
129
+ /**
130
+ * The first of `keys` the raw payload carries, `undefined` when it carries none — the
131
+ * `a ?? b ?? c` every shim used to spell by hand, with dotted keys for the harnesses
132
+ * that nest the tool call one level down.
133
+ */
134
+ function payloadValue(raw, keys) {
135
+ const fields = asRecord(raw);
136
+ for (const key of keys) {
137
+ const dot = key.indexOf('.');
138
+ const value = dot === -1 ? fields[key] : asRecord(fields[key.slice(0, dot)])[key.slice(dot + 1)];
139
+ if (value !== undefined && value !== null)
140
+ return value;
141
+ }
142
+ return undefined;
143
+ }
144
+ /**
145
+ * The adapter a {@link HarnessHookSchema} describes. Everything shared lives here
146
+ * once: the tool mapping, the rewrite-input splice, both announcements, the deny
147
+ * fallback, and the rule that a schema with no `rewrite` renders a deny instead.
148
+ */
149
+ export function shimFromSchema(schema) {
150
+ const { cwdKey, rewrite } = schema;
151
+ return {
152
+ toRequest: (raw) => toolCallRequest(payloadValue(raw, schema.toolNameKeys), payloadValue(raw, schema.toolInputKeys), { read: schema.readTools, bash: schema.bashTools }),
153
+ ...(cwdKey === undefined
154
+ ? {}
155
+ : {
156
+ cwd: (raw) => {
157
+ const cwd = asRecord(raw)[cwdKey];
158
+ return typeof cwd === 'string' && cwd !== '' ? cwd : undefined;
159
+ },
160
+ }),
161
+ pass: () => ({ stdout: '', exitCode: 0 }),
162
+ deny: (_raw, _request, decision) => ({
163
+ stdout: `${JSON.stringify(schema.deny(decision.reason ?? DENIED_WITHOUT_REASON))}\n`,
164
+ exitCode: 0,
165
+ }),
166
+ ...(rewrite === undefined
167
+ ? {}
168
+ : {
169
+ rewrite: (raw, _request, decision) => {
170
+ const suggestion = decision.suggestion ?? '';
171
+ const input = {
172
+ ...asRecord(payloadValue(raw, schema.toolInputKeys)),
173
+ command: decision.suggestion,
174
+ };
175
+ const document = rewrite.document({
176
+ input,
177
+ suggestion,
178
+ announcement: rewroteReason(suggestion),
179
+ });
180
+ return {
181
+ stdout: `${JSON.stringify(document)}\n`,
182
+ ...(rewrite.announce === 'stderr'
183
+ ? { stderr: `${rewriteAnnouncement(suggestion, decision.reason ?? '')}\n` }
184
+ : {}),
185
+ exitCode: 0,
186
+ };
187
+ },
188
+ }),
189
+ };
190
+ }
191
+ export { isMainModule };
107
192
  //# sourceMappingURL=shim.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shim.js","sourceRoot":"","sources":["../../src/hooks/shim.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shim.js","sourceRoot":"","sources":["../../src/hooks/shim.ts"],"names":[],"mappings":"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","sourcesContent":["import process from 'node:process';\n\nimport { decide, isMainModule, readAllOfStdin, readGuardSettings } from './guard-core.ts';\nimport type { GuardDecision, GuardRequest, GuardSettings } from './guard-core.ts';\n\n/**\n * The shim runtime — the one loop every per-harness shim runs.\n *\n * A shim is a thin adapter: it maps its harness's native PreToolUse stdin schema\n * onto a {@link GuardRequest}, hands that to the guard core, and renders the\n * {@link GuardDecision} back in the harness's native output schema. All policy —\n * threshold, windows, suggestion rendering, enforcement mode — lives in\n * `guard-core.ts`; a shim that grew an opinion of its own would be a second guard\n * that drifts from the first.\n *\n * Most of a shim is a *table*, not code: which tool names mean read and shell, which\n * payload keys carry them, and the two documents the harness's schema wants back. That\n * table is a {@link HarnessHookSchema}, `shimFromSchema` turns one into a\n * {@link ShimAdapter}, and every harness's schema lives in its profile\n * (`src/harness/<id>.ts`). {@link ShimAdapter} stays public as the escape hatch for a\n * harness a table cannot express.\n *\n * The enforcement gate lives here, once, because it is the same for every harness:\n *\n * - **deny mode (the default)**: a deny is rendered as the harness's deny, with the\n * guard's steering reason. The transcript stays truthful — the model sees what it\n * asked for refused and why, and learns to run the replacement (and\n * `smelt retrieve`) itself.\n * - **rewrite mode (`hooks.enforcement: \"rewrite\"` in smelt.config.json)**: when the\n * denied call is a Bash command, the guard produced a faithful executable\n * `suggestion`, and this harness can modify tool input, the shim substitutes the\n * suggestion instead of denying. A harness that cannot rewrite falls back to the\n * deny — with the exact command in the reason — so rewrite mode never silently\n * weakens into nothing. A substitution is always announced: in the decision\n * reason where the harness's rewrite schema carries one (Claude Code, Codex),\n * and on stderr where it does not (Gemini, Cursor, Hermes, the opencode\n * plugin) — a rewrite nobody can see would change what the model asked for\n * without telling anyone. And a shim never rewrites in deny mode: a silent\n * rewrite changes what the model asked for without telling it, which is this\n * project's signature failure shape applied to the harness.\n */\n\n/** What one harness shim supplies. Everything else is {@link runShim}'s. */\nexport interface ShimAdapter {\n /** Map the harness's raw stdin JSON to a guard request; `undefined` = pass through. */\n readonly toRequest: (raw: unknown) => GuardRequest | undefined;\n /**\n * The working directory tool-relative paths resolve against, read from the raw\n * payload when the harness sends one (Claude Code's hook stdin carries `cwd`: the\n * *session's* Bash cwd, which after a `cd` differs from this hook process's own).\n * `undefined` falls back to the shim process's cwd.\n */\n readonly cwd?: (raw: unknown) => string | undefined;\n /** Render an allow. Most harnesses: empty stdout, exit 0. */\n readonly pass: () => ShimOutput;\n /** Render a deny, in the harness's schema. */\n readonly deny: (raw: unknown, request: GuardRequest, decision: GuardDecision) => ShimOutput;\n /**\n * Render an input rewrite (only ever called for a Bash-shaped request whose\n * decision carries a faithful `suggestion`, and only in rewrite mode). Omit on\n * harnesses whose hook schema cannot modify tool input — they deny instead. A\n * schema with no reason channel must announce the substitution via `stderr`.\n */\n readonly rewrite?: (raw: unknown, request: GuardRequest, decision: GuardDecision) => ShimOutput;\n}\n\n/** What a shim writes and how it exits. `stdout` is a complete JSON line or ''. */\nexport interface ShimOutput {\n readonly stdout: string;\n /** Written to the shim process's stderr — the announcement channel for harnesses\n * whose rewrite schema has no reason field. Never a decision by itself. */\n readonly stderr?: string;\n readonly exitCode: number;\n}\n\n/** The pure half of the shim loop, for tests: raw harness input → rendered output. */\nexport function renderShimDecision(\n adapter: ShimAdapter,\n raw: unknown,\n settings: GuardSettings,\n cwd: string,\n statFile?: Parameters<typeof decide>[3],\n): ShimOutput {\n const request = adapter.toRequest(raw);\n if (request === undefined) return adapter.pass();\n const effectiveCwd = adapter.cwd?.(raw) ?? cwd;\n const decision =\n statFile === undefined\n ? decide(request, settings, effectiveCwd)\n : decide(request, settings, effectiveCwd, statFile);\n if (decision.action === 'allow') return adapter.pass();\n if (\n settings.enforcement === 'rewrite' &&\n adapter.rewrite !== undefined &&\n request.tool === 'Bash' &&\n decision.suggestion !== undefined\n ) {\n return adapter.rewrite(raw, request, decision);\n }\n return adapter.deny(raw, request, decision);\n}\n\n/**\n * The whole shim as a process: read the harness's stdin, decide, render, exit.\n * Fail open exactly like the guard core — unparseable stdin passes with a stderr\n * warning, and an unexpected error passes too. A shim crash must never read as a\n * policy decision.\n */\nexport function runShimMain(adapter: ShimAdapter): void {\n let output: ShimOutput;\n try {\n const text = readAllOfStdin();\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch {\n process.stderr.write(\n `smelt shim: stdin was not JSON — allowing the call. Fix the hook wiring.\\n`,\n );\n raw = undefined;\n }\n if (raw === undefined) {\n output = adapter.pass();\n } else {\n const settings = readGuardSettings(process.cwd(), (text_) =>\n process.stderr.write(`${text_}\\n`),\n );\n output = renderShimDecision(adapter, raw, settings, process.cwd());\n }\n } catch (error) {\n process.stderr.write(\n `smelt shim: unexpected error — allowing the call. ` +\n `${error instanceof Error ? (error.stack ?? error.message) : String(error)}\\n`,\n );\n output = adapter.pass();\n }\n if (output.stderr !== undefined && output.stderr !== '') process.stderr.write(output.stderr);\n if (output.stdout !== '') process.stdout.write(output.stdout);\n process.exitCode = output.exitCode;\n}\n\n/**\n * Map one `{tool name, tool input}` pair — the shape every surveyed harness feeds its\n * pre-tool hook, under varying key spellings — onto a {@link GuardRequest}.\n * `undefined` for tools the guard has no opinion on: pass through.\n */\nexport function toolCallRequest(\n toolName: unknown,\n toolInput: unknown,\n names: { readonly read: readonly string[]; readonly bash: readonly string[] },\n): GuardRequest | undefined {\n if (typeof toolName !== 'string') return undefined;\n const input =\n typeof toolInput === 'object' && toolInput !== null && !Array.isArray(toolInput)\n ? (toolInput as Record<string, unknown>)\n : {};\n\n if (names.read.includes(toolName)) {\n const path = firstString(input, ['file_path', 'path', 'absolute_path', 'filePath']);\n if (path === undefined) return undefined;\n const offsetLimited =\n firstDefined(input, ['offset', 'limit', 'start_line', 'end_line']) !== undefined;\n return { tool: 'Read', input: { path, offsetLimited } };\n }\n if (names.bash.includes(toolName)) {\n const command = firstString(input, ['command']);\n if (command === undefined) return undefined;\n return { tool: 'Bash', input: { command } };\n }\n return undefined;\n}\n\nfunction firstString(input: Record<string, unknown>, keys: readonly string[]): string | undefined {\n for (const key of keys) {\n const value = input[key];\n if (typeof value === 'string' && value !== '') return value;\n }\n return undefined;\n}\n\nfunction firstDefined(input: Record<string, unknown>, keys: readonly string[]): unknown {\n for (const key of keys) {\n if (input[key] !== undefined && input[key] !== null) return input[key];\n }\n return undefined;\n}\n\n/** The raw stdin as a keyed record, or an empty record when it is not object-shaped. */\nexport function asRecord(raw: unknown): Record<string, unknown> {\n return typeof raw === 'object' && raw !== null && !Array.isArray(raw)\n ? (raw as Record<string, unknown>)\n : {};\n}\n\n/* ------------------------------------------------------------------------------------\n * The hook schema, as data\n * ---------------------------------------------------------------------------------- */\n\n/**\n * One harness's pre-tool hook schema — everything that varies between shims, as a\n * table. Everything that does not vary (the tool mapping, the rewrite-input splice,\n * the announcement, the deny fallback) belongs to {@link shimFromSchema} and exists\n * exactly once.\n *\n * A schema states capability, never invents it: a harness whose hook cannot modify\n * tool input simply omits {@link rewrite}, and `renderShimDecision` then falls back to\n * the deny — whose reason still carries the exact replacement command.\n */\nexport interface HarnessHookSchema {\n /** Tool names this harness spells a file read with. */\n readonly readTools: readonly string[];\n /** Tool names this harness spells a shell command with. */\n readonly bashTools: readonly string[];\n /**\n * Where the tool name lives in the raw payload, in priority order — harnesses\n * disagree about the spelling (`tool_name`, `toolName`), and some nest the call.\n * A dotted key reads through one level of nesting (`preToolUse.toolName`).\n */\n readonly toolNameKeys: readonly string[];\n /** Where the tool's input object lives, same rules as {@link toolNameKeys}. */\n readonly toolInputKeys: readonly string[];\n /**\n * The payload key carrying the working directory relative paths resolve against,\n * for the harnesses that send one (Claude Code's hook stdin carries the *session's*\n * cwd, which after a `cd` differs from the hook process's own). Absent = the shim\n * process's cwd.\n */\n readonly cwdKey?: string;\n /** The harness's deny document, with the guard's steering reason in its one slot. */\n readonly deny: (reason: string) => unknown;\n /** The harness's input-rewrite document. Absent on a deny-only harness. */\n readonly rewrite?: HarnessRewriteSchema;\n}\n\n/** What a rewrite renders, and where the substitution is announced. */\nexport interface HarnessRewriteSchema {\n /** The rewrite document this harness's schema wants back. */\n readonly document: (rewrite: RewriteSlots) => unknown;\n /**\n * Where the substitution is announced. `'reason'` when the document carries a\n * reason channel the model reads (the template puts {@link RewriteSlots.announcement}\n * there); `'stderr'` when it does not — a rewrite nobody can see would change what\n * the model asked for without telling anyone.\n */\n readonly announce: 'reason' | 'stderr';\n}\n\n/** What a rewrite document is built from. Filled in by {@link shimFromSchema}. */\nexport interface RewriteSlots {\n /**\n * The tool's own input with `command` replaced by the suggestion — the splice every\n * rewriting harness needs, and which four shims used to carry verbatim. Harnesses\n * whose rewrite is a shallow merge send only the changed key instead.\n */\n readonly input: Record<string, unknown>;\n /** The replacement command itself. */\n readonly suggestion: string;\n /** The announcement, for a document with a reason channel. */\n readonly announcement: string;\n}\n\n/** What a deny says when the decision carries no reason — never an empty message. */\nexport const DENIED_WITHOUT_REASON = 'denied by the smelt guard';\n\n/**\n * The announcement for a rewrite whose document carries a reason channel the model\n * reads (Claude Code, Codex): the model is told, in its own transcript, that the\n * command it asked for is not the command that ran.\n */\nexport function rewroteReason(suggestion: string): string {\n return `smelt rewrote this command (hooks.enforcement: \"rewrite\"): ${suggestion}`;\n}\n\n/**\n * The stderr announcement, in two halves so a *generated* consumer can splice values\n * between them: the opencode plugin this installer writes is JavaScript source, and\n * its copy of this sentence used to be hand-typed inside a string template where\n * nothing could see it drift from the shims'. Both halves are pinned by\n * `test/guards/harness-registry.test.ts`.\n */\nexport const REWRITE_ANNOUNCEMENT_OPENING =\n 'smelt guard (rewrite mode): substituted the command in-flight with `';\nexport const REWRITE_ANNOUNCEMENT_JOIN = '`. ';\n\n/** The one stderr announcement, for a rewrite schema with no reason channel. */\nexport function rewriteAnnouncement(suggestion: string, reason: string): string {\n return `${REWRITE_ANNOUNCEMENT_OPENING}${suggestion}${REWRITE_ANNOUNCEMENT_JOIN}${reason}`;\n}\n\n/**\n * The first of `keys` the raw payload carries, `undefined` when it carries none — the\n * `a ?? b ?? c` every shim used to spell by hand, with dotted keys for the harnesses\n * that nest the tool call one level down.\n */\nfunction payloadValue(raw: unknown, keys: readonly string[]): unknown {\n const fields = asRecord(raw);\n for (const key of keys) {\n const dot = key.indexOf('.');\n const value =\n dot === -1 ? fields[key] : asRecord(fields[key.slice(0, dot)])[key.slice(dot + 1)];\n if (value !== undefined && value !== null) return value;\n }\n return undefined;\n}\n\n/**\n * The adapter a {@link HarnessHookSchema} describes. Everything shared lives here\n * once: the tool mapping, the rewrite-input splice, both announcements, the deny\n * fallback, and the rule that a schema with no `rewrite` renders a deny instead.\n */\nexport function shimFromSchema(schema: HarnessHookSchema): ShimAdapter {\n const { cwdKey, rewrite } = schema;\n return {\n toRequest: (raw) =>\n toolCallRequest(\n payloadValue(raw, schema.toolNameKeys),\n payloadValue(raw, schema.toolInputKeys),\n { read: schema.readTools, bash: schema.bashTools },\n ),\n ...(cwdKey === undefined\n ? {}\n : {\n cwd: (raw: unknown): string | undefined => {\n const cwd = asRecord(raw)[cwdKey];\n return typeof cwd === 'string' && cwd !== '' ? cwd : undefined;\n },\n }),\n pass: () => ({ stdout: '', exitCode: 0 }),\n deny: (_raw, _request, decision) => ({\n stdout: `${JSON.stringify(schema.deny(decision.reason ?? DENIED_WITHOUT_REASON))}\\n`,\n exitCode: 0,\n }),\n ...(rewrite === undefined\n ? {}\n : {\n rewrite: (raw: unknown, _request: GuardRequest, decision: GuardDecision): ShimOutput => {\n const suggestion = decision.suggestion ?? '';\n const input = {\n ...asRecord(payloadValue(raw, schema.toolInputKeys)),\n command: decision.suggestion,\n };\n const document = rewrite.document({\n input,\n suggestion,\n announcement: rewroteReason(suggestion),\n });\n return {\n stdout: `${JSON.stringify(document)}\\n`,\n ...(rewrite.announce === 'stderr'\n ? { stderr: `${rewriteAnnouncement(suggestion, decision.reason ?? '')}\\n` }\n : {}),\n exitCode: 0,\n };\n },\n }),\n };\n}\n\nexport { isMainModule };\n"]}
@@ -1,23 +1,10 @@
1
1
  import type { ShimAdapter } from '../shim.ts';
2
2
  /**
3
- * Claude Code shim — VERIFIED tier.
4
- *
5
- * Schema per <https://code.claude.com/docs/en/hooks> (verified 2026-09-02; the deep
6
- * dive is docs/research/2026-09-02-agent-enforcement.md § 1):
7
- *
8
- * - stdin: `{ hook_event_name: "PreToolUse", tool_name, tool_input, cwd }`. For
9
- * `Read`, `tool_input.file_path` is already absolute and `offset`/`limit` mark a
10
- * windowed read; for `Bash`, `tool_input.command` is the full command string, and
11
- * a relative path in it resolves against the payload's `cwd` — the *session's*
12
- * working directory, which after the model `cd`s differs from this hook
13
- * process's own cwd.
14
- * - deny: `hookSpecificOutput.permissionDecision: "deny"` with
15
- * `permissionDecisionReason` — which is **shown to the model**, so the guard's
16
- * reason (the exact replacement command, the `smelt retrieve` contract) lands in
17
- * the transcript as steering.
18
- * - rewrite (opt-in, `hooks.enforcement: "rewrite"`): `updatedInput` replaces the
19
- * entire input object of the *same* tool (v2.0.10+), so a Bash command can be
20
- * substituted but a Read can never become a Bash call — Reads deny in every mode.
3
+ * Claude Code shim — VERIFIED tier. The runnable front door only: every fact about this
4
+ * harness, its hook schema included, lives in its profile
5
+ * (`src/harness/claude-code.ts`), and `shimFromSchema` turns that schema into the
6
+ * adapter below. The installer wires `node dist/hooks/shims/claude-code.js` as the
7
+ * harness's hook command; this file is what that runs.
21
8
  */
22
9
  export declare const adapter: ShimAdapter;
23
10
  //# sourceMappingURL=claude-code.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../../src/hooks/shims/claude-code.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,OAAO,EAAE,WAqCrB,CAAC"}
1
+ {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../../src/hooks/shims/claude-code.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,WAAuC,CAAC","sourcesContent":["import { claudeCode } from '../../harness/claude-code.ts';\nimport { shimAdapterOf } from '../../harness/profile.ts';\nimport { isMainModule, runShimMain } from '../shim.ts';\nimport type { ShimAdapter } from '../shim.ts';\n\n/**\n * Claude Code shim — VERIFIED tier. The runnable front door only: every fact about this\n * harness, its hook schema included, lives in its profile\n * (`src/harness/claude-code.ts`), and `shimFromSchema` turns that schema into the\n * adapter below. The installer wires `node dist/hooks/shims/claude-code.js` as the\n * harness's hook command; this file is what that runs.\n */\nexport const adapter: ShimAdapter = shimAdapterOf(claudeCode);\n\nif (isMainModule(import.meta.url)) runShimMain(adapter);\n"]}
@@ -1,61 +1,14 @@
1
- import { asRecord, isMainModule, runShimMain, toolCallRequest } from '../shim.js';
1
+ import { claudeCode } from '../../harness/claude-code.js';
2
+ import { shimAdapterOf } from '../../harness/profile.js';
3
+ import { isMainModule, runShimMain } from '../shim.js';
2
4
  /**
3
- * Claude Code shim — VERIFIED tier.
4
- *
5
- * Schema per <https://code.claude.com/docs/en/hooks> (verified 2026-09-02; the deep
6
- * dive is docs/research/2026-09-02-agent-enforcement.md § 1):
7
- *
8
- * - stdin: `{ hook_event_name: "PreToolUse", tool_name, tool_input, cwd }`. For
9
- * `Read`, `tool_input.file_path` is already absolute and `offset`/`limit` mark a
10
- * windowed read; for `Bash`, `tool_input.command` is the full command string, and
11
- * a relative path in it resolves against the payload's `cwd` — the *session's*
12
- * working directory, which after the model `cd`s differs from this hook
13
- * process's own cwd.
14
- * - deny: `hookSpecificOutput.permissionDecision: "deny"` with
15
- * `permissionDecisionReason` — which is **shown to the model**, so the guard's
16
- * reason (the exact replacement command, the `smelt retrieve` contract) lands in
17
- * the transcript as steering.
18
- * - rewrite (opt-in, `hooks.enforcement: "rewrite"`): `updatedInput` replaces the
19
- * entire input object of the *same* tool (v2.0.10+), so a Bash command can be
20
- * substituted but a Read can never become a Bash call — Reads deny in every mode.
5
+ * Claude Code shim — VERIFIED tier. The runnable front door only: every fact about this
6
+ * harness, its hook schema included, lives in its profile
7
+ * (`src/harness/claude-code.ts`), and `shimFromSchema` turns that schema into the
8
+ * adapter below. The installer wires `node dist/hooks/shims/claude-code.js` as the
9
+ * harness's hook command; this file is what that runs.
21
10
  */
22
- export const adapter = {
23
- toRequest: (raw) => {
24
- const fields = asRecord(raw);
25
- return toolCallRequest(fields['tool_name'], fields['tool_input'], {
26
- read: ['Read'],
27
- bash: ['Bash'],
28
- });
29
- },
30
- cwd: (raw) => {
31
- const cwd = asRecord(raw)['cwd'];
32
- return typeof cwd === 'string' && cwd !== '' ? cwd : undefined;
33
- },
34
- pass: () => ({ stdout: '', exitCode: 0 }),
35
- deny: (_raw, _request, decision) => ({
36
- stdout: `${JSON.stringify({
37
- hookSpecificOutput: {
38
- hookEventName: 'PreToolUse',
39
- permissionDecision: 'deny',
40
- permissionDecisionReason: decision.reason ?? 'denied by the smelt guard',
41
- },
42
- })}\n`,
43
- exitCode: 0,
44
- }),
45
- rewrite: (raw, _request, decision) => ({
46
- stdout: `${JSON.stringify({
47
- hookSpecificOutput: {
48
- hookEventName: 'PreToolUse',
49
- permissionDecision: 'allow',
50
- permissionDecisionReason: `smelt rewrote this command (hooks.enforcement: "rewrite"): ` +
51
- `${decision.suggestion ?? ''}`,
52
- // updatedInput replaces the whole input object — unchanged fields ride along.
53
- updatedInput: { ...asRecord(asRecord(raw)['tool_input']), command: decision.suggestion },
54
- },
55
- })}\n`,
56
- exitCode: 0,
57
- }),
58
- };
11
+ export const adapter = shimAdapterOf(claudeCode);
59
12
  if (isMainModule(import.meta.url))
60
13
  runShimMain(adapter);
61
14
  //# sourceMappingURL=claude-code.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/hooks/shims/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,OAAO,GAAgB;IAClC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;QACjB,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC7B,OAAO,eAAe,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE;YAChE,IAAI,EAAE,CAAC,MAAM,CAAC;YACd,IAAI,EAAE,CAAC,MAAM,CAAC;SACf,CAAC,CAAC;IACL,CAAC;IACD,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;QACX,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACjE,CAAC;IACD,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzC,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QACnC,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;YACxB,kBAAkB,EAAE;gBAClB,aAAa,EAAE,YAAY;gBAC3B,kBAAkB,EAAE,MAAM;gBAC1B,wBAAwB,EAAE,QAAQ,CAAC,MAAM,IAAI,2BAA2B;aACzE;SACF,CAAC,IAAI;QACN,QAAQ,EAAE,CAAC;KACZ,CAAC;IACF,OAAO,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QACrC,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;YACxB,kBAAkB,EAAE;gBAClB,aAAa,EAAE,YAAY;gBAC3B,kBAAkB,EAAE,OAAO;gBAC3B,wBAAwB,EACtB,6DAA6D;oBAC7D,GAAG,QAAQ,CAAC,UAAU,IAAI,EAAE,EAAE;gBAChC,8EAA8E;gBAC9E,YAAY,EAAE,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAE;aACzF;SACF,CAAC,IAAI;QACN,QAAQ,EAAE,CAAC;KACZ,CAAC;CACH,CAAC;AAEF,IAAI,YAAY,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC;IAAE,WAAW,CAAC,OAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/hooks/shims/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGvD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAgB,aAAa,CAAC,UAAU,CAAC,CAAC;AAE9D,IAAI,YAAY,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC;IAAE,WAAW,CAAC,OAAO,CAAC,CAAC","sourcesContent":["import { claudeCode } from '../../harness/claude-code.ts';\nimport { shimAdapterOf } from '../../harness/profile.ts';\nimport { isMainModule, runShimMain } from '../shim.ts';\nimport type { ShimAdapter } from '../shim.ts';\n\n/**\n * Claude Code shim — VERIFIED tier. The runnable front door only: every fact about this\n * harness, its hook schema included, lives in its profile\n * (`src/harness/claude-code.ts`), and `shimFromSchema` turns that schema into the\n * adapter below. The installer wires `node dist/hooks/shims/claude-code.js` as the\n * harness's hook command; this file is what that runs.\n */\nexport const adapter: ShimAdapter = shimAdapterOf(claudeCode);\n\nif (isMainModule(import.meta.url)) runShimMain(adapter);\n"]}
@@ -1,17 +1,10 @@
1
1
  import type { ShimAdapter } from '../shim.ts';
2
2
  /**
3
- * Cline shim — EXPERIMENTAL tier: schema mapped from the capability matrix
4
- * (docs/research/2026-09-02-harness-capability-matrix.md, Cline row; primary source
5
- * <https://docs.cline.bot/features/hooks>), not yet smoke-tested against the real
6
- * binary.
7
- *
8
- * - event: `PreToolUse`, delivered to an executable under `.clinerules/hooks/`;
9
- * stdin carries the tool call (accepted spellings: `tool_name`/`tool_input`,
10
- * `toolName`/`toolInput`, or nested under `preToolUse`).
11
- * - deny: `{ "cancel": true, "errorMessage": … }`. **Deny-only**: the response
12
- * schema has no input-modification field, so under
13
- * `hooks.enforcement: "rewrite"` this harness falls back to the deny, whose
14
- * reason still carries the exact replacement pipeline.
3
+ * Cline shim — EXPERIMENTAL tier. The runnable front door only: every fact about this
4
+ * harness, its hook schema included, lives in its profile
5
+ * (`src/harness/cline.ts`), and `shimFromSchema` turns that schema into the
6
+ * adapter below. The installer wires `node dist/hooks/shims/cline.js` as the
7
+ * harness's hook command; this file is what that runs.
15
8
  */
16
9
  export declare const adapter: ShimAdapter;
17
10
  //# sourceMappingURL=cline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cline.d.ts","sourceRoot":"","sources":["../../../src/hooks/shims/cline.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,OAAO,EAAE,WAqBrB,CAAC"}
1
+ {"version":3,"file":"cline.d.ts","sourceRoot":"","sources":["../../../src/hooks/shims/cline.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,WAAkC,CAAC","sourcesContent":["import { cline } from '../../harness/cline.ts';\nimport { shimAdapterOf } from '../../harness/profile.ts';\nimport { isMainModule, runShimMain } from '../shim.ts';\nimport type { ShimAdapter } from '../shim.ts';\n\n/**\n * Cline shim — EXPERIMENTAL tier. The runnable front door only: every fact about this\n * harness, its hook schema included, lives in its profile\n * (`src/harness/cline.ts`), and `shimFromSchema` turns that schema into the\n * adapter below. The installer wires `node dist/hooks/shims/cline.js` as the\n * harness's hook command; this file is what that runs.\n */\nexport const adapter: ShimAdapter = shimAdapterOf(cline);\n\nif (isMainModule(import.meta.url)) runShimMain(adapter);\n"]}