@astralyn/pi 1.4.11 → 1.5.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 (546) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/dist/bundle/chunks/anthropic-messages-G5ZGBHOH.js +6 -0
  3. package/dist/bundle/chunks/azure-openai-responses-EMPTMYNF.js +2 -0
  4. package/dist/bundle/chunks/bedrock-converse-stream.js +22 -15
  5. package/dist/bundle/chunks/chunk-AXX7FFFD.js +2 -0
  6. package/dist/bundle/chunks/chunk-FNGB3ASD.js +2 -0
  7. package/dist/bundle/chunks/chunk-FPALVF3F.js +4 -0
  8. package/dist/bundle/chunks/chunk-H3UF54OB.js +9 -0
  9. package/dist/bundle/chunks/chunk-IC6JXX2J.js +10 -0
  10. package/dist/bundle/chunks/{chunk-TH3QDDPD.js → chunk-IRUUTK4W.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-MZJC45TM.js → chunk-J7L6O5XA.js} +3 -3
  12. package/dist/bundle/chunks/{chunk-DLVLAQEG.js → chunk-KBFO53OG.js} +3 -3
  13. package/dist/bundle/chunks/{chunk-TPVFPFJP.js → chunk-P7VXFB2M.js} +1 -1
  14. package/dist/bundle/chunks/chunk-PSYLMRL6.js +9 -0
  15. package/dist/bundle/chunks/chunk-QNZARXLE.js +82 -0
  16. package/dist/bundle/chunks/chunk-R3YHAMWH.js +1503 -0
  17. package/dist/bundle/chunks/chunk-RAIYJ5FC.js +4 -0
  18. package/dist/bundle/chunks/{chunk-OV2VMHBX.js → chunk-SR6EWNPW.js} +1 -1
  19. package/dist/bundle/chunks/chunk-TA3YH2ZI.js +16 -0
  20. package/dist/bundle/chunks/{chunk-NUQMVNKQ.js → chunk-THAJ4BZF.js} +58 -62
  21. package/dist/bundle/chunks/{chunk-24FY4C5S.js → chunk-TRSJS3FM.js} +1 -1
  22. package/dist/bundle/chunks/chunk-ZRI3ICDE.js +2 -0
  23. package/dist/bundle/chunks/{cli-MBFCFGI2.js → cli-LAZQG54B.js} +11 -9
  24. package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-7BKATOEJ.js → cloudflare-workers-ai-system-one-4L2ABUJE.js} +1 -1
  25. package/dist/bundle/chunks/{execute-VLAIP26K.js → execute-ACWDKC3C.js} +1 -1
  26. package/dist/bundle/chunks/github-copilot.js +1 -1
  27. package/dist/bundle/chunks/{google-generative-ai-HTUSU45F.js → google-generative-ai-OOVDGS5W.js} +1 -1
  28. package/dist/bundle/chunks/{google-vertex-AVQV4P76.js → google-vertex-IK5RNG7J.js} +1 -1
  29. package/dist/bundle/chunks/image-resize-worker.js +1 -1
  30. package/dist/bundle/chunks/kimi-coding.js +1 -1
  31. package/dist/bundle/chunks/{llama-cpp-classify-27QYLJZY.js → llama-cpp-classify-XHAVT37C.js} +1 -1
  32. package/dist/bundle/chunks/meta.js +1 -1
  33. package/dist/bundle/chunks/mistral-conversations-Z56KY4OJ.js +5 -0
  34. package/dist/bundle/chunks/{openai-codex-responses-Q25MHDFX.js → openai-codex-responses-5NAH3SK6.js} +1 -1
  35. package/dist/bundle/chunks/openai-completions-S7S6PO3J.js +7 -0
  36. package/dist/bundle/chunks/{openai-decisions-3WYFPGSK.js → openai-decisions-7A36EAHE.js} +1 -1
  37. package/dist/bundle/chunks/{openai-responses-E4BNZIQK.js → openai-responses-ZQRZJKH4.js} +1 -1
  38. package/dist/bundle/chunks/{openrouter-images-CBP3OPOD.js → openrouter-images-X7PX72ON.js} +1 -1
  39. package/dist/bundle/chunks/pi-messages-TXNWPLI4.js +8 -0
  40. package/dist/bundle/chunks/radius.js +1 -1
  41. package/dist/bundle/chunks/{runtime-3RPOJS5T.js → runtime-X3XOMNXQ.js} +1 -1
  42. package/dist/bundle/chunks/{typesafe-system-one-BNICP2LS.js → typesafe-system-one-XJGMSHWL.js} +1 -1
  43. package/dist/bundle/chunks/virtual-modules-T2KLVAFL.js +2 -0
  44. package/dist/bundle/cli.js +1 -1
  45. package/dist/bundle/index.js +1 -1
  46. package/dist/bundle/rpc-entry.js +1 -1
  47. package/dist/cli/args.d.ts.map +1 -1
  48. package/dist/cli/args.js +8 -7
  49. package/dist/cli/args.js.map +1 -1
  50. package/dist/config.d.ts +10 -0
  51. package/dist/config.d.ts.map +1 -1
  52. package/dist/config.js +24 -5
  53. package/dist/config.js.map +1 -1
  54. package/dist/core/agent-session-runtime.d.ts +0 -5
  55. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  56. package/dist/core/agent-session-runtime.js +12 -28
  57. package/dist/core/agent-session-runtime.js.map +1 -1
  58. package/dist/core/agent-session.d.ts +21 -14
  59. package/dist/core/agent-session.d.ts.map +1 -1
  60. package/dist/core/agent-session.js +67 -93
  61. package/dist/core/agent-session.js.map +1 -1
  62. package/dist/core/compaction/branch-summarization.d.ts +4 -2
  63. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  64. package/dist/core/compaction/branch-summarization.js +16 -4
  65. package/dist/core/compaction/branch-summarization.js.map +1 -1
  66. package/dist/core/exec.d.ts +9 -1
  67. package/dist/core/exec.d.ts.map +1 -1
  68. package/dist/core/exec.js +104 -60
  69. package/dist/core/exec.js.map +1 -1
  70. package/dist/core/export-html/template.css +9 -0
  71. package/dist/core/export-html/template.js +165 -45
  72. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  73. package/dist/core/export-html/tool-renderer.js +5 -0
  74. package/dist/core/export-html/tool-renderer.js.map +1 -1
  75. package/dist/core/extensions/index.d.ts +1 -1
  76. package/dist/core/extensions/index.d.ts.map +1 -1
  77. package/dist/core/extensions/index.js.map +1 -1
  78. package/dist/core/extensions/loader.d.ts.map +1 -1
  79. package/dist/core/extensions/loader.js +7 -6
  80. package/dist/core/extensions/loader.js.map +1 -1
  81. package/dist/core/extensions/pi-ai-extension-view.d.ts +19 -0
  82. package/dist/core/extensions/pi-ai-extension-view.d.ts.map +1 -0
  83. package/dist/core/extensions/pi-ai-extension-view.js +22 -0
  84. package/dist/core/extensions/pi-ai-extension-view.js.map +1 -0
  85. package/dist/core/extensions/runner.d.ts +0 -1
  86. package/dist/core/extensions/runner.d.ts.map +1 -1
  87. package/dist/core/extensions/runner.js +7 -12
  88. package/dist/core/extensions/runner.js.map +1 -1
  89. package/dist/core/extensions/types.d.ts +41 -23
  90. package/dist/core/extensions/types.d.ts.map +1 -1
  91. package/dist/core/extensions/types.js.map +1 -1
  92. package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
  93. package/dist/core/extensions/virtual-modules.js +8 -7
  94. package/dist/core/extensions/virtual-modules.js.map +1 -1
  95. package/dist/core/mcp-servers.d.ts +11 -4
  96. package/dist/core/mcp-servers.d.ts.map +1 -1
  97. package/dist/core/mcp-servers.js +15 -5
  98. package/dist/core/mcp-servers.js.map +1 -1
  99. package/dist/core/model-config.d.ts +1678 -2029
  100. package/dist/core/model-config.d.ts.map +1 -1
  101. package/dist/core/model-config.js +2 -3
  102. package/dist/core/model-config.js.map +1 -1
  103. package/dist/core/model-resolver.d.ts.map +1 -1
  104. package/dist/core/model-resolver.js +16 -10
  105. package/dist/core/model-resolver.js.map +1 -1
  106. package/dist/core/package-manager.d.ts +14 -0
  107. package/dist/core/package-manager.d.ts.map +1 -1
  108. package/dist/core/package-manager.js +160 -46
  109. package/dist/core/package-manager.js.map +1 -1
  110. package/dist/core/pi-ai-schemas.d.ts +163 -0
  111. package/dist/core/pi-ai-schemas.d.ts.map +1 -0
  112. package/dist/core/pi-ai-schemas.js +21 -0
  113. package/dist/core/pi-ai-schemas.js.map +1 -0
  114. package/dist/core/pi-manifest.d.ts +1 -0
  115. package/dist/core/pi-manifest.d.ts.map +1 -1
  116. package/dist/core/pi-manifest.js +4 -0
  117. package/dist/core/pi-manifest.js.map +1 -1
  118. package/dist/core/project-trust.js +1 -1
  119. package/dist/core/project-trust.js.map +1 -1
  120. package/dist/core/quiescence.d.ts +24 -0
  121. package/dist/core/quiescence.d.ts.map +1 -0
  122. package/dist/core/quiescence.js +81 -0
  123. package/dist/core/quiescence.js.map +1 -0
  124. package/dist/core/resource-loader.d.ts +4 -1
  125. package/dist/core/resource-loader.d.ts.map +1 -1
  126. package/dist/core/resource-loader.js +41 -28
  127. package/dist/core/resource-loader.js.map +1 -1
  128. package/dist/core/sdk.d.ts.map +1 -1
  129. package/dist/core/sdk.js +3 -1
  130. package/dist/core/sdk.js.map +1 -1
  131. package/dist/core/session-manager.d.ts +7 -0
  132. package/dist/core/session-manager.d.ts.map +1 -1
  133. package/dist/core/session-manager.js +32 -13
  134. package/dist/core/session-manager.js.map +1 -1
  135. package/dist/core/settings-manager.d.ts +2 -0
  136. package/dist/core/settings-manager.d.ts.map +1 -1
  137. package/dist/core/settings-manager.js +11 -0
  138. package/dist/core/settings-manager.js.map +1 -1
  139. package/dist/core/settings-schema.d.ts +4 -2
  140. package/dist/core/settings-schema.d.ts.map +1 -1
  141. package/dist/core/settings-schema.js +8 -1
  142. package/dist/core/settings-schema.js.map +1 -1
  143. package/dist/core/skills.d.ts.map +1 -1
  144. package/dist/core/skills.js +6 -14
  145. package/dist/core/skills.js.map +1 -1
  146. package/dist/core/slash-command-name.d.ts +6 -0
  147. package/dist/core/slash-command-name.d.ts.map +1 -0
  148. package/dist/core/slash-command-name.js +11 -0
  149. package/dist/core/slash-command-name.js.map +1 -0
  150. package/dist/core/slash-commands.js +2 -2
  151. package/dist/core/slash-commands.js.map +1 -1
  152. package/dist/core/source-info.d.ts +9 -0
  153. package/dist/core/source-info.d.ts.map +1 -1
  154. package/dist/core/source-info.js +13 -0
  155. package/dist/core/source-info.js.map +1 -1
  156. package/dist/core/system-prompt.d.ts.map +1 -1
  157. package/dist/core/system-prompt.js +5 -6
  158. package/dist/core/system-prompt.js.map +1 -1
  159. package/dist/core/tasks/codec.d.ts +14 -0
  160. package/dist/core/tasks/codec.d.ts.map +1 -1
  161. package/dist/core/tasks/codec.js +57 -4
  162. package/dist/core/tasks/codec.js.map +1 -1
  163. package/dist/core/tasks/record.d.ts +1 -7
  164. package/dist/core/tasks/record.d.ts.map +1 -1
  165. package/dist/core/tasks/record.js +0 -18
  166. package/dist/core/tasks/record.js.map +1 -1
  167. package/dist/core/tasks/reminder.d.ts +3 -2
  168. package/dist/core/tasks/reminder.d.ts.map +1 -1
  169. package/dist/core/tasks/reminder.js +4 -3
  170. package/dist/core/tasks/reminder.js.map +1 -1
  171. package/dist/core/tasks/runtime.d.ts +0 -2
  172. package/dist/core/tasks/runtime.d.ts.map +1 -1
  173. package/dist/core/tasks/runtime.js +2 -15
  174. package/dist/core/tasks/runtime.js.map +1 -1
  175. package/dist/core/tasks/session.d.ts +9 -2
  176. package/dist/core/tasks/session.d.ts.map +1 -1
  177. package/dist/core/tasks/session.js +23 -9
  178. package/dist/core/tasks/session.js.map +1 -1
  179. package/dist/core/tasks/types.d.ts +1 -18
  180. package/dist/core/tasks/types.d.ts.map +1 -1
  181. package/dist/core/tasks/types.js +1 -1
  182. package/dist/core/tasks/types.js.map +1 -1
  183. package/dist/core/tools/bash.d.ts +8 -7
  184. package/dist/core/tools/bash.d.ts.map +1 -1
  185. package/dist/core/tools/bash.js +6 -5
  186. package/dist/core/tools/bash.js.map +1 -1
  187. package/dist/core/tools/edit.d.ts +3 -3
  188. package/dist/core/tools/edit.d.ts.map +1 -1
  189. package/dist/core/tools/edit.js +2 -4
  190. package/dist/core/tools/edit.js.map +1 -1
  191. package/dist/core/tools/find.d.ts +2 -2
  192. package/dist/core/tools/find.d.ts.map +1 -1
  193. package/dist/core/tools/find.js.map +1 -1
  194. package/dist/core/tools/grep.d.ts +2 -2
  195. package/dist/core/tools/grep.d.ts.map +1 -1
  196. package/dist/core/tools/grep.js +1 -1
  197. package/dist/core/tools/grep.js.map +1 -1
  198. package/dist/core/tools/ls.d.ts +2 -2
  199. package/dist/core/tools/ls.d.ts.map +1 -1
  200. package/dist/core/tools/ls.js.map +1 -1
  201. package/dist/core/tools/powershell.d.ts +1 -5
  202. package/dist/core/tools/powershell.d.ts.map +1 -1
  203. package/dist/core/tools/read.d.ts +2 -2
  204. package/dist/core/tools/read.d.ts.map +1 -1
  205. package/dist/core/tools/read.js.map +1 -1
  206. package/dist/core/tools/render-utils.d.ts +4 -6
  207. package/dist/core/tools/render-utils.d.ts.map +1 -1
  208. package/dist/core/tools/render-utils.js +19 -41
  209. package/dist/core/tools/render-utils.js.map +1 -1
  210. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  211. package/dist/core/tools/renderers/bash.js +3 -25
  212. package/dist/core/tools/renderers/bash.js.map +1 -1
  213. package/dist/core/tools/renderers/write.d.ts.map +1 -1
  214. package/dist/core/tools/renderers/write.js +18 -19
  215. package/dist/core/tools/renderers/write.js.map +1 -1
  216. package/dist/core/tools/shell-execution.d.ts +20 -13
  217. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  218. package/dist/core/tools/shell-execution.js +165 -183
  219. package/dist/core/tools/shell-execution.js.map +1 -1
  220. package/dist/core/tools/shell-tool.d.ts +9 -14
  221. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  222. package/dist/core/tools/shell-tool.js +38 -66
  223. package/dist/core/tools/shell-tool.js.map +1 -1
  224. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -4
  225. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  226. package/dist/core/tools/tool-definition-wrapper.js +2 -3
  227. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  228. package/dist/core/tools/write.d.ts +2 -2
  229. package/dist/core/tools/write.d.ts.map +1 -1
  230. package/dist/core/tools/write.js.map +1 -1
  231. package/dist/core/trust-manager.d.ts.map +1 -1
  232. package/dist/core/trust-manager.js +30 -13
  233. package/dist/core/trust-manager.js.map +1 -1
  234. package/dist/core/usage-totals.d.ts +0 -9
  235. package/dist/core/usage-totals.d.ts.map +1 -1
  236. package/dist/core/usage-totals.js +24 -91
  237. package/dist/core/usage-totals.js.map +1 -1
  238. package/dist/extensions/agent/activity-lines.d.ts +2 -3
  239. package/dist/extensions/agent/activity-lines.d.ts.map +1 -1
  240. package/dist/extensions/agent/activity-lines.js +5 -9
  241. package/dist/extensions/agent/activity-lines.js.map +1 -1
  242. package/dist/extensions/agent/activity.d.ts +0 -2
  243. package/dist/extensions/agent/activity.d.ts.map +1 -1
  244. package/dist/extensions/agent/activity.js +1 -1
  245. package/dist/extensions/agent/activity.js.map +1 -1
  246. package/dist/extensions/agent/progress.d.ts +0 -3
  247. package/dist/extensions/agent/progress.d.ts.map +1 -1
  248. package/dist/extensions/agent/progress.js +2 -8
  249. package/dist/extensions/agent/progress.js.map +1 -1
  250. package/dist/extensions/agent/render.js +1 -1
  251. package/dist/extensions/agent/render.js.map +1 -1
  252. package/dist/extensions/agent/tool.d.ts.map +1 -1
  253. package/dist/extensions/agent/tool.js +0 -6
  254. package/dist/extensions/agent/tool.js.map +1 -1
  255. package/dist/{core/isolated-session.d.ts → extensions/agent/worker-session.d.ts} +6 -6
  256. package/dist/extensions/agent/worker-session.d.ts.map +1 -0
  257. package/dist/{core/isolated-session.js → extensions/agent/worker-session.js} +9 -9
  258. package/dist/extensions/agent/worker-session.js.map +1 -0
  259. package/dist/extensions/agent/worker.d.ts +0 -3
  260. package/dist/extensions/agent/worker.d.ts.map +1 -1
  261. package/dist/extensions/agent/worker.js +2 -3
  262. package/dist/extensions/agent/worker.js.map +1 -1
  263. package/dist/extensions/btw/agent.d.ts.map +1 -1
  264. package/dist/extensions/btw/agent.js +2 -1
  265. package/dist/extensions/btw/agent.js.map +1 -1
  266. package/dist/extensions/cached-compaction/render.d.ts.map +1 -1
  267. package/dist/extensions/cached-compaction/render.js +3 -3
  268. package/dist/extensions/cached-compaction/render.js.map +1 -1
  269. package/dist/extensions/codemode/renderer.d.ts.map +1 -1
  270. package/dist/extensions/codemode/renderer.js +6 -2
  271. package/dist/extensions/codemode/renderer.js.map +1 -1
  272. package/dist/extensions/codemode/tool.d.ts +2 -1
  273. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  274. package/dist/extensions/codemode/tool.js +33 -8
  275. package/dist/extensions/codemode/tool.js.map +1 -1
  276. package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
  277. package/dist/extensions/deepwiki/schema.js +1 -1
  278. package/dist/extensions/deepwiki/schema.js.map +1 -1
  279. package/dist/extensions/llama/ui.d.ts.map +1 -1
  280. package/dist/extensions/llama/ui.js +16 -4
  281. package/dist/extensions/llama/ui.js.map +1 -1
  282. package/dist/extensions/mcp/cli.d.ts.map +1 -1
  283. package/dist/extensions/mcp/cli.js +34 -8
  284. package/dist/extensions/mcp/cli.js.map +1 -1
  285. package/dist/extensions/mcp/oauth.d.ts +1 -1
  286. package/dist/extensions/mcp/oauth.d.ts.map +1 -1
  287. package/dist/extensions/mcp/oauth.js +36 -13
  288. package/dist/extensions/mcp/oauth.js.map +1 -1
  289. package/dist/extensions/mcp/ui.d.ts +1 -0
  290. package/dist/extensions/mcp/ui.d.ts.map +1 -1
  291. package/dist/extensions/mcp/ui.js +33 -24
  292. package/dist/extensions/mcp/ui.js.map +1 -1
  293. package/dist/extensions/run-summary/index.d.ts +1 -1
  294. package/dist/extensions/run-summary/index.d.ts.map +1 -1
  295. package/dist/extensions/run-summary/index.js +11 -23
  296. package/dist/extensions/run-summary/index.js.map +1 -1
  297. package/dist/extensions/statusline/usage.d.ts.map +1 -1
  298. package/dist/extensions/statusline/usage.js +2 -1
  299. package/dist/extensions/statusline/usage.js.map +1 -1
  300. package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
  301. package/dist/extensions/tasks/tool/schema.js +1 -1
  302. package/dist/extensions/tasks/tool/schema.js.map +1 -1
  303. package/dist/extensions/tasks/ui/completion-render.d.ts +5 -1
  304. package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
  305. package/dist/extensions/tasks/ui/completion-render.js +25 -70
  306. package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
  307. package/dist/extensions/tasks/ui/inspector.d.ts +1 -1
  308. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
  309. package/dist/extensions/tasks/ui/inspector.js +0 -6
  310. package/dist/extensions/tasks/ui/inspector.js.map +1 -1
  311. package/dist/extensions/tasks/ui/manager.d.ts +1 -1
  312. package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
  313. package/dist/extensions/tasks/ui/manager.js.map +1 -1
  314. package/dist/extensions/tasks/ui/views.d.ts +2 -4
  315. package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
  316. package/dist/extensions/tasks/ui/views.js +3 -7
  317. package/dist/extensions/tasks/ui/views.js.map +1 -1
  318. package/dist/extensions/tool-presentation/fallback.d.ts.map +1 -0
  319. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/fallback.js +5 -5
  320. package/dist/extensions/tool-presentation/fallback.js.map +1 -0
  321. package/dist/extensions/tool-presentation/index.js +1 -1
  322. package/dist/extensions/tool-presentation/index.js.map +1 -1
  323. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/shell.d.ts +1 -1
  324. package/dist/extensions/tool-presentation/shell.d.ts.map +1 -0
  325. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/shell.js +3 -3
  326. package/dist/extensions/tool-presentation/shell.js.map +1 -0
  327. package/dist/extensions/tool-search/tool.d.ts +21 -6
  328. package/dist/extensions/tool-search/tool.d.ts.map +1 -1
  329. package/dist/extensions/tool-search/tool.js +104 -36
  330. package/dist/extensions/tool-search/tool.js.map +1 -1
  331. package/dist/index.d.ts +2 -2
  332. package/dist/index.d.ts.map +1 -1
  333. package/dist/index.js.map +1 -1
  334. package/dist/main.d.ts.map +1 -1
  335. package/dist/main.js +15 -8
  336. package/dist/main.js.map +1 -1
  337. package/dist/modes/interactive/components/assistant-message.d.ts +5 -3
  338. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  339. package/dist/modes/interactive/components/assistant-message.js +61 -45
  340. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  341. package/dist/modes/interactive/components/config-selector-skills.d.ts +54 -0
  342. package/dist/modes/interactive/components/config-selector-skills.d.ts.map +1 -0
  343. package/dist/modes/interactive/components/config-selector-skills.js +178 -0
  344. package/dist/modes/interactive/components/config-selector-skills.js.map +1 -0
  345. package/dist/modes/interactive/components/config-selector.d.ts +2 -11
  346. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  347. package/dist/modes/interactive/components/config-selector.js +31 -181
  348. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  349. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  350. package/dist/modes/interactive/components/custom-editor.js +7 -0
  351. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  352. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  353. package/dist/modes/interactive/components/custom-entry.js +2 -1
  354. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  355. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  356. package/dist/modes/interactive/components/custom-message.js +2 -1
  357. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  358. package/dist/modes/interactive/components/extension-editor.d.ts +2 -0
  359. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  360. package/dist/modes/interactive/components/extension-editor.js +4 -0
  361. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  362. package/dist/modes/interactive/components/login-dialog.d.ts +5 -0
  363. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  364. package/dist/modes/interactive/components/login-dialog.js +103 -10
  365. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  366. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -1
  367. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
  368. package/dist/modes/interactive/components/markdown-transform.js +3 -2
  369. package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
  370. package/dist/modes/interactive/components/model-selector.d.ts +1 -0
  371. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  372. package/dist/modes/interactive/components/model-selector.js +17 -6
  373. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  374. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -0
  375. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  376. package/dist/modes/interactive/components/oauth-selector.js +13 -4
  377. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  378. package/dist/modes/interactive/components/scoped-models-selector.d.ts +1 -0
  379. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  380. package/dist/modes/interactive/components/scoped-models-selector.js +14 -3
  381. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  382. package/dist/modes/interactive/components/session-selector-search.d.ts +4 -0
  383. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  384. package/dist/modes/interactive/components/session-selector-search.js +86 -22
  385. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  386. package/dist/modes/interactive/components/session-selector.d.ts +2 -1
  387. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  388. package/dist/modes/interactive/components/session-selector.js +15 -23
  389. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  390. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
  391. package/dist/modes/interactive/components/settings-submenu.js +2 -0
  392. package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
  393. package/dist/modes/interactive/components/tool-execution.d.ts +7 -0
  394. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  395. package/dist/modes/interactive/components/tool-execution.js +48 -9
  396. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  397. package/dist/modes/interactive/components/tree-selector.d.ts +1 -0
  398. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  399. package/dist/modes/interactive/components/tree-selector.js +5 -6
  400. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  401. package/dist/modes/interactive/components/user-message-selector.d.ts +1 -0
  402. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  403. package/dist/modes/interactive/components/user-message-selector.js +9 -1
  404. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  405. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  406. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  407. package/dist/modes/interactive/components/user-message.js +4 -2
  408. package/dist/modes/interactive/components/user-message.js.map +1 -1
  409. package/dist/modes/interactive/editor-host.d.ts.map +1 -1
  410. package/dist/modes/interactive/editor-host.js +3 -2
  411. package/dist/modes/interactive/editor-host.js.map +1 -1
  412. package/dist/modes/interactive/external-editor.d.ts +1 -0
  413. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  414. package/dist/modes/interactive/external-editor.js +17 -5
  415. package/dist/modes/interactive/external-editor.js.map +1 -1
  416. package/dist/modes/interactive/interactive-mode.d.ts +8 -12
  417. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  418. package/dist/modes/interactive/interactive-mode.js +169 -112
  419. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  420. package/dist/modes/interactive/model-search.d.ts +10 -0
  421. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  422. package/dist/modes/interactive/model-search.js +21 -0
  423. package/dist/modes/interactive/model-search.js.map +1 -1
  424. package/dist/modes/interactive/theme/theme.d.ts +10 -0
  425. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  426. package/dist/modes/interactive/theme/theme.js +30 -23
  427. package/dist/modes/interactive/theme/theme.js.map +1 -1
  428. package/dist/modes/interactive/tool-view/chat.d.ts +2 -2
  429. package/dist/modes/interactive/tool-view/chat.d.ts.map +1 -1
  430. package/dist/modes/interactive/tool-view/chat.js +22 -19
  431. package/dist/modes/interactive/tool-view/chat.js.map +1 -1
  432. package/dist/modes/interactive/transcript-layout.d.ts +2 -0
  433. package/dist/modes/interactive/transcript-layout.d.ts.map +1 -1
  434. package/dist/modes/interactive/transcript-layout.js +5 -2
  435. package/dist/modes/interactive/transcript-layout.js.map +1 -1
  436. package/dist/modes/rpc/rpc-client.d.ts +9 -1
  437. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  438. package/dist/modes/rpc/rpc-client.js +23 -23
  439. package/dist/modes/rpc/rpc-client.js.map +1 -1
  440. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  441. package/dist/modes/rpc/rpc-mode.js +0 -3
  442. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  443. package/dist/package-manager-cli.d.ts.map +1 -1
  444. package/dist/package-manager-cli.js +55 -4
  445. package/dist/package-manager-cli.js.map +1 -1
  446. package/dist/utils/ansi.d.ts.map +1 -1
  447. package/dist/utils/ansi.js +5 -2
  448. package/dist/utils/ansi.js.map +1 -1
  449. package/dist/utils/clipboard-command.d.ts.map +1 -1
  450. package/dist/utils/clipboard-command.js +4 -0
  451. package/dist/utils/clipboard-command.js.map +1 -1
  452. package/dist/utils/git.d.ts +1 -1
  453. package/dist/utils/git.d.ts.map +1 -1
  454. package/dist/utils/git.js.map +1 -1
  455. package/dist/utils/image-resize-core.d.ts.map +1 -1
  456. package/dist/utils/image-resize-core.js +5 -3
  457. package/dist/utils/image-resize-core.js.map +1 -1
  458. package/dist/utils/open-browser.d.ts.map +1 -1
  459. package/dist/utils/open-browser.js +4 -1
  460. package/dist/utils/open-browser.js.map +1 -1
  461. package/dist/utils/paths.d.ts +17 -0
  462. package/dist/utils/paths.d.ts.map +1 -1
  463. package/dist/utils/paths.js +42 -1
  464. package/dist/utils/paths.js.map +1 -1
  465. package/dist/utils/shell.d.ts.map +1 -1
  466. package/dist/utils/shell.js +14 -0
  467. package/dist/utils/shell.js.map +1 -1
  468. package/dist/utils/syntax-highlight.d.ts +5 -0
  469. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  470. package/dist/utils/syntax-highlight.js +7 -0
  471. package/dist/utils/syntax-highlight.js.map +1 -1
  472. package/dist/utils/tools-manager.d.ts.map +1 -1
  473. package/dist/utils/tools-manager.js +30 -35
  474. package/dist/utils/tools-manager.js.map +1 -1
  475. package/dist/utils/usage.d.ts +5 -0
  476. package/dist/utils/usage.d.ts.map +1 -0
  477. package/dist/utils/usage.js +16 -0
  478. package/dist/utils/usage.js.map +1 -0
  479. package/docs/bundled/README.md +1 -1
  480. package/docs/bundled/extensions/agent.md +5 -5
  481. package/docs/bundled/extensions/run-summary.md +4 -4
  482. package/docs/bundled/tasks.md +2 -4
  483. package/docs/bundled/tool-presentation.md +2 -2
  484. package/docs/custom-provider.md +1 -1
  485. package/docs/environment-variables.md +2 -0
  486. package/docs/extensions.md +36 -21
  487. package/docs/keybindings.md +1 -1
  488. package/docs/llama-cpp.md +17 -12
  489. package/docs/mcp.md +6 -4
  490. package/docs/packages.md +26 -1
  491. package/docs/rpc.md +1 -1
  492. package/docs/sdk.md +7 -5
  493. package/docs/session-format.md +2 -2
  494. package/docs/sessions.md +10 -0
  495. package/docs/settings.md +5 -4
  496. package/docs/terminal-setup.md +2 -2
  497. package/docs/tmux.md +6 -0
  498. package/docs/tui.md +12 -7
  499. package/docs/usage.md +19 -9
  500. package/docs/windows.md +29 -0
  501. package/examples/extensions/README.md +2 -1
  502. package/examples/extensions/custom-provider-anthropic/index.ts +27 -31
  503. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  504. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  505. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  506. package/examples/extensions/debug-provider.ts +2 -2
  507. package/examples/extensions/gondolin/package-lock.json +19 -29
  508. package/examples/extensions/gondolin/package.json +2 -2
  509. package/examples/extensions/preset.ts +2 -0
  510. package/examples/extensions/reload-runtime.ts +17 -5
  511. package/examples/extensions/tools.ts +2 -0
  512. package/examples/extensions/with-deps/package-lock.json +2 -2
  513. package/examples/extensions/with-deps/package.json +1 -1
  514. package/package.json +9 -9
  515. package/schemas/models.schema.json +36 -36
  516. package/schemas/settings.schema.json +17 -0
  517. package/dist/bundle/chunks/anthropic-messages-HWL6AS7T.js +0 -6
  518. package/dist/bundle/chunks/azure-openai-responses-4YYPDYV5.js +0 -2
  519. package/dist/bundle/chunks/chunk-6JS2SOFO.js +0 -11
  520. package/dist/bundle/chunks/chunk-ANCZPKX7.js +0 -2
  521. package/dist/bundle/chunks/chunk-FEZ5RM2B.js +0 -2
  522. package/dist/bundle/chunks/chunk-LPF7HQ3S.js +0 -4
  523. package/dist/bundle/chunks/chunk-MMNIHCU7.js +0 -2
  524. package/dist/bundle/chunks/chunk-PUU43PDV.js +0 -1484
  525. package/dist/bundle/chunks/chunk-R267VV5T.js +0 -82
  526. package/dist/bundle/chunks/chunk-RVKT7OUB.js +0 -9
  527. package/dist/bundle/chunks/chunk-SA2AQYEI.js +0 -7
  528. package/dist/bundle/chunks/chunk-ZAIGBRV5.js +0 -16
  529. package/dist/bundle/chunks/mistral-conversations-V2JJTMJ5.js +0 -5
  530. package/dist/bundle/chunks/openai-completions-TXZXILJR.js +0 -7
  531. package/dist/bundle/chunks/pi-messages-LBJQ4NGP.js +0 -8
  532. package/dist/bundle/chunks/virtual-modules-63XNTSVN.js +0 -2
  533. package/dist/core/isolated-session.d.ts.map +0 -1
  534. package/dist/core/isolated-session.js.map +0 -1
  535. package/dist/modes/interactive/tool-view/fallback.d.ts.map +0 -1
  536. package/dist/modes/interactive/tool-view/fallback.js.map +0 -1
  537. package/dist/modes/interactive/tool-view/shell.d.ts.map +0 -1
  538. package/dist/modes/interactive/tool-view/shell.js.map +0 -1
  539. package/dist/utils/path-identity.d.ts +0 -12
  540. package/dist/utils/path-identity.d.ts.map +0 -1
  541. package/dist/utils/path-identity.js +0 -63
  542. package/dist/utils/path-identity.js.map +0 -1
  543. package/examples/extensions/sandbox/index.ts +0 -321
  544. package/examples/extensions/sandbox/package-lock.json +0 -92
  545. package/examples/extensions/sandbox/package.json +0 -19
  546. /package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/fallback.d.ts +0 -0
