@chances-ai/engine 24.0.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 (389) hide show
  1. package/dist/agents/discover.d.ts +30 -0
  2. package/dist/agents/discover.d.ts.map +1 -0
  3. package/dist/agents/discover.js +183 -0
  4. package/dist/agents/discover.js.map +1 -0
  5. package/dist/agents/index.d.ts +20 -0
  6. package/dist/agents/index.d.ts.map +1 -0
  7. package/dist/agents/index.js +52 -0
  8. package/dist/agents/index.js.map +1 -0
  9. package/dist/agents/parse.d.ts +61 -0
  10. package/dist/agents/parse.d.ts.map +1 -0
  11. package/dist/agents/parse.js +527 -0
  12. package/dist/agents/parse.js.map +1 -0
  13. package/dist/agents/types.d.ts +52 -0
  14. package/dist/agents/types.d.ts.map +1 -0
  15. package/dist/agents/types.js +8 -0
  16. package/dist/agents/types.js.map +1 -0
  17. package/dist/ai/adapters/ai-sdk-stream.d.ts +19 -0
  18. package/dist/ai/adapters/ai-sdk-stream.d.ts.map +1 -0
  19. package/dist/ai/adapters/ai-sdk-stream.js +125 -0
  20. package/dist/ai/adapters/ai-sdk-stream.js.map +1 -0
  21. package/dist/ai/adapters/ai-sdk.d.ts +56 -0
  22. package/dist/ai/adapters/ai-sdk.d.ts.map +1 -0
  23. package/dist/ai/adapters/ai-sdk.js +112 -0
  24. package/dist/ai/adapters/ai-sdk.js.map +1 -0
  25. package/dist/ai/adapters/mock.d.ts +13 -0
  26. package/dist/ai/adapters/mock.d.ts.map +1 -0
  27. package/dist/ai/adapters/mock.js +54 -0
  28. package/dist/ai/adapters/mock.js.map +1 -0
  29. package/dist/ai/adapters/openai-compatible.d.ts +23 -0
  30. package/dist/ai/adapters/openai-compatible.d.ts.map +1 -0
  31. package/dist/ai/adapters/openai-compatible.js +45 -0
  32. package/dist/ai/adapters/openai-compatible.js.map +1 -0
  33. package/dist/ai/cost.d.ts +3 -0
  34. package/dist/ai/cost.d.ts.map +1 -0
  35. package/dist/ai/cost.js +5 -0
  36. package/dist/ai/cost.js.map +1 -0
  37. package/dist/ai/index.d.ts +12 -0
  38. package/dist/ai/index.d.ts.map +1 -0
  39. package/dist/ai/index.js +11 -0
  40. package/dist/ai/index.js.map +1 -0
  41. package/dist/ai/known-models.d.ts +20 -0
  42. package/dist/ai/known-models.d.ts.map +1 -0
  43. package/dist/ai/known-models.js +129 -0
  44. package/dist/ai/known-models.js.map +1 -0
  45. package/dist/ai/registry.d.ts +12 -0
  46. package/dist/ai/registry.d.ts.map +1 -0
  47. package/dist/ai/registry.js +24 -0
  48. package/dist/ai/registry.js.map +1 -0
  49. package/dist/ai/retry.d.ts +11 -0
  50. package/dist/ai/retry.d.ts.map +1 -0
  51. package/dist/ai/retry.js +14 -0
  52. package/dist/ai/retry.js.map +1 -0
  53. package/dist/ai/router.d.ts +25 -0
  54. package/dist/ai/router.d.ts.map +1 -0
  55. package/dist/ai/router.js +36 -0
  56. package/dist/ai/router.js.map +1 -0
  57. package/dist/ai/setup.d.ts +23 -0
  58. package/dist/ai/setup.d.ts.map +1 -0
  59. package/dist/ai/setup.js +47 -0
  60. package/dist/ai/setup.js.map +1 -0
  61. package/dist/ai/summarizer.d.ts +24 -0
  62. package/dist/ai/summarizer.d.ts.map +1 -0
  63. package/dist/ai/summarizer.js +56 -0
  64. package/dist/ai/summarizer.js.map +1 -0
  65. package/dist/ai/types.d.ts +83 -0
  66. package/dist/ai/types.d.ts.map +1 -0
  67. package/dist/ai/types.js +2 -0
  68. package/dist/ai/types.js.map +1 -0
  69. package/dist/core/compaction/circuit-breaker.d.ts +32 -0
  70. package/dist/core/compaction/circuit-breaker.d.ts.map +1 -0
  71. package/dist/core/compaction/circuit-breaker.js +42 -0
  72. package/dist/core/compaction/circuit-breaker.js.map +1 -0
  73. package/dist/core/compaction/compactor.d.ts +75 -0
  74. package/dist/core/compaction/compactor.d.ts.map +1 -0
  75. package/dist/core/compaction/compactor.js +261 -0
  76. package/dist/core/compaction/compactor.js.map +1 -0
  77. package/dist/core/compaction/estimate.d.ts +39 -0
  78. package/dist/core/compaction/estimate.d.ts.map +1 -0
  79. package/dist/core/compaction/estimate.js +74 -0
  80. package/dist/core/compaction/estimate.js.map +1 -0
  81. package/dist/core/compaction/index.d.ts +5 -0
  82. package/dist/core/compaction/index.d.ts.map +1 -0
  83. package/dist/core/compaction/index.js +5 -0
  84. package/dist/core/compaction/index.js.map +1 -0
  85. package/dist/core/compaction/prune.d.ts +43 -0
  86. package/dist/core/compaction/prune.d.ts.map +1 -0
  87. package/dist/core/compaction/prune.js +51 -0
  88. package/dist/core/compaction/prune.js.map +1 -0
  89. package/dist/core/engine.d.ts +268 -0
  90. package/dist/core/engine.d.ts.map +1 -0
  91. package/dist/core/engine.js +767 -0
  92. package/dist/core/engine.js.map +1 -0
  93. package/dist/core/index.d.ts +6 -0
  94. package/dist/core/index.d.ts.map +1 -0
  95. package/dist/core/index.js +6 -0
  96. package/dist/core/index.js.map +1 -0
  97. package/dist/core/task-tool.d.ts +175 -0
  98. package/dist/core/task-tool.d.ts.map +1 -0
  99. package/dist/core/task-tool.js +901 -0
  100. package/dist/core/task-tool.js.map +1 -0
  101. package/dist/core/workspace-query.d.ts +83 -0
  102. package/dist/core/workspace-query.d.ts.map +1 -0
  103. package/dist/core/workspace-query.js +217 -0
  104. package/dist/core/workspace-query.js.map +1 -0
  105. package/dist/core/worktree/active-marker.d.ts +31 -0
  106. package/dist/core/worktree/active-marker.d.ts.map +1 -0
  107. package/dist/core/worktree/active-marker.js +109 -0
  108. package/dist/core/worktree/active-marker.js.map +1 -0
  109. package/dist/core/worktree/create.d.ts +40 -0
  110. package/dist/core/worktree/create.d.ts.map +1 -0
  111. package/dist/core/worktree/create.js +121 -0
  112. package/dist/core/worktree/create.js.map +1 -0
  113. package/dist/core/worktree/errors.d.ts +7 -0
  114. package/dist/core/worktree/errors.d.ts.map +1 -0
  115. package/dist/core/worktree/errors.js +11 -0
  116. package/dist/core/worktree/errors.js.map +1 -0
  117. package/dist/core/worktree/gc.d.ts +39 -0
  118. package/dist/core/worktree/gc.d.ts.map +1 -0
  119. package/dist/core/worktree/gc.js +146 -0
  120. package/dist/core/worktree/gc.js.map +1 -0
  121. package/dist/core/worktree/git.d.ts +53 -0
  122. package/dist/core/worktree/git.d.ts.map +1 -0
  123. package/dist/core/worktree/git.js +166 -0
  124. package/dist/core/worktree/git.js.map +1 -0
  125. package/dist/core/worktree/index.d.ts +8 -0
  126. package/dist/core/worktree/index.d.ts.map +1 -0
  127. package/dist/core/worktree/index.js +8 -0
  128. package/dist/core/worktree/index.js.map +1 -0
  129. package/dist/core/worktree/paths.d.ts +26 -0
  130. package/dist/core/worktree/paths.d.ts.map +1 -0
  131. package/dist/core/worktree/paths.js +57 -0
  132. package/dist/core/worktree/paths.js.map +1 -0
  133. package/dist/core/worktree/slug.d.ts +6 -0
  134. package/dist/core/worktree/slug.d.ts.map +1 -0
  135. package/dist/core/worktree/slug.js +21 -0
  136. package/dist/core/worktree/slug.js.map +1 -0
  137. package/dist/local-vault/file-store.d.ts +64 -0
  138. package/dist/local-vault/file-store.d.ts.map +1 -0
  139. package/dist/local-vault/file-store.js +225 -0
  140. package/dist/local-vault/file-store.js.map +1 -0
  141. package/dist/local-vault/index.d.ts +57 -0
  142. package/dist/local-vault/index.d.ts.map +1 -0
  143. package/dist/local-vault/index.js +68 -0
  144. package/dist/local-vault/index.js.map +1 -0
  145. package/dist/local-vault/keychain.d.ts +58 -0
  146. package/dist/local-vault/keychain.d.ts.map +1 -0
  147. package/dist/local-vault/keychain.js +200 -0
  148. package/dist/local-vault/keychain.js.map +1 -0
  149. package/dist/local-vault/mutex.d.ts +20 -0
  150. package/dist/local-vault/mutex.d.ts.map +1 -0
  151. package/dist/local-vault/mutex.js +44 -0
  152. package/dist/local-vault/mutex.js.map +1 -0
  153. package/dist/local-vault/passphrase.d.ts +30 -0
  154. package/dist/local-vault/passphrase.d.ts.map +1 -0
  155. package/dist/local-vault/passphrase.js +72 -0
  156. package/dist/local-vault/passphrase.js.map +1 -0
  157. package/dist/lsp/config.d.ts +34 -0
  158. package/dist/lsp/config.d.ts.map +1 -0
  159. package/dist/lsp/config.js +68 -0
  160. package/dist/lsp/config.js.map +1 -0
  161. package/dist/lsp/detect.d.ts +7 -0
  162. package/dist/lsp/detect.d.ts.map +1 -0
  163. package/dist/lsp/detect.js +78 -0
  164. package/dist/lsp/detect.js.map +1 -0
  165. package/dist/lsp/errors.d.ts +11 -0
  166. package/dist/lsp/errors.d.ts.map +1 -0
  167. package/dist/lsp/errors.js +11 -0
  168. package/dist/lsp/errors.js.map +1 -0
  169. package/dist/lsp/formatters.d.ts +147 -0
  170. package/dist/lsp/formatters.d.ts.map +1 -0
  171. package/dist/lsp/formatters.js +259 -0
  172. package/dist/lsp/formatters.js.map +1 -0
  173. package/dist/lsp/index.d.ts +31 -0
  174. package/dist/lsp/index.d.ts.map +1 -0
  175. package/dist/lsp/index.js +31 -0
  176. package/dist/lsp/index.js.map +1 -0
  177. package/dist/lsp/instance.d.ts +72 -0
  178. package/dist/lsp/instance.d.ts.map +1 -0
  179. package/dist/lsp/instance.js +489 -0
  180. package/dist/lsp/instance.js.map +1 -0
  181. package/dist/lsp/lazy-load.d.ts +27 -0
  182. package/dist/lsp/lazy-load.d.ts.map +1 -0
  183. package/dist/lsp/lazy-load.js +57 -0
  184. package/dist/lsp/lazy-load.js.map +1 -0
  185. package/dist/lsp/manager.d.ts +59 -0
  186. package/dist/lsp/manager.d.ts.map +1 -0
  187. package/dist/lsp/manager.js +242 -0
  188. package/dist/lsp/manager.js.map +1 -0
  189. package/dist/lsp/ops.d.ts +13 -0
  190. package/dist/lsp/ops.d.ts.map +1 -0
  191. package/dist/lsp/ops.js +225 -0
  192. package/dist/lsp/ops.js.map +1 -0
  193. package/dist/lsp/rpc.d.ts +47 -0
  194. package/dist/lsp/rpc.d.ts.map +1 -0
  195. package/dist/lsp/rpc.js +134 -0
  196. package/dist/lsp/rpc.js.map +1 -0
  197. package/dist/lsp/safe-uri.d.ts +18 -0
  198. package/dist/lsp/safe-uri.d.ts.map +1 -0
  199. package/dist/lsp/safe-uri.js +96 -0
  200. package/dist/lsp/safe-uri.js.map +1 -0
  201. package/dist/lsp/types.d.ts +70 -0
  202. package/dist/lsp/types.d.ts.map +1 -0
  203. package/dist/lsp/types.js +16 -0
  204. package/dist/lsp/types.js.map +1 -0
  205. package/dist/mcp/bridge.d.ts +57 -0
  206. package/dist/mcp/bridge.d.ts.map +1 -0
  207. package/dist/mcp/bridge.js +98 -0
  208. package/dist/mcp/bridge.js.map +1 -0
  209. package/dist/mcp/category.d.ts +22 -0
  210. package/dist/mcp/category.d.ts.map +1 -0
  211. package/dist/mcp/category.js +11 -0
  212. package/dist/mcp/category.js.map +1 -0
  213. package/dist/mcp/client.d.ts +228 -0
  214. package/dist/mcp/client.d.ts.map +1 -0
  215. package/dist/mcp/client.js +352 -0
  216. package/dist/mcp/client.js.map +1 -0
  217. package/dist/mcp/content.d.ts +86 -0
  218. package/dist/mcp/content.d.ts.map +1 -0
  219. package/dist/mcp/content.js +147 -0
  220. package/dist/mcp/content.js.map +1 -0
  221. package/dist/mcp/env.d.ts +19 -0
  222. package/dist/mcp/env.d.ts.map +1 -0
  223. package/dist/mcp/env.js +50 -0
  224. package/dist/mcp/env.js.map +1 -0
  225. package/dist/mcp/host.d.ts +199 -0
  226. package/dist/mcp/host.d.ts.map +1 -0
  227. package/dist/mcp/host.js +530 -0
  228. package/dist/mcp/host.js.map +1 -0
  229. package/dist/mcp/index.d.ts +18 -0
  230. package/dist/mcp/index.d.ts.map +1 -0
  231. package/dist/mcp/index.js +17 -0
  232. package/dist/mcp/index.js.map +1 -0
  233. package/dist/mcp/load-mcp-host.d.ts +32 -0
  234. package/dist/mcp/load-mcp-host.d.ts.map +1 -0
  235. package/dist/mcp/load-mcp-host.js +49 -0
  236. package/dist/mcp/load-mcp-host.js.map +1 -0
  237. package/dist/mcp/oauth/callback-server.d.ts +73 -0
  238. package/dist/mcp/oauth/callback-server.d.ts.map +1 -0
  239. package/dist/mcp/oauth/callback-server.js +280 -0
  240. package/dist/mcp/oauth/callback-server.js.map +1 -0
  241. package/dist/mcp/oauth/config-hash.d.ts +24 -0
  242. package/dist/mcp/oauth/config-hash.d.ts.map +1 -0
  243. package/dist/mcp/oauth/config-hash.js +55 -0
  244. package/dist/mcp/oauth/config-hash.js.map +1 -0
  245. package/dist/mcp/oauth/error-normalize.d.ts +39 -0
  246. package/dist/mcp/oauth/error-normalize.d.ts.map +1 -0
  247. package/dist/mcp/oauth/error-normalize.js +91 -0
  248. package/dist/mcp/oauth/error-normalize.js.map +1 -0
  249. package/dist/mcp/oauth/provider.d.ts +190 -0
  250. package/dist/mcp/oauth/provider.d.ts.map +1 -0
  251. package/dist/mcp/oauth/provider.js +305 -0
  252. package/dist/mcp/oauth/provider.js.map +1 -0
  253. package/dist/mcp/oauth/refresh-coalescer.d.ts +46 -0
  254. package/dist/mcp/oauth/refresh-coalescer.d.ts.map +1 -0
  255. package/dist/mcp/oauth/refresh-coalescer.js +77 -0
  256. package/dist/mcp/oauth/refresh-coalescer.js.map +1 -0
  257. package/dist/mcp/oauth/sdk-shapes.d.ts +77 -0
  258. package/dist/mcp/oauth/sdk-shapes.d.ts.map +1 -0
  259. package/dist/mcp/oauth/sdk-shapes.js +21 -0
  260. package/dist/mcp/oauth/sdk-shapes.js.map +1 -0
  261. package/dist/mcp/parse.d.ts +28 -0
  262. package/dist/mcp/parse.d.ts.map +1 -0
  263. package/dist/mcp/parse.js +209 -0
  264. package/dist/mcp/parse.js.map +1 -0
  265. package/dist/mcp/prompts.d.ts +31 -0
  266. package/dist/mcp/prompts.d.ts.map +1 -0
  267. package/dist/mcp/prompts.js +71 -0
  268. package/dist/mcp/prompts.js.map +1 -0
  269. package/dist/mcp/redact.d.ts +62 -0
  270. package/dist/mcp/redact.d.ts.map +1 -0
  271. package/dist/mcp/redact.js +87 -0
  272. package/dist/mcp/redact.js.map +1 -0
  273. package/dist/mcp/resources.d.ts +70 -0
  274. package/dist/mcp/resources.d.ts.map +1 -0
  275. package/dist/mcp/resources.js +170 -0
  276. package/dist/mcp/resources.js.map +1 -0
  277. package/dist/mcp/types.d.ts +123 -0
  278. package/dist/mcp/types.d.ts.map +1 -0
  279. package/dist/mcp/types.js +2 -0
  280. package/dist/mcp/types.js.map +1 -0
  281. package/dist/memory/frontmatter.d.ts +18 -0
  282. package/dist/memory/frontmatter.d.ts.map +1 -0
  283. package/dist/memory/frontmatter.js +81 -0
  284. package/dist/memory/frontmatter.js.map +1 -0
  285. package/dist/memory/index.d.ts +5 -0
  286. package/dist/memory/index.d.ts.map +1 -0
  287. package/dist/memory/index.js +5 -0
  288. package/dist/memory/index.js.map +1 -0
  289. package/dist/memory/store.d.ts +44 -0
  290. package/dist/memory/store.d.ts.map +1 -0
  291. package/dist/memory/store.js +237 -0
  292. package/dist/memory/store.js.map +1 -0
  293. package/dist/memory/tools.d.ts +11 -0
  294. package/dist/memory/tools.d.ts.map +1 -0
  295. package/dist/memory/tools.js +159 -0
  296. package/dist/memory/tools.js.map +1 -0
  297. package/dist/memory/types.d.ts +32 -0
  298. package/dist/memory/types.d.ts.map +1 -0
  299. package/dist/memory/types.js +20 -0
  300. package/dist/memory/types.js.map +1 -0
  301. package/dist/plugin-api/index.d.ts +167 -0
  302. package/dist/plugin-api/index.d.ts.map +1 -0
  303. package/dist/plugin-api/index.js +151 -0
  304. package/dist/plugin-api/index.js.map +1 -0
  305. package/dist/plugin-logger/index.d.ts +21 -0
  306. package/dist/plugin-logger/index.d.ts.map +1 -0
  307. package/dist/plugin-logger/index.js +59 -0
  308. package/dist/plugin-logger/index.js.map +1 -0
  309. package/dist/session/index.d.ts +125 -0
  310. package/dist/session/index.d.ts.map +1 -0
  311. package/dist/session/index.js +202 -0
  312. package/dist/session/index.js.map +1 -0
  313. package/dist/tools/approval.d.ts +33 -0
  314. package/dist/tools/approval.d.ts.map +1 -0
  315. package/dist/tools/approval.js +53 -0
  316. package/dist/tools/approval.js.map +1 -0
  317. package/dist/tools/builtins/_shared.d.ts +94 -0
  318. package/dist/tools/builtins/_shared.d.ts.map +1 -0
  319. package/dist/tools/builtins/_shared.js +246 -0
  320. package/dist/tools/builtins/_shared.js.map +1 -0
  321. package/dist/tools/builtins/ask-user-question.d.ts +27 -0
  322. package/dist/tools/builtins/ask-user-question.d.ts.map +1 -0
  323. package/dist/tools/builtins/ask-user-question.js +191 -0
  324. package/dist/tools/builtins/ask-user-question.js.map +1 -0
  325. package/dist/tools/builtins/bash.d.ts +3 -0
  326. package/dist/tools/builtins/bash.d.ts.map +1 -0
  327. package/dist/tools/builtins/bash.js +158 -0
  328. package/dist/tools/builtins/bash.js.map +1 -0
  329. package/dist/tools/builtins/diff.d.ts +3 -0
  330. package/dist/tools/builtins/diff.d.ts.map +1 -0
  331. package/dist/tools/builtins/diff.js +83 -0
  332. package/dist/tools/builtins/diff.js.map +1 -0
  333. package/dist/tools/builtins/edit.d.ts +3 -0
  334. package/dist/tools/builtins/edit.d.ts.map +1 -0
  335. package/dist/tools/builtins/edit.js +40 -0
  336. package/dist/tools/builtins/edit.js.map +1 -0
  337. package/dist/tools/builtins/glob.d.ts +3 -0
  338. package/dist/tools/builtins/glob.d.ts.map +1 -0
  339. package/dist/tools/builtins/glob.js +37 -0
  340. package/dist/tools/builtins/glob.js.map +1 -0
  341. package/dist/tools/builtins/grep.d.ts +3 -0
  342. package/dist/tools/builtins/grep.d.ts.map +1 -0
  343. package/dist/tools/builtins/grep.js +81 -0
  344. package/dist/tools/builtins/grep.js.map +1 -0
  345. package/dist/tools/builtins/lsp.d.ts +3 -0
  346. package/dist/tools/builtins/lsp.d.ts.map +1 -0
  347. package/dist/tools/builtins/lsp.js +102 -0
  348. package/dist/tools/builtins/lsp.js.map +1 -0
  349. package/dist/tools/builtins/pty.d.ts +64 -0
  350. package/dist/tools/builtins/pty.d.ts.map +1 -0
  351. package/dist/tools/builtins/pty.js +536 -0
  352. package/dist/tools/builtins/pty.js.map +1 -0
  353. package/dist/tools/builtins/read.d.ts +3 -0
  354. package/dist/tools/builtins/read.d.ts.map +1 -0
  355. package/dist/tools/builtins/read.js +18 -0
  356. package/dist/tools/builtins/read.js.map +1 -0
  357. package/dist/tools/builtins/web-fetch.d.ts +4 -0
  358. package/dist/tools/builtins/web-fetch.d.ts.map +1 -0
  359. package/dist/tools/builtins/web-fetch.js +353 -0
  360. package/dist/tools/builtins/web-fetch.js.map +1 -0
  361. package/dist/tools/builtins/write.d.ts +3 -0
  362. package/dist/tools/builtins/write.d.ts.map +1 -0
  363. package/dist/tools/builtins/write.js +48 -0
  364. package/dist/tools/builtins/write.js.map +1 -0
  365. package/dist/tools/builtins.d.ts +9 -0
  366. package/dist/tools/builtins.d.ts.map +1 -0
  367. package/dist/tools/builtins.js +29 -0
  368. package/dist/tools/builtins.js.map +1 -0
  369. package/dist/tools/diff.d.ts +18 -0
  370. package/dist/tools/diff.d.ts.map +1 -0
  371. package/dist/tools/diff.js +57 -0
  372. package/dist/tools/diff.js.map +1 -0
  373. package/dist/tools/index.d.ts +10 -0
  374. package/dist/tools/index.d.ts.map +1 -0
  375. package/dist/tools/index.js +9 -0
  376. package/dist/tools/index.js.map +1 -0
  377. package/dist/tools/permission.d.ts +120 -0
  378. package/dist/tools/permission.d.ts.map +1 -0
  379. package/dist/tools/permission.js +208 -0
  380. package/dist/tools/permission.js.map +1 -0
  381. package/dist/tools/registry.d.ts +12 -0
  382. package/dist/tools/registry.d.ts.map +1 -0
  383. package/dist/tools/registry.js +19 -0
  384. package/dist/tools/registry.js.map +1 -0
  385. package/dist/tools/types.d.ts +244 -0
  386. package/dist/tools/types.d.ts.map +1 -0
  387. package/dist/tools/types.js +15 -0
  388. package/dist/tools/types.js.map +1 -0
  389. package/package.json +109 -0
