@tomsun28/pizza 0.1.0 → 0.1.1

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 (382) hide show
  1. package/README.md +20 -143
  2. package/README.zh-CN.md +36 -0
  3. package/dist/bun/cli.d.ts +2 -0
  4. package/dist/bun/cli.js +6 -0
  5. package/dist/bun/register-bedrock.d.ts +1 -0
  6. package/dist/bun/register-bedrock.js +3 -0
  7. package/dist/cli/args.d.ts +48 -0
  8. package/dist/cli/args.js +330 -0
  9. package/dist/cli/config-selector.d.ts +13 -0
  10. package/dist/cli/config-selector.js +30 -0
  11. package/dist/cli/file-processor.d.ts +14 -0
  12. package/dist/cli/file-processor.js +82 -0
  13. package/dist/cli/initial-message.d.ts +17 -0
  14. package/dist/cli/initial-message.js +21 -0
  15. package/dist/cli/list-models.d.ts +8 -0
  16. package/dist/cli/list-models.js +96 -0
  17. package/dist/cli.d.ts +2 -0
  18. package/dist/cli.js +68 -0
  19. package/dist/config.d.ts +79 -0
  20. package/dist/config.js +223 -0
  21. package/dist/core/agent/index.d.ts +6 -0
  22. package/dist/core/agent/index.js +6 -0
  23. package/dist/core/agent/types.d.ts +202 -0
  24. package/dist/core/agent/types.js +51 -0
  25. package/dist/core/auth-storage.d.ts +135 -0
  26. package/dist/core/auth-storage.js +417 -0
  27. package/dist/core/bash-executor.d.ts +31 -0
  28. package/dist/core/bash-executor.js +107 -0
  29. package/dist/core/compaction/branch-summarization.d.ts +87 -0
  30. package/dist/core/compaction/branch-summarization.js +242 -0
  31. package/dist/core/compaction/compaction-engine.d.ts +40 -0
  32. package/dist/core/compaction/compaction-engine.js +292 -0
  33. package/dist/core/compaction/compaction.d.ts +106 -0
  34. package/dist/core/compaction/compaction.js +295 -0
  35. package/dist/core/compaction/index.d.ts +7 -0
  36. package/dist/core/compaction/index.js +7 -0
  37. package/dist/core/compaction/utils.d.ts +37 -0
  38. package/dist/core/compaction/utils.js +152 -0
  39. package/dist/core/defaults.d.ts +2 -0
  40. package/dist/core/defaults.js +1 -0
  41. package/dist/core/diagnostics.d.ts +14 -0
  42. package/dist/core/diagnostics.js +1 -0
  43. package/dist/core/event-bus.d.ts +8 -0
  44. package/dist/core/event-bus.js +24 -0
  45. package/dist/core/event-store/events.d.ts +465 -0
  46. package/dist/core/event-store/events.js +6 -0
  47. package/dist/core/event-store/index.d.ts +10 -0
  48. package/dist/core/event-store/index.js +10 -0
  49. package/dist/core/event-store/sqlite-store.d.ts +27 -0
  50. package/dist/core/event-store/sqlite-store.js +275 -0
  51. package/dist/core/event-store/store.d.ts +91 -0
  52. package/dist/core/event-store/store.js +7 -0
  53. package/dist/core/event-store/thread-scoped-store.d.ts +29 -0
  54. package/dist/core/event-store/thread-scoped-store.js +50 -0
  55. package/dist/core/event-store/types.d.ts +70 -0
  56. package/dist/core/event-store/types.js +7 -0
  57. package/dist/core/event-store/workspace.d.ts +37 -0
  58. package/dist/core/event-store/workspace.js +71 -0
  59. package/dist/core/exec.d.ts +28 -0
  60. package/dist/core/exec.js +74 -0
  61. package/dist/core/export-html/ansi-to-html.d.ts +21 -0
  62. package/dist/core/export-html/ansi-to-html.js +248 -0
  63. package/dist/core/export-html/index.d.ts +29 -0
  64. package/dist/core/export-html/index.js +186 -0
  65. package/dist/core/export-html/template.css +1017 -0
  66. package/dist/core/export-html/template.html +55 -0
  67. package/dist/core/export-html/template.js +1742 -0
  68. package/dist/core/export-html/tool-renderer.d.ts +39 -0
  69. package/dist/core/export-html/tool-renderer.js +94 -0
  70. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  71. package/dist/core/export-html/vendor/marked.min.js +6 -0
  72. package/dist/core/extensions/index.d.ts +12 -0
  73. package/dist/core/extensions/index.js +9 -0
  74. package/dist/core/extensions/loader.d.ts +24 -0
  75. package/dist/core/extensions/loader.js +492 -0
  76. package/dist/core/extensions/runner.d.ts +167 -0
  77. package/dist/core/extensions/runner.js +898 -0
  78. package/dist/core/extensions/session-context.d.ts +67 -0
  79. package/dist/core/extensions/session-context.js +272 -0
  80. package/dist/core/extensions/types.d.ts +1147 -0
  81. package/dist/core/extensions/types.js +44 -0
  82. package/dist/core/extensions/wrapper.d.ts +19 -0
  83. package/dist/core/extensions/wrapper.js +21 -0
  84. package/dist/core/footer-data-provider.d.ts +47 -0
  85. package/dist/core/footer-data-provider.js +321 -0
  86. package/dist/core/goal/index.d.ts +3 -0
  87. package/dist/core/goal/index.js +1 -0
  88. package/dist/core/goal/scheduler.d.ts +83 -0
  89. package/dist/core/goal/scheduler.js +154 -0
  90. package/dist/core/goal/types.d.ts +182 -0
  91. package/dist/core/goal/types.js +11 -0
  92. package/dist/core/index.d.ts +8 -0
  93. package/dist/core/index.js +8 -0
  94. package/dist/core/intent/classifier.d.ts +53 -0
  95. package/dist/core/intent/classifier.js +353 -0
  96. package/dist/core/intent/index.d.ts +8 -0
  97. package/dist/core/intent/index.js +8 -0
  98. package/dist/core/intent/tool-adapter.d.ts +31 -0
  99. package/dist/core/intent/tool-adapter.js +168 -0
  100. package/dist/core/intent/types.d.ts +71 -0
  101. package/dist/core/intent/types.js +6 -0
  102. package/dist/core/keybindings.d.ts +297 -0
  103. package/dist/core/keybindings.js +250 -0
  104. package/dist/core/messages.d.ts +30 -0
  105. package/dist/core/messages.js +134 -0
  106. package/dist/core/model-registry.d.ts +131 -0
  107. package/dist/core/model-registry.js +634 -0
  108. package/dist/core/model-resolver.d.ts +109 -0
  109. package/dist/core/model-resolver.js +486 -0
  110. package/dist/core/output-guard.d.ts +5 -0
  111. package/dist/core/output-guard.js +58 -0
  112. package/dist/core/package-manager.d.ts +196 -0
  113. package/dist/core/package-manager.js +1873 -0
  114. package/dist/core/projection/boundary-inferrer.d.ts +58 -0
  115. package/dist/core/projection/boundary-inferrer.js +122 -0
  116. package/dist/core/projection/event-to-message.d.ts +35 -0
  117. package/dist/core/projection/event-to-message.js +253 -0
  118. package/dist/core/projection/goal-projection.d.ts +67 -0
  119. package/dist/core/projection/goal-projection.js +339 -0
  120. package/dist/core/projection/index.d.ts +13 -0
  121. package/dist/core/projection/index.js +13 -0
  122. package/dist/core/projection/session-manager.d.ts +100 -0
  123. package/dist/core/projection/session-manager.js +331 -0
  124. package/dist/core/projection/session-projection.d.ts +58 -0
  125. package/dist/core/projection/session-projection.js +257 -0
  126. package/dist/core/projection/task-history.d.ts +13 -0
  127. package/dist/core/projection/task-history.js +61 -0
  128. package/dist/core/projection/timeline-projection.d.ts +82 -0
  129. package/dist/core/projection/timeline-projection.js +276 -0
  130. package/dist/core/projection/types.d.ts +69 -0
  131. package/dist/core/projection/types.js +6 -0
  132. package/dist/core/prompt-templates.d.ts +51 -0
  133. package/dist/core/prompt-templates.js +249 -0
  134. package/dist/core/resolve-config-value.d.ts +22 -0
  135. package/dist/core/resolve-config-value.js +125 -0
  136. package/dist/core/resource-loader.d.ts +193 -0
  137. package/dist/core/resource-loader.js +685 -0
  138. package/dist/core/runtime/ai-client.d.ts +12 -0
  139. package/dist/core/runtime/ai-client.js +153 -0
  140. package/dist/core/runtime/checkpoint.d.ts +12 -0
  141. package/dist/core/runtime/checkpoint.js +78 -0
  142. package/dist/core/runtime/index.d.ts +12 -0
  143. package/dist/core/runtime/index.js +12 -0
  144. package/dist/core/runtime/llm-types.d.ts +99 -0
  145. package/dist/core/runtime/llm-types.js +6 -0
  146. package/dist/core/runtime/local-runtime.d.ts +23 -0
  147. package/dist/core/runtime/local-runtime.js +59 -0
  148. package/dist/core/runtime/policies.d.ts +72 -0
  149. package/dist/core/runtime/policies.js +37 -0
  150. package/dist/core/runtime/reactor.d.ts +213 -0
  151. package/dist/core/runtime/reactor.js +992 -0
  152. package/dist/core/runtime/runtime.d.ts +191 -0
  153. package/dist/core/runtime/runtime.js +449 -0
  154. package/dist/core/runtime/types.d.ts +42 -0
  155. package/dist/core/runtime/types.js +1 -0
  156. package/dist/core/sdk.d.ts +12 -0
  157. package/dist/core/sdk.js +10 -0
  158. package/dist/core/session-context-builder.d.ts +9 -0
  159. package/dist/core/session-context-builder.js +87 -0
  160. package/dist/core/session-cwd.d.ts +18 -0
  161. package/dist/core/session-cwd.js +36 -0
  162. package/dist/core/session-facade-factory.d.ts +79 -0
  163. package/dist/core/session-facade-factory.js +460 -0
  164. package/dist/core/session-facade.d.ts +57 -0
  165. package/dist/core/session-facade.js +91 -0
  166. package/dist/core/session-listing.d.ts +30 -0
  167. package/dist/core/session-listing.js +168 -0
  168. package/dist/core/session-reader.d.ts +19 -0
  169. package/dist/core/session-reader.js +101 -0
  170. package/dist/core/session-ref.d.ts +7 -0
  171. package/dist/core/session-ref.js +25 -0
  172. package/dist/core/session-services.d.ts +51 -0
  173. package/dist/core/session-services.js +90 -0
  174. package/dist/core/session-stats.d.ts +43 -0
  175. package/dist/core/session-stats.js +41 -0
  176. package/dist/core/settings-manager.d.ts +236 -0
  177. package/dist/core/settings-manager.js +706 -0
  178. package/dist/core/skill-block-parser.d.ts +12 -0
  179. package/dist/core/skill-block-parser.js +15 -0
  180. package/dist/core/skills.d.ts +59 -0
  181. package/dist/core/skills.js +408 -0
  182. package/dist/core/slash-commands.d.ts +13 -0
  183. package/dist/core/slash-commands.js +17 -0
  184. package/dist/core/source-info.d.ts +17 -0
  185. package/dist/core/source-info.js +18 -0
  186. package/dist/core/system-prompt.d.ts +27 -0
  187. package/dist/core/system-prompt.js +179 -0
  188. package/dist/core/timings.d.ts +7 -0
  189. package/dist/core/timings.js +30 -0
  190. package/dist/core/tools/bash.d.ts +95 -0
  191. package/dist/core/tools/bash.js +513 -0
  192. package/dist/core/tools/builtin-commands.d.ts +75 -0
  193. package/dist/core/tools/builtin-commands.js +503 -0
  194. package/dist/core/tools/compat-commands.d.ts +12 -0
  195. package/dist/core/tools/compat-commands.js +1280 -0
  196. package/dist/core/tools/edit-diff.d.ts +59 -0
  197. package/dist/core/tools/edit-diff.js +263 -0
  198. package/dist/core/tools/edit.d.ts +49 -0
  199. package/dist/core/tools/edit.js +340 -0
  200. package/dist/core/tools/file-mutation-queue.d.ts +5 -0
  201. package/dist/core/tools/file-mutation-queue.js +36 -0
  202. package/dist/core/tools/find.d.ts +34 -0
  203. package/dist/core/tools/find.js +459 -0
  204. package/dist/core/tools/grep.d.ts +36 -0
  205. package/dist/core/tools/grep.js +422 -0
  206. package/dist/core/tools/index.d.ts +70 -0
  207. package/dist/core/tools/index.js +129 -0
  208. package/dist/core/tools/line-anchors.d.ts +33 -0
  209. package/dist/core/tools/line-anchors.js +151 -0
  210. package/dist/core/tools/ls.d.ts +36 -0
  211. package/dist/core/tools/ls.js +268 -0
  212. package/dist/core/tools/path-utils.d.ts +7 -0
  213. package/dist/core/tools/path-utils.js +80 -0
  214. package/dist/core/tools/read.d.ts +35 -0
  215. package/dist/core/tools/read.js +244 -0
  216. package/dist/core/tools/render-utils.d.ts +20 -0
  217. package/dist/core/tools/render-utils.js +48 -0
  218. package/dist/core/tools/session-split.d.ts +9 -0
  219. package/dist/core/tools/session-split.js +77 -0
  220. package/dist/core/tools/tool-definition-wrapper.d.ts +13 -0
  221. package/dist/core/tools/tool-definition-wrapper.js +32 -0
  222. package/dist/core/tools/truncate.d.ts +69 -0
  223. package/dist/core/tools/truncate.js +204 -0
  224. package/dist/core/tools/write.d.ts +25 -0
  225. package/dist/core/tools/write.js +211 -0
  226. package/dist/core/types/session-types.d.ts +123 -0
  227. package/dist/core/types/session-types.js +8 -0
  228. package/dist/index.d.ts +27 -0
  229. package/dist/index.js +38 -0
  230. package/dist/main.d.ts +11 -2
  231. package/dist/main.js +577 -149
  232. package/dist/modes/event-mapper.d.ts +115 -0
  233. package/dist/modes/event-mapper.js +200 -0
  234. package/dist/modes/gui/server.d.ts +14 -0
  235. package/dist/modes/gui/server.js +1032 -0
  236. package/dist/modes/index.d.ts +10 -0
  237. package/dist/modes/index.js +9 -0
  238. package/dist/modes/interactive/assets/clankolas.png +0 -0
  239. package/dist/modes/interactive/components/armin.d.ts +33 -0
  240. package/dist/modes/interactive/components/armin.js +328 -0
  241. package/dist/modes/interactive/components/assistant-message.d.ts +19 -0
  242. package/dist/modes/interactive/components/assistant-message.js +115 -0
  243. package/dist/modes/interactive/components/bash-execution.d.ts +33 -0
  244. package/dist/modes/interactive/components/bash-execution.js +169 -0
  245. package/dist/modes/interactive/components/bordered-loader.d.ts +15 -0
  246. package/dist/modes/interactive/components/bordered-loader.js +50 -0
  247. package/dist/modes/interactive/components/branch-summary-message.d.ts +15 -0
  248. package/dist/modes/interactive/components/branch-summary-message.js +41 -0
  249. package/dist/modes/interactive/components/brand-header.d.ts +33 -0
  250. package/dist/modes/interactive/components/brand-header.js +235 -0
  251. package/dist/modes/interactive/components/compaction-summary-message.d.ts +15 -0
  252. package/dist/modes/interactive/components/compaction-summary-message.js +42 -0
  253. package/dist/modes/interactive/components/config-selector.d.ts +70 -0
  254. package/dist/modes/interactive/components/config-selector.js +469 -0
  255. package/dist/modes/interactive/components/countdown-timer.d.ts +13 -0
  256. package/dist/modes/interactive/components/countdown-timer.js +27 -0
  257. package/dist/modes/interactive/components/custom-editor.d.ts +27 -0
  258. package/dist/modes/interactive/components/custom-editor.js +94 -0
  259. package/dist/modes/interactive/components/custom-message.d.ts +19 -0
  260. package/dist/modes/interactive/components/custom-message.js +73 -0
  261. package/dist/modes/interactive/components/daxnuts.d.ts +22 -0
  262. package/dist/modes/interactive/components/daxnuts.js +137 -0
  263. package/dist/modes/interactive/components/diff.d.ts +11 -0
  264. package/dist/modes/interactive/components/diff.js +132 -0
  265. package/dist/modes/interactive/components/dynamic-border.d.ts +14 -0
  266. package/dist/modes/interactive/components/dynamic-border.js +19 -0
  267. package/dist/modes/interactive/components/earendil-announcement.d.ts +4 -0
  268. package/dist/modes/interactive/components/earendil-announcement.js +39 -0
  269. package/dist/modes/interactive/components/extension-editor.d.ts +19 -0
  270. package/dist/modes/interactive/components/extension-editor.js +105 -0
  271. package/dist/modes/interactive/components/extension-input.d.ts +22 -0
  272. package/dist/modes/interactive/components/extension-input.js +54 -0
  273. package/dist/modes/interactive/components/extension-selector.d.ts +23 -0
  274. package/dist/modes/interactive/components/extension-selector.js +70 -0
  275. package/dist/modes/interactive/components/footer.d.ts +55 -0
  276. package/dist/modes/interactive/components/footer.js +207 -0
  277. package/dist/modes/interactive/components/index.d.ts +31 -0
  278. package/dist/modes/interactive/components/index.js +32 -0
  279. package/dist/modes/interactive/components/keybinding-hints.d.ts +7 -0
  280. package/dist/modes/interactive/components/keybinding-hints.js +21 -0
  281. package/dist/modes/interactive/components/login-dialog.d.ts +41 -0
  282. package/dist/modes/interactive/components/login-dialog.js +138 -0
  283. package/dist/modes/interactive/components/model-selector.d.ts +32 -0
  284. package/dist/modes/interactive/components/model-selector.js +209 -0
  285. package/dist/modes/interactive/components/oauth-selector.d.ts +18 -0
  286. package/dist/modes/interactive/components/oauth-selector.js +91 -0
  287. package/dist/modes/interactive/components/settings-selector.d.ts +57 -0
  288. package/dist/modes/interactive/components/settings-selector.js +299 -0
  289. package/dist/modes/interactive/components/show-images-selector.d.ts +9 -0
  290. package/dist/modes/interactive/components/show-images-selector.js +37 -0
  291. package/dist/modes/interactive/components/skill-invocation-message.d.ts +16 -0
  292. package/dist/modes/interactive/components/skill-invocation-message.js +44 -0
  293. package/dist/modes/interactive/components/theme-selector.d.ts +10 -0
  294. package/dist/modes/interactive/components/theme-selector.js +47 -0
  295. package/dist/modes/interactive/components/thinking-selector.d.ts +10 -0
  296. package/dist/modes/interactive/components/thinking-selector.js +50 -0
  297. package/dist/modes/interactive/components/timeline-view.d.ts +31 -0
  298. package/dist/modes/interactive/components/timeline-view.js +81 -0
  299. package/dist/modes/interactive/components/tool-execution.d.ts +64 -0
  300. package/dist/modes/interactive/components/tool-execution.js +305 -0
  301. package/dist/modes/interactive/components/tree-selector.d.ts +88 -0
  302. package/dist/modes/interactive/components/tree-selector.js +1072 -0
  303. package/dist/modes/interactive/components/user-message-selector.d.ts +29 -0
  304. package/dist/modes/interactive/components/user-message-selector.js +110 -0
  305. package/dist/modes/interactive/components/user-message.d.ts +9 -0
  306. package/dist/modes/interactive/components/user-message.js +27 -0
  307. package/dist/modes/interactive/components/visual-truncate.d.ts +23 -0
  308. package/dist/modes/interactive/components/visual-truncate.js +32 -0
  309. package/dist/modes/interactive/interactive-mode.d.ts +394 -0
  310. package/dist/modes/interactive/interactive-mode.js +4116 -0
  311. package/dist/modes/interactive/theme/dark.json +85 -0
  312. package/dist/modes/interactive/theme/light.json +84 -0
  313. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  314. package/dist/modes/interactive/theme/theme.d.ts +80 -0
  315. package/dist/modes/interactive/theme/theme.js +973 -0
  316. package/dist/modes/print-mode.d.ts +27 -0
  317. package/dist/modes/print-mode.js +102 -0
  318. package/dist/modes/rpc/jsonl.d.ts +16 -0
  319. package/dist/modes/rpc/jsonl.js +48 -0
  320. package/dist/modes/rpc/rpc-client.d.ts +219 -0
  321. package/dist/modes/rpc/rpc-client.js +405 -0
  322. package/dist/modes/rpc/rpc-mode.d.ts +19 -0
  323. package/dist/modes/rpc/rpc-mode.js +381 -0
  324. package/dist/modes/rpc/rpc-types.d.ts +406 -0
  325. package/dist/modes/rpc/rpc-types.js +7 -0
  326. package/dist/package-manager-cli.d.ts +3 -0
  327. package/dist/package-manager-cli.js +233 -0
  328. package/dist/utils/changelog.d.ts +20 -0
  329. package/dist/utils/changelog.js +86 -0
  330. package/dist/utils/child-process.d.ts +10 -0
  331. package/dist/utils/child-process.js +77 -0
  332. package/dist/utils/clipboard-image.d.ts +10 -0
  333. package/dist/utils/clipboard-image.js +244 -0
  334. package/dist/utils/clipboard-native.d.ts +7 -0
  335. package/dist/utils/clipboard-native.js +13 -0
  336. package/dist/utils/clipboard.d.ts +1 -0
  337. package/dist/utils/clipboard.js +77 -0
  338. package/dist/utils/exif-orientation.d.ts +4 -0
  339. package/dist/utils/exif-orientation.js +157 -0
  340. package/dist/utils/frontmatter.d.ts +7 -0
  341. package/dist/utils/frontmatter.js +25 -0
  342. package/dist/utils/git.d.ts +25 -0
  343. package/dist/utils/git.js +162 -0
  344. package/dist/utils/image-convert.d.ts +8 -0
  345. package/dist/utils/image-convert.js +38 -0
  346. package/dist/utils/image-resize.d.ts +35 -0
  347. package/dist/utils/image-resize.js +136 -0
  348. package/dist/utils/mime.d.ts +1 -0
  349. package/dist/utils/mime.js +25 -0
  350. package/dist/utils/path-shims.d.ts +1 -0
  351. package/dist/utils/path-shims.js +90 -0
  352. package/dist/utils/paths.d.ts +6 -0
  353. package/dist/utils/paths.js +18 -0
  354. package/dist/utils/photon.d.ts +20 -0
  355. package/dist/utils/photon.js +120 -0
  356. package/dist/utils/shell.d.ts +29 -0
  357. package/dist/utils/shell.js +189 -0
  358. package/dist/utils/sleep.d.ts +4 -0
  359. package/dist/utils/sleep.js +16 -0
  360. package/dist/utils/tools-manager.d.ts +3 -0
  361. package/dist/utils/tools-manager.js +101 -0
  362. package/dist/vendor/bin/darwin-arm64/fd +0 -0
  363. package/dist/vendor/bin/darwin-arm64/rg +0 -0
  364. package/dist/vendor/bin/darwin-x64/fd +0 -0
  365. package/dist/vendor/bin/darwin-x64/rg +0 -0
  366. package/dist/vendor/bin/linux-arm64/fd +0 -0
  367. package/dist/vendor/bin/linux-arm64/rg +0 -0
  368. package/dist/vendor/bin/linux-x64/fd +0 -0
  369. package/dist/vendor/bin/linux-x64/rg +0 -0
  370. package/dist/vendor/bin/win32-arm64/fd.exe +0 -0
  371. package/dist/vendor/bin/win32-arm64/rg.exe +0 -0
  372. package/dist/vendor/bin/win32-x64/fd.exe +0 -0
  373. package/dist/vendor/bin/win32-x64/rg.exe +0 -0
  374. package/package.json +90 -26
  375. package/dist/extension/core.d.ts +0 -69
  376. package/dist/extension/core.js +0 -270
  377. package/dist/extension/core.js.map +0 -1
  378. package/dist/extension/index.d.ts +0 -14
  379. package/dist/extension/index.js +0 -374
  380. package/dist/extension/index.js.map +0 -1
  381. package/dist/main.js.map +0 -1
  382. package/themes/pizza.json +0 -87