@@ -1,6 +1,6 @@
1
- import type { AgentTool } from "@earendil-works/pi-agent-core";
2
1
  import { type Static, Type } from "typebox";
3
2
  import type { ToolDefinition } from "../extensions/types.ts";
3
+ import { type TypeBoxAgentTool } from "./tool-definition-wrapper.ts";
4
4
  import { type TruncationResult } from "./truncate.ts";
5
5
  declare const lsSchema: Type.TObject<{
6
6
  path: Type.TOptional<Type.TString>;
@@ -36,6 +36,6 @@ export interface LsToolOptions {
36
36
  operations?: LsOperations;
37
37
  }
38
38
  export declare function createLsToolDefinition(cwd: string, options?: LsToolOptions): ToolDefinition<typeof lsSchema, LsToolDetails | undefined>;
39
- export declare function createLsTool(cwd: string, options?: LsToolOptions): AgentTool<typeof lsSchema>;
39
+ export declare function createLsTool(cwd: string, options?: LsToolOptions): TypeBoxAgentTool<typeof lsSchema>;
40
40
  export {};
41
41
  //# sourceMappingURL=ls.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../../src/core/tools/ls.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAI/E,OAAO,EAAiC,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAEnG,QAAA,MAAM,QAAQ;;;EAGZ,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;CAGjC,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAC;AAIlD,MAAM,WAAW,aAAa;IAC7B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,2BAA2B;IAC3B,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7D,wDAAwD;IACxD,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,OAAO,CAAA;KAAE,CAAC,GAAG;QAAE,WAAW,EAAE,MAAM,OAAO,CAAA;KAAE,CAAC;IACzG,6BAA6B;IAC7B,OAAO,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC;CAChE;AAQD,MAAM,WAAW,aAAa;IAC7B,yEAAyE;IACzE,UAAU,CAAC,EAAE,YAAY,CAAC;CAC1B;AAED,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,aAAa,GACrB,cAAc,CAAC,OAAO,QAAQ,EAAE,aAAa,GAAG,SAAS,CAAC,CAkH5D;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC,OAAO,QAAQ,CAAC,CAE7F"}
1
+ {"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../../src/core/tools/ls.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG/E,OAAO,EAAE,KAAK,gBAAgB,EAAsB,MAAM,8BAA8B,CAAC;AACzF,OAAO,EAAiC,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAEnG,QAAA,MAAM,QAAQ;;;EAGZ,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;CAGjC,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAC;AAIlD,MAAM,WAAW,aAAa;IAC7B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,2BAA2B;IAC3B,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7D,wDAAwD;IACxD,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,OAAO,CAAA;KAAE,CAAC,GAAG;QAAE,WAAW,EAAE,MAAM,OAAO,CAAA;KAAE,CAAC;IACzG,6BAA6B;IAC7B,OAAO,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC;CAChE;AAQD,MAAM,WAAW,aAAa;IAC7B,yEAAyE;IACzE,UAAU,CAAC,EAAE,YAAY,CAAC;CAC1B;AAED,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,aAAa,GACrB,cAAc,CAAC,OAAO,QAAQ,EAAE,aAAa,GAAG,SAAS,CAAC,CAkH5D;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,gBAAgB,CAAC,OAAO,QAAQ,CAAC,CAEpG"}
@@ -1 +1 @@
1
- {"version":3,"file":"ls.js","sourceRoot":"","sources":["../../../src/core/tools/ls.ts"],"names":[],"mappings":"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","sourcesContent":["import { readdir as fsReaddir, stat as fsStat } from \"node:fs/promises\";\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport nodePath from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { ExtensionContext, ToolDefinition } from \"../extensions/types.ts\";\nimport { pathExists, resolveToCwd } from \"./path-utils.ts\";\nimport { lsRenderers } from \"./renderers/ls.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\n\nconst lsSchema = Type.Object({\n\tpath: Type.Optional(Type.String({ description: \"Directory to list (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of entries to return (default: 500)\" })),\n});\n\nexport const lsToolSystemPromptContribution = {\n\tsnippet: \"List directory contents\",\n\tguidelines: [],\n} as const;\n\nexport type LsToolInput = Static<typeof lsSchema>;\n\nconst DEFAULT_LIMIT = 500;\n\nexport interface LsToolDetails {\n\ttruncation?: TruncationResult;\n\tentryLimitReached?: number;\n}\n\n/**\n * Pluggable operations for the ls tool.\n * Override these to delegate directory listing to remote systems (for example SSH).\n */\nexport interface LsOperations {\n\t/** Check if path exists */\n\texists: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Get file or directory stats. Throws if not found. */\n\tstat: (absolutePath: string) => Promise<{ isDirectory: () => boolean }> | { isDirectory: () => boolean };\n\t/** Read directory entries */\n\treaddir: (absolutePath: string) => Promise<string[]> | string[];\n}\n\nconst defaultLsOperations: LsOperations = {\n\texists: pathExists,\n\tstat: fsStat,\n\treaddir: fsReaddir,\n};\n\nexport interface LsToolOptions {\n\t/** Custom operations for directory listing. Default: local filesystem */\n\toperations?: LsOperations;\n}\n\nexport function createLsToolDefinition(\n\tcwd: string,\n\toptions?: LsToolOptions,\n): ToolDefinition<typeof lsSchema, LsToolDetails | undefined> {\n\tconst ops = options?.operations ?? defaultLsOperations;\n\treturn {\n\t\tname: \"ls\",\n\t\tlabel: \"ls\",\n\t\tdescription: `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).`,\n\t\tpromptSnippet: lsToolSystemPromptContribution.snippet,\n\t\tparameters: lsSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ path, limit }: { path?: string; limit?: number },\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\tctx?: ExtensionContext,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst onAbort = () => reject(new Error(\"Operation aborted\"));\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst dirPath = resolveToCwd(path || \".\", ctx?.cwd || cwd);\n\t\t\t\t\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\n\n\t\t\t\t\t\t// Check if path exists.\n\t\t\t\t\t\tif (!(await ops.exists(dirPath))) {\n\t\t\t\t\t\t\treject(new Error(`Path not found: ${dirPath}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Check if path is a directory.\n\t\t\t\t\t\tconst stat = await ops.stat(dirPath);\n\t\t\t\t\t\tif (!stat.isDirectory()) {\n\t\t\t\t\t\t\treject(new Error(`Not a directory: ${dirPath}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Read directory entries.\n\t\t\t\t\t\tlet entries: string[];\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tentries = await ops.readdir(dirPath);\n\t\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\t\treject(new Error(`Cannot read directory: ${e.message}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Sort alphabetically, case-insensitive.\n\t\t\t\t\t\tentries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));\n\n\t\t\t\t\t\t// Format entries with directory indicators.\n\t\t\t\t\t\tconst results: string[] = [];\n\t\t\t\t\t\tlet entryLimitReached = false;\n\t\t\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\t\t\tif (results.length >= effectiveLimit) {\n\t\t\t\t\t\t\t\tentryLimitReached = true;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst fullPath = nodePath.join(dirPath, entry);\n\t\t\t\t\t\t\tlet suffix = \"\";\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst entryStat = await ops.stat(fullPath);\n\t\t\t\t\t\t\t\tif (entryStat.isDirectory()) suffix = \"/\";\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// Skip entries we cannot stat.\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tresults.push(entry + suffix);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\n\t\t\t\t\t\tif (results.length === 0) {\n\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"(empty directory)\" }], details: undefined });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rawOutput = results.join(\"\\n\");\n\t\t\t\t\t\t// Apply byte truncation. There is no separate line limit because entry count is already capped.\n\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\tconst details: LsToolDetails = {};\n\t\t\t\t\t\t// Build actionable notices for truncation and entry limits.\n\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\tif (entryLimitReached) {\n\t\t\t\t\t\t\tnotices.push(`${effectiveLimit} entries limit reached. Use limit=${effectiveLimit * 2} for more`);\n\t\t\t\t\t\t\tdetails.entryLimitReached = effectiveLimit;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\toutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: output }],\n\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\treject(e);\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\t...lsRenderers,\n\t};\n}\n\nexport function createLsTool(cwd: string, options?: LsToolOptions): AgentTool<typeof lsSchema> {\n\treturn wrapToolDefinition(createLsToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"ls.js","sourceRoot":"","sources":["../../../src/core/tools/ls.ts"],"names":[],"mappings":"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","sourcesContent":["import { readdir as fsReaddir, stat as fsStat } from \"node:fs/promises\";\nimport nodePath from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { ExtensionContext, ToolDefinition } from \"../extensions/types.ts\";\nimport { pathExists, resolveToCwd } from \"./path-utils.ts\";\nimport { lsRenderers } from \"./renderers/ls.ts\";\nimport { type TypeBoxAgentTool, wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\n\nconst lsSchema = Type.Object({\n\tpath: Type.Optional(Type.String({ description: \"Directory to list (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of entries to return (default: 500)\" })),\n});\n\nexport const lsToolSystemPromptContribution = {\n\tsnippet: \"List directory contents\",\n\tguidelines: [],\n} as const;\n\nexport type LsToolInput = Static<typeof lsSchema>;\n\nconst DEFAULT_LIMIT = 500;\n\nexport interface LsToolDetails {\n\ttruncation?: TruncationResult;\n\tentryLimitReached?: number;\n}\n\n/**\n * Pluggable operations for the ls tool.\n * Override these to delegate directory listing to remote systems (for example SSH).\n */\nexport interface LsOperations {\n\t/** Check if path exists */\n\texists: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Get file or directory stats. Throws if not found. */\n\tstat: (absolutePath: string) => Promise<{ isDirectory: () => boolean }> | { isDirectory: () => boolean };\n\t/** Read directory entries */\n\treaddir: (absolutePath: string) => Promise<string[]> | string[];\n}\n\nconst defaultLsOperations: LsOperations = {\n\texists: pathExists,\n\tstat: fsStat,\n\treaddir: fsReaddir,\n};\n\nexport interface LsToolOptions {\n\t/** Custom operations for directory listing. Default: local filesystem */\n\toperations?: LsOperations;\n}\n\nexport function createLsToolDefinition(\n\tcwd: string,\n\toptions?: LsToolOptions,\n): ToolDefinition<typeof lsSchema, LsToolDetails | undefined> {\n\tconst ops = options?.operations ?? defaultLsOperations;\n\treturn {\n\t\tname: \"ls\",\n\t\tlabel: \"ls\",\n\t\tdescription: `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).`,\n\t\tpromptSnippet: lsToolSystemPromptContribution.snippet,\n\t\tparameters: lsSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ path, limit }: { path?: string; limit?: number },\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\tctx?: ExtensionContext,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst onAbort = () => reject(new Error(\"Operation aborted\"));\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst dirPath = resolveToCwd(path || \".\", ctx?.cwd || cwd);\n\t\t\t\t\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\n\n\t\t\t\t\t\t// Check if path exists.\n\t\t\t\t\t\tif (!(await ops.exists(dirPath))) {\n\t\t\t\t\t\t\treject(new Error(`Path not found: ${dirPath}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Check if path is a directory.\n\t\t\t\t\t\tconst stat = await ops.stat(dirPath);\n\t\t\t\t\t\tif (!stat.isDirectory()) {\n\t\t\t\t\t\t\treject(new Error(`Not a directory: ${dirPath}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Read directory entries.\n\t\t\t\t\t\tlet entries: string[];\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tentries = await ops.readdir(dirPath);\n\t\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\t\treject(new Error(`Cannot read directory: ${e.message}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Sort alphabetically, case-insensitive.\n\t\t\t\t\t\tentries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));\n\n\t\t\t\t\t\t// Format entries with directory indicators.\n\t\t\t\t\t\tconst results: string[] = [];\n\t\t\t\t\t\tlet entryLimitReached = false;\n\t\t\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\t\t\tif (results.length >= effectiveLimit) {\n\t\t\t\t\t\t\t\tentryLimitReached = true;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst fullPath = nodePath.join(dirPath, entry);\n\t\t\t\t\t\t\tlet suffix = \"\";\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst entryStat = await ops.stat(fullPath);\n\t\t\t\t\t\t\t\tif (entryStat.isDirectory()) suffix = \"/\";\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// Skip entries we cannot stat.\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tresults.push(entry + suffix);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\n\t\t\t\t\t\tif (results.length === 0) {\n\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"(empty directory)\" }], details: undefined });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rawOutput = results.join(\"\\n\");\n\t\t\t\t\t\t// Apply byte truncation. There is no separate line limit because entry count is already capped.\n\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\tconst details: LsToolDetails = {};\n\t\t\t\t\t\t// Build actionable notices for truncation and entry limits.\n\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\tif (entryLimitReached) {\n\t\t\t\t\t\t\tnotices.push(`${effectiveLimit} entries limit reached. Use limit=${effectiveLimit * 2} for more`);\n\t\t\t\t\t\t\tdetails.entryLimitReached = effectiveLimit;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\toutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: output }],\n\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\treject(e);\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\t...lsRenderers,\n\t};\n}\n\nexport function createLsTool(cwd: string, options?: LsToolOptions): TypeBoxAgentTool<typeof lsSchema> {\n\treturn wrapToolDefinition(createLsToolDefinition(cwd, options));\n}\n"]}
@@ -13,9 +13,5 @@ export interface PowerShellToolOptions extends Pick<BashToolOptions, "operations
13
13
  }