@@ -0,0 +1,120 @@
1
+ import type { PermissionPolicy, ToolCategory } from "@chances-ai/runtime/config";
2
+ import type { ApprovalMode } from "@chances-ai/runtime";
3
+ import type { AuthorizationRequest, PermissionResolver, QuestionDecision, QuestionRequest } from "./types.js";
4
+ /**
5
+ * (5.3) The full result of a permission check. `check()` returns just `allow`
6
+ * for backwards-compatible callers; `evaluate()` returns this so the engine can
7
+ * surface a precise reason (plan-mode block, deny-with-feedback) in the tool
8
+ * result.
9
+ */
10
+ export interface PermissionEvaluation {
11
+ allow: boolean;
12
+ /** Why it was denied (or mode-allowed); surfaced in the tool result. */
13
+ reason?: string;
14
+ /** Which layer decided. `mode` = the session approval mode forced it. */
15
+ source?: "policy" | "mode" | "resolver";
16
+ /** Deny-with-feedback: free text the user wants relayed to the model. */
17
+ feedback?: string;
18
+ }
19
+ /**
20
+ * Chain of responsibility for a tool invocation:
21
+ * per-tool rule -> category default -> (prompt|host-bridged) -> resolver.
22
+ * `allow` short-circuits true, `deny` short-circuits false, the rest delegate
23
+ * to the resolver (which is the interactive prompt, or an auto-policy in -p mode).
24
+ *
25
+ * **Session positive-decision cache.** Once the resolver returns `true` for a
26
+ * tool name with a `prompt`-category default, subsequent checks of the same
27
+ * tool name skip the resolver for the rest of this `PermissionGate`'s
28
+ * lifetime. This is scoped to MCP-bridged names (`mcp__*`) by default — the
29
+ * `cacheScope` predicate is overridable for tests and future expansion. The
30
+ * cache only stores positives; a `false` from the resolver always re-prompts
31
+ * (so a user who initially says "no" doesn't get silently locked out when
32
+ * they want to reconsider).
33
+ *
34
+ * Rationale: a freshly-added MCP server typically exposes 5–30 tools. Without
35
+ * a cache, the user is re-prompted on every single call for every single
36
+ * tool — claude-code and oh-my-pi both cache, and the trust signal is the
37
+ * user's act of adding the server to config in the first place. Per-tool
38
+ * explicit `deny` in `policy.tools` still wins (we check that first).
39
+ */
40
+ export type PermissionCacheScope = (req: AuthorizationRequest) => boolean;
41
+ export declare class PermissionGate {
42
+ private readonly policy;
43
+ private readonly resolver;
44
+ private readonly cacheScope;
45
+ private readonly getMode;
46
+ private readonly allowCache;
47
+ /**
48
+ * Promise chain that serialises every resolver invocation across the gate.
49
+ * Without this, two concurrent tool calls (e.g. parent's sync tool +
50
+ * background child's tool, post-3.4) both reach `this.resolver(...)`,
51
+ * and the TUI's view-model has exactly one `pending` slot — the second
52
+ * request overwrites the first, orphaning the first promise. Codex
53
+ * Round-1 MUST-FIX #1.
54
+ *
55
+ * The chain only wraps the actual resolver call: every fast-path
56
+ * decision (allow rule, deny rule, positive-decision cache hit) returns
57
+ * BEFORE acquiring the lock, so non-prompt categories stay O(1) and
58
+ * don't slow down with a queue of in-flight prompts.
59
+ */
60
+ private resolveLock;
61
+ constructor(policy: PermissionPolicy, resolver: PermissionResolver, cacheScope?: PermissionCacheScope, getMode?: () => ApprovalMode);
62
+ /** Boolean shim over {@link evaluate} for callers that only need the verdict
63
+ * (RPC/ACP host, LSP resolver, legacy tests). */
64
+ check(req: AuthorizationRequest): Promise<boolean>;
65
+ /**
66
+ * (5.3) Whether the session mode blocks this whole tool category outright
67
+ * (plan's read-only floor), as a synchronous pre-check the engine runs
68
+ * BEFORE a tool's `permission()` null-bypass — so plan can't be skipped by an
69
+ * op that would otherwise bypass the gate (codex Round-1 MUST-FIX #1). Pure
70
+ * function of `(category, getMode())`; shares `isBlockedByMode` with
71
+ * `evaluate` so there's one source of truth.
72
+ */
73
+ blockByMode(category: ToolCategory): {
74
+ reason: string;
75
+ } | null;
76
+ /**
77
+ * Full decision. Precedence (docs/5.3-design.md D3) over the existing static
78
+ * lookup `tools[name] ?? defaults[category]`:
79
+ * 1. static `deny` (per-tool OR category) → DENY — the absolute floor no
80
+ * mode overrides (codex Round-1 MUST-FIX #4: yolo must not bypass a
81
+ * configured deny).
82
+ * 2. mode blocks the tier (plan) → DENY — overrides a standing `allow`.
83
+ * 3. static `allow` → ALLOW.
84
+ * 4. mode auto-approves the tier (yolo / auto-edit) → ALLOW, no prompt.
85
+ * 5. static `prompt`/`host-bridged` → positive-cache hit, else resolver.
86
+ */
87
+ evaluate(req: AuthorizationRequest): Promise<PermissionEvaluation>;
88
+ /**
89
+ * (5.10b SHOULD-FIX #2) Surgical extraction of the per-gate serialization lock
90
+ * shared by `evaluate` (authorization) and `ask` (question): snapshot the
91
+ * previous lock, install our own, await the snapshot (chaining works whether
92
+ * or not it rejected), run `fn`, release. Nothing evaluate-specific lives here.
93
+ */
94
+ private withResolverLock;
95
+ /**
96
+ * (5.10b) The QUESTION channel — used ONLY by the read-only `ask_user_question`
97
+ * tool (the engine fail-closes any other tool that emits a `question` request).
98
+ * Deliberately bypasses `evaluate`'s allow / auto-approve / positive-cache /
99
+ * mode precedence — a question is not an authorization — but PRESERVES the
100
+ * static `deny` floor (per-tool rule OR category default) so an operator can
101
+ * disable the asker. Shares `evaluate`'s serialization lock so a question and
102
+ * an authorization never race for the resolver's single `pending` slot. A
103
+ * non-question (or stray boolean) decision ⇒ declined (never auth-on-question).
104
+ */
105
+ ask(req: QuestionRequest): Promise<QuestionDecision>;
106
+ /**
107
+ * Drops one cache key from the positive-decision cache. The MCP host
108
+ * calls this with the tool name when a server is restarted or
109
+ * removed — without it, a previously approved tool name could silently
110
+ * authorize a *different* implementation after the server's tool set
111
+ * changed. (5.1) Op-enum tools call this with their per-op cache key
112
+ * (e.g. `pty.kill.SIGTERM/<session_id>`) when a session terminates so
113
+ * a re-used session id can't carry a stale approval.
114
+ */
115
+ invalidate(name: string): void;
116
+ /** Drops every cached positive decision. Useful for "I'm rotating creds,
117
+ * re-prompt me" UX or as a wholesale teardown when MCP is reloaded. */
118
+ invalidateAll(): void;
119
+ }
120
+ //# sourceMappingURL=permission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../src/tools/permission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EAChB,MAAM,YAAY,CAAC;AAGpB;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACxC,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC;AAsB1E,qBAAa,cAAc;IAkBvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAO3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IA1B1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,WAAW,CAAoC;gBAGpC,MAAM,EAAE,gBAAgB,EACxB,QAAQ,EAAE,kBAAkB,EAC5B,UAAU,GAAE,oBAA0C,EAOtD,OAAO,GAAE,MAAM,YAA8B;IAGhE;sDACkD;IAC5C,KAAK,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IAIxD;;;;;;;OAOG;IACH,WAAW,CAAC,QAAQ,EAAE,YAAY,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAK9D;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAkExE;;;;;OAKG;YACW,gBAAgB;IAc9B;;;;;;;;;OASG;IACG,GAAG,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAa1D;;;;;;;;OAQG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI9B;2EACuE;IACvE,aAAa,IAAI,IAAI;CAGtB"}
@@ -0,0 +1,208 @@
1
+ import { isAutoApprovedByMode, isBlockedByMode, modeBlockReason } from "./approval.js";
2
+ /**
3
+ * Default cache scope. Three cohorts are cached by default:
4
+ * 1. **MCP-bridged tools** (`mcp__*`) — pre-5.1 behaviour preserved.
5
+ * The user's act of adding a server to config is the trust
6
+ * signal; once they say "yes" to a tool, they shouldn't be
7
+ * re-prompted on every call.
8
+ * 2. **Per-op cacheKey shapes** — any request that ships an
9
+ * explicit `cacheKey` opts in to caching. The op-enum tools
10
+ * (5.1's `pty`, future siblings) use this for per-`(session,
11
+ * operation, arg-class)` scoping so e.g. approving SIGTERM on
12
+ * session X does not pre-approve SIGKILL on the same session
13
+ * (codex Round-2 MUST-FIX #2 — without this broadening the
14
+ * hook's cacheKey was dead code).
15
+ * 3. Everything else stays un-cached so the user re-prompts per
16
+ * call by default — that matches `web_fetch`'s per-URL gating
17
+ * intent and the file-write defaults.
18
+ */
19
+ const DEFAULT_CACHE_SCOPE = (req) => req.name.startsWith("mcp__") || req.cacheKey !== undefined;
20
+ export class PermissionGate {
21
+ policy;
22
+ resolver;
23
+ cacheScope;
24
+ getMode;
25
+ allowCache = new Set();
26
+ /**
27
+ * Promise chain that serialises every resolver invocation across the gate.
28
+ * Without this, two concurrent tool calls (e.g. parent's sync tool +
29
+ * background child's tool, post-3.4) both reach `this.resolver(...)`,
30
+ * and the TUI's view-model has exactly one `pending` slot — the second
31
+ * request overwrites the first, orphaning the first promise. Codex
32
+ * Round-1 MUST-FIX #1.
33
+ *
34
+ * The chain only wraps the actual resolver call: every fast-path
35
+ * decision (allow rule, deny rule, positive-decision cache hit) returns
36
+ * BEFORE acquiring the lock, so non-prompt categories stay O(1) and
37
+ * don't slow down with a queue of in-flight prompts.
38
+ */
39
+ resolveLock = Promise.resolve();
40
+ constructor(policy, resolver, cacheScope = DEFAULT_CACHE_SCOPE,
41
+ // (5.3) Session approval-mode getter. Optional 4th positional so every
42
+ // existing `new PermissionGate(policy, resolver[, cacheScope])` call site
43
+ // keeps working at `default` mode (codex Round-1 MUST-FIX #2 — back-compat).
44
+ // A getter (not the holder) keeps tools decoupled from runtime's
45
+ // ApprovalState; read fresh on every check so a mid-turn Shift+Tab lands
46
+ // immediately.
47
+ getMode = () => "default") {
48
+ this.policy = policy;
49
+ this.resolver = resolver;
50
+ this.cacheScope = cacheScope;
51
+ this.getMode = getMode;
52
+ }
53
+ /** Boolean shim over {@link evaluate} for callers that only need the verdict
54
+ * (RPC/ACP host, LSP resolver, legacy tests). */
55
+ async check(req) {
56
+ return (await this.evaluate(req)).allow;
57
+ }
58
+ /**
59
+ * (5.3) Whether the session mode blocks this whole tool category outright
60
+ * (plan's read-only floor), as a synchronous pre-check the engine runs
61
+ * BEFORE a tool's `permission()` null-bypass — so plan can't be skipped by an
62
+ * op that would otherwise bypass the gate (codex Round-1 MUST-FIX #1). Pure
63
+ * function of `(category, getMode())`; shares `isBlockedByMode` with
64
+ * `evaluate` so there's one source of truth.
65
+ */
66
+ blockByMode(category) {
67
+ const mode = this.getMode();
68
+ return isBlockedByMode(category, mode) ? { reason: modeBlockReason(mode) } : null;
69
+ }
70
+ /**
71
+ * Full decision. Precedence (docs/5.3-design.md D3) over the existing static
72
+ * lookup `tools[name] ?? defaults[category]`:
73
+ * 1. static `deny` (per-tool OR category) → DENY — the absolute floor no
74
+ * mode overrides (codex Round-1 MUST-FIX #4: yolo must not bypass a
75
+ * configured deny).
76
+ * 2. mode blocks the tier (plan) → DENY — overrides a standing `allow`.
77
+ * 3. static `allow` → ALLOW.
78
+ * 4. mode auto-approves the tier (yolo / auto-edit) → ALLOW, no prompt.
79
+ * 5. static `prompt`/`host-bridged` → positive-cache hit, else resolver.
80
+ */
81
+ async evaluate(req) {
82
+ // (5.1) Cache key falls back to `name`. Per-op shapes set `cacheKey`.
83
+ const key = req.cacheKey ?? req.name;
84
+ const mode = this.getMode();
85
+ const staticDecision = this.policy.tools?.[req.name] ?? this.policy.defaults[req.category];
86
+ if (staticDecision === "deny") {
87
+ return { allow: false, reason: `denied by policy (${req.category})`, source: "policy" };
88
+ }
89
+ if (isBlockedByMode(req.category, mode)) {
90
+ return { allow: false, reason: modeBlockReason(mode), source: "mode" };
91
+ }
92
+ if (staticDecision === "allow")
93
+ return { allow: true, source: "policy" };
94
+ if (isAutoApprovedByMode(req.category, mode))
95
+ return { allow: true, source: "mode" };
96
+ // "prompt" / "host-bridged" defer to the resolver unless a positive
97
+ // decision for this key is already cached this session. The cache only
98
+ // holds keys that were intentionally remembered (scoped auto-cache OR an
99
+ // explicit `remember:true` "always"), so a hit is always honored —
100
+ // independent of `cacheScope`, which only governs *adding* below.
101
+ if (this.allowCache.has(key))
102
+ return { allow: true, source: "policy" };
103
+ // Acquire the per-gate serialisation lock, then run the resolver step. The
104
+ // post-wait cache re-check + mode re-read live INSIDE this callback (NOT in
105
+ // `withResolverLock`) — they are evaluate-specific, not generic to the lock
106
+ // (codex R1 SHOULD-FIX #2 — surgical extraction).
107
+ return this.withResolverLock(async () => {
108
+ // Re-check the cache after the wait — another queued call may have
109
+ // populated it (see the read-before-lock note above re: cacheScope).
110
+ if (this.allowCache.has(key))
111
+ return { allow: true, source: "policy" };
112
+ // (5.3 codex Round-1 SHOULD-FIX #1) Re-read the mode after the wait too:
113
+ // the user may have flipped to plan (→ block) or yolo (→ skip the now-
114
+ // stale prompt) while this request sat in the queue.
115
+ const modeNow = this.getMode();
116
+ if (isBlockedByMode(req.category, modeNow)) {
117
+ return { allow: false, reason: modeBlockReason(modeNow), source: "mode" };
118
+ }
119
+ if (isAutoApprovedByMode(req.category, modeNow))
120
+ return { allow: true, source: "mode" };
121
+ // (5.2 MUST-FIX #1 / 5.3) The resolver returns a bare boolean (legacy) or
122
+ // a PermissionDecision. Caching rule:
123
+ // - bare boolean: cache iff `cacheScope` (legacy, scope-gated).
124
+ // - {remember:false}: never cache (allow-once).
125
+ // - {remember:true}: cache regardless of scope — an explicit human/host
126
+ // "always" should stick even for un-scoped tools like file-write
127
+ // (this is the TUI's "[a] yes, don't ask" path).
128
+ // - {} (remember omitted): scope-gated, preserving 5.2 ACP semantics.
129
+ const decision = await this.resolver(req);
130
+ // (5.10b) A question decision must never reach the authorization path — it
131
+ // carries no allow/deny. Defensive: the engine only sends authorization
132
+ // requests here, so a stray question ⇒ treat as a denial.
133
+ if (typeof decision !== "boolean" && decision.kind === "question") {
134
+ return { allow: false, source: "resolver" };
135
+ }
136
+ const explicit = typeof decision !== "boolean";
137
+ const granted = explicit ? decision.allow : decision;
138
+ const remember = explicit ? decision.remember !== false : true;
139
+ const feedback = explicit ? decision.feedback : undefined;
140
+ const cacheIt = granted && remember && (this.cacheScope(req) || (explicit && decision.remember === true));
141
+ if (cacheIt)
142
+ this.allowCache.add(key);
143
+ return granted
144
+ ? { allow: true, source: "resolver" }
145
+ : { allow: false, source: "resolver", feedback };
146
+ });
147
+ }
148
+ /**
149
+ * (5.10b SHOULD-FIX #2) Surgical extraction of the per-gate serialization lock
150
+ * shared by `evaluate` (authorization) and `ask` (question): snapshot the
151
+ * previous lock, install our own, await the snapshot (chaining works whether
152
+ * or not it rejected), run `fn`, release. Nothing evaluate-specific lives here.
153
+ */
154
+ async withResolverLock(fn) {
155
+ const previousLock = this.resolveLock;
156
+ let release;
157
+ this.resolveLock = new Promise((r) => {
158
+ release = r;
159
+ });
160
+ try {
161
+ await previousLock.catch(() => { });
162
+ return await fn();
163
+ }
164
+ finally {
165
+ release();
166
+ }
167
+ }
168
+ /**
169
+ * (5.10b) The QUESTION channel — used ONLY by the read-only `ask_user_question`
170
+ * tool (the engine fail-closes any other tool that emits a `question` request).
171
+ * Deliberately bypasses `evaluate`'s allow / auto-approve / positive-cache /
172
+ * mode precedence — a question is not an authorization — but PRESERVES the
173
+ * static `deny` floor (per-tool rule OR category default) so an operator can
174
+ * disable the asker. Shares `evaluate`'s serialization lock so a question and
175
+ * an authorization never race for the resolver's single `pending` slot. A
176
+ * non-question (or stray boolean) decision ⇒ declined (never auth-on-question).
177
+ */
178
+ async ask(req) {
179
+ const staticDecision = this.policy.tools?.[req.name] ?? this.policy.defaults[req.category];
180
+ if (staticDecision === "deny") {
181
+ return { kind: "question", answers: {}, declined: true };
182
+ }
183
+ return this.withResolverLock(async () => {
184
+ const decision = await this.resolver(req);
185
+ return typeof decision === "boolean" || decision.kind !== "question"
186
+ ? { kind: "question", answers: {}, declined: true }
187
+ : decision;
188
+ });
189
+ }
190
+ /**
191
+ * Drops one cache key from the positive-decision cache. The MCP host
192
+ * calls this with the tool name when a server is restarted or
193
+ * removed — without it, a previously approved tool name could silently
194
+ * authorize a *different* implementation after the server's tool set
195
+ * changed. (5.1) Op-enum tools call this with their per-op cache key
196
+ * (e.g. `pty.kill.SIGTERM/<session_id>`) when a session terminates so
197
+ * a re-used session id can't carry a stale approval.
198
+ */
199
+ invalidate(name) {
200
+ this.allowCache.delete(name);
201
+ }
202
+ /** Drops every cached positive decision. Useful for "I'm rotating creds,
203
+ * re-prompt me" UX or as a wholesale teardown when MCP is reloaded. */
204
+ invalidateAll() {
205
+ this.allowCache.clear();
206
+ }
207
+ }
208
+ //# sourceMappingURL=permission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission.js","sourceRoot":"","sources":["../../src/tools/permission.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAyCvF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,mBAAmB,GAAyB,CAAC,GAAG,EAAE,EAAE,CACxD,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC;AAE7D,MAAM,OAAO,cAAc;IAkBN;IACA;IACA;IAOA;IA1BF,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAChD;;;;;;;;;;;;OAYG;IACK,WAAW,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAEvD,YACmB,MAAwB,EACxB,QAA4B,EAC5B,aAAmC,mBAAmB;IACvE,uEAAuE;IACvE,0EAA0E;IAC1E,6EAA6E;IAC7E,iEAAiE;IACjE,yEAAyE;IACzE,eAAe;IACE,UAA8B,GAAG,EAAE,CAAC,SAAS;QAT7C,WAAM,GAAN,MAAM,CAAkB;QACxB,aAAQ,GAAR,QAAQ,CAAoB;QAC5B,eAAU,GAAV,UAAU,CAA4C;QAOtD,YAAO,GAAP,OAAO,CAAsC;IAC7D,CAAC;IAEJ;sDACkD;IAClD,KAAK,CAAC,KAAK,CAAC,GAAyB;QACnC,OAAO,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1C,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,QAAsB;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5B,OAAO,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACpF,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,QAAQ,CAAC,GAAyB;QACtC,sEAAsE;QACtE,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5B,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE3F,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;YAC9B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,GAAG,CAAC,QAAQ,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;QAC1F,CAAC;QACD,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;YACxC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACzE,CAAC;QACD,IAAI,cAAc,KAAK,OAAO;YAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;QACzE,IAAI,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAErF,oEAAoE;QACpE,uEAAuE;QACvE,yEAAyE;QACzE,mEAAmE;QACnE,kEAAkE;QAClE,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;QAEvE,2EAA2E;QAC3E,4EAA4E;QAC5E,4EAA4E;QAC5E,kDAAkD;QAClD,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE;YACtC,mEAAmE;YACnE,qEAAqE;YACrE,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;YACvE,yEAAyE;YACzE,uEAAuE;YACvE,qDAAqD;YACrD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC/B,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;gBAC3C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC5E,CAAC;YACD,IAAI,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC;gBAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAExF,0EAA0E;YAC1E,sCAAsC;YACtC,kEAAkE;YAClE,kDAAkD;YAClD,0EAA0E;YAC1E,qEAAqE;YACrE,qDAAqD;YACrD,wEAAwE;YACxE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC1C,2EAA2E;YAC3E,wEAAwE;YACxE,0DAA0D;YAC1D,IAAI,OAAO,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAClE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;YAC9C,CAAC;YACD,MAAM,QAAQ,GAAG,OAAO,QAAQ,KAAK,SAAS,CAAC;YAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;YACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;YAC/D,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1D,MAAM,OAAO,GAAG,OAAO,IAAI,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC;YAC1G,IAAI,OAAO;gBAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtC,OAAO,OAAO;gBACZ,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE;gBACrC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,gBAAgB,CAAI,EAAoB;QACpD,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC;QACtC,IAAI,OAAoB,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE;YACzC,OAAO,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACnC,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,GAAG,CAAC,GAAoB;QAC5B,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3F,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;YAC9B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC3D,CAAC;QACD,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE;YACtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC1C,OAAO,OAAO,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU;gBAClE,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBACnD,CAAC,CAAC,QAAQ,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACH,UAAU,CAAC,IAAY;QACrB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;2EACuE;IACvE,aAAa;QACX,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { Tool } from "./types.js";
2
+ /** Registry pattern: built-in and plugin tools share one namespace. */
3
+ export declare class ToolRegistry {
4
+ private readonly tools;
5
+ register(tool: Tool): void;
6
+ /** Removes a tool by name, returning true if it existed. Used by PluginHost
7
+ * rollback when a plugin's onLoad throws after registering a tool. */
8
+ unregister(name: string): boolean;
9
+ get(name: string): Tool | undefined;
10
+ list(): Tool[];
11
+ }
12
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,uEAAuE;AACvE,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IAEjD,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAI1B;0EACsE;IACtE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAInC,IAAI,IAAI,IAAI,EAAE;CAGf"}
@@ -0,0 +1,19 @@
1
+ /** Registry pattern: built-in and plugin tools share one namespace. */
2
+ export class ToolRegistry {
3
+ tools = new Map();
4
+ register(tool) {
5
+ this.tools.set(tool.name, tool);
6
+ }
7
+ /** Removes a tool by name, returning true if it existed. Used by PluginHost
8
+ * rollback when a plugin's onLoad throws after registering a tool. */
9
+ unregister(name) {
10
+ return this.tools.delete(name);
11
+ }
12
+ get(name) {
13
+ return this.tools.get(name);
14
+ }
15
+ list() {
16
+ return [...this.tools.values()];
17
+ }
18
+ }
19
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAEA,uEAAuE;AACvE,MAAM,OAAO,YAAY;IACN,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAC;IAEjD,QAAQ,CAAC,IAAU;QACjB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAED;0EACsE;IACtE,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAClC,CAAC;CACF"}
@@ -0,0 +1,244 @@
1
+ import type { JSONValue } from "@chances-ai/runtime";
2
+ import type { ToolCategory } from "@chances-ai/runtime/config";
3
+ export type { ToolCategory };
4
+ /** Minimum LSP host shape consumed by the `lsp` built-in tool. Kept
5
+ * narrow so this package doesn't depend on `@chances-ai/lsp` for
6
+ * types — the engine wires the real instance in at boot time and
7
+ * downcasts. (codex Round-1 MUST-FIX #1.) */
8
+ export interface ToolLspHost {
9
+ execute(req: {
10
+ op: string;
11
+ filePath?: string;
12
+ line?: number;
13
+ character?: number;
14
+ query?: string;
15
+ cwd: string;
16
+ signal: AbortSignal;
17
+ }): Promise<{
18
+ ok: boolean;
19
+ output: string;
20
+ }>;
21
+ }
22
+ export interface ToolContext {
23
+ workspaceRoot: string;
24
+ cwd: string;
25
+ signal: AbortSignal;
26
+ /**
27
+ * (4.1) The parent (non-isolated) workspace root. Inside an isolated
28
+ * subagent, `workspaceRoot` and `cwd` flip to the worktree path, but
29
+ * **artifact persistence paths** (e.g. `bash`'s oversized-output dump
30
+ * under `.chances/tool-results/`) should land in the PARENT workspace
31
+ * so the parent's `.chances/` directory accumulates the durable
32
+ * record. Otherwise a clean-removed worktree could swallow the
33
+ * persisted file just as the tool returns its path.
34
+ *
35
+ * Outside isolation, this equals `workspaceRoot`. Tools that emit
36
+ * artifacts should prefer `parentWorkspaceRoot ?? workspaceRoot` so
37
+ * the contract is uniform across both branches. Round-2 SHOULD-FIX
38
+ * #4.
39
+ */
40
+ parentWorkspaceRoot?: string;
41
+ /**
42
+ * (4.2) Optional LSP host wired in at boot when the user has
43
+ * `vscode-jsonrpc` installed AND `config.lsp.enabled !== false`.
44
+ * Undefined when the peer is absent or LSP is disabled — the `lsp`
45
+ * tool fails fast with a labelled `ok:false` in that case.
46
+ * codex Round-1 MUST-FIX #1 — wrapper cannot reach a CLI-boot-time
47
+ * host without this engine plumbing.
48
+ */
49
+ lsp?: ToolLspHost;
50
+ /**
51
+ * (5.7) The engine's tool-call id for THIS execution — the same
52
+ * `callId` carried on the `tool:call` / `tool:result` bus events and
53
+ * the provider's `tool_call.id`. The engine stamps it on the ctx
54
+ * before both `permission()` and `execute()` (see `core/engine.ts`).
55
+ *
56
+ * Tools that persist oversized output use it to name the artifact
57
+ * directory (`.chances/tool-results/<callId>/…`) so a client can join
58
+ * the saved file to the `tool_result` it received — mirrors
59
+ * claude-code's `.claude/tool-results/<toolUseId>`. Undefined for
60
+ * non-engine callers (tests, plugins invoking a tool directly), where
61
+ * persistence falls back to a freshly-minted `createId`.
62
+ */
63
+ callId?: string;
64
+ /**
65
+ * (5.10b) The user's answers to an `ask_user_question` call. The engine
66
+ * populates this ONLY on the question branch — and ONLY for the read-only ask
67
+ * tool — immediately before `execute()`; `summarize()` and every other
68
+ * tool/branch never see it. The ask tool reads it to format the model-facing
69
+ * result string (the engine never serializes answers itself).
70
+ */
71
+ questionDecision?: QuestionDecision;
72
+ }
73
+ export interface ToolResult {
74
+ ok: boolean;
75
+ output: string;
76
+ }
77
+ /** Command pattern: each tool is a self-describing, executable unit. */
78
+ export interface Tool {
79
+ name: string;
80
+ description: string;
81
+ category: ToolCategory;
82
+ /** JSON Schema for the args object (shared with the provider via core). */
83
+ parameters: JSONValue;
84
+ /** One-line, human-readable description of a specific invocation (used by the
85
+ * permission prompt and diff approval). Receives the same ctx as execute so
86
+ * that path-aware previews (e.g. create vs overwrite) resolve against the
87
+ * workspace, not process.cwd. */
88
+ summarize(args: JSONValue, ctx: ToolContext): string;
89
+ execute(args: JSONValue, ctx: ToolContext): Promise<ToolResult>;
90
+ /**
91
+ * (5.1) Per-call permission shape. When implemented, the engine asks
92
+ * this hook BEFORE calling `gate.check(...)`:
93
+ * - Return `null` to bypass the gate entirely. Used by op-enum
94
+ * tools (e.g. `pty.read`, `pty.resize`) whose ops are already
95
+ * covered by a parent op's approval.
96
+ * - Return a {@link PermissionRequest} (with optional `cacheKey`)
97
+ * to override the legacy `{name, category, summarize(args)}`
98
+ * shape — lets ops vary their category, prompt summary, and
99
+ * positive-decision cache scope independently.
100
+ *
101
+ * When undefined (the default for all 10 existing builtins), the
102
+ * engine constructs a request from `{name, category, summarize(args),
103
+ * args}` exactly as in 1.x→5.0 — fully backwards compatible.
104
+ *
105
+ * Codex Round-1 MUST-FIX #1 (5.1 design) — without this hook a
106
+ * single op-enum tool can't bypass cheap ops while re-prompting
107
+ * destructive ones.
108
+ */
109
+ permission?(args: JSONValue, ctx: ToolContext): PermissionRequest | null;
110
+ }
111
+ /**
112
+ * (5.10b) A request to AUTHORIZE a side-effecting tool call — the original
113
+ * (1.x→5.x) permission shape. `kind` is optional and defaults to
114
+ * `"authorization"`, so every existing producer/resolver that omits it stays
115
+ * byte-identical at runtime. The `question` variant ({@link QuestionRequest})
116
+ * rides the SAME resolver channel but is NOT an authorization — see
117
+ * {@link PermissionGate.ask}.
118
+ */
119
+ export interface AuthorizationRequest {
120
+ kind?: "authorization";
121
+ name: string;
122
+ category: ToolCategory;
123
+ summary: string;
124
+ args: JSONValue;
125
+ /**
126
+ * (5.1) Optional cache key for `PermissionGate`'s positive-decision
127
+ * cache. When undefined, the gate uses `name` (legacy behaviour). Use
128
+ * this to scope per-call cache decisions (e.g.
129
+ * `pty.kill.SIGTERM/<session_id>` so approving SIGTERM on session
130
+ * `pty_abc` doesn't pre-approve SIGTERM on session `pty_xyz`, and
131
+ * doesn't pre-approve SIGKILL on either). Distinct cache keys are
132
+ * also distinct invalidation targets via `gate.invalidate(cacheKey)`.
133
+ */
134
+ cacheKey?: string;
135
+ /**
136
+ * (5.2 codex Round-1 MUST-FIX #3) Optional id of the originating tool
137
+ * call. The engine stamps `call.callId` here before `gate.check`, so a
138
+ * resolver that surfaces the prompt to an out-of-process client (the RPC
139
+ * / ACP host) can ship a self-contained `request_permission` frame that
140
+ * the client joins to the preceding `tool_call.callId`. Undefined on
141
+ * direct/in-process resolvers (TUI, auto-policy) that don't need it.
142
+ */
143
+ callId?: string;
144
+ }
145
+ /** One option in a {@link QuestionSpec}. Schema-locked: the model declares these
146
+ * options; the UI injects the "Other" free-text row itself (the model never
147
+ * declares it). */
148
+ export interface QuestionOption {
149
+ label: string;
150
+ description?: string;
151
+ /** Optional Markdown preview shown side-by-side when present (single-select). */
152
+ preview?: string;
153
+ }
154
+ /** One question in a {@link QuestionRequest}. Mirrors the `ask_user_question`
155
+ * tool's zod schema, which validates it (1–4 questions, 2–4 options, unique
156
+ * labels) BEFORE the request is built. */
157
+ export interface QuestionSpec {
158
+ question: string;
159
+ header: string;
160
+ options: QuestionOption[];
161
+ multiSelect?: boolean;
162
+ }
163
+ /**
164
+ * (5.10b) A request to ASK the user structured questions — emitted ONLY by the
165
+ * read-only `ask_user_question` tool's `permission()` hook. It deliberately
166
+ * bypasses the allow/deny precedence in {@link PermissionGate.evaluate} (a
167
+ * question is not an authorization) but still honors a static `deny` floor via
168
+ * {@link PermissionGate.ask}. The engine FAIL-CLOSES any OTHER tool that emits
169
+ * this variant (it would otherwise be an authorization escape — codex R1).
170
+ */
171
+ export interface QuestionRequest {
172
+ kind: "question";
173
+ name: string;
174
+ /** Read-only category of the asker (`search`). `gate.ask` reads it for the
175
+ * static-deny floor; the engine asserts it is a read-only category. */
176
+ category: ToolCategory;
177
+ callId?: string;
178
+ questions: QuestionSpec[];
179
+ }
180
+ /**
181
+ * (5.10b) Discriminated union carried by the resolver channel. An omitted
182
+ * `kind` ⇒ authorization (back-compat: every existing producer builds the
183
+ * authorization shape untouched).
184
+ */
185
+ export type PermissionRequest = AuthorizationRequest | QuestionRequest;
186
+ /**
187
+ * (5.2 codex Round-1 MUST-FIX #1) A resolver decision richer than a bare
188
+ * boolean. `remember: false` tells the gate NOT to cache a positive
189
+ * decision (ACP `allow_once` vs `allow_always`) even when the request is
190
+ * cache-scoped (`mcp__*` / `cacheKey`). Omitted ⇒ `true` ⇒ the gate's
191
+ * pre-5.2 caching behaviour is preserved. `kind` omitted ⇒ authorization
192
+ * (a bare boolean is also an authorization allow/deny).
193
+ */
194
+ export interface AuthorizationDecision {
195
+ kind?: "authorization";
196
+ allow: boolean;
197
+ remember?: boolean;
198
+ /**
199
+ * (5.3) On a denial (`allow: false`), optional free text the user typed via
200
+ * the "no, and tell the model what to do" prompt option. The gate passes it
201
+ * through to `PermissionEvaluation.feedback`; the engine appends it to the
202
+ * `ok:false` tool result so the model can adapt instead of just retrying.
203
+ * Ignored on an allow. Undefined for the plain "no".
204
+ */
205
+ feedback?: string;
206
+ }
207
+ /**
208
+ * (5.10b) The user's answers to a {@link QuestionRequest}, carried back through
209
+ * the resolver. `answers` maps each question text to the selected option labels
210
+ * (plus any free text typed into the "Other" row). `declined` is set when the
211
+ * user cancels OR the resolver is non-interactive (`-p` / RPC / ACP) — the ask
212
+ * tool turns either into a deterministic "declined" tool result.
213
+ */
214
+ export interface QuestionDecision {
215
+ kind: "question";
216
+ answers: Record<string, string[]>;
217
+ annotations?: Record<string, {
218
+ preview?: string;
219
+ notes?: string;
220
+ }>;
221
+ declined?: boolean;
222
+ }
223
+ /** Discriminated union of resolver decisions. Omitted `kind` ⇒ authorization. */
224
+ export type PermissionDecision = AuthorizationDecision | QuestionDecision;
225
+ /**
226
+ * Asks an external decider (interactive prompt, or auto-policy) to approve a
227
+ * tool call OR answer questions. For an {@link AuthorizationRequest} the
228
+ * resolver returns a bare `boolean` (legacy, = `{allow, remember:true}`) or an
229
+ * {@link AuthorizationDecision}; for a {@link QuestionRequest} it returns a
230
+ * {@link QuestionDecision} (a non-interactive resolver returns
231
+ * `{kind:"question", answers:{}, declined:true}`). Resolvers MUST narrow on
232
+ * `req.kind` before reading authorization-only fields (codex R1 SHOULD-FIX).
233
+ */
234
+ export type PermissionResolver = (req: PermissionRequest) => Promise<boolean | PermissionDecision>;
235
+ /** The one tool name allowed to use the `question` permission channel. The
236
+ * engine fail-closes any other tool that emits a `question` request (codex R1
237
+ * MUST-FIX: the channel skips `gate.evaluate`, so it must be unreachable by a
238
+ * side-effecting tool). */
239
+ export declare const ASK_USER_QUESTION_TOOL_NAME = "ask_user_question";
240
+ /** Read-only tool categories. The question channel is double-guarded: the asker
241
+ * must BOTH be {@link ASK_USER_QUESTION_TOOL_NAME} AND declare a category in
242
+ * this set, so a side-effecting category can never reach it. */
243
+ export declare const READONLY_CATEGORIES: ReadonlySet<ToolCategory>;
244
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /** The one tool name allowed to use the `question` permission channel. The
2
+ * engine fail-closes any other tool that emits a `question` request (codex R1
3
+ * MUST-FIX: the channel skips `gate.evaluate`, so it must be unreachable by a
4
+ * side-effecting tool). */
5
+ export const ASK_USER_QUESTION_TOOL_NAME = "ask_user_question";
6
+ /** Read-only tool categories. The question channel is double-guarded: the asker
7
+ * must BOTH be {@link ASK_USER_QUESTION_TOOL_NAME} AND declare a category in
8
+ * this set, so a side-effecting category can never reach it. */
9
+ export const READONLY_CATEGORIES = new Set([
10
+ "file-read",
11
+ "search",
12
+ "memory-read",
13
+ "network-read",
14
+ ]);
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAqPA;;;4BAG4B;AAC5B,MAAM,CAAC,MAAM,2BAA2B,GAAG,mBAAmB,CAAC;AAE/D;;iEAEiE;AACjE,MAAM,CAAC,MAAM,mBAAmB,GAA8B,IAAI,GAAG,CAAe;IAClF,WAAW;IACX,QAAQ;IACR,aAAa;IACb,cAAc;CACf,CAAC,CAAC"}