@tomsun28/pizza 0.0.9 → 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 -25
  379. package/dist/extension/index.js +0 -303
  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,459 @@
1
+ import { createInterface } from "node:readline";
2
+ import { Text } from "@earendil-works/pi-tui";
3
+ import { Type } from "@sinclair/typebox";
4
+ import { spawn } from "child_process";
5
+ import { existsSync, readdirSync, readFileSync, statSync } from "fs";
6
+ import ignore from "ignore";
7
+ import { minimatch } from "minimatch";
8
+ import path from "path";
9
+ import { keyHint } from "../../modes/interactive/components/keybinding-hints.js";
10
+ import { ensureTool } from "../../utils/tools-manager.js";
11
+ import { resolveToCwd } from "./path-utils.js";
12
+ import { getTextOutput, invalidArgText, shortenPath, str } from "./render-utils.js";
13
+ import { wrapToolDefinition } from "./tool-definition-wrapper.js";
14
+ import { DEFAULT_MAX_BYTES, formatSize, truncateHead } from "./truncate.js";
15
+ function toPosixPath(value) {
16
+ return value.split(path.sep).join("/");
17
+ }
18
+ function prefixIgnorePattern(line, prefix) {
19
+ const trimmed = line.trim();
20
+ if (!trimmed)
21
+ return null;
22
+ if (trimmed.startsWith("#") && !trimmed.startsWith("\\#"))
23
+ return null;
24
+ let pattern = trimmed;
25
+ let negated = false;
26
+ if (pattern.startsWith("!")) {
27
+ negated = true;
28
+ pattern = pattern.slice(1);
29
+ }
30
+ else if (pattern.startsWith("\\!")) {
31
+ pattern = pattern.slice(1);
32
+ }
33
+ if (pattern.startsWith("/")) {
34
+ pattern = pattern.slice(1);
35
+ }
36
+ const hasSlash = pattern.includes("/");
37
+ const scoped = prefix && !hasSlash ? `${prefix}**/${pattern}` : `${prefix}${pattern}`;
38
+ return negated ? `!${scoped}` : scoped;
39
+ }
40
+ function addIgnoreRules(ig, dir, rootDir) {
41
+ const relativeDir = path.relative(rootDir, dir);
42
+ const prefix = relativeDir ? `${toPosixPath(relativeDir)}/` : "";
43
+ for (const filename of IGNORE_FILE_NAMES) {
44
+ const ignorePath = path.join(dir, filename);
45
+ if (!existsSync(ignorePath))
46
+ continue;
47
+ try {
48
+ const content = readFileSync(ignorePath, "utf-8");
49
+ const patterns = content
50
+ .split(/\r?\n/)
51
+ .map((line) => prefixIgnorePattern(line, prefix))
52
+ .filter((line) => Boolean(line));
53
+ if (patterns.length > 0) {
54
+ ig.add(patterns);
55
+ }
56
+ }
57
+ catch { }
58
+ }
59
+ }
60
+ function assertValidFindPattern(pattern) {
61
+ let escaped = false;
62
+ let inClass = false;
63
+ for (const char of pattern) {
64
+ if (escaped) {
65
+ escaped = false;
66
+ continue;
67
+ }
68
+ if (char === "\\") {
69
+ escaped = true;
70
+ continue;
71
+ }
72
+ if (char === "[" && !inClass) {
73
+ inClass = true;
74
+ continue;
75
+ }
76
+ if (char === "]" && inClass) {
77
+ inClass = false;
78
+ }
79
+ }
80
+ if (inClass) {
81
+ throw new Error("fd error: error parsing glob: unclosed character class");
82
+ }
83
+ }
84
+ function nodeGlobMatch(relativePath, pattern) {
85
+ if (pattern.includes("/")) {
86
+ const normalizedPattern = pattern.startsWith("/") ? pattern.slice(1) : pattern;
87
+ return minimatch(relativePath, normalizedPattern, { dot: true });
88
+ }
89
+ return minimatch(path.posix.basename(relativePath), pattern, { dot: true });
90
+ }
91
+ function findWithNode(pattern, searchPath, limit) {
92
+ assertValidFindPattern(pattern);
93
+ const ig = ignore();
94
+ const results = [];
95
+ const walk = (dir) => {
96
+ if (results.length >= limit)
97
+ return;
98
+ addIgnoreRules(ig, dir, searchPath);
99
+ let entries;
100
+ try {
101
+ entries = readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
102
+ }
103
+ catch {
104
+ return;
105
+ }
106
+ for (const entry of entries) {
107
+ if (results.length >= limit)
108
+ return;
109
+ if (entry.name === ".git" || entry.name === "node_modules")
110
+ continue;
111
+ const fullPath = path.join(dir, entry.name);
112
+ let isDirectory = entry.isDirectory();
113
+ let isFile = entry.isFile();
114
+ if (entry.isSymbolicLink()) {
115
+ try {
116
+ const stats = statSync(fullPath);
117
+ isDirectory = stats.isDirectory();
118
+ isFile = stats.isFile();
119
+ }
120
+ catch {
121
+ continue;
122
+ }
123
+ }
124
+ const relativePath = toPosixPath(path.relative(searchPath, fullPath));
125
+ const ignorePath = isDirectory ? `${relativePath}/` : relativePath;
126
+ if (ig.ignores(ignorePath))
127
+ continue;
128
+ if (isFile && nodeGlobMatch(relativePath, pattern)) {
129
+ results.push(relativePath);
130
+ }
131
+ if (isDirectory) {
132
+ walk(fullPath);
133
+ }
134
+ }
135
+ };
136
+ walk(searchPath);
137
+ return results;
138
+ }
139
+ const findSchema = Type.Object({
140
+ pattern: Type.String({
141
+ description: "Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'",
142
+ }),
143
+ path: Type.Optional(Type.String({ description: "Directory to search in (default: current directory)" })),
144
+ limit: Type.Optional(Type.Number({ description: "Maximum number of results (default: 1000)" })),
145
+ });
146
+ const DEFAULT_LIMIT = 1000;
147
+ const IGNORE_FILE_NAMES = [".gitignore", ".ignore", ".fdignore"];
148
+ const defaultFindOperations = {
149
+ exists: existsSync,
150
+ // This is a placeholder. Actual fd execution happens in execute() when no custom glob is provided.
151
+ glob: () => [],
152
+ };
153
+ function formatFindCall(args, theme) {
154
+ const pattern = str(args?.pattern);
155
+ const rawPath = str(args?.path);
156
+ const path = rawPath !== null ? shortenPath(rawPath || ".") : null;
157
+ const limit = args?.limit;
158
+ const invalidArg = invalidArgText(theme);
159
+ let text = theme.fg("toolTitle", theme.bold("find")) +
160
+ " " +
161
+ (pattern === null ? invalidArg : theme.fg("accent", pattern || "")) +
162
+ theme.fg("toolOutput", ` in ${path === null ? invalidArg : path}`);
163
+ if (limit !== undefined) {
164
+ text += theme.fg("toolOutput", ` (limit ${limit})`);
165
+ }
166
+ return text;
167
+ }
168
+ function formatFindResult(result, options, theme, showImages) {
169
+ const output = getTextOutput(result, showImages).trim();
170
+ let text = "";
171
+ if (output) {
172
+ const lines = output.split("\n");
173
+ const maxLines = options.expanded ? lines.length : 20;
174
+ const displayLines = lines.slice(0, maxLines);
175
+ const remaining = lines.length - maxLines;
176
+ text += `\n${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
177
+ if (remaining > 0) {
178
+ text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("app.tools.expand", "to expand")})`;
179
+ }
180
+ }
181
+ const resultLimit = result.details?.resultLimitReached;
182
+ const truncation = result.details?.truncation;
183
+ if (resultLimit || truncation?.truncated) {
184
+ const warnings = [];
185
+ if (resultLimit)
186
+ warnings.push(`${resultLimit} results limit`);
187
+ if (truncation?.truncated)
188
+ warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
189
+ text += `\n${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
190
+ }
191
+ return text;
192
+ }
193
+ export function createFindToolDefinition(cwd, options) {
194
+ const customOps = options?.operations;
195
+ return {
196
+ name: "find",
197
+ label: "find",
198
+ description: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,
199
+ promptSnippet: "Find files by glob pattern (respects .gitignore)",
200
+ parameters: findSchema,
201
+ async execute(_toolCallId, { pattern, path: searchDir, limit }, signal, _onUpdate, _ctx) {
202
+ return new Promise((resolve, reject) => {
203
+ if (signal?.aborted) {
204
+ reject(new Error("Operation aborted"));
205
+ return;
206
+ }
207
+ let settled = false;
208
+ let stopChild;
209
+ const settle = (fn) => {
210
+ if (settled)
211
+ return;
212
+ settled = true;
213
+ signal?.removeEventListener("abort", onAbort);
214
+ stopChild = undefined;
215
+ fn();
216
+ };
217
+ const onAbort = () => {
218
+ stopChild?.();
219
+ settle(() => reject(new Error("Operation aborted")));
220
+ };
221
+ signal?.addEventListener("abort", onAbort, { once: true });
222
+ (async () => {
223
+ try {
224
+ const searchPath = resolveToCwd(searchDir || ".", cwd);
225
+ const effectiveLimit = limit ?? DEFAULT_LIMIT;
226
+ const ops = customOps ?? defaultFindOperations;
227
+ // If custom operations provide glob(), use that instead of fd.
228
+ if (customOps?.glob) {
229
+ if (!(await ops.exists(searchPath))) {
230
+ settle(() => reject(new Error(`Path not found: ${searchPath}`)));
231
+ return;
232
+ }
233
+ if (signal?.aborted) {
234
+ settle(() => reject(new Error("Operation aborted")));
235
+ return;
236
+ }
237
+ const results = await ops.glob(pattern, searchPath, {
238
+ ignore: ["**/node_modules/**", "**/.git/**"],
239
+ limit: effectiveLimit,
240
+ });
241
+ if (signal?.aborted) {
242
+ settle(() => reject(new Error("Operation aborted")));
243
+ return;
244
+ }
245
+ if (results.length === 0) {
246
+ settle(() => resolve({
247
+ content: [{ type: "text", text: "No files found matching pattern" }],
248
+ details: undefined,
249
+ }));
250
+ return;
251
+ }
252
+ // Relativize paths against the search root for stable output.
253
+ const relativized = results.map((p) => {
254
+ if (p.startsWith(searchPath))
255
+ return toPosixPath(p.slice(searchPath.length + 1));
256
+ return toPosixPath(path.relative(searchPath, p));
257
+ });
258
+ const resultLimitReached = relativized.length >= effectiveLimit;
259
+ const rawOutput = relativized.join("\n");
260
+ const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
261
+ let resultOutput = truncation.content;
262
+ const details = {};
263
+ const notices = [];
264
+ if (resultLimitReached) {
265
+ notices.push(`${effectiveLimit} results limit reached`);
266
+ details.resultLimitReached = effectiveLimit;
267
+ }
268
+ if (truncation.truncated) {
269
+ notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
270
+ details.truncation = truncation;
271
+ }
272
+ if (notices.length > 0) {
273
+ resultOutput += `\n\n[${notices.join(". ")}]`;
274
+ }
275
+ settle(() => resolve({
276
+ content: [{ type: "text", text: resultOutput }],
277
+ details: Object.keys(details).length > 0 ? details : undefined,
278
+ }));
279
+ return;
280
+ }
281
+ // Default implementation uses fd.
282
+ const fdPath = await ensureTool("fd", true);
283
+ if (signal?.aborted) {
284
+ settle(() => reject(new Error("Operation aborted")));
285
+ return;
286
+ }
287
+ if (!fdPath) {
288
+ if (!existsSync(searchPath)) {
289
+ settle(() => reject(new Error(`Path not found: ${searchPath}`)));
290
+ return;
291
+ }
292
+ try {
293
+ const results = findWithNode(pattern, searchPath, effectiveLimit);
294
+ if (results.length === 0) {
295
+ settle(() => resolve({
296
+ content: [{ type: "text", text: "No files found matching pattern" }],
297
+ details: undefined,
298
+ }));
299
+ return;
300
+ }
301
+ const resultLimitReached = results.length >= effectiveLimit;
302
+ const rawOutput = results.join("\n");
303
+ const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
304
+ let resultOutput = truncation.content;
305
+ const details = {};
306
+ const notices = [];
307
+ if (resultLimitReached) {
308
+ notices.push(`${effectiveLimit} results limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`);
309
+ details.resultLimitReached = effectiveLimit;
310
+ }
311
+ if (truncation.truncated) {
312
+ notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
313
+ details.truncation = truncation;
314
+ }
315
+ if (notices.length > 0) {
316
+ resultOutput += `\n\n[${notices.join(". ")}]`;
317
+ }
318
+ settle(() => resolve({
319
+ content: [{ type: "text", text: resultOutput }],
320
+ details: Object.keys(details).length > 0 ? details : undefined,
321
+ }));
322
+ }
323
+ catch (error) {
324
+ const message = error instanceof Error ? error.message : String(error);
325
+ settle(() => reject(new Error(message)));
326
+ }
327
+ return;
328
+ }
329
+ // Build fd arguments. --no-require-git makes fd apply hierarchical .gitignore
330
+ // semantics whether or not the search path is inside a git repository, without
331
+ // leaking sibling-directory rules the way --ignore-file (a global source) would.
332
+ const args = [
333
+ "--glob",
334
+ "--color=never",
335
+ "--hidden",
336
+ "--no-require-git",
337
+ "--max-results",
338
+ String(effectiveLimit),
339
+ ];
340
+ // fd --glob matches against the basename unless --full-path is set; in --full-path
341
+ // mode it matches against the absolute candidate path, so a path-containing
342
+ // pattern like 'src/**/*.spec.ts' needs a leading '**/' to match anything.
343
+ let effectivePattern = pattern;
344
+ if (pattern.includes("/")) {
345
+ args.push("--full-path");
346
+ if (!pattern.startsWith("/") && !pattern.startsWith("**/") && pattern !== "**") {
347
+ effectivePattern = `**/${pattern}`;
348
+ }
349
+ }
350
+ args.push(effectivePattern, searchPath);
351
+ const child = spawn(fdPath, args, { stdio: ["ignore", "pipe", "pipe"] });
352
+ const rl = createInterface({ input: child.stdout });
353
+ let stderr = "";
354
+ const lines = [];
355
+ stopChild = () => {
356
+ if (!child.killed) {
357
+ child.kill();
358
+ }
359
+ };
360
+ const cleanup = () => {
361
+ rl.close();
362
+ };
363
+ child.stderr?.on("data", (chunk) => {
364
+ stderr += chunk.toString();
365
+ });
366
+ rl.on("line", (line) => {
367
+ lines.push(line);
368
+ });
369
+ child.on("error", (error) => {
370
+ cleanup();
371
+ settle(() => reject(new Error(`Failed to run fd: ${error.message}`)));
372
+ });
373
+ child.on("close", (code) => {
374
+ cleanup();
375
+ if (signal?.aborted) {
376
+ settle(() => reject(new Error("Operation aborted")));
377
+ return;
378
+ }
379
+ const output = lines.join("\n");
380
+ if (code !== 0) {
381
+ const errorMsg = stderr.trim() || `fd exited with code ${code}`;
382
+ if (!output) {
383
+ settle(() => reject(new Error(errorMsg)));
384
+ return;
385
+ }
386
+ }
387
+ if (!output) {
388
+ settle(() => resolve({
389
+ content: [{ type: "text", text: "No files found matching pattern" }],
390
+ details: undefined,
391
+ }));
392
+ return;
393
+ }
394
+ const relativized = [];
395
+ for (const rawLine of lines) {
396
+ const line = rawLine.replace(/\r$/, "").trim();
397
+ if (!line)
398
+ continue;
399
+ const hadTrailingSlash = line.endsWith("/") || line.endsWith("\\");
400
+ let relativePath = line;
401
+ if (line.startsWith(searchPath)) {
402
+ relativePath = line.slice(searchPath.length + 1);
403
+ }
404
+ else {
405
+ relativePath = path.relative(searchPath, line);
406
+ }
407
+ if (hadTrailingSlash && !relativePath.endsWith("/"))
408
+ relativePath += "/";
409
+ relativized.push(toPosixPath(relativePath));
410
+ }
411
+ const resultLimitReached = relativized.length >= effectiveLimit;
412
+ const rawOutput = relativized.join("\n");
413
+ const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
414
+ let resultOutput = truncation.content;
415
+ const details = {};
416
+ const notices = [];
417
+ if (resultLimitReached) {
418
+ notices.push(`${effectiveLimit} results limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`);
419
+ details.resultLimitReached = effectiveLimit;
420
+ }
421
+ if (truncation.truncated) {
422
+ notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
423
+ details.truncation = truncation;
424
+ }
425
+ if (notices.length > 0) {
426
+ resultOutput += `\n\n[${notices.join(". ")}]`;
427
+ }
428
+ settle(() => resolve({
429
+ content: [{ type: "text", text: resultOutput }],
430
+ details: Object.keys(details).length > 0 ? details : undefined,
431
+ }));
432
+ });
433
+ }
434
+ catch (e) {
435
+ if (signal?.aborted) {
436
+ settle(() => reject(new Error("Operation aborted")));
437
+ return;
438
+ }
439
+ const error = e instanceof Error ? e : new Error(String(e));
440
+ settle(() => reject(error));
441
+ }
442
+ })();
443
+ });
444
+ },
445
+ renderCall(args, theme, context) {
446
+ const text = context.lastComponent ?? new Text("", 0, 0);
447
+ text.setText(formatFindCall(args, theme));
448
+ return text;
449
+ },
450
+ renderResult(result, options, theme, context) {
451
+ const text = context.lastComponent ?? new Text("", 0, 0);
452
+ text.setText(formatFindResult(result, options, theme, context.showImages));
453
+ return text;
454
+ },
455
+ };
456
+ }
457
+ export function createFindTool(cwd, options) {
458
+ return wrapToolDefinition(createFindToolDefinition(cwd, options));
459
+ }
@@ -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 grepSchema: import("@sinclair/typebox").TObject<{
6
+ pattern: import("@sinclair/typebox").TString;
7
+ path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
8
+ glob: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
9
+ ignoreCase: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
10
+ literal: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
11
+ context: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
12
+ limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
13
+ }>;
14
+ export type GrepToolInput = Static<typeof grepSchema>;
15
+ export interface GrepToolDetails {
16
+ truncation?: TruncationResult;
17
+ matchLimitReached?: number;
18
+ linesTruncated?: boolean;
19
+ }
20
+ /**
21
+ * Pluggable operations for the grep tool.
22
+ * Override these to delegate search to remote systems (for example SSH).
23
+ */
24
+ export interface GrepOperations {
25
+ /** Check if path is a directory. Throws if path does not exist. */
26
+ isDirectory: (absolutePath: string) => Promise<boolean> | boolean;
27
+ /** Read file contents for context lines */
28
+ readFile: (absolutePath: string) => Promise<string> | string;
29
+ }
30
+ export interface GrepToolOptions {
31
+ /** Custom operations for grep. Default: local filesystem plus ripgrep */
32
+ operations?: GrepOperations;
33
+ }
34
+ export declare function createGrepToolDefinition(cwd: string, options?: GrepToolOptions): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined>;
35
+ export declare function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema>;
36
+ export {};