14
14
  export declare function createLocalPowerShellOperations(): PowerShellOperations;
15
15
  export declare function createPowerShellToolDefinition(cwd: string, options?: PowerShellToolOptions): ReturnType<typeof createShellToolDefinition>;
16
- export declare function createPowerShellTool(cwd: string, options?: PowerShellToolOptions): import("@earendil-works/pi-agent-core").AgentTool<import("typebox").TObject<{
17
- command: import("typebox").TString;
18
- timeout: import("typebox").TOptional<import("typebox").TNumber>;
19
- background: import("typebox").TOptional<import("typebox").TBoolean>;
20
- }>, BashToolDetails | undefined>;
16
+ export declare function createPowerShellTool(cwd: string, options?: PowerShellToolOptions): import("@earendil-works/pi-agent-core").AgentTool<any, BashToolDetails | undefined>;
21
17
  //# sourceMappingURL=powershell.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"powershell.d.ts","sourceRoot":"","sources":["../../../src/core/tools/powershell.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,EAGpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAKtG,eAAO,MAAM,sCAAsC;;;CAGzC,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAClD,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,CAAC;AACtD,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAChD,MAAM,MAAM,qBAAqB,GAAG,eAAe,CAAC;AACpD,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAEhD,MAAM,WAAW,qBAChB,SAAQ,IAAI,CAAC,eAAe,EAAE,YAAY,GAAG,0BAA0B,GAAG,WAAW,CAAC;CAAG;AAE1F,wBAAgB,+BAA+B,IAAI,oBAAoB,CAKtE;AAYD,wBAAgB,8BAA8B,CAC7C,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC7B,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAK9C;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;;;;iCAQhF"}
