@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,353 @@
1
+ import { AppError, ErrorCode } from "@chances-ai/runtime";
2
+ import { optBool, optNum, str } from "./_shared.js";
3
+ const DEFAULT_TIMEOUT_MS = 30_000;
4
+ const DEFAULT_MAX_BYTES = 250 * 1024;
5
+ /** Absolute ceiling on caller-supplied `maxBytes`. A misbehaving model could
6
+ * otherwise ask for a multi-GB body and force memory growth. 4 MiB is
7
+ * generous for any realistic doc page while still bounded. */
8
+ const MAX_BYTES_CEILING = 4 * 1024 * 1024;
9
+ const MAX_REDIRECTS = 10;
10
+ const URL_MAX_LENGTH = 2048;
11
+ /**
12
+ * Refuses RFC1918, loopback, link-local, CGNAT, and common internal hostnames.
13
+ * The goal is SSRF defense: a model that asks for `http://169.254.169.254/...`
14
+ * (cloud metadata) or `http://10.0.0.5/admin` (an internal box) must be denied
15
+ * before the gate even prompts. Operators who legitimately want to fetch a
16
+ * local dev server can edit the config — the explicit override is the trust
17
+ * signal, not a silent fallback.
18
+ */
19
+ function isPrivateIPv4(a, b) {
20
+ if (a === 0)
21
+ return true; // 0.0.0.0/8
22
+ if (a === 10)
23
+ return true; // 10.0.0.0/8
24
+ if (a === 127)
25
+ return true; // loopback
26
+ if (a === 169 && b === 254)
27
+ return true; // link-local
28
+ if (a === 172 && b >= 16 && b <= 31)
29
+ return true; // 172.16.0.0/12
30
+ if (a === 192 && b === 168)
31
+ return true; // 192.168.0.0/16
32
+ if (a === 100 && b >= 64 && b <= 127)
33
+ return true; // CGNAT 100.64.0.0/10
34
+ return false;
35
+ }
36
+ /**
37
+ * If `inner` is an IPv4-mapped IPv6 address (`::ffff:a.b.c.d` or its hex
38
+ * canonicalization like `::ffff:7f00:1`), return the embedded IPv4 octets.
39
+ * URL parsers (Bun's included) silently canonicalize the dotted form into
40
+ * hex, so a check that only sees `127.0.0.1` literals misses an attacker
41
+ * who writes `[::ffff:127.0.0.1]` — it lands as `[::ffff:7f00:1]` and
42
+ * defeats the IPv4 branch entirely.
43
+ */
44
+ function parseMappedIPv4(inner) {
45
+ // Bun normalizes `::ffff:127.0.0.1` to `::ffff:7f00:1` and elides leading zeros.
46
+ // Reject early if the address isn't a mapped form.
47
+ const mapped = inner.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
48
+ if (mapped) {
49
+ const hi = parseInt(mapped[1], 16);
50
+ const lo = parseInt(mapped[2], 16);
51
+ return [(hi >> 8) & 0xff, hi & 0xff, (lo >> 8) & 0xff, lo & 0xff];
52
+ }
53
+ // Dotted-quad form preserved (e.g. some parsers leave `::ffff:127.0.0.1`).
54
+ const dotted = inner.match(/^::ffff:(\d+)\.(\d+)\.(\d+)\.(\d+)$/i);
55
+ if (dotted) {
56
+ return [Number(dotted[1]), Number(dotted[2]), Number(dotted[3]), Number(dotted[4])];
57
+ }
58
+ return null;
59
+ }
60
+ function isPrivateHost(hostname) {
61
+ // Normalize once: lowercase + strip *all* trailing dots. `localhost.` is
62
+ // the same host as `localhost` in DNS; `localhost..` is malformed but a
63
+ // resolver may still accept it, so a single-dot strip would leave a
64
+ // bypass. Trailing dots are never load-bearing for the public suffix.
65
+ const host = hostname.toLowerCase().replace(/\.+$/, "");
66
+ const ipv4 = host.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
67
+ if (ipv4)
68
+ return isPrivateIPv4(Number(ipv4[1]), Number(ipv4[2]));
69
+ if (host.startsWith("[") && host.endsWith("]")) {
70
+ const inner = host.slice(1, -1);
71
+ if (inner === "::1" || inner === "::")
72
+ return true;
73
+ const mapped = parseMappedIPv4(inner);
74
+ if (mapped)
75
+ return isPrivateIPv4(mapped[0], mapped[1]);
76
+ // Unique local addresses fc00::/7 (covers fc** and fd**).
77
+ if (inner.startsWith("fc") || inner.startsWith("fd"))
78
+ return true;
79
+ // Link-local fe80::/10 — top 10 bits of the first hextet are 1111111010,
80
+ // so the first hextet falls in the range fe80–febf inclusive. `fe80:`
81
+ // alone misses `fea0::1`, `febf::1`, etc.
82
+ const firstHextet = parseInt(inner.split(":")[0], 16);
83
+ if (!Number.isNaN(firstHextet) && (firstHextet & 0xffc0) === 0xfe80)
84
+ return true;
85
+ return false;
86
+ }
87
+ if (host === "localhost")
88
+ return true;
89
+ if (host.endsWith(".localhost"))
90
+ return true;
91
+ if (host.endsWith(".local"))
92
+ return true;
93
+ if (host.endsWith(".internal"))
94
+ return true;
95
+ return false;
96
+ }
97
+ function validateUrl(raw) {
98
+ if (raw.length > URL_MAX_LENGTH) {
99
+ throw new AppError(ErrorCode.Tool, `URL too long (>${URL_MAX_LENGTH} chars)`);
100
+ }
101
+ let u;
102
+ try {
103
+ u = new URL(raw);
104
+ }
105
+ catch {
106
+ throw new AppError(ErrorCode.Tool, `Invalid URL: ${raw}`);
107
+ }
108
+ if (u.protocol !== "http:" && u.protocol !== "https:") {
109
+ throw new AppError(ErrorCode.Tool, `Unsupported URL scheme: ${u.protocol}`);
110
+ }
111
+ if (u.username || u.password) {
112
+ throw new AppError(ErrorCode.Tool, "URL must not contain credentials");
113
+ }
114
+ if (isPrivateHost(u.hostname)) {
115
+ throw new AppError(ErrorCode.Tool, `Refusing to fetch private/local address: ${u.hostname}`);
116
+ }
117
+ return u;
118
+ }
119
+ /** Same registrable host, or one is the `www.` variant of the other. */
120
+ function isSameHostOrWwwVariant(a, b) {
121
+ if (a.host === b.host)
122
+ return true;
123
+ const stripWww = (h) => (h.startsWith("www.") ? h.slice(4) : h);
124
+ return stripWww(a.host) === stripWww(b.host);
125
+ }
126
+ /**
127
+ * Minimal HTML → readable text. Deliberately string-based (no DOM, no turndown
128
+ * dep) for v1: we trade markdown fidelity for a 60-LoC implementation with
129
+ * zero new dependencies. Most use cases (docs, README mirrors, news pages)
130
+ * survive this cleanly; rich pages still produce *readable* text even if the
131
+ * markdown is rough. `raw: true` bypasses this entirely for callers that want
132
+ * the original HTML. A turndown / readability upgrade is a v2+ candidate.
133
+ */
134
+ function decodeEntities(s) {
135
+ return s
136
+ .replace(/&nbsp;/g, " ")
137
+ .replace(/&amp;/g, "&")
138
+ .replace(/&lt;/g, "<")
139
+ .replace(/&gt;/g, ">")
140
+ .replace(/&quot;/g, '"')
141
+ .replace(/&#39;/g, "'")
142
+ .replace(/&apos;/g, "'");
143
+ }
144
+ export function htmlToText(html) {
145
+ // Capture title before we touch tags — a title like `<title>A <b>B</b></title>`
146
+ // would otherwise either keep `<b>` (bad heading) or get duplicated as body
147
+ // text after we strip and replace block tags.
148
+ const titleMatch = html.match(/<title[^>]*>([\s\S]*?)<\/title>/i);
149
+ const title = titleMatch?.[1] ? decodeEntities(titleMatch[1].replace(/<[^>]+>/g, "")).trim() : "";
150
+ let s = html
151
+ .replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "")
152
+ .replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, "")
153
+ // Best-effort: an unclosed <script> or <style> would otherwise leak its
154
+ // body into output. Drop everything from an unclosed opener to end.
155
+ .replace(/<script\b[^>]*>[\s\S]*$/gi, "")
156
+ .replace(/<style\b[^>]*>[\s\S]*$/gi, "")
157
+ .replace(/<!--[\s\S]*?-->/g, "")
158
+ // Strip the captured title block so it isn't duplicated in body output.
159
+ .replace(/<title[^>]*>[\s\S]*?<\/title>/gi, "")
160
+ .replace(/<\/(p|div|section|article|li|tr|h[1-6])[^>]*>/gi, "\n\n")
161
+ .replace(/<(p|div|section|article|li|tr|h[1-6])[^>]*>/gi, "\n")
162
+ .replace(/<br\s*\/?>/gi, "\n")
163
+ .replace(/<hr\s*\/?>/gi, "\n---\n")
164
+ .replace(/<[^>]+>/g, "");
165
+ s = decodeEntities(s)
166
+ .replace(/[ \t]+/g, " ")
167
+ .replace(/\n[ \t]+/g, "\n")
168
+ .replace(/\n{3,}/g, "\n\n")
169
+ .trim();
170
+ if (title)
171
+ return `# ${title}\n\n${s}`;
172
+ return s;
173
+ }
174
+ async function readBodyCapped(res, maxBytes) {
175
+ const reader = res.body?.getReader();
176
+ if (!reader)
177
+ return { body: "", truncated: false };
178
+ const chunks = [];
179
+ let received = 0;
180
+ let truncated = false;
181
+ for (;;) {
182
+ const { value, done } = await reader.read();
183
+ if (done)
184
+ break;
185
+ if (received + value.byteLength > maxBytes) {
186
+ const room = maxBytes - received;
187
+ if (room > 0)
188
+ chunks.push(value.subarray(0, room));
189
+ truncated = true;
190
+ try {
191
+ await reader.cancel();
192
+ }
193
+ catch {
194
+ /* best-effort */
195
+ }
196
+ break;
197
+ }
198
+ chunks.push(value);
199
+ received += value.byteLength;
200
+ }
201
+ // Decode as UTF-8; lossy for non-UTF responses but the LLM will see "?" runs
202
+ // rather than crash. We mark Content-Type in the header so the model knows.
203
+ const total = chunks.reduce((acc, c) => acc + c.byteLength, 0);
204
+ const merged = new Uint8Array(total);
205
+ let offset = 0;
206
+ for (const c of chunks) {
207
+ merged.set(c, offset);
208
+ offset += c.byteLength;
209
+ }
210
+ return { body: new TextDecoder("utf-8", { fatal: false }).decode(merged), truncated };
211
+ }
212
+ async function followRedirects(initial, signal, maxBytes) {
213
+ let url = initial;
214
+ let redirectsLeft = MAX_REDIRECTS;
215
+ for (;;) {
216
+ const res = await fetch(url.toString(), { redirect: "manual", signal });
217
+ const status = res.status;
218
+ if (status >= 300 && status < 400) {
219
+ const loc = res.headers.get("location");
220
+ if (loc) {
221
+ if (redirectsLeft-- === 0) {
222
+ throw new AppError(ErrorCode.Tool, `Too many redirects (>${MAX_REDIRECTS})`);
223
+ }
224
+ const target = new URL(loc, url);
225
+ // Re-validate: a redirect to file://, localhost, or a private IP must
226
+ // be refused regardless of how friendly the source URL looked.
227
+ validateUrl(target.toString());
228
+ if (!isSameHostOrWwwVariant(url, target)) {
229
+ try {
230
+ await res.body?.cancel();
231
+ }
232
+ catch {
233
+ /* best-effort */
234
+ }
235
+ return {
236
+ finalUrl: url.toString(),
237
+ status,
238
+ contentType: "text/plain",
239
+ body: `Cross-host redirect to ${target.toString()} — re-invoke web_fetch with the new URL if you trust it.`,
240
+ truncated: false,
241
+ };
242
+ }
243
+ try {
244
+ await res.body?.cancel();
245
+ }
246
+ catch {
247
+ /* best-effort */
248
+ }
249
+ url = target;
250
+ continue;
251
+ }
252
+ }
253
+ const contentType = res.headers.get("content-type") ?? "application/octet-stream";
254
+ const { body, truncated } = await readBodyCapped(res, maxBytes);
255
+ return { finalUrl: url.toString(), status, contentType, body, truncated };
256
+ }
257
+ }
258
+ export const webFetchTool = {
259
+ name: "web_fetch",
260
+ description: "Fetch a URL and return its content as text the model can read. http(s) only; literal private IPs (RFC1918, loopback, link-local, CGNAT, IPv4-mapped IPv6) and credentials in the URL are rejected. Note: lexical filtering only — a public hostname that DNS-resolves to a private address is NOT blocked at the validator (a v2+ item); the per-call `network-read` prompt is the user-side defense. text/html is reduced to readable text; JSON / markdown / plain text pass through. Use raw:true to get the unprocessed body. Cross-host redirects are not followed automatically — a one-line note is returned instead so the model can re-invoke with the new URL.",
261
+ category: "network-read",
262
+ parameters: {
263
+ type: "object",
264
+ properties: {
265
+ url: { type: "string", description: "Absolute http(s) URL to fetch." },
266
+ raw: { type: "boolean", description: "Skip HTML→text reduction; return the body as received." },
267
+ maxBytes: {
268
+ type: "number",
269
+ description: `Cap on body bytes (default ${DEFAULT_MAX_BYTES}). Responses are truncated to fit.`,
270
+ },
271
+ timeoutMs: {
272
+ type: "number",
273
+ description: `Per-request timeout in ms (default ${DEFAULT_TIMEOUT_MS}).`,
274
+ },
275
+ },
276
+ required: ["url"],
277
+ },
278
+ summarize: (args) => `web_fetch ${str(args, "url")}`,
279
+ // (5.3) Scope the permission cache to the specific URL. Without a cacheKey
280
+ // the gate would key on the bare tool name `web_fetch`, so a single
281
+ // "[a] yes, don't ask again" (or an explicit remember) would blanket-approve
282
+ // EVERY future URL — defeating the per-URL egress defense (codex 5.3 Round-2
283
+ // MUST-FIX #1). With a per-URL key, approving URL A never pre-approves URL B;
284
+ // re-fetching the identical URL you just approved simply doesn't re-prompt.
285
+ // The raw URL string is used verbatim (no normalization) — any textual
286
+ // difference re-prompts, which is the safe direction.
287
+ permission(args) {
288
+ const url = str(args, "url");
289
+ return {
290
+ name: "web_fetch",
291
+ category: "network-read",
292
+ summary: `web_fetch ${url}`,
293
+ args,
294
+ cacheKey: `web_fetch:${url}`,
295
+ };
296
+ },
297
+ async execute(args, ctx) {
298
+ const raw = optBool(args, "raw") ?? false;
299
+ const requestedMaxBytes = optNum(args, "maxBytes") ?? DEFAULT_MAX_BYTES;
300
+ // Clamp model-controlled cap into [1, MAX_BYTES_CEILING]. Non-positive /
301
+ // non-finite values fall through to the default — silently accepting "0"
302
+ // would always return an empty body which is unhelpful, and accepting a
303
+ // huge value would let a model force memory growth.
304
+ const maxBytes = Number.isFinite(requestedMaxBytes) && requestedMaxBytes >= 1
305
+ ? Math.min(Math.floor(requestedMaxBytes), MAX_BYTES_CEILING)
306
+ : DEFAULT_MAX_BYTES;
307
+ const timeoutMs = optNum(args, "timeoutMs") ?? DEFAULT_TIMEOUT_MS;
308
+ let initial;
309
+ try {
310
+ initial = validateUrl(str(args, "url"));
311
+ }
312
+ catch (e) {
313
+ return { ok: false, output: e.message };
314
+ }
315
+ // Compose request timeout + caller cancel into one signal.
316
+ const ac = new AbortController();
317
+ const timer = setTimeout(() => ac.abort(new Error(`Timeout after ${timeoutMs} ms`)), timeoutMs);
318
+ let onAbort;
319
+ if (ctx.signal.aborted) {
320
+ ac.abort(ctx.signal.reason ?? new Error("Cancelled"));
321
+ }
322
+ else {
323
+ onAbort = () => ac.abort(ctx.signal.reason ?? new Error("Cancelled"));
324
+ ctx.signal.addEventListener("abort", onAbort, { once: true });
325
+ }
326
+ try {
327
+ const r = await followRedirects(initial, ac.signal, maxBytes);
328
+ const isHtml = /^\s*text\/html\b/i.test(r.contentType);
329
+ const body = !raw && isHtml ? htmlToText(r.body) : r.body;
330
+ const header = [
331
+ `URL: ${initial.toString()}`,
332
+ `Final-URL: ${r.finalUrl}`,
333
+ `Status: ${r.status}`,
334
+ `Content-Type: ${r.contentType}`,
335
+ `Truncated: ${r.truncated}`,
336
+ ].join("\n");
337
+ // ok:true even for HTTP 4xx/5xx — the model can read the status line in
338
+ // the header and the error body below. ok:false is reserved for network
339
+ // / validation / timeout failures where there's nothing meaningful to return.
340
+ return { ok: true, output: `${header}\n\n${body}` };
341
+ }
342
+ catch (e) {
343
+ const err = e;
344
+ return { ok: false, output: `web_fetch failed: ${err.message}` };
345
+ }
346
+ finally {
347
+ clearTimeout(timer);
348
+ if (onAbort)
349
+ ctx.signal.removeEventListener("abort", onAbort);
350
+ }
351
+ },
352
+ };
353
+ //# sourceMappingURL=web-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-fetch.js","sourceRoot":"","sources":["../../../src/tools/builtins/web-fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Tool } from "../types.js";
2
+ export declare const writeTool: Tool;
3
+ //# sourceMappingURL=write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/tools/builtins/write.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,aAAa,CAAC;AAGpD,eAAO,MAAM,SAAS,EAAE,IAuCvB,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import { native } from "@chances-ai/native";
4
+ import { linesDiff } from "../diff.js";
5
+ import { PREVIEW_BYTE_CAP, safePath, str } from "./_shared.js";
6
+ export const writeTool = {
7
+ name: "write",
8
+ description: "Create or overwrite a file in the workspace.",
9
+ category: "file-write",
10
+ parameters: {
11
+ type: "object",
12
+ properties: { path: { type: "string" }, content: { type: "string" } },
13
+ required: ["path", "content"],
14
+ },
15
+ summarize: (args, ctx) => {
16
+ const path = str(args, "path");
17
+ const content = str(args, "content");
18
+ let abs = null;
19
+ try {
20
+ abs = safePath(ctx, path, { resolveSymlinks: true });
21
+ }
22
+ catch {
23
+ return `write ${path} (${content.length} bytes)`;
24
+ }
25
+ if (!existsSync(abs)) {
26
+ const lineCount = content === "" ? 0 : content.split("\n").length;
27
+ return `create ${path} (${content.length} bytes, ${lineCount} lines)`;
28
+ }
29
+ const priorSize = statSync(abs).size;
30
+ if (priorSize > PREVIEW_BYTE_CAP || content.length > PREVIEW_BYTE_CAP) {
31
+ return `overwrite ${path} (${priorSize} → ${content.length} bytes; diff preview skipped)`;
32
+ }
33
+ const before = readFileSync(abs, "utf8");
34
+ if (before === content)
35
+ return `overwrite ${path} (no changes)`;
36
+ return `overwrite ${path}\n${linesDiff(before, content)}`;
37
+ },
38
+ async execute(args, ctx) {
39
+ const path = safePath(ctx, str(args, "path"), { resolveSymlinks: true });
40
+ mkdirSync(dirname(path), { recursive: true });
41
+ writeFileSync(path, str(args, "content"));
42
+ // Drop the shared fs-scan cache for this dir so a later glob/ast in the
43
+ // same turn sees the new file ([10.4]).
44
+ native.invalidateFsScanCache(dirname(path));
45
+ return { ok: true, output: `Wrote ${str(args, "path")}` };
46
+ },
47
+ };
48
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../../src/tools/builtins/write.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Tool } from "./types.js";
2
+ /**
3
+ * Registry of first-party tools the engine ships with. New tools live in their
4
+ * own module under `./builtins/<name>.ts`; this file is a pure barrel so the
5
+ * registration surface stays one-line-per-tool and reviewers can see the full
6
+ * tool inventory at a glance.
7
+ */
8
+ export declare const builtinTools: Tool[];
9
+ //# sourceMappingURL=builtins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../../src/tools/builtins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAYvC;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,IAAI,EAW9B,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { readTool } from "./builtins/read.js";
2
+ import { writeTool } from "./builtins/write.js";
3
+ import { editTool } from "./builtins/edit.js";
4
+ import { bashTool } from "./builtins/bash.js";
5
+ import { grepTool } from "./builtins/grep.js";
6
+ import { globTool } from "./builtins/glob.js";
7
+ import { diffTool } from "./builtins/diff.js";
8
+ import { webFetchTool } from "./builtins/web-fetch.js";
9
+ import { lspTool } from "./builtins/lsp.js";
10
+ import { askUserQuestionTool } from "./builtins/ask-user-question.js";
11
+ /**
12
+ * Registry of first-party tools the engine ships with. New tools live in their
13
+ * own module under `./builtins/<name>.ts`; this file is a pure barrel so the
14
+ * registration surface stays one-line-per-tool and reviewers can see the full
15
+ * tool inventory at a glance.
16
+ */
17
+ export const builtinTools = [
18
+ readTool,
19
+ writeTool,
20
+ editTool,
21
+ bashTool,
22
+ grepTool,
23
+ globTool,
24
+ diffTool,
25
+ webFetchTool,
26
+ lspTool,
27
+ askUserQuestionTool,
28
+ ];
29
+ //# sourceMappingURL=builtins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtins.js","sourceRoot":"","sources":["../../src/tools/builtins.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAW;IAClC,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,mBAAmB;CACpB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Block-diff helper used by `write` / `edit` to give the permission overlay
3
+ * something meaningful to render. This is not a Myers LCS diff: it finds the
4
+ * leading and trailing common prefixes and shows everything between as a
5
+ * removed-then-added block. That is "good enough" for an approval preview —
6
+ * the user sees what changes; line numbers anchor the change against the
7
+ * original file. For workflows that need a true diff (e.g. patch review) a 2.x
8
+ * tool can produce one via the native crate.
9
+ */
10
+ export declare function linesDiff(before: string, after: string, maxLines?: number): string;
11
+ /** Compact summary line that pairs with `linesDiff` in tool summaries:
12
+ * `2 deletions, 3 additions` etc. Cheap to compute and useful even when the
13
+ * full diff is truncated for display. */
14
+ export declare function diffStats(before: string, after: string): {
15
+ removed: number;
16
+ added: number;
17
+ };
18
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/tools/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAK,GAAG,MAAM,CA4B9E;AAED;;yCAEyC;AACzC,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAa3F"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Block-diff helper used by `write` / `edit` to give the permission overlay
3
+ * something meaningful to render. This is not a Myers LCS diff: it finds the
4
+ * leading and trailing common prefixes and shows everything between as a
5
+ * removed-then-added block. That is "good enough" for an approval preview —
6
+ * the user sees what changes; line numbers anchor the change against the
7
+ * original file. For workflows that need a true diff (e.g. patch review) a 2.x
8
+ * tool can produce one via the native crate.
9
+ */
10
+ export function linesDiff(before, after, maxLines = 14) {
11
+ if (before === after)
12
+ return "(no changes)";
13
+ const a = before.split("\n");
14
+ const b = after.split("\n");
15
+ let start = 0;
16
+ while (start < a.length && start < b.length && a[start] === b[start])
17
+ start++;
18
+ let endA = a.length;
19
+ let endB = b.length;
20
+ while (endA > start && endB > start && a[endA - 1] === b[endB - 1]) {
21
+ endA--;
22
+ endB--;
23
+ }
24
+ const removed = a.slice(start, endA);
25
+ const added = b.slice(start, endB);
26
+ const rows = [`@@ -${start + 1},${removed.length} +${start + 1},${added.length} @@`];
27
+ for (const line of removed)
28
+ rows.push(`- ${line}`);
29
+ for (const line of added)
30
+ rows.push(`+ ${line}`);
31
+ if (rows.length <= maxLines + 1)
32
+ return rows.join("\n");
33
+ const half = Math.floor(maxLines / 2);
34
+ const head = rows.slice(0, half);
35
+ const tail = rows.slice(rows.length - half);
36
+ return [...head, `… (${rows.length - maxLines} lines elided)`, ...tail].join("\n");
37
+ }
38
+ /** Compact summary line that pairs with `linesDiff` in tool summaries:
39
+ * `2 deletions, 3 additions` etc. Cheap to compute and useful even when the
40
+ * full diff is truncated for display. */
41
+ export function diffStats(before, after) {
42
+ if (before === after)
43
+ return { removed: 0, added: 0 };
44
+ const a = before.split("\n");
45
+ const b = after.split("\n");
46
+ let start = 0;
47
+ while (start < a.length && start < b.length && a[start] === b[start])
48
+ start++;
49
+ let endA = a.length;
50
+ let endB = b.length;
51
+ while (endA > start && endB > start && a[endA - 1] === b[endB - 1]) {
52
+ endA--;
53
+ endB--;
54
+ }
55
+ return { removed: endA - start, added: endB - start };
56
+ }
57
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/tools/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export type { Tool, ToolContext, ToolLspHost, ToolResult, ToolCategory, PermissionRequest, AuthorizationRequest, QuestionRequest, QuestionSpec, QuestionOption, PermissionResolver, PermissionDecision, AuthorizationDecision, QuestionDecision, } from "./types.js";
2
+ export { ASK_USER_QUESTION_TOOL_NAME, READONLY_CATEGORIES } from "./types.js";
3
+ export { ToolRegistry } from "./registry.js";
4
+ export { type PermissionCacheScope, type PermissionEvaluation, PermissionGate } from "./permission.js";
5
+ export { CATEGORY_TIER, isAutoApprovedByMode, isBlockedByMode, modeBlockReason, } from "./approval.js";
6
+ export { builtinTools } from "./builtins.js";
7
+ export { type CreatePtyToolDeps, createPtyTool } from "./builtins/pty.js";
8
+ export { cleanOutput, persistFullOutput, stripAnsi } from "./builtins/_shared.js";
9
+ export { linesDiff, diffStats } from "./diff.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,IAAI,EACJ,WAAW,EACX,WAAW,EACX,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,oBAAoB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACvG,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,eAAe,GAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,KAAK,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,9 @@
1
+ export { ASK_USER_QUESTION_TOOL_NAME, READONLY_CATEGORIES } from "./types.js";
2
+ export { ToolRegistry } from "./registry.js";
3
+ export { PermissionGate } from "./permission.js";
4
+ export { CATEGORY_TIER, isAutoApprovedByMode, isBlockedByMode, modeBlockReason, } from "./approval.js";
5
+ export { builtinTools } from "./builtins.js";
6
+ export { createPtyTool } from "./builtins/pty.js";
7
+ export { cleanOutput, persistFullOutput, stripAnsi } from "./builtins/_shared.js";
8
+ export { linesDiff, diffStats } from "./diff.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAwD,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACvG,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,eAAe,GAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAA0B,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}