@@ -0,0 +1,151 @@
1
+ import { createHash } from "crypto";
2
+ const HASH_LENGTH = 2;
3
+ const LINE_ANCHOR_PATTERN = /^([1-9]\d*)#([0-9a-f]{2})$/;
4
+ export function hashLine(line) {
5
+ return createHash("sha256").update(line, "utf-8").digest("hex").slice(0, HASH_LENGTH);
6
+ }
7
+ export function formatLineAnchor(lineNumber, line) {
8
+ return `${lineNumber}#${hashLine(line)}`;
9
+ }
10
+ export function formatRange(start, end = start) {
11
+ const startId = `${start.line}#${start.hash}`;
12
+ const endId = `${end.line}#${end.hash}`;
13
+ return startId === endId ? startId : `${startId}..${endId}`;
14
+ }
15
+ export function looksLikeRange(value) {
16
+ try {
17
+ parseRange(value);
18
+ return true;
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ }
24
+ export function parseRange(range) {
25
+ const trimmed = range.trim();
26
+ if (!trimmed) {
27
+ throw new Error("range must not be empty.");
28
+ }
29
+ const parts = trimmed.split("..");
30
+ if (parts.length > 2) {
31
+ throw new Error(`Invalid range "${range}". Expected <line>#<hash> or <start>#<hash>..<end>#<hash>.`);
32
+ }
33
+ const start = parseLineAnchor(parts[0], range);
34
+ const end = parseLineAnchor(parts[1] ?? parts[0], range);
35
+ if (start.line > end.line) {
36
+ throw new Error(`Invalid range "${range}". Start line must be before or equal to end line.`);
37
+ }
38
+ return { start, end };
39
+ }
40
+ export function buildLineRecords(content) {
41
+ if (content.length === 0) {
42
+ return [
43
+ {
44
+ lineNumber: 1,
45
+ text: "",
46
+ startIndex: 0,
47
+ contentEndIndex: 0,
48
+ replacementEndIndex: 0,
49
+ hash: hashLine(""),
50
+ },
51
+ ];
52
+ }
53
+ const records = [];
54
+ let startIndex = 0;
55
+ let lineNumber = 1;
56
+ for (let i = 0; i < content.length; i++) {
57
+ if (content[i] !== "\n")
58
+ continue;
59
+ const text = content.slice(startIndex, i);
60
+ records.push({
61
+ lineNumber,
62
+ text,
63
+ startIndex,
64
+ contentEndIndex: i,
65
+ replacementEndIndex: i + 1,
66
+ hash: hashLine(text),
67
+ });
68
+ startIndex = i + 1;
69
+ lineNumber++;
70
+ }
71
+ if (startIndex < content.length) {
72
+ const text = content.slice(startIndex);
73
+ records.push({
74
+ lineNumber,
75
+ text,
76
+ startIndex,
77
+ contentEndIndex: content.length,
78
+ replacementEndIndex: content.length,
79
+ hash: hashLine(text),
80
+ });
81
+ }
82
+ return records;
83
+ }
84
+ export function annotateTextWithLineAnchors(text, startLine = 1) {
85
+ const lines = text.split("\n");
86
+ if (text.endsWith("\n")) {
87
+ lines.pop();
88
+ }
89
+ if (lines.length === 0) {
90
+ return "";
91
+ }
92
+ return lines.map((line, index) => `${formatLineAnchor(startLine + index, line)} | ${line}`).join("\n");
93
+ }
94
+ export function resolveRange(content, range, path) {
95
+ const anchor = parseRange(range);
96
+ const records = buildLineRecords(content);
97
+ const length = anchor.end.line - anchor.start.line + 1;
98
+ const direct = resolveByRecordIndex(records, anchor.start.line - 1, length, anchor);
99
+ if (direct) {
100
+ return buildResolvedRange(content, range, records, direct.startIndex, direct.endIndex, false);
101
+ }
102
+ const candidates = [];
103
+ for (let i = 0; i <= records.length - length; i++) {
104
+ const candidate = resolveByRecordIndex(records, i, length, anchor);
105
+ if (candidate) {
106
+ candidates.push(candidate);
107
+ }
108
+ }
109
+ if (candidates.length === 1) {
110
+ return buildResolvedRange(content, range, records, candidates[0].startIndex, candidates[0].endIndex, true);
111
+ }
112
+ if (candidates.length > 1) {
113
+ throw new Error(`range ${range} is ambiguous in ${path}. Re-read a smaller region and use current line anchors.`);
114
+ }
115
+ throw new Error(`range ${range} is stale in ${path}. Re-read the file and use current line anchors.`);
116
+ }
117
+ function parseLineAnchor(value, originalRange) {
118
+ const match = value?.match(LINE_ANCHOR_PATTERN);
119
+ if (!match) {
120
+ throw new Error(`Invalid range "${originalRange}". Expected <line>#<2-hex-hash> or <start>#<hash>..<end>#<hash>.`);
121
+ }
122
+ return {
123
+ line: Number(match[1]),
124
+ hash: match[2],
125
+ };
126
+ }
127
+ function resolveByRecordIndex(records, startIndex, length, anchor) {
128
+ if (startIndex < 0)
129
+ return undefined;
130
+ const endIndex = startIndex + length - 1;
131
+ if (endIndex >= records.length)
132
+ return undefined;
133
+ const start = records[startIndex];
134
+ const end = records[endIndex];
135
+ if (start.hash !== anchor.start.hash || end.hash !== anchor.end.hash)
136
+ return undefined;
137
+ return { startIndex, endIndex };
138
+ }
139
+ function buildResolvedRange(content, range, records, startRecordIndex, endRecordIndex, usedRelocation) {
140
+ const start = records[startRecordIndex];
141
+ const end = records[endRecordIndex];
142
+ return {
143
+ range,
144
+ startLine: start.lineNumber,
145
+ endLine: end.lineNumber,
146
+ startIndex: start.startIndex,
147
+ endIndex: end.replacementEndIndex,
148
+ existingText: content.slice(start.startIndex, end.replacementEndIndex),
149
+ usedRelocation,
150
+ };
151
+ }
@@ -0,0 +1,36 @@
1
+ import type { AgentTool } from "../agent/types.js";
2
+ import { type Static } from "@sinclair/typebox";
3
+ import type { ToolDefinition } from "../extensions/types.js";
4
+ import { type TruncationResult } from "./truncate.js";
5
+ declare const lsSchema: import("@sinclair/typebox").TObject<{
6
+ path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
7
+ limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
8
+ }>;
9
+ export type LsToolInput = Static<typeof lsSchema>;
10
+ export interface LsToolDetails {
11
+ truncation?: TruncationResult;
12
+ entryLimitReached?: number;
13
+ }
14
+ /**
15
+ * Pluggable operations for the ls tool.
16
+ * Override these to delegate directory listing to remote systems (for example SSH).
17
+ */
18
+ export interface LsOperations {
19
+ /** Check if path exists */
20
+ exists: (absolutePath: string) => Promise<boolean> | boolean;
21
+ /** Get file or directory stats. Throws if not found. */
22
+ stat: (absolutePath: string) => Promise<{
23
+ isDirectory: () => boolean;
24
+ }> | {
25
+ isDirectory: () => boolean;
26
+ };
27
+ /** Read directory entries */
28
+ readdir: (absolutePath: string) => Promise<string[]> | string[];
29
+ }
30
+ export interface LsToolOptions {
31
+ /** Custom operations for directory listing. Default: local filesystem */
32
+ operations?: LsOperations;
33
+ }
34
+ export declare function createLsToolDefinition(cwd: string, options?: LsToolOptions): ToolDefinition<typeof lsSchema, LsToolDetails | undefined>;
35
+ export declare function createLsTool(cwd: string, options?: LsToolOptions): AgentTool<typeof lsSchema>;
36
+ export {};
@@ -0,0 +1,268 @@
1
+ import { Text } from "@earendil-works/pi-tui";
2
+ import { Type } from "@sinclair/typebox";
3
+ import { existsSync, readdirSync, statSync } from "fs";
4
+ import { minimatch } from "minimatch";
5
+ import nodePath from "path";
6
+ import { keyHint } from "../../modes/interactive/components/keybinding-hints.js";
7
+ import { resolveToCwd } from "./path-utils.js";
8
+ import { getTextOutput, invalidArgText, shortenPath, str } from "./render-utils.js";
9
+ import { wrapToolDefinition } from "./tool-definition-wrapper.js";
10
+ import { DEFAULT_MAX_BYTES, formatSize, truncateHead } from "./truncate.js";
11
+ const lsSchema = Type.Object({
12
+ path: Type.Optional(Type.String({ description: "Directory to list (default: current directory)" })),
13
+ limit: Type.Optional(Type.Number({ description: "Maximum number of entries to return (default: 500)" })),
14
+ });
15
+ const DEFAULT_LIMIT = 500;
16
+ const GLOB_PATTERN_RE = /[*?[\]{}]/;
17
+ const defaultLsOperations = {
18
+ exists: existsSync,
19
+ stat: statSync,
20
+ readdir: readdirSync,
21
+ };
22
+ function toPosixPath(value) {
23
+ return value.split(nodePath.sep).join("/");
24
+ }
25
+ function hasGlobPattern(value) {
26
+ return GLOB_PATTERN_RE.test(value);
27
+ }
28
+ function splitGlobPath(rawPath) {
29
+ let root = rawPath;
30
+ while (root && hasGlobPattern(root)) {
31
+ const parent = nodePath.dirname(root);
32
+ if (parent === root)
33
+ break;
34
+ root = parent;
35
+ }
36
+ if (!root || root === rawPath)
37
+ root = ".";
38
+ return {
39
+ root,
40
+ pattern: toPosixPath(nodePath.relative(root, rawPath)),
41
+ };
42
+ }
43
+ async function listGlobEntries(rawPath, cwd, ops, effectiveLimit, signal) {
44
+ const { root, pattern } = splitGlobPath(rawPath);
45
+ const rootPath = resolveToCwd(root, cwd);
46
+ if (!(await ops.exists(rootPath))) {
47
+ throw new Error(`Path not found: ${rootPath}`);
48
+ }
49
+ const rootStat = await ops.stat(rootPath);
50
+ if (!rootStat.isDirectory()) {
51
+ throw new Error(`Not a directory: ${rootPath}`);
52
+ }
53
+ const results = [];
54
+ let entryLimitReached = false;
55
+ const isAbsoluteInput = nodePath.isAbsolute(rawPath);
56
+ const displayRoot = root === "." ? "" : root;
57
+ const walk = async (dirPath) => {
58
+ if (signal?.aborted)
59
+ throw new Error("Operation aborted");
60
+ if (results.length >= effectiveLimit) {
61
+ entryLimitReached = true;
62
+ return;
63
+ }
64
+ let entries;
65
+ try {
66
+ entries = await ops.readdir(dirPath);
67
+ }
68
+ catch {
69
+ return;
70
+ }
71
+ entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
72
+ for (const entry of entries) {
73
+ if (results.length >= effectiveLimit) {
74
+ entryLimitReached = true;
75
+ return;
76
+ }
77
+ const fullPath = nodePath.join(dirPath, entry);
78
+ let entryStat;
79
+ try {
80
+ entryStat = await ops.stat(fullPath);
81
+ }
82
+ catch {
83
+ continue;
84
+ }
85
+ const relativeFromRoot = toPosixPath(nodePath.relative(rootPath, fullPath));
86
+ if (minimatch(relativeFromRoot, pattern, { dot: true })) {
87
+ const suffix = entryStat.isDirectory() ? "/" : "";
88
+ if (isAbsoluteInput) {
89
+ results.push(toPosixPath(fullPath) + suffix);
90
+ }
91
+ else {
92
+ const displayPath = displayRoot ? nodePath.join(displayRoot, relativeFromRoot) : relativeFromRoot;
93
+ results.push(toPosixPath(displayPath) + suffix);
94
+ }
95
+ }
96
+ if (entryStat.isDirectory()) {
97
+ await walk(fullPath);
98
+ }
99
+ }
100
+ };
101
+ await walk(rootPath);
102
+ return { results, entryLimitReached };
103
+ }
104
+ function formatLsCall(args, theme) {
105
+ const rawPath = str(args?.path);
106
+ const path = rawPath !== null ? shortenPath(rawPath || ".") : null;
107
+ const limit = args?.limit;
108
+ const invalidArg = invalidArgText(theme);
109
+ let text = `${theme.fg("toolTitle", theme.bold("ls"))} ${path === null ? invalidArg : theme.fg("accent", path)}`;
110
+ if (limit !== undefined) {
111
+ text += theme.fg("toolOutput", ` (limit ${limit})`);
112
+ }
113
+ return text;
114
+ }
115
+ function formatLsResult(result, options, theme, showImages) {
116
+ const output = getTextOutput(result, showImages).trim();
117
+ let text = "";
118
+ if (output) {
119
+ const lines = output.split("\n");
120
+ const maxLines = options.expanded ? lines.length : 20;
121
+ const displayLines = lines.slice(0, maxLines);
122
+ const remaining = lines.length - maxLines;
123
+ text += `\n${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
124
+ if (remaining > 0) {
125
+ text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("app.tools.expand", "to expand")})`;
126
+ }
127
+ }
128
+ const entryLimit = result.details?.entryLimitReached;
129
+ const truncation = result.details?.truncation;
130
+ if (entryLimit || truncation?.truncated) {
131
+ const warnings = [];
132
+ if (entryLimit)
133
+ warnings.push(`${entryLimit} entries limit`);
134
+ if (truncation?.truncated)
135
+ warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
136
+ text += `\n${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
137
+ }
138
+ return text;
139
+ }
140
+ export function createLsToolDefinition(cwd, options) {
141
+ const ops = options?.operations ?? defaultLsOperations;
142
+ return {
143
+ name: "ls",
144
+ label: "ls",
145
+ description: `List directory contents. Returns entries sorted alphabetically, with '/' suffix for directories. Includes dotfiles. Output is truncated to ${DEFAULT_LIMIT} entries or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,
146
+ promptSnippet: "List directory contents",
147
+ parameters: lsSchema,
148
+ async execute(_toolCallId, { path, limit }, signal, _onUpdate, _ctx) {
149
+ return new Promise((resolve, reject) => {
150
+ if (signal?.aborted) {
151
+ reject(new Error("Operation aborted"));
152
+ return;
153
+ }
154
+ const onAbort = () => reject(new Error("Operation aborted"));
155
+ signal?.addEventListener("abort", onAbort, { once: true });
156
+ (async () => {
157
+ try {
158
+ const dirPath = resolveToCwd(path || ".", cwd);
159
+ const effectiveLimit = limit ?? DEFAULT_LIMIT;
160
+ let results = [];
161
+ let entryLimitReached = false;
162
+ if (path && hasGlobPattern(path)) {
163
+ try {
164
+ const globResult = await listGlobEntries(path, cwd, ops, effectiveLimit, signal);
165
+ results = globResult.results;
166
+ entryLimitReached = globResult.entryLimitReached;
167
+ }
168
+ catch (error) {
169
+ reject(error);
170
+ return;
171
+ }
172
+ }
173
+ else {
174
+ // Check if path exists.
175
+ if (!(await ops.exists(dirPath))) {
176
+ reject(new Error(`Path not found: ${dirPath}`));
177
+ return;
178
+ }
179
+ // Check if path is a directory.
180
+ const stat = await ops.stat(dirPath);
181
+ if (!stat.isDirectory()) {
182
+ reject(new Error(`Not a directory: ${dirPath}`));
183
+ return;
184
+ }
185
+ // Read directory entries.
186
+ let entries;
187
+ try {
188
+ entries = await ops.readdir(dirPath);
189
+ }
190
+ catch (e) {
191
+ reject(new Error(`Cannot read directory: ${e.message}`));
192
+ return;
193
+ }
194
+ // Sort alphabetically, case-insensitive.
195
+ entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
196
+ // Format entries with directory indicators.
197
+ for (const entry of entries) {
198
+ if (results.length >= effectiveLimit) {
199
+ entryLimitReached = true;
200
+ break;
201
+ }
202
+ const fullPath = nodePath.join(dirPath, entry);
203
+ let suffix = "";
204
+ try {
205
+ const entryStat = await ops.stat(fullPath);
206
+ if (entryStat.isDirectory())
207
+ suffix = "/";
208
+ }
209
+ catch {
210
+ // Skip entries we cannot stat.
211
+ continue;
212
+ }
213
+ results.push(entry + suffix);
214
+ }
215
+ }
216
+ signal?.removeEventListener("abort", onAbort);
217
+ if (results.length === 0) {
218
+ resolve({
219
+ content: [{ type: "text", text: path && hasGlobPattern(path) ? "No entries found matching pattern" : "(empty directory)" }],
220
+ details: undefined,
221
+ });
222
+ return;
223
+ }
224
+ const rawOutput = results.join("\n");
225
+ // Apply byte truncation. There is no separate line limit because entry count is already capped.
226
+ const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
227
+ let output = truncation.content;
228
+ const details = {};
229
+ // Build actionable notices for truncation and entry limits.
230
+ const notices = [];
231
+ if (entryLimitReached) {
232
+ notices.push(`${effectiveLimit} entries limit reached. Use limit=${effectiveLimit * 2} for more`);
233
+ details.entryLimitReached = effectiveLimit;
234
+ }
235
+ if (truncation.truncated) {
236
+ notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
237
+ details.truncation = truncation;
238
+ }
239
+ if (notices.length > 0) {
240
+ output += `\n\n[${notices.join(". ")}]`;
241
+ }
242
+ resolve({
243
+ content: [{ type: "text", text: output }],
244
+ details: Object.keys(details).length > 0 ? details : undefined,
245
+ });
246
+ }
247
+ catch (e) {
248
+ signal?.removeEventListener("abort", onAbort);
249
+ reject(e);
250
+ }
251
+ })();
252
+ });
253
+ },
254
+ renderCall(args, theme, context) {
255
+ const text = context.lastComponent ?? new Text("", 0, 0);
256
+ text.setText(formatLsCall(args, theme));
257
+ return text;
258
+ },
259
+ renderResult(result, options, theme, context) {
260
+ const text = context.lastComponent ?? new Text("", 0, 0);
261
+ text.setText(formatLsResult(result, options, theme, context.showImages));
262
+ return text;
263
+ },
264
+ };
265
+ }
266
+ export function createLsTool(cwd, options) {
267
+ return wrapToolDefinition(createLsToolDefinition(cwd, options));
268
+ }
@@ -0,0 +1,7 @@
1
+ export declare function expandPath(filePath: string): string;
2
+ /**
3
+ * Resolve a path relative to the given cwd.
4
+ * Handles ~ expansion and absolute paths.
5
+ */
6
+ export declare function resolveToCwd(filePath: string, cwd: string): string;
7
+ export declare function resolveReadPath(filePath: string, cwd: string): string;
@@ -0,0 +1,80 @@
1
+ import { accessSync, constants } from "node:fs";
2
+ import * as os from "node:os";
3
+ import { isAbsolute, resolve as resolvePath } from "node:path";
4
+ const UNICODE_SPACES = /[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;
5
+ const NARROW_NO_BREAK_SPACE = "\u202F";
6
+ function normalizeUnicodeSpaces(str) {
7
+ return str.replace(UNICODE_SPACES, " ");
8
+ }
9
+ function tryMacOSScreenshotPath(filePath) {
10
+ return filePath.replace(/ (AM|PM)\./gi, `${NARROW_NO_BREAK_SPACE}$1.`);
11
+ }
12
+ function tryNFDVariant(filePath) {
13
+ // macOS stores filenames in NFD (decomposed) form, try converting user input to NFD
14
+ return filePath.normalize("NFD");
15
+ }
16
+ function tryCurlyQuoteVariant(filePath) {
17
+ // macOS uses U+2019 (right single quotation mark) in screenshot names like "Capture d'écran"
18
+ // Users typically type U+0027 (straight apostrophe)
19
+ return filePath.replace(/'/g, "\u2019");
20
+ }
21
+ function fileExists(filePath) {
22
+ try {
23
+ accessSync(filePath, constants.F_OK);
24
+ return true;
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
30
+ function normalizeAtPrefix(filePath) {
31
+ return filePath.startsWith("@") ? filePath.slice(1) : filePath;
32
+ }
33
+ export function expandPath(filePath) {
34
+ const normalized = normalizeUnicodeSpaces(normalizeAtPrefix(filePath));
35
+ if (normalized === "~") {
36
+ return os.homedir();
37
+ }
38
+ if (normalized.startsWith("~/")) {
39
+ return os.homedir() + normalized.slice(1);
40
+ }
41
+ return normalized;
42
+ }
43
+ /**
44
+ * Resolve a path relative to the given cwd.
45
+ * Handles ~ expansion and absolute paths.
46
+ */
47
+ export function resolveToCwd(filePath, cwd) {
48
+ const expanded = expandPath(filePath);
49
+ if (isAbsolute(expanded)) {
50
+ return expanded;
51
+ }
52
+ return resolvePath(cwd, expanded);
53
+ }
54
+ export function resolveReadPath(filePath, cwd) {
55
+ const resolved = resolveToCwd(filePath, cwd);
56
+ if (fileExists(resolved)) {
57
+ return resolved;
58
+ }
59
+ // Try macOS AM/PM variant (narrow no-break space before AM/PM)
60
+ const amPmVariant = tryMacOSScreenshotPath(resolved);
61
+ if (amPmVariant !== resolved && fileExists(amPmVariant)) {
62
+ return amPmVariant;
63
+ }
64
+ // Try NFD variant (macOS stores filenames in NFD form)
65
+ const nfdVariant = tryNFDVariant(resolved);
66
+ if (nfdVariant !== resolved && fileExists(nfdVariant)) {
67
+ return nfdVariant;
68
+ }
69
+ // Try curly quote variant (macOS uses U+2019 in screenshot names)
70
+ const curlyVariant = tryCurlyQuoteVariant(resolved);
71
+ if (curlyVariant !== resolved && fileExists(curlyVariant)) {
72
+ return curlyVariant;
73
+ }
74
+ // Try combined NFD + curly quote (for French macOS screenshots like "Capture d'écran")
75
+ const nfdCurlyVariant = tryCurlyQuoteVariant(nfdVariant);
76
+ if (nfdCurlyVariant !== resolved && fileExists(nfdCurlyVariant)) {
77
+ return nfdCurlyVariant;
78
+ }
79
+ return resolved;
80
+ }
@@ -0,0 +1,35 @@
1
+ import type { AgentTool } from "../agent/types.js";
2
+ import { type Static } from "@sinclair/typebox";
3
+ import type { ToolDefinition } from "../extensions/types.js";
4
+ import { type TruncationResult } from "./truncate.js";
5
+ declare const readSchema: import("@sinclair/typebox").TObject<{
6
+ path: import("@sinclair/typebox").TString;
7
+ offset: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
8
+ limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
9
+ anchors: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"line">, import("@sinclair/typebox").TLiteral<"none">]>>;
10
+ }>;
11
+ export type ReadToolInput = Static<typeof readSchema>;
12
+ export interface ReadToolDetails {
13
+ truncation?: TruncationResult;
14
+ }
15
+ /**
16
+ * Pluggable operations for the read tool.
17
+ * Override these to delegate file reading to remote systems (for example SSH).
18
+ */
19
+ export interface ReadOperations {
20
+ /** Read file contents as a Buffer */
21
+ readFile: (absolutePath: string) => Promise<Buffer>;
22
+ /** Check if file is readable (throw if not) */
23
+ access: (absolutePath: string) => Promise<void>;
24
+ /** Detect image MIME type, return null or undefined for non-images */
25
+ detectImageMimeType?: (absolutePath: string) => Promise<string | null | undefined>;
26
+ }
27
+ export interface ReadToolOptions {
28
+ /** Whether to auto-resize images to 2000x2000 max. Default: true */
29
+ autoResizeImages?: boolean;
30
+ /** Custom operations for file reading. Default: local filesystem */
31
+ operations?: ReadOperations;
32
+ }
33
+ export declare function createReadToolDefinition(cwd: string, options?: ReadToolOptions): ToolDefinition<typeof readSchema, ReadToolDetails | undefined>;
34
+ export declare function createReadTool(cwd: string, options?: ReadToolOptions): AgentTool<typeof readSchema>;
35
+ export {};