1
+ {"version":3,"file":"powershell.d.ts","sourceRoot":"","sources":["../../../src/core/tools/powershell.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,EAGpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAKtG,eAAO,MAAM,sCAAsC;;;CAGzC,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAClD,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,CAAC;AACtD,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAChD,MAAM,MAAM,qBAAqB,GAAG,eAAe,CAAC;AACpD,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAEhD,MAAM,WAAW,qBAChB,SAAQ,IAAI,CAAC,eAAe,EAAE,YAAY,GAAG,0BAA0B,GAAG,WAAW,CAAC;CAAG;AAE1F,wBAAgB,+BAA+B,IAAI,oBAAoB,CAKtE;AAYD,wBAAgB,8BAA8B,CAC7C,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC7B,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAK9C;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,uFAQhF"}
@@ -1,7 +1,7 @@
1
- import type { AgentTool } from "@earendil-works/pi-agent-core";
2
1
  import type { ModelImageResizeOptions } from "@earendil-works/pi-ai";
3
2
  import { type Static, Type } from "typebox";
4
3
  import type { ToolDefinition } from "../extensions/types.ts";
4
+ import { type TypeBoxAgentTool } from "./tool-definition-wrapper.ts";
5
5
  import { type TruncationResult } from "./truncate.ts";
6
6
  declare const readSchema: Type.TObject<{
7
7
  path: Type.TString;
@@ -50,6 +50,6 @@ export interface ReadToolOptions {
50
50
  operations?: ReadOperations;
51
51
  }
52
52
  export declare function createReadToolDefinition(cwd: string, options?: ReadToolOptions): ToolDefinition<typeof readSchema, ReadToolDetails | undefined>;
53
- export declare function createReadTool(cwd: string, options?: ReadToolOptions): AgentTool<typeof readSchema>;
53
+ export declare function createReadTool(cwd: string, options?: ReadToolOptions): TypeBoxAgentTool<typeof readSchema>;
54
54
  export {};
55
55
  //# sourceMappingURL=read.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/core/tools/read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAA4B,uBAAuB,EAAe,MAAM,uBAAuB,CAAC;AAG5G,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAI/E,OAAO,EAAoD,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAEtH,QAAA,MAAM,UAAU;;;;EAId,CAAC;AAEH,eAAO,MAAM,gCAAgC;;;CAGnC,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD;;;;;GAKG;AACH,QAAA,MAAM,gBAAgB;;;;;IAGpB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,qCAAqC;IACrC,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,+CAA+C;IAC/C,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,sEAAsE;IACtE,mBAAmB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CACnF;AAQD,MAAM,WAAW,eAAe;IAC/B,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gFAAgF;IAChF,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAgBD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAmIhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG"}
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/core/tools/read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA4B,uBAAuB,EAAe,MAAM,uBAAuB,CAAC;AAG5G,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG/E,OAAO,EAAE,KAAK,gBAAgB,EAAsB,MAAM,8BAA8B,CAAC;AACzF,OAAO,EAAoD,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAEtH,QAAA,MAAM,UAAU;;;;EAId,CAAC;AAEH,eAAO,MAAM,gCAAgC;;;CAGnC,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD;;;;;GAKG;AACH,QAAA,MAAM,gBAAgB;;;;;IAGpB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,qCAAqC;IACrC,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,+CAA+C;IAC/C,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,sEAAsE;IACtE,mBAAmB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CACnF;AAQD,MAAM,WAAW,eAAe;IAC/B,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gFAAgF;IAChF,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAgBD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAmIhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,gBAAgB,CAAC,OAAO,UAAU,CAAC,CAE1G"}
@@ -1 +1 @@
1
- {"version":3,"file":"read.js","sourceRoot":"","sources":["../../../src/core/tools/read.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport type { Api, ImageContent, Model, ModelImageResizeOptions, TextContent } from \"@earendil-works/pi-ai\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile } from \"fs/promises\";\nimport { type Static, Type } from \"typebox\";\nimport { processImage } from \"../../utils/image-process.ts\";\nimport { detectSupportedImageMimeTypeFromFile } from \"../../utils/mime.ts\";\nimport type { ExtensionContext, ToolDefinition } from \"../extensions/types.ts\";\nimport { resolveReadPathAsync } from \"./path-utils.ts\";\nimport { readRenderers } from \"./renderers/read.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\n\nconst readSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to read (relative or absolute)\" }),\n\toffset: Type.Optional(Type.Number({ description: \"Line number to start reading from (1-indexed)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of lines to read\" })),\n});\n\nexport const readToolSystemPromptContribution = {\n\tsnippet: \"Read file contents\",\n\tguidelines: [\"Use read to examine files instead of cat or sed.\"],\n} as const;\n\nexport type ReadToolInput = Static<typeof readSchema>;\n\n/**\n * Result for programmatic callers such as codemode scripts: the text for text files, and an image\n * block for images that codemode's `image()` accepts. `note` is the text that goes with the image,\n * such as resize hints. Property descriptions are left out so the type stays on one line in tool\n * descriptions.\n */\nconst readOutputSchema = Type.Union([\n\tType.String(),\n\tType.Object({ type: Type.Literal(\"image\"), data: Type.String(), mimeType: Type.String(), note: Type.String() }),\n]);\n\nexport type ReadToolOutput = Static<typeof readOutputSchema>;\n\nexport interface ReadToolDetails {\n\ttruncation?: TruncationResult;\n}\n\n/**\n * Pluggable operations for the read tool.\n * Override these to delegate file reading to remote systems (for example SSH).\n */\nexport interface ReadOperations {\n\t/** Read file contents as a Buffer */\n\treadFile: (absolutePath: string) => Promise<Buffer>;\n\t/** Check if file is readable (throw if not) */\n\taccess: (absolutePath: string) => Promise<void>;\n\t/** Detect image MIME type, return null or undefined for non-images */\n\tdetectImageMimeType?: (absolutePath: string) => Promise<string | null | undefined>;\n}\n\nconst defaultReadOperations: ReadOperations = {\n\treadFile: (path) => fsReadFile(path),\n\taccess: (path) => fsAccess(path, constants.R_OK),\n\tdetectImageMimeType: detectSupportedImageMimeTypeFromFile,\n};\n\nexport interface ReadToolOptions {\n\t/** Whether to auto-resize images. Default: true */\n\tautoResizeImages?: boolean;\n\t/** Fallback resize profile when the execution context has no model metadata. */\n\tresizeOptions?: ModelImageResizeOptions;\n\t/** Custom operations for file reading. Default: local filesystem */\n\toperations?: ReadOperations;\n}\n\n/** The image block and its note, or the text for text files and images that could not be processed. */\nfunction toReadOutput(content: (TextContent | ImageContent)[]): ReadToolOutput {\n\tconst text = content.find((block) => block.type === \"text\")?.text ?? \"\";\n\tconst image = content.find((block) => block.type === \"image\");\n\treturn image ? { type: \"image\", data: image.data, mimeType: image.mimeType, note: text } : text;\n}\n\nfunction getNonVisionImageNote(model: Model<Api> | undefined): string | undefined {\n\tif (!model || model.input.includes(\"image\")) {\n\t\treturn undefined;\n\t}\n\treturn \"[Current model does not support images. The image will be omitted from this request.]\";\n}\n\nexport function createReadToolDefinition(\n\tcwd: string,\n\toptions?: ReadToolOptions,\n): ToolDefinition<typeof readSchema, ReadToolDetails | undefined> {\n\tconst autoResizeImages = options?.autoResizeImages ?? true;\n\tconst fallbackResizeOptions = options?.resizeOptions;\n\tconst ops = options?.operations ?? defaultReadOperations;\n\treturn {\n\t\tname: \"read\",\n\t\tlabel: \"read\",\n\t\tdescription: `Read the contents of a file. Supports text files and images (jpg, png, gif, webp, bmp). Images are sent as attachments. For text files, output is truncated to ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.`,\n\t\tpromptSnippet: readToolSystemPromptContribution.snippet,\n\t\tpromptGuidelines: [...readToolSystemPromptContribution.guidelines],\n\t\tparameters: readSchema,\n\t\toutputSchema: readOutputSchema,\n\t\tconstrainedSampling: { type: \"json_schema\", strict: \"prefer\" },\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ path, offset, limit }: { path: string; offset?: number; limit?: number },\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\tctx?: ExtensionContext,\n\t\t) {\n\t\t\treturn new Promise<{ content: (TextContent | ImageContent)[]; details: ReadToolDetails | undefined }>(\n\t\t\t\t(resolve, reject) => {\n\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet aborted = false;\n\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t};\n\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t\t(async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst absolutePath = await resolveReadPathAsync(path, ctx?.cwd || cwd);\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\t// Check if file exists and is readable.\n\t\t\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\tconst mimeType = ops.detectImageMimeType ? await ops.detectImageMimeType(absolutePath) : undefined;\n\t\t\t\t\t\t\tlet content: (TextContent | ImageContent)[];\n\t\t\t\t\t\t\tlet details: ReadToolDetails | undefined;\n\t\t\t\t\t\t\tconst nonVisionImageNote = getNonVisionImageNote(ctx?.model);\n\t\t\t\t\t\t\tif (mimeType) {\n\t\t\t\t\t\t\t\t// Read image as binary.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tconst processed = await processImage(buffer, mimeType, {\n\t\t\t\t\t\t\t\t\tautoResizeImages,\n\t\t\t\t\t\t\t\t\tresizeOptions: ctx?.model?.inputLimits?.images?.resize ?? fallbackResizeOptions,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tif (!processed.ok) {\n\t\t\t\t\t\t\t\t\tlet textNote = `Read image file [${mimeType}]\\n${processed.message}`;\n\t\t\t\t\t\t\t\t\tif (nonVisionImageNote) textNote += `\\n${nonVisionImageNote}`;\n\t\t\t\t\t\t\t\t\tcontent = [{ type: \"text\", text: textNote }];\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tlet textNote = `Read image file [${processed.mimeType}]`;\n\t\t\t\t\t\t\t\t\tif (processed.hints.length > 0) textNote += `\\n${processed.hints.join(\"\\n\")}`;\n\t\t\t\t\t\t\t\t\tif (nonVisionImageNote) textNote += `\\n${nonVisionImageNote}`;\n\t\t\t\t\t\t\t\t\tcontent = [\n\t\t\t\t\t\t\t\t\t\t{ type: \"text\", text: textNote },\n\t\t\t\t\t\t\t\t\t\t{ type: \"image\", data: processed.data, mimeType: processed.mimeType },\n\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Read text content.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tconst textContent = buffer.toString(\"utf-8\");\n\t\t\t\t\t\t\t\tconst allLines = textContent.split(\"\\n\");\n\t\t\t\t\t\t\t\tconst totalFileLines = allLines.length;\n\t\t\t\t\t\t\t\t// Apply offset if specified. Convert from 1-indexed input to 0-indexed array access.\n\t\t\t\t\t\t\t\tconst startLine = offset ? Math.max(0, offset - 1) : 0;\n\t\t\t\t\t\t\t\tconst startLineDisplay = startLine + 1;\n\t\t\t\t\t\t\t\t// Check if offset is out of bounds.\n\t\t\t\t\t\t\t\tif (startLine >= allLines.length) {\n\t\t\t\t\t\t\t\t\tthrow new Error(`Offset ${offset} is beyond end of file (${allLines.length} lines total)`);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tlet selectedContent: string;\n\t\t\t\t\t\t\t\tlet userLimitedLines: number | undefined;\n\t\t\t\t\t\t\t\t// If limit is specified by the user, honor it first. Otherwise truncateHead decides.\n\t\t\t\t\t\t\t\tif (limit !== undefined) {\n\t\t\t\t\t\t\t\t\tconst endLine = Math.min(startLine + limit, allLines.length);\n\t\t\t\t\t\t\t\t\tselectedContent = allLines.slice(startLine, endLine).join(\"\\n\");\n\t\t\t\t\t\t\t\t\tuserLimitedLines = endLine - startLine;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tselectedContent = allLines.slice(startLine).join(\"\\n\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Apply truncation, respecting both line and byte limits.\n\t\t\t\t\t\t\t\tconst truncation = truncateHead(selectedContent);\n\t\t\t\t\t\t\t\tlet outputText: string;\n\t\t\t\t\t\t\t\tif (truncation.firstLineExceedsLimit) {\n\t\t\t\t\t\t\t\t\t// First line alone exceeds the byte limit. Point the model at a bash fallback.\n\t\t\t\t\t\t\t\t\tconst firstLineSize = formatSize(Buffer.byteLength(allLines[startLine], \"utf-8\"));\n\t\t\t\t\t\t\t\t\toutputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize(DEFAULT_MAX_BYTES)} limit. Use bash: sed -n '${startLineDisplay}p' ${path} | head -c ${DEFAULT_MAX_BYTES}]`;\n\t\t\t\t\t\t\t\t\tdetails = { truncation };\n\t\t\t\t\t\t\t\t} else if (truncation.truncated) {\n\t\t\t\t\t\t\t\t\t// Truncation occurred. Build an actionable continuation notice.\n\t\t\t\t\t\t\t\t\tconst endLineDisplay = startLineDisplay + truncation.outputLines - 1;\n\t\t\t\t\t\t\t\t\tconst nextOffset = endLineDisplay + 1;\n\t\t\t\t\t\t\t\t\toutputText = truncation.content;\n\t\t\t\t\t\t\t\t\tif (truncation.truncatedBy === \"lines\") {\n\t\t\t\t\t\t\t\t\t\toutputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines}. Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\toutputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tdetails = { truncation };\n\t\t\t\t\t\t\t\t} else if (userLimitedLines !== undefined && startLine + userLimitedLines < allLines.length) {\n\t\t\t\t\t\t\t\t\t// User-specified limit stopped early, but the file still has more content.\n\t\t\t\t\t\t\t\t\tconst remaining = allLines.length - (startLine + userLimitedLines);\n\t\t\t\t\t\t\t\t\tconst nextOffset = startLine + userLimitedLines + 1;\n\t\t\t\t\t\t\t\t\toutputText = `${truncation.content}\\n\\n[${remaining} more lines in file. Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// No truncation and no remaining user-limited content.\n\t\t\t\t\t\t\t\t\toutputText = truncation.content;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontent = [{ type: \"text\", text: outputText }];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tresolve({ content, details });\n\t\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tif (!aborted) reject(error);\n\t\t\t\t\t\t}\n\t\t\t\t\t})();\n\t\t\t\t},\n\t\t\t).then((result) => ({ ...result, structuredContent: toReadOutput(result.content) }));\n\t\t},\n\t\t...readRenderers,\n\t};\n}\n\nexport function createReadTool(cwd: string, options?: ReadToolOptions): AgentTool<typeof readSchema> {\n\treturn wrapToolDefinition(createReadToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../../src/core/tools/read.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, ImageContent, Model, ModelImageResizeOptions, TextContent } from \"@earendil-works/pi-ai\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile } from \"fs/promises\";\nimport { type Static, Type } from \"typebox\";\nimport { processImage } from \"../../utils/image-process.ts\";\nimport { detectSupportedImageMimeTypeFromFile } from \"../../utils/mime.ts\";\nimport type { ExtensionContext, ToolDefinition } from \"../extensions/types.ts\";\nimport { resolveReadPathAsync } from \"./path-utils.ts\";\nimport { readRenderers } from \"./renderers/read.ts\";\nimport { type TypeBoxAgentTool, wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\n\nconst readSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to read (relative or absolute)\" }),\n\toffset: Type.Optional(Type.Number({ description: \"Line number to start reading from (1-indexed)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of lines to read\" })),\n});\n\nexport const readToolSystemPromptContribution = {\n\tsnippet: \"Read file contents\",\n\tguidelines: [\"Use read to examine files instead of cat or sed.\"],\n} as const;\n\nexport type ReadToolInput = Static<typeof readSchema>;\n\n/**\n * Result for programmatic callers such as codemode scripts: the text for text files, and an image\n * block for images that codemode's `image()` accepts. `note` is the text that goes with the image,\n * such as resize hints. Property descriptions are left out so the type stays on one line in tool\n * descriptions.\n */\nconst readOutputSchema = Type.Union([\n\tType.String(),\n\tType.Object({ type: Type.Literal(\"image\"), data: Type.String(), mimeType: Type.String(), note: Type.String() }),\n]);\n\nexport type ReadToolOutput = Static<typeof readOutputSchema>;\n\nexport interface ReadToolDetails {\n\ttruncation?: TruncationResult;\n}\n\n/**\n * Pluggable operations for the read tool.\n * Override these to delegate file reading to remote systems (for example SSH).\n */\nexport interface ReadOperations {\n\t/** Read file contents as a Buffer */\n\treadFile: (absolutePath: string) => Promise<Buffer>;\n\t/** Check if file is readable (throw if not) */\n\taccess: (absolutePath: string) => Promise<void>;\n\t/** Detect image MIME type, return null or undefined for non-images */\n\tdetectImageMimeType?: (absolutePath: string) => Promise<string | null | undefined>;\n}\n\nconst defaultReadOperations: ReadOperations = {\n\treadFile: (path) => fsReadFile(path),\n\taccess: (path) => fsAccess(path, constants.R_OK),\n\tdetectImageMimeType: detectSupportedImageMimeTypeFromFile,\n};\n\nexport interface ReadToolOptions {\n\t/** Whether to auto-resize images. Default: true */\n\tautoResizeImages?: boolean;\n\t/** Fallback resize profile when the execution context has no model metadata. */\n\tresizeOptions?: ModelImageResizeOptions;\n\t/** Custom operations for file reading. Default: local filesystem */\n\toperations?: ReadOperations;\n}\n\n/** The image block and its note, or the text for text files and images that could not be processed. */\nfunction toReadOutput(content: (TextContent | ImageContent)[]): ReadToolOutput {\n\tconst text = content.find((block) => block.type === \"text\")?.text ?? \"\";\n\tconst image = content.find((block) => block.type === \"image\");\n\treturn image ? { type: \"image\", data: image.data, mimeType: image.mimeType, note: text } : text;\n}\n\nfunction getNonVisionImageNote(model: Model<Api> | undefined): string | undefined {\n\tif (!model || model.input.includes(\"image\")) {\n\t\treturn undefined;\n\t}\n\treturn \"[Current model does not support images. The image will be omitted from this request.]\";\n}\n\nexport function createReadToolDefinition(\n\tcwd: string,\n\toptions?: ReadToolOptions,\n): ToolDefinition<typeof readSchema, ReadToolDetails | undefined> {\n\tconst autoResizeImages = options?.autoResizeImages ?? true;\n\tconst fallbackResizeOptions = options?.resizeOptions;\n\tconst ops = options?.operations ?? defaultReadOperations;\n\treturn {\n\t\tname: \"read\",\n\t\tlabel: \"read\",\n\t\tdescription: `Read the contents of a file. Supports text files and images (jpg, png, gif, webp, bmp). Images are sent as attachments. For text files, output is truncated to ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.`,\n\t\tpromptSnippet: readToolSystemPromptContribution.snippet,\n\t\tpromptGuidelines: [...readToolSystemPromptContribution.guidelines],\n\t\tparameters: readSchema,\n\t\toutputSchema: readOutputSchema,\n\t\tconstrainedSampling: { type: \"json_schema\", strict: \"prefer\" },\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ path, offset, limit }: { path: string; offset?: number; limit?: number },\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\tctx?: ExtensionContext,\n\t\t) {\n\t\t\treturn new Promise<{ content: (TextContent | ImageContent)[]; details: ReadToolDetails | undefined }>(\n\t\t\t\t(resolve, reject) => {\n\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet aborted = false;\n\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t};\n\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t\t(async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst absolutePath = await resolveReadPathAsync(path, ctx?.cwd || cwd);\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\t// Check if file exists and is readable.\n\t\t\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\tconst mimeType = ops.detectImageMimeType ? await ops.detectImageMimeType(absolutePath) : undefined;\n\t\t\t\t\t\t\tlet content: (TextContent | ImageContent)[];\n\t\t\t\t\t\t\tlet details: ReadToolDetails | undefined;\n\t\t\t\t\t\t\tconst nonVisionImageNote = getNonVisionImageNote(ctx?.model);\n\t\t\t\t\t\t\tif (mimeType) {\n\t\t\t\t\t\t\t\t// Read image as binary.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tconst processed = await processImage(buffer, mimeType, {\n\t\t\t\t\t\t\t\t\tautoResizeImages,\n\t\t\t\t\t\t\t\t\tresizeOptions: ctx?.model?.inputLimits?.images?.resize ?? fallbackResizeOptions,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tif (!processed.ok) {\n\t\t\t\t\t\t\t\t\tlet textNote = `Read image file [${mimeType}]\\n${processed.message}`;\n\t\t\t\t\t\t\t\t\tif (nonVisionImageNote) textNote += `\\n${nonVisionImageNote}`;\n\t\t\t\t\t\t\t\t\tcontent = [{ type: \"text\", text: textNote }];\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tlet textNote = `Read image file [${processed.mimeType}]`;\n\t\t\t\t\t\t\t\t\tif (processed.hints.length > 0) textNote += `\\n${processed.hints.join(\"\\n\")}`;\n\t\t\t\t\t\t\t\t\tif (nonVisionImageNote) textNote += `\\n${nonVisionImageNote}`;\n\t\t\t\t\t\t\t\t\tcontent = [\n\t\t\t\t\t\t\t\t\t\t{ type: \"text\", text: textNote },\n\t\t\t\t\t\t\t\t\t\t{ type: \"image\", data: processed.data, mimeType: processed.mimeType },\n\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Read text content.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tconst textContent = buffer.toString(\"utf-8\");\n\t\t\t\t\t\t\t\tconst allLines = textContent.split(\"\\n\");\n\t\t\t\t\t\t\t\tconst totalFileLines = allLines.length;\n\t\t\t\t\t\t\t\t// Apply offset if specified. Convert from 1-indexed input to 0-indexed array access.\n\t\t\t\t\t\t\t\tconst startLine = offset ? Math.max(0, offset - 1) : 0;\n\t\t\t\t\t\t\t\tconst startLineDisplay = startLine + 1;\n\t\t\t\t\t\t\t\t// Check if offset is out of bounds.\n\t\t\t\t\t\t\t\tif (startLine >= allLines.length) {\n\t\t\t\t\t\t\t\t\tthrow new Error(`Offset ${offset} is beyond end of file (${allLines.length} lines total)`);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tlet selectedContent: string;\n\t\t\t\t\t\t\t\tlet userLimitedLines: number | undefined;\n\t\t\t\t\t\t\t\t// If limit is specified by the user, honor it first. Otherwise truncateHead decides.\n\t\t\t\t\t\t\t\tif (limit !== undefined) {\n\t\t\t\t\t\t\t\t\tconst endLine = Math.min(startLine + limit, allLines.length);\n\t\t\t\t\t\t\t\t\tselectedContent = allLines.slice(startLine, endLine).join(\"\\n\");\n\t\t\t\t\t\t\t\t\tuserLimitedLines = endLine - startLine;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tselectedContent = allLines.slice(startLine).join(\"\\n\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Apply truncation, respecting both line and byte limits.\n\t\t\t\t\t\t\t\tconst truncation = truncateHead(selectedContent);\n\t\t\t\t\t\t\t\tlet outputText: string;\n\t\t\t\t\t\t\t\tif (truncation.firstLineExceedsLimit) {\n\t\t\t\t\t\t\t\t\t// First line alone exceeds the byte limit. Point the model at a bash fallback.\n\t\t\t\t\t\t\t\t\tconst firstLineSize = formatSize(Buffer.byteLength(allLines[startLine], \"utf-8\"));\n\t\t\t\t\t\t\t\t\toutputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize(DEFAULT_MAX_BYTES)} limit. Use bash: sed -n '${startLineDisplay}p' ${path} | head -c ${DEFAULT_MAX_BYTES}]`;\n\t\t\t\t\t\t\t\t\tdetails = { truncation };\n\t\t\t\t\t\t\t\t} else if (truncation.truncated) {\n\t\t\t\t\t\t\t\t\t// Truncation occurred. Build an actionable continuation notice.\n\t\t\t\t\t\t\t\t\tconst endLineDisplay = startLineDisplay + truncation.outputLines - 1;\n\t\t\t\t\t\t\t\t\tconst nextOffset = endLineDisplay + 1;\n\t\t\t\t\t\t\t\t\toutputText = truncation.content;\n\t\t\t\t\t\t\t\t\tif (truncation.truncatedBy === \"lines\") {\n\t\t\t\t\t\t\t\t\t\toutputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines}. Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\toutputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tdetails = { truncation };\n\t\t\t\t\t\t\t\t} else if (userLimitedLines !== undefined && startLine + userLimitedLines < allLines.length) {\n\t\t\t\t\t\t\t\t\t// User-specified limit stopped early, but the file still has more content.\n\t\t\t\t\t\t\t\t\tconst remaining = allLines.length - (startLine + userLimitedLines);\n\t\t\t\t\t\t\t\t\tconst nextOffset = startLine + userLimitedLines + 1;\n\t\t\t\t\t\t\t\t\toutputText = `${truncation.content}\\n\\n[${remaining} more lines in file. Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// No truncation and no remaining user-limited content.\n\t\t\t\t\t\t\t\t\toutputText = truncation.content;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontent = [{ type: \"text\", text: outputText }];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tresolve({ content, details });\n\t\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tif (!aborted) reject(error);\n\t\t\t\t\t\t}\n\t\t\t\t\t})();\n\t\t\t\t},\n\t\t\t).then((result) => ({ ...result, structuredContent: toReadOutput(result.content) }));\n\t\t},\n\t\t...readRenderers,\n\t};\n}\n\nexport function createReadTool(cwd: string, options?: ReadToolOptions): TypeBoxAgentTool<typeof readSchema> {\n\treturn wrapToolDefinition(createReadToolDefinition(cwd, options));\n}\n"]}
@@ -28,20 +28,18 @@ export type ToolRenderResultLike<TDetails> = {
28
28
  export declare function formatToolCallWithArgs(title: string, args: unknown, theme: Theme, expanded: boolean): string;
29
29
  /** Duration as `4.2s` below a minute, then `1m 30s` and `2h 3m 4s`. */
30
30
  export declare function formatToolDuration(ms: number): string;
31
- declare const toolTimerLifecycle: unique symbol;
32
- /** Row-owned clock state shared by the call and result renderers. */
31
+ /** Renderer state of {@link startToolTimer} and {@link toolTimerText}, kept in `ToolRenderContext.state`. */
33
32
  interface ToolTimerState {
34
33
  startedAt?: number;
35
34
  endedAt?: number;
36
35
  interval?: ReturnType<typeof setInterval>;
37
- dispose?: () => void;
38
- [toolTimerLifecycle]?: "active" | "disposed";
39
36
  }
40
37
  /** Start the row's clock once execution starts. Call from `renderCall`. */
41
38
  export declare function startToolTimer(context: ToolRenderContext<ToolTimerState>): void;
42
39
  /**
43
- * Return `Elapsed 4.2s` while live or `Took 4.2s` once final. Only a running clock
44
- * schedules repaints; settlement, handoff and row disposal stop them.
40
+ * The row's timing line, from `renderResult`: `Elapsed 4.2s` while the result is partial, redrawn
41
+ * every second, and `Took 4.2s` once it is final. Undefined when the row has no start time and no
42
+ * recorded duration. Settlement, a background handoff and row disposal end the redraws for good.
45
43
  */
46
44
  export declare function toolTimerText(context: ToolRenderContext<ToolTimerState>, isPartial: boolean): string | undefined;
47
45
  export declare function invalidArgText(theme: Theme): string;
@@ -1 +1 @@
1
- {"version":3,"file":"render-utils.d.ts","sourceRoot":"","sources":["../../../src/core/tools/render-utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AAIpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAOjD;AAED,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAIjF;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAIjD;AAOD,gGAAgG;AAChG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAU3E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,aAAa,CAC5B,MAAM,EACH;IACA,OAAO,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACF,GACD,SAAS,EACZ,UAAU,EAAE,OAAO,GACjB,MAAM,CAsBR;AAED,MAAM,MAAM,oBAAoB,CAAC,QAAQ,IAAI;IAC5C,OAAO,EAAE,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACxC,OAAO,EAAE,QAAQ,CAAC;CAClB,CAAC;AAIF;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAkB5G;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAUrD;AAED,QAAA,MAAM,kBAAkB,eAA+B,CAAC;AAExD,qEAAqE;AACrE,UAAU,cAAc;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,CAAC,kBAAkB,CAAC,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;CAC7C;AAoBD,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,OAAO,EAAE,iBAAiB,CAAC,cAAc,CAAC,GAAG,IAAI,CAO/E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,iBAAiB,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAmBhH;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEnD;AAED,wBAAgB,cAAc,CAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAClC,MAAM,CAKR"}
1
+ {"version":3,"file":"render-utils.d.ts","sourceRoot":"","sources":["../../../src/core/tools/render-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AAIpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAGjD;AAED,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAIjF;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAIjD;AAOD,gGAAgG;AAChG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAU3E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,aAAa,CAC5B,MAAM,EAAE;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,SAAS,EACzG,UAAU,EAAE,OAAO,GACjB,MAAM,CAsBR;AAED,MAAM,MAAM,oBAAoB,CAAC,QAAQ,IAAI;IAC5C,OAAO,EAAE,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACxC,OAAO,EAAE,QAAQ,CAAC;CAClB,CAAC;AAIF;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAkB5G;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAUrD;AAED,6GAA6G;AAC7G,UAAU,cAAc;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;CAC1C;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,OAAO,EAAE,iBAAiB,CAAC,cAAc,CAAC,GAAG,IAAI,CAM/E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,iBAAiB,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAqBhH;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEnD;AAED,wBAAgB,cAAc,CAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAClC,MAAM,CAKR"}
@@ -1,17 +1,12 @@
1
- import * as os from "node:os";
2
1
  import { pathToFileURL } from "node:url";
3
2
  import { getCapabilities, getImageDimensions, hyperlink, imageFallback } from "@earendil-works/pi-tui";
4
3
  import { stripAnsi } from "../../utils/ansi.js";
5
- import { resolvePath } from "../../utils/paths.js";
4
+ import { resolvePath, shortenHomePath } from "../../utils/paths.js";
6
5
  import { sanitizeBinaryOutput } from "../../utils/shell.js";
7
6
  export function shortenPath(path) {
8
7
  if (typeof path !== "string")
9
8
  return "";
10
- const home = os.homedir();
11
- if (path.startsWith(home)) {
12
- return `~${path.slice(home.length)}`;
13
- }
14
- return path;
9
+ return shortenHomePath(path);
15
10
  }
16
11
  export function linkPath(styledText, rawPath, cwd) {
17
12
  if (!getCapabilities().hyperlinks)
@@ -110,53 +105,36 @@ export function formatToolDuration(ms) {
110
105
  return `${minutes}m ${remainder}s`;
111
106
  return `${Math.floor(minutes / 60)}h ${minutes % 60}m ${remainder}s`;
112
107
  }
113
- const toolTimerLifecycle = Symbol("toolTimerLifecycle");
114
- function stopToolTimer(state) {
115
- state.endedAt ??= Date.now();
116
- if (state.interval !== undefined)
117
- clearInterval(state.interval);
118
- state.interval = undefined;
119
- }
120
- function bindToolTimerDisposal(state) {
121
- if (state[toolTimerLifecycle])
122
- return;
123
- state[toolTimerLifecycle] = "active";
124
- const previousDispose = state.dispose;
125
- state.dispose = () => {
126
- if (state[toolTimerLifecycle] === "disposed")
127
- return;
128
- state[toolTimerLifecycle] = "disposed";
129
- stopToolTimer(state);
130
- previousDispose?.call(state);
131
- };
132
- }
133
108
  /** Start the row's clock once execution starts. Call from `renderCall`. */
134
109
  export function startToolTimer(context) {
135
110
  const state = context.state;
136
- bindToolTimerDisposal(state);
137
- if (context.executionStarted && state.startedAt === undefined && state[toolTimerLifecycle] !== "disposed") {
111
+ if (context.executionStarted && state.startedAt === undefined) {
138
112
  state.startedAt = Date.now();
139
113
  state.endedAt = undefined;
140
114
  }
141
115
  }
142
116
  /**
143
- * Return `Elapsed 4.2s` while live or `Took 4.2s` once final. Only a running clock
144
- * schedules repaints; settlement, handoff and row disposal stop them.
117
+ * The row's timing line, from `renderResult`: `Elapsed 4.2s` while the result is partial, redrawn
118
+ * every second, and `Took 4.2s` once it is final. Undefined when the row has no start time and no
119
+ * recorded duration. Settlement, a background handoff and row disposal end the redraws for good.
145
120
  */
146
121
  export function toolTimerText(context, isPartial) {
147
122
  const state = context.state;
148
- bindToolTimerDisposal(state);
149
- if (!isPartial || context.isError) {
150
- stopToolTimer(state);
123
+ // A disposed row keeps its cleared handle, so a late render never arms another clock.
124
+ if (state.startedAt !== undefined && state.endedAt === undefined && isPartial && !state.interval) {
125
+ const interval = setInterval(() => context.invalidate(), 1000);
126
+ state.interval = interval;
127
+ context.onDispose(() => clearInterval(interval));
151
128
  }
152
- else if (context.executionStarted &&
153
- state.startedAt !== undefined &&
154
- state.endedAt === undefined &&
155
- state[toolTimerLifecycle] !== "disposed" &&
156
- state.interval === undefined) {
157
- state.interval = setInterval(() => context.invalidate(), 1000);
129
+ if (!isPartial || context.isError) {
130
+ state.endedAt ??= Date.now();
131
+ if (state.interval) {
132
+ clearInterval(state.interval);
133
+ state.interval = undefined;
134
+ }
158
135
  }
159
- // A recorded monotonic duration survives reloads; the local clock is only the live/legacy fallback.
136
+ // A final result's recorded duration wins: it is monotonic and survives reloads. The renderer's own clock is the
137
+ // fallback for live progress and for results stored without one.
160
138
  if (!isPartial && context.durationMs !== undefined)
161
139
  return `Took ${formatToolDuration(context.durationMs)}`;
162
140
  if (state.startedAt === undefined)
@@ -1 +1 @@
1
- {"version":3,"file":"render-utils.js","sourceRoot":"","sources":["../../../src/core/tools/render-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import * as os from \"node:os\";\nimport { pathToFileURL } from \"node:url\";\nimport type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport { getCapabilities, getImageDimensions, hyperlink, imageFallback } from \"@earendil-works/pi-tui\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { stripAnsi } from \"../../utils/ansi.ts\";\nimport { resolvePath } from \"../../utils/paths.ts\";\nimport { sanitizeBinaryOutput } from \"../../utils/shell.ts\";\nimport type { ToolRenderContext } from \"../extensions/types.ts\";\n\nexport function shortenPath(path: unknown): string {\n\tif (typeof path !== \"string\") return \"\";\n\tconst home = os.homedir();\n\tif (path.startsWith(home)) {\n\t\treturn `~${path.slice(home.length)}`;\n\t}\n\treturn path;\n}\n\nexport function linkPath(styledText: string, rawPath: string, cwd: string): string {\n\tif (!getCapabilities().hyperlinks) return styledText;\n\tconst absolutePath = resolvePath(rawPath, cwd);\n\treturn hyperlink(styledText, pathToFileURL(absolutePath).href);\n}\n\nexport function str(value: unknown): string | null {\n\tif (typeof value === \"string\") return value;\n\tif (value == null) return \"\";\n\treturn null;\n}\n\nfunction parseLineNumber(value: unknown): number | undefined {\n\tif (typeof value === \"string\" && value.trim() !== \"\") value = Number(value);\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\n/** Format finite numbers or numeric strings as a read line range, omitting malformed ranges. */\nexport function formatReadLineRange(offset: unknown, limit: unknown): string {\n\t// Strict schemas represent omitted optional arguments as null.\n\tif (offset == null && limit == null) return \"\";\n\tconst start = offset == null ? 1 : parseLineNumber(offset);\n\tif (start === undefined) return \"\";\n\tif (limit == null) return `:${start}`;\n\tconst count = parseLineNumber(limit);\n\tif (count === undefined) return \"\";\n\tconst end = start + count - 1;\n\treturn `:${start}${end ? `-${end}` : \"\"}`;\n}\n\nexport function replaceTabs(text: string): string {\n\treturn text.replace(/\\t/g, \" \");\n}\n\nexport function normalizeDisplayText(text: string): string {\n\treturn text.replace(/\\r/g, \"\");\n}\n\nexport function getTextOutput(\n\tresult:\n\t\t| {\n\t\t\t\tcontent: Array<{\n\t\t\t\t\ttype: string;\n\t\t\t\t\ttext?: string;\n\t\t\t\t\tdata?: string;\n\t\t\t\t\tmimeType?: string;\n\t\t\t\t}>;\n\t\t }\n\t\t| undefined,\n\tshowImages: boolean,\n): string {\n\tif (!result) return \"\";\n\n\tconst textBlocks = result.content.filter((c) => c.type === \"text\");\n\tconst imageBlocks = result.content.filter((c) => c.type === \"image\");\n\n\tlet output = textBlocks.map((c) => sanitizeBinaryOutput(stripAnsi(c.text || \"\")).replace(/\\r/g, \"\")).join(\"\\n\");\n\n\tconst caps = getCapabilities();\n\tif (imageBlocks.length > 0 && (!caps.images || !showImages)) {\n\t\tconst imageIndicators = imageBlocks\n\t\t\t.map((img) => {\n\t\t\t\tconst mimeType = img.mimeType ?? \"image/unknown\";\n\t\t\t\tconst dims =\n\t\t\t\t\timg.data && img.mimeType ? (getImageDimensions(img.data, img.mimeType) ?? undefined) : undefined;\n\t\t\t\treturn imageFallback(mimeType, dims);\n\t\t\t})\n\t\t\t.join(\"\\n\");\n\t\toutput = output ? `${output}\\n${imageIndicators}` : imageIndicators;\n\t}\n\n\treturn output;\n}\n\nexport type ToolRenderResultLike<TDetails> = {\n\tcontent: (TextContent | ImageContent)[];\n\tdetails: TDetails;\n};\n\nconst COLLAPSED_ARGS_CHARS = 100;\n\n/**\n * Generic tool call header: the title followed by the arguments. Collapsed, they are `key=value`\n * pairs on the title line, cut to {@link COLLAPSED_ARGS_CHARS}. Expanded, each is a `key: value`\n * line below the title, with strings shown raw and continuation lines indented.\n */\nexport function formatToolCallWithArgs(title: string, args: unknown, theme: Theme, expanded: boolean): string {\n\tconst header = theme.fg(\"toolTitle\", theme.bold(title));\n\tif (args == null) return header;\n\tconst entries =\n\t\ttypeof args === \"object\" && !Array.isArray(args)\n\t\t\t? Object.entries(args)\n\t\t\t: ([[\"args\", args]] as [string, unknown][]);\n\tif (entries.length === 0) return header;\n\tif (expanded) {\n\t\tconst lines = entries.map(([key, value]) => {\n\t\t\tconst text = typeof value === \"string\" ? value : (JSON.stringify(value, null, 2) ?? String(value));\n\t\t\treturn ` ${key}: ${replaceTabs(text).replace(/\\r/g, \"\").split(\"\\n\").join(\"\\n \")}`;\n\t\t});\n\t\treturn `${header}\\n${theme.fg(\"muted\", lines.join(\"\\n\"))}`;\n\t}\n\tconst pairs = entries.map(([key, value]) => `${key}=${JSON.stringify(value) ?? String(value)}`).join(\" \");\n\tconst preview = pairs.length > COLLAPSED_ARGS_CHARS ? `${pairs.slice(0, COLLAPSED_ARGS_CHARS - 3)}...` : pairs;\n\treturn `${header} ${theme.fg(\"muted\", preview)}`;\n}\n\n/** Duration as `4.2s` below a minute, then `1m 30s` and `2h 3m 4s`. */\nexport function formatToolDuration(ms: number): string {\n\tconst seconds = ms / 1000;\n\tif (seconds < 60) return `${seconds.toFixed(1)}s`;\n\n\tconst totalSeconds = Math.floor(seconds);\n\tconst minutes = Math.floor(totalSeconds / 60);\n\tconst remainder = totalSeconds % 60;\n\tif (minutes < 60) return `${minutes}m ${remainder}s`;\n\n\treturn `${Math.floor(minutes / 60)}h ${minutes % 60}m ${remainder}s`;\n}\n\nconst toolTimerLifecycle = Symbol(\"toolTimerLifecycle\");\n\n/** Row-owned clock state shared by the call and result renderers. */\ninterface ToolTimerState {\n\tstartedAt?: number;\n\tendedAt?: number;\n\tinterval?: ReturnType<typeof setInterval>;\n\tdispose?: () => void;\n\t[toolTimerLifecycle]?: \"active\" | \"disposed\";\n}\n\nfunction stopToolTimer(state: ToolTimerState): void {\n\tstate.endedAt ??= Date.now();\n\tif (state.interval !== undefined) clearInterval(state.interval);\n\tstate.interval = undefined;\n}\n\nfunction bindToolTimerDisposal(state: ToolTimerState): void {\n\tif (state[toolTimerLifecycle]) return;\n\tstate[toolTimerLifecycle] = \"active\";\n\tconst previousDispose = state.dispose;\n\tstate.dispose = () => {\n\t\tif (state[toolTimerLifecycle] === \"disposed\") return;\n\t\tstate[toolTimerLifecycle] = \"disposed\";\n\t\tstopToolTimer(state);\n\t\tpreviousDispose?.call(state);\n\t};\n}\n\n/** Start the row's clock once execution starts. Call from `renderCall`. */\nexport function startToolTimer(context: ToolRenderContext<ToolTimerState>): void {\n\tconst state = context.state;\n\tbindToolTimerDisposal(state);\n\tif (context.executionStarted && state.startedAt === undefined && state[toolTimerLifecycle] !== \"disposed\") {\n\t\tstate.startedAt = Date.now();\n\t\tstate.endedAt = undefined;\n\t}\n}\n\n/**\n * Return `Elapsed 4.2s` while live or `Took 4.2s` once final. Only a running clock\n * schedules repaints; settlement, handoff and row disposal stop them.\n */\nexport function toolTimerText(context: ToolRenderContext<ToolTimerState>, isPartial: boolean): string | undefined {\n\tconst state = context.state;\n\tbindToolTimerDisposal(state);\n\tif (!isPartial || context.isError) {\n\t\tstopToolTimer(state);\n\t} else if (\n\t\tcontext.executionStarted &&\n\t\tstate.startedAt !== undefined &&\n\t\tstate.endedAt === undefined &&\n\t\tstate[toolTimerLifecycle] !== \"disposed\" &&\n\t\tstate.interval === undefined\n\t) {\n\t\tstate.interval = setInterval(() => context.invalidate(), 1000);\n\t}\n\t// A recorded monotonic duration survives reloads; the local clock is only the live/legacy fallback.\n\tif (!isPartial && context.durationMs !== undefined) return `Took ${formatToolDuration(context.durationMs)}`;\n\tif (state.startedAt === undefined) return undefined;\n\tconst endTime = state.endedAt ?? Date.now();\n\treturn `${isPartial ? \"Elapsed\" : \"Took\"} ${formatToolDuration(endTime - state.startedAt)}`;\n}\n\nexport function invalidArgText(theme: Theme): string {\n\treturn theme.fg(\"error\", \"[invalid arg]\");\n}\n\nexport function renderToolPath(\n\trawPath: string | null,\n\ttheme: Theme,\n\tcwd: string,\n\toptions?: { emptyFallback?: string },\n): string {\n\tif (rawPath === null) return invalidArgText(theme);\n\tconst value = rawPath || options?.emptyFallback;\n\tif (!value) return theme.fg(\"toolOutput\", \"...\");\n\treturn linkPath(theme.fg(\"accent\", shortenPath(value)), value, cwd);\n}\n"]}
1
+ {"version":3,"file":"render-utils.js","sourceRoot":"","sources":["../../../src/core/tools/render-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { pathToFileURL } from \"node:url\";\nimport type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport { getCapabilities, getImageDimensions, hyperlink, imageFallback } from \"@earendil-works/pi-tui\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { stripAnsi } from \"../../utils/ansi.ts\";\nimport { resolvePath, shortenHomePath } from \"../../utils/paths.ts\";\nimport { sanitizeBinaryOutput } from \"../../utils/shell.ts\";\nimport type { ToolRenderContext } from \"../extensions/types.ts\";\n\nexport function shortenPath(path: unknown): string {\n\tif (typeof path !== \"string\") return \"\";\n\treturn shortenHomePath(path);\n}\n\nexport function linkPath(styledText: string, rawPath: string, cwd: string): string {\n\tif (!getCapabilities().hyperlinks) return styledText;\n\tconst absolutePath = resolvePath(rawPath, cwd);\n\treturn hyperlink(styledText, pathToFileURL(absolutePath).href);\n}\n\nexport function str(value: unknown): string | null {\n\tif (typeof value === \"string\") return value;\n\tif (value == null) return \"\";\n\treturn null;\n}\n\nfunction parseLineNumber(value: unknown): number | undefined {\n\tif (typeof value === \"string\" && value.trim() !== \"\") value = Number(value);\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\n/** Format finite numbers or numeric strings as a read line range, omitting malformed ranges. */\nexport function formatReadLineRange(offset: unknown, limit: unknown): string {\n\t// Strict schemas represent omitted optional arguments as null.\n\tif (offset == null && limit == null) return \"\";\n\tconst start = offset == null ? 1 : parseLineNumber(offset);\n\tif (start === undefined) return \"\";\n\tif (limit == null) return `:${start}`;\n\tconst count = parseLineNumber(limit);\n\tif (count === undefined) return \"\";\n\tconst end = start + count - 1;\n\treturn `:${start}${end ? `-${end}` : \"\"}`;\n}\n\nexport function replaceTabs(text: string): string {\n\treturn text.replace(/\\t/g, \" \");\n}\n\nexport function normalizeDisplayText(text: string): string {\n\treturn text.replace(/\\r/g, \"\");\n}\n\nexport function getTextOutput(\n\tresult: { content: Array<{ type: string; text?: string; data?: string; mimeType?: string }> } | undefined,\n\tshowImages: boolean,\n): string {\n\tif (!result) return \"\";\n\n\tconst textBlocks = result.content.filter((c) => c.type === \"text\");\n\tconst imageBlocks = result.content.filter((c) => c.type === \"image\");\n\n\tlet output = textBlocks.map((c) => sanitizeBinaryOutput(stripAnsi(c.text || \"\")).replace(/\\r/g, \"\")).join(\"\\n\");\n\n\tconst caps = getCapabilities();\n\tif (imageBlocks.length > 0 && (!caps.images || !showImages)) {\n\t\tconst imageIndicators = imageBlocks\n\t\t\t.map((img) => {\n\t\t\t\tconst mimeType = img.mimeType ?? \"image/unknown\";\n\t\t\t\tconst dims =\n\t\t\t\t\timg.data && img.mimeType ? (getImageDimensions(img.data, img.mimeType) ?? undefined) : undefined;\n\t\t\t\treturn imageFallback(mimeType, dims);\n\t\t\t})\n\t\t\t.join(\"\\n\");\n\t\toutput = output ? `${output}\\n${imageIndicators}` : imageIndicators;\n\t}\n\n\treturn output;\n}\n\nexport type ToolRenderResultLike<TDetails> = {\n\tcontent: (TextContent | ImageContent)[];\n\tdetails: TDetails;\n};\n\nconst COLLAPSED_ARGS_CHARS = 100;\n\n/**\n * Generic tool call header: the title followed by the arguments. Collapsed, they are `key=value`\n * pairs on the title line, cut to {@link COLLAPSED_ARGS_CHARS}. Expanded, each is a `key: value`\n * line below the title, with strings shown raw and continuation lines indented.\n */\nexport function formatToolCallWithArgs(title: string, args: unknown, theme: Theme, expanded: boolean): string {\n\tconst header = theme.fg(\"toolTitle\", theme.bold(title));\n\tif (args == null) return header;\n\tconst entries =\n\t\ttypeof args === \"object\" && !Array.isArray(args)\n\t\t\t? Object.entries(args)\n\t\t\t: ([[\"args\", args]] as [string, unknown][]);\n\tif (entries.length === 0) return header;\n\tif (expanded) {\n\t\tconst lines = entries.map(([key, value]) => {\n\t\t\tconst text = typeof value === \"string\" ? value : (JSON.stringify(value, null, 2) ?? String(value));\n\t\t\treturn ` ${key}: ${replaceTabs(text).replace(/\\r/g, \"\").split(\"\\n\").join(\"\\n \")}`;\n\t\t});\n\t\treturn `${header}\\n${theme.fg(\"muted\", lines.join(\"\\n\"))}`;\n\t}\n\tconst pairs = entries.map(([key, value]) => `${key}=${JSON.stringify(value) ?? String(value)}`).join(\" \");\n\tconst preview = pairs.length > COLLAPSED_ARGS_CHARS ? `${pairs.slice(0, COLLAPSED_ARGS_CHARS - 3)}...` : pairs;\n\treturn `${header} ${theme.fg(\"muted\", preview)}`;\n}\n\n/** Duration as `4.2s` below a minute, then `1m 30s` and `2h 3m 4s`. */\nexport function formatToolDuration(ms: number): string {\n\tconst seconds = ms / 1000;\n\tif (seconds < 60) return `${seconds.toFixed(1)}s`;\n\n\tconst totalSeconds = Math.floor(seconds);\n\tconst minutes = Math.floor(totalSeconds / 60);\n\tconst remainder = totalSeconds % 60;\n\tif (minutes < 60) return `${minutes}m ${remainder}s`;\n\n\treturn `${Math.floor(minutes / 60)}h ${minutes % 60}m ${remainder}s`;\n}\n\n/** Renderer state of {@link startToolTimer} and {@link toolTimerText}, kept in `ToolRenderContext.state`. */\ninterface ToolTimerState {\n\tstartedAt?: number;\n\tendedAt?: number;\n\tinterval?: ReturnType<typeof setInterval>;\n}\n\n/** Start the row's clock once execution starts. Call from `renderCall`. */\nexport function startToolTimer(context: ToolRenderContext<ToolTimerState>): void {\n\tconst state = context.state;\n\tif (context.executionStarted && state.startedAt === undefined) {\n\t\tstate.startedAt = Date.now();\n\t\tstate.endedAt = undefined;\n\t}\n}\n\n/**\n * The row's timing line, from `renderResult`: `Elapsed 4.2s` while the result is partial, redrawn\n * every second, and `Took 4.2s` once it is final. Undefined when the row has no start time and no\n * recorded duration. Settlement, a background handoff and row disposal end the redraws for good.\n */\nexport function toolTimerText(context: ToolRenderContext<ToolTimerState>, isPartial: boolean): string | undefined {\n\tconst state = context.state;\n\t// A disposed row keeps its cleared handle, so a late render never arms another clock.\n\tif (state.startedAt !== undefined && state.endedAt === undefined && isPartial && !state.interval) {\n\t\tconst interval = setInterval(() => context.invalidate(), 1000);\n\t\tstate.interval = interval;\n\t\tcontext.onDispose(() => clearInterval(interval));\n\t}\n\tif (!isPartial || context.isError) {\n\t\tstate.endedAt ??= Date.now();\n\t\tif (state.interval) {\n\t\t\tclearInterval(state.interval);\n\t\t\tstate.interval = undefined;\n\t\t}\n\t}\n\t// A final result's recorded duration wins: it is monotonic and survives reloads. The renderer's own clock is the\n\t// fallback for live progress and for results stored without one.\n\tif (!isPartial && context.durationMs !== undefined) return `Took ${formatToolDuration(context.durationMs)}`;\n\tif (state.startedAt === undefined) return undefined;\n\tconst endTime = state.endedAt ?? Date.now();\n\treturn `${isPartial ? \"Elapsed\" : \"Took\"} ${formatToolDuration(endTime - state.startedAt)}`;\n}\n\nexport function invalidArgText(theme: Theme): string {\n\treturn theme.fg(\"error\", \"[invalid arg]\");\n}\n\nexport function renderToolPath(\n\trawPath: string | null,\n\ttheme: Theme,\n\tcwd: string,\n\toptions?: { emptyFallback?: string },\n): string {\n\tif (rawPath === null) return invalidArgText(theme);\n\tconst value = rawPath || options?.emptyFallback;\n\tif (!value) return theme.fg(\"toolOutput\", \"...\");\n\treturn linkPath(theme.fg(\"accent\", shortenPath(value)), value, cwd);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/renderers/bash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,cAAc,EAA8C,MAAM,2BAA2B,CAAC;AAC5G,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMlD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAqM3C,4GAA4G;AAC5G,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ,CAAC,GAC9C,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,CAmB/D"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/renderers/bash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,2BAA2B,CAAC;AACzF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMlD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AA0K3C,4GAA4G;AAC5G,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ,CAAC,GAC9C,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,CAoB/D"}
@@ -49,29 +49,6 @@ class BashCallRenderComponent {
49
49
  return [formatTruncatedShellCall(this.command, this.timeout, width, this.config)];
50
50
  }
51
51
  }
52
- const shellTimerHooked = Symbol("shellTimerHooked");
53
- /**
54
- * Start the row's clock and hook disposal once. Either slot can initialize timing, since
55
- * extensions may replace the other slot; upstream's timer state outlives a replaced slot, but
56
- * its refresh interval must still end when the row is disposed mid-run.
57
- */
58
- function ensureShellTimer(context) {
59
- startToolTimer(context);
60
- const state = context.state;
61
- if (state[shellTimerHooked])
62
- return;
63
- state[shellTimerHooked] = true;
64
- const previousDispose = state.dispose;
65
- state.dispose = () => {
66
- try {
67
- previousDispose?.call(state);
68
- }
69
- finally {
70
- clearInterval(state.interval);
71
- state.interval = undefined;
72
- }
73
- };
74
- }
75
52
  function formatShellPrompt(prompt) {
76
53
  return theme.fg("toolTitle", theme.bold(`${prompt} `));
77
54
  }
@@ -165,13 +142,14 @@ function rebuildBashResultRenderComponent(component, result, options, showImages
165
142
  export function createShellRenderers(config) {
166
143
  return {
167
144
  renderCall(args, _theme, context) {
168
- ensureShellTimer(context);
145
+ startToolTimer(context);
169
146
  const component = context.lastComponent ?? new BashCallRenderComponent(config);
170
147
  component.update(args, context.expanded);
171
148
  return component;
172
149
  },
173
150
  renderResult(result, options, _theme, context) {
174
- ensureShellTimer(context);
151
+ // Either slot may start the clock: an extension can replace the other one.
152
+ startToolTimer(context);
175
153
  const timerText = toolTimerText(context, options.isPartial);
176
154
  const component = context.lastComponent ?? new Container();
177
155
  const submitted = context.args?.background === true;
@@ -1 +1 @@
1
- {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../../src/core/tools/renderers/bash.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Presentation for the shell tools.\n *\n * Renderers live apart from the implementation so a process that only displays tool output does not\n * load the execution path or its typebox parameter schema. `bash.ts` spreads these into the shell\n * tool definition, so the tool's public shape is unchanged.\n */\n\nimport { type Component, Container, Spacer, Text, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport { keyHint } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport { VisualLinePreview } from \"../../../modes/interactive/components/visual-truncate.ts\";\nimport { highlightCode, theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { ToolDefinition, ToolRenderContext, ToolRenderResultOptions } from \"../../extensions/types.ts\";\nimport type { ShellToolConfig } from \"../bash.ts\";\nimport { getTextOutput, invalidArgText, startToolTimer, str, toolTimerText } from \"../render-utils.ts\";\nimport type { BashRenderState, BashToolDetails } from \"../shell-tool.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize } from \"../truncate.ts\";\n\nconst BASH_PREVIEW_LINES = 5;\nexport const BASH_UPDATE_THROTTLE_MS = 100;\nclass BashCallRenderComponent implements Component {\n\tprivate command: string | null = \"\";\n\tprivate timeout: number | undefined;\n\tprivate expanded = false;\n\tprivate cachedWidth: number | undefined;\n\tprivate cachedLines: string[] | undefined;\n\tprivate readonly config: Pick<ShellToolConfig, \"name\" | \"prompt\">;\n\n\tconstructor(config: Pick<ShellToolConfig, \"name\" | \"prompt\">) {\n\t\tthis.config = config;\n\t}\n\n\tupdate(args: { command?: string; timeout?: number } | undefined, expanded: boolean): void {\n\t\tconst command = str(args?.command);\n\t\tconst timeout = args?.timeout as number | undefined;\n\t\tif (this.command === command && this.timeout === timeout && this.expanded === expanded) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.command = command;\n\t\tthis.timeout = timeout;\n\t\tthis.expanded = expanded;\n\t\tthis.invalidate();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.cachedLines === undefined || this.cachedWidth !== width) {\n\t\t\tthis.cachedLines = this.renderLines(Math.max(1, width));\n\t\t\tthis.cachedWidth = width;\n\t\t}\n\t\treturn this.cachedLines;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tprivate renderLines(width: number): string[] {\n\t\tconst fullCall = formatFullShellCall(this.command, this.timeout, this.config);\n\t\tconst fullLines = new Text(fullCall, 0, 0).render(width);\n\t\tif (this.expanded || fullLines.length <= 1) return fullLines;\n\t\treturn [formatTruncatedShellCall(this.command, this.timeout, width, this.config)];\n\t}\n}\n\nconst shellTimerHooked = Symbol(\"shellTimerHooked\");\ntype ShellTimerState = BashRenderState & {\n\tinterval?: ReturnType<typeof setInterval>;\n\t[shellTimerHooked]?: true;\n};\n\n/**\n * Start the row's clock and hook disposal once. Either slot can initialize timing, since\n * extensions may replace the other slot; upstream's timer state outlives a replaced slot, but\n * its refresh interval must still end when the row is disposed mid-run.\n */\nfunction ensureShellTimer(context: ToolRenderContext<ShellTimerState>): void {\n\tstartToolTimer(context);\n\tconst state = context.state;\n\tif (state[shellTimerHooked]) return;\n\tstate[shellTimerHooked] = true;\n\tconst previousDispose = state.dispose;\n\tstate.dispose = () => {\n\t\ttry {\n\t\t\tpreviousDispose?.call(state);\n\t\t} finally {\n\t\t\tclearInterval(state.interval);\n\t\t\tstate.interval = undefined;\n\t\t}\n\t};\n}\n\nfunction formatShellPrompt(prompt: string): string {\n\treturn theme.fg(\"toolTitle\", theme.bold(`${prompt} `));\n}\nfunction formatShellTimeout(timeout: number | undefined): string {\n\treturn timeout ? theme.fg(\"muted\", ` (timeout ${timeout}s)`) : \"\";\n}\nfunction styleShellCommand(command: string, config: Pick<ShellToolConfig, \"name\" | \"prompt\">): string {\n\tconst language = config.name === \"powershell\" ? \"powershell\" : \"bash\";\n\treturn highlightCode(command, language).join(\"\\n\");\n}\nfunction formatFullShellCall(\n\tcommand: string | null,\n\ttimeout: number | undefined,\n\tconfig: Pick<ShellToolConfig, \"name\" | \"prompt\">,\n): string {\n\tconst commandDisplay =\n\t\tcommand === null\n\t\t\t? invalidArgText(theme)\n\t\t\t: command\n\t\t\t\t? styleShellCommand(command, config)\n\t\t\t\t: theme.fg(\"toolOutput\", \"...\");\n\treturn formatShellPrompt(config.prompt) + commandDisplay + formatShellTimeout(timeout);\n}\nfunction fitCollapsedShellCall(\n\tbody: string,\n\ttimeout: number | undefined,\n\twidth: number,\n\tsuffix: string,\n\tconfig: Pick<ShellToolConfig, \"name\" | \"prompt\">,\n): string {\n\tconst prompt = formatShellPrompt(config.prompt);\n\tconst timeoutSuffix = formatShellTimeout(timeout);\n\tconst bodyWidth = Math.max(0, width - visibleWidth(prompt) - visibleWidth(suffix) - visibleWidth(timeoutSuffix));\n\tconst fittedBody = truncateToWidth(body, bodyWidth, \"\");\n\treturn truncateToWidth(prompt + fittedBody + suffix + timeoutSuffix, width, \"…\");\n}\nfunction formatTruncatedShellCall(\n\tcommand: string | null,\n\ttimeout: number | undefined,\n\twidth: number,\n\tconfig: Pick<ShellToolConfig, \"name\" | \"prompt\">,\n): string {\n\tif (command === null) return truncateToWidth(formatFullShellCall(command, timeout, config), width, \"…\");\n\tif (!command) return formatFullShellCall(command, timeout, config);\n\tconst physicalLines = command.split(/\\r?\\n/).filter((line) => line.trim());\n\tconst firstNonEmptyLine = physicalLines[0]?.trim() ?? command.trim();\n\tconst hiddenLines = Math.max(0, physicalLines.length - 1);\n\tconst suffix =\n\t\thiddenLines > 0\n\t\t\t? theme.fg(\"muted\", ` (+${hiddenLines} line${hiddenLines === 1 ? \"\" : \"s\"})`)\n\t\t\t: theme.fg(\"muted\", \" …\");\n\treturn fitCollapsedShellCall(styleShellCommand(firstNonEmptyLine, config), timeout, width, suffix, config);\n}\nfunction rebuildBashResultRenderComponent(\n\tcomponent: Container,\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: BashToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\tshowImages: boolean,\n\ttimerText: string | undefined,\n\tsubmittedAsBackground: boolean,\n): void {\n\tcomponent.clear();\n\n\tconst background = result.details?.background;\n\tlet output =\n\t\tbackground?.kind === \"background\"\n\t\t\t? `${submittedAsBackground ? \"Running in the background\" : \"Moved to background\"} · ${background.taskId}`\n\t\t\t: getTextOutput(result as any, showImages).trim();\n\tconst truncation = result.details?.truncation;\n\tconst fullOutputPath = result.details?.fullOutputPath;\n\tif (!options.isPartial && truncation?.truncated && fullOutputPath && output.endsWith(\"]\")) {\n\t\tconst footerStart = output.lastIndexOf(\"\\n\\n[\");\n\t\tif (footerStart !== -1 && output.slice(footerStart).includes(fullOutputPath)) {\n\t\t\toutput = output.slice(0, footerStart).trimEnd();\n\t\t}\n\t}\n\n\tif (output) {\n\t\tconst styledOutput = output\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => theme.fg(\"toolOutput\", line))\n\t\t\t.join(\"\\n\");\n\n\t\tif (options.expanded) {\n\t\t\tcomponent.addChild(new Text(`\\n${styledOutput}`, 0, 0));\n\t\t} else {\n\t\t\tcomponent.addChild(new Spacer(1));\n\t\t\tcomponent.addChild(\n\t\t\t\tnew VisualLinePreview({\n\t\t\t\t\ttext: styledOutput,\n\t\t\t\t\tmaxVisualLines: BASH_PREVIEW_LINES,\n\t\t\t\t\tkeep: \"end\",\n\t\t\t\t\tformatHint: (hidden) =>\n\t\t\t\t\t\ttheme.fg(\"muted\", `... (${hidden} earlier lines,`) +\n\t\t\t\t\t\t` ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\tif (truncation?.truncated || fullOutputPath) {\n\t\tconst warnings: string[] = [];\n\t\tif (fullOutputPath) {\n\t\t\twarnings.push(`Full output: ${fullOutputPath}`);\n\t\t}\n\t\tif (truncation?.truncated) {\n\t\t\tif (truncation.truncatedBy === \"lines\") {\n\t\t\t\twarnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);\n\t\t\t} else {\n\t\t\t\twarnings.push(\n\t\t\t\t\t`Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tcomponent.addChild(new Text(`\\n${theme.fg(\"warning\", `[${warnings.join(\". \")}]`)}`, 0, 0));\n\t}\n\n\tif (timerText) component.addChild(new Text(`\\n${theme.fg(\"muted\", timerText)}`, 0, 0));\n}\n\n/** Shell renderers are shared by bash and powershell, which differ in the prompt and highlight language. */\nexport function createShellRenderers(\n\tconfig: Pick<ShellToolConfig, \"name\" | \"prompt\">,\n): Pick<ToolDefinition<any, any>, \"renderCall\" | \"renderResult\"> {\n\treturn {\n\t\trenderCall(args, _theme, context) {\n\t\t\tensureShellTimer(context);\n\t\t\tconst component =\n\t\t\t\t(context.lastComponent as BashCallRenderComponent | undefined) ?? new BashCallRenderComponent(config);\n\t\t\tcomponent.update(args as { command?: string; timeout?: number } | undefined, context.expanded);\n\t\t\treturn component;\n\t\t},\n\t\trenderResult(result, options, _theme, context) {\n\t\t\tensureShellTimer(context);\n\t\t\tconst timerText = toolTimerText(context, options.isPartial);\n\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\tconst submitted = (context.args as { background?: boolean } | undefined)?.background === true;\n\t\t\trebuildBashResultRenderComponent(component, result as any, options, context.showImages, timerText, submitted);\n\t\t\tcomponent.invalidate();\n\t\t\treturn component;\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../../src/core/tools/renderers/bash.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Presentation for the shell tools.\n *\n * Renderers live apart from the implementation so a process that only displays tool output does not\n * load the execution path or its typebox parameter schema. `bash.ts` spreads these into the shell\n * tool definition, so the tool's public shape is unchanged.\n */\n\nimport { type Component, Container, Spacer, Text, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport { keyHint } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport { VisualLinePreview } from \"../../../modes/interactive/components/visual-truncate.ts\";\nimport { highlightCode, theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../../extensions/types.ts\";\nimport type { ShellToolConfig } from \"../bash.ts\";\nimport { getTextOutput, invalidArgText, startToolTimer, str, toolTimerText } from \"../render-utils.ts\";\nimport type { BashToolDetails } from \"../shell-tool.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize } from \"../truncate.ts\";\n\nconst BASH_PREVIEW_LINES = 5;\nexport const BASH_UPDATE_THROTTLE_MS = 100;\nclass BashCallRenderComponent implements Component {\n\tprivate command: string | null = \"\";\n\tprivate timeout: number | undefined;\n\tprivate expanded = false;\n\tprivate cachedWidth: number | undefined;\n\tprivate cachedLines: string[] | undefined;\n\tprivate readonly config: Pick<ShellToolConfig, \"name\" | \"prompt\">;\n\n\tconstructor(config: Pick<ShellToolConfig, \"name\" | \"prompt\">) {\n\t\tthis.config = config;\n\t}\n\n\tupdate(args: { command?: string; timeout?: number } | undefined, expanded: boolean): void {\n\t\tconst command = str(args?.command);\n\t\tconst timeout = args?.timeout as number | undefined;\n\t\tif (this.command === command && this.timeout === timeout && this.expanded === expanded) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.command = command;\n\t\tthis.timeout = timeout;\n\t\tthis.expanded = expanded;\n\t\tthis.invalidate();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.cachedLines === undefined || this.cachedWidth !== width) {\n\t\t\tthis.cachedLines = this.renderLines(Math.max(1, width));\n\t\t\tthis.cachedWidth = width;\n\t\t}\n\t\treturn this.cachedLines;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tprivate renderLines(width: number): string[] {\n\t\tconst fullCall = formatFullShellCall(this.command, this.timeout, this.config);\n\t\tconst fullLines = new Text(fullCall, 0, 0).render(width);\n\t\tif (this.expanded || fullLines.length <= 1) return fullLines;\n\t\treturn [formatTruncatedShellCall(this.command, this.timeout, width, this.config)];\n\t}\n}\n\nfunction formatShellPrompt(prompt: string): string {\n\treturn theme.fg(\"toolTitle\", theme.bold(`${prompt} `));\n}\nfunction formatShellTimeout(timeout: number | undefined): string {\n\treturn timeout ? theme.fg(\"muted\", ` (timeout ${timeout}s)`) : \"\";\n}\nfunction styleShellCommand(command: string, config: Pick<ShellToolConfig, \"name\" | \"prompt\">): string {\n\tconst language = config.name === \"powershell\" ? \"powershell\" : \"bash\";\n\treturn highlightCode(command, language).join(\"\\n\");\n}\nfunction formatFullShellCall(\n\tcommand: string | null,\n\ttimeout: number | undefined,\n\tconfig: Pick<ShellToolConfig, \"name\" | \"prompt\">,\n): string {\n\tconst commandDisplay =\n\t\tcommand === null\n\t\t\t? invalidArgText(theme)\n\t\t\t: command\n\t\t\t\t? styleShellCommand(command, config)\n\t\t\t\t: theme.fg(\"toolOutput\", \"...\");\n\treturn formatShellPrompt(config.prompt) + commandDisplay + formatShellTimeout(timeout);\n}\nfunction fitCollapsedShellCall(\n\tbody: string,\n\ttimeout: number | undefined,\n\twidth: number,\n\tsuffix: string,\n\tconfig: Pick<ShellToolConfig, \"name\" | \"prompt\">,\n): string {\n\tconst prompt = formatShellPrompt(config.prompt);\n\tconst timeoutSuffix = formatShellTimeout(timeout);\n\tconst bodyWidth = Math.max(0, width - visibleWidth(prompt) - visibleWidth(suffix) - visibleWidth(timeoutSuffix));\n\tconst fittedBody = truncateToWidth(body, bodyWidth, \"\");\n\treturn truncateToWidth(prompt + fittedBody + suffix + timeoutSuffix, width, \"…\");\n}\nfunction formatTruncatedShellCall(\n\tcommand: string | null,\n\ttimeout: number | undefined,\n\twidth: number,\n\tconfig: Pick<ShellToolConfig, \"name\" | \"prompt\">,\n): string {\n\tif (command === null) return truncateToWidth(formatFullShellCall(command, timeout, config), width, \"…\");\n\tif (!command) return formatFullShellCall(command, timeout, config);\n\tconst physicalLines = command.split(/\\r?\\n/).filter((line) => line.trim());\n\tconst firstNonEmptyLine = physicalLines[0]?.trim() ?? command.trim();\n\tconst hiddenLines = Math.max(0, physicalLines.length - 1);\n\tconst suffix =\n\t\thiddenLines > 0\n\t\t\t? theme.fg(\"muted\", ` (+${hiddenLines} line${hiddenLines === 1 ? \"\" : \"s\"})`)\n\t\t\t: theme.fg(\"muted\", \" …\");\n\treturn fitCollapsedShellCall(styleShellCommand(firstNonEmptyLine, config), timeout, width, suffix, config);\n}\nfunction rebuildBashResultRenderComponent(\n\tcomponent: Container,\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: BashToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\tshowImages: boolean,\n\ttimerText: string | undefined,\n\tsubmittedAsBackground: boolean,\n): void {\n\tcomponent.clear();\n\n\tconst background = result.details?.background;\n\tlet output =\n\t\tbackground?.kind === \"background\"\n\t\t\t? `${submittedAsBackground ? \"Running in the background\" : \"Moved to background\"} · ${background.taskId}`\n\t\t\t: getTextOutput(result as any, showImages).trim();\n\tconst truncation = result.details?.truncation;\n\tconst fullOutputPath = result.details?.fullOutputPath;\n\tif (!options.isPartial && truncation?.truncated && fullOutputPath && output.endsWith(\"]\")) {\n\t\tconst footerStart = output.lastIndexOf(\"\\n\\n[\");\n\t\tif (footerStart !== -1 && output.slice(footerStart).includes(fullOutputPath)) {\n\t\t\toutput = output.slice(0, footerStart).trimEnd();\n\t\t}\n\t}\n\n\tif (output) {\n\t\tconst styledOutput = output\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => theme.fg(\"toolOutput\", line))\n\t\t\t.join(\"\\n\");\n\n\t\tif (options.expanded) {\n\t\t\tcomponent.addChild(new Text(`\\n${styledOutput}`, 0, 0));\n\t\t} else {\n\t\t\tcomponent.addChild(new Spacer(1));\n\t\t\tcomponent.addChild(\n\t\t\t\tnew VisualLinePreview({\n\t\t\t\t\ttext: styledOutput,\n\t\t\t\t\tmaxVisualLines: BASH_PREVIEW_LINES,\n\t\t\t\t\tkeep: \"end\",\n\t\t\t\t\tformatHint: (hidden) =>\n\t\t\t\t\t\ttheme.fg(\"muted\", `... (${hidden} earlier lines,`) +\n\t\t\t\t\t\t` ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\tif (truncation?.truncated || fullOutputPath) {\n\t\tconst warnings: string[] = [];\n\t\tif (fullOutputPath) {\n\t\t\twarnings.push(`Full output: ${fullOutputPath}`);\n\t\t}\n\t\tif (truncation?.truncated) {\n\t\t\tif (truncation.truncatedBy === \"lines\") {\n\t\t\t\twarnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);\n\t\t\t} else {\n\t\t\t\twarnings.push(\n\t\t\t\t\t`Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tcomponent.addChild(new Text(`\\n${theme.fg(\"warning\", `[${warnings.join(\". \")}]`)}`, 0, 0));\n\t}\n\n\tif (timerText) component.addChild(new Text(`\\n${theme.fg(\"muted\", timerText)}`, 0, 0));\n}\n\n/** Shell renderers are shared by bash and powershell, which differ in the prompt and highlight language. */\nexport function createShellRenderers(\n\tconfig: Pick<ShellToolConfig, \"name\" | \"prompt\">,\n): Pick<ToolDefinition<any, any>, \"renderCall\" | \"renderResult\"> {\n\treturn {\n\t\trenderCall(args, _theme, context) {\n\t\t\tstartToolTimer(context);\n\t\t\tconst component =\n\t\t\t\t(context.lastComponent as BashCallRenderComponent | undefined) ?? new BashCallRenderComponent(config);\n\t\t\tcomponent.update(args as { command?: string; timeout?: number } | undefined, context.expanded);\n\t\t\treturn component;\n\t\t},\n\t\trenderResult(result, options, _theme, context) {\n\t\t\t// Either slot may start the clock: an extension can replace the other one.\n\t\t\tstartToolTimer(context);\n\t\t\tconst timerText = toolTimerText(context, options.isPartial);\n\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\tconst submitted = (context.args as { background?: boolean } | undefined)?.background === true;\n\t\t\trebuildBashResultRenderComponent(component, result as any, options, context.showImages, timerText, submitted);\n\t\t\tcomponent.invalidate();\n\t\t\treturn component;\n\t\t},\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/renderers/write.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,2BAA2B,CAAC;AAqIzF,eAAO,MAAM,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,YAAY,GAAG,cAAc,CAoCxF,CAAC"}
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/renderers/write.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,2BAA2B,CAAC;AA6IzF,eAAO,MAAM,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,YAAY,GAAG,cAAc,CAkCxF,CAAC"}