@astralyn/pi 1.4.10 → 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 (595) hide show
  1. package/CHANGELOG.md +88 -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-UCH27AVQ.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-MF3T3ETJ.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-FQKRO4XJ.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 -96
  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 +2 -2
  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 +20 -12
  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/delivery.d.ts +4 -20
  164. package/dist/core/tasks/delivery.d.ts.map +1 -1
  165. package/dist/core/tasks/delivery.js +5 -58
  166. package/dist/core/tasks/delivery.js.map +1 -1
  167. package/dist/core/tasks/limits.d.ts +3 -19
  168. package/dist/core/tasks/limits.d.ts.map +1 -1
  169. package/dist/core/tasks/limits.js +3 -24
  170. package/dist/core/tasks/limits.js.map +1 -1
  171. package/dist/core/tasks/record.d.ts +1 -7
  172. package/dist/core/tasks/record.d.ts.map +1 -1
  173. package/dist/core/tasks/record.js +0 -18
  174. package/dist/core/tasks/record.js.map +1 -1
  175. package/dist/core/tasks/reminder.d.ts +3 -2
  176. package/dist/core/tasks/reminder.d.ts.map +1 -1
  177. package/dist/core/tasks/reminder.js +4 -3
  178. package/dist/core/tasks/reminder.js.map +1 -1
  179. package/dist/core/tasks/runtime.d.ts +1 -14
  180. package/dist/core/tasks/runtime.d.ts.map +1 -1
  181. package/dist/core/tasks/runtime.js +3 -96
  182. package/dist/core/tasks/runtime.js.map +1 -1
  183. package/dist/core/tasks/session.d.ts +9 -5
  184. package/dist/core/tasks/session.d.ts.map +1 -1
  185. package/dist/core/tasks/session.js +22 -24
  186. package/dist/core/tasks/session.js.map +1 -1
  187. package/dist/core/tasks/types.d.ts +3 -92
  188. package/dist/core/tasks/types.d.ts.map +1 -1
  189. package/dist/core/tasks/types.js +3 -3
  190. package/dist/core/tasks/types.js.map +1 -1
  191. package/dist/core/tools/bash.d.ts +8 -7
  192. package/dist/core/tools/bash.d.ts.map +1 -1
  193. package/dist/core/tools/bash.js +6 -5
  194. package/dist/core/tools/bash.js.map +1 -1
  195. package/dist/core/tools/edit.d.ts +3 -3
  196. package/dist/core/tools/edit.d.ts.map +1 -1
  197. package/dist/core/tools/edit.js +2 -4
  198. package/dist/core/tools/edit.js.map +1 -1
  199. package/dist/core/tools/find.d.ts +2 -2
  200. package/dist/core/tools/find.d.ts.map +1 -1
  201. package/dist/core/tools/find.js.map +1 -1
  202. package/dist/core/tools/grep.d.ts +2 -2
  203. package/dist/core/tools/grep.d.ts.map +1 -1
  204. package/dist/core/tools/grep.js +1 -1
  205. package/dist/core/tools/grep.js.map +1 -1
  206. package/dist/core/tools/ls.d.ts +2 -2
  207. package/dist/core/tools/ls.d.ts.map +1 -1
  208. package/dist/core/tools/ls.js.map +1 -1
  209. package/dist/core/tools/powershell.d.ts +1 -5
  210. package/dist/core/tools/powershell.d.ts.map +1 -1
  211. package/dist/core/tools/read.d.ts +2 -2
  212. package/dist/core/tools/read.d.ts.map +1 -1
  213. package/dist/core/tools/read.js.map +1 -1
  214. package/dist/core/tools/render-utils.d.ts +4 -6
  215. package/dist/core/tools/render-utils.d.ts.map +1 -1
  216. package/dist/core/tools/render-utils.js +19 -41
  217. package/dist/core/tools/render-utils.js.map +1 -1
  218. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  219. package/dist/core/tools/renderers/bash.js +3 -25
  220. package/dist/core/tools/renderers/bash.js.map +1 -1
  221. package/dist/core/tools/renderers/write.d.ts.map +1 -1
  222. package/dist/core/tools/renderers/write.js +18 -19
  223. package/dist/core/tools/renderers/write.js.map +1 -1
  224. package/dist/core/tools/shell-execution.d.ts +20 -13
  225. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  226. package/dist/core/tools/shell-execution.js +165 -183
  227. package/dist/core/tools/shell-execution.js.map +1 -1
  228. package/dist/core/tools/shell-tool.d.ts +9 -14
  229. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  230. package/dist/core/tools/shell-tool.js +38 -66
  231. package/dist/core/tools/shell-tool.js.map +1 -1
  232. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -4
  233. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  234. package/dist/core/tools/tool-definition-wrapper.js +2 -3
  235. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  236. package/dist/core/tools/write.d.ts +2 -2
  237. package/dist/core/tools/write.d.ts.map +1 -1
  238. package/dist/core/tools/write.js.map +1 -1
  239. package/dist/core/trust-manager.d.ts.map +1 -1
  240. package/dist/core/trust-manager.js +30 -13
  241. package/dist/core/trust-manager.js.map +1 -1
  242. package/dist/core/usage-totals.d.ts +0 -9
  243. package/dist/core/usage-totals.d.ts.map +1 -1
  244. package/dist/core/usage-totals.js +24 -91
  245. package/dist/core/usage-totals.js.map +1 -1
  246. package/dist/extensions/agent/activity-lines.d.ts +2 -3
  247. package/dist/extensions/agent/activity-lines.d.ts.map +1 -1
  248. package/dist/extensions/agent/activity-lines.js +5 -9
  249. package/dist/extensions/agent/activity-lines.js.map +1 -1
  250. package/dist/extensions/agent/activity.d.ts +0 -2
  251. package/dist/extensions/agent/activity.d.ts.map +1 -1
  252. package/dist/extensions/agent/activity.js +1 -1
  253. package/dist/extensions/agent/activity.js.map +1 -1
  254. package/dist/extensions/agent/progress.d.ts +0 -3
  255. package/dist/extensions/agent/progress.d.ts.map +1 -1
  256. package/dist/extensions/agent/progress.js +2 -8
  257. package/dist/extensions/agent/progress.js.map +1 -1
  258. package/dist/extensions/agent/render.js +1 -1
  259. package/dist/extensions/agent/render.js.map +1 -1
  260. package/dist/extensions/agent/tool.d.ts.map +1 -1
  261. package/dist/extensions/agent/tool.js +0 -6
  262. package/dist/extensions/agent/tool.js.map +1 -1
  263. package/dist/{core/isolated-session.d.ts → extensions/agent/worker-session.d.ts} +6 -6
  264. package/dist/extensions/agent/worker-session.d.ts.map +1 -0
  265. package/dist/{core/isolated-session.js → extensions/agent/worker-session.js} +9 -9
  266. package/dist/extensions/agent/worker-session.js.map +1 -0
  267. package/dist/extensions/agent/worker.d.ts +0 -3
  268. package/dist/extensions/agent/worker.d.ts.map +1 -1
  269. package/dist/extensions/agent/worker.js +2 -3
  270. package/dist/extensions/agent/worker.js.map +1 -1
  271. package/dist/extensions/btw/agent.d.ts.map +1 -1
  272. package/dist/extensions/btw/agent.js +2 -1
  273. package/dist/extensions/btw/agent.js.map +1 -1
  274. package/dist/extensions/cached-compaction/render.d.ts.map +1 -1
  275. package/dist/extensions/cached-compaction/render.js +3 -3
  276. package/dist/extensions/cached-compaction/render.js.map +1 -1
  277. package/dist/extensions/cached-compaction/summary.d.ts +1 -1
  278. package/dist/extensions/cached-compaction/summary.d.ts.map +1 -1
  279. package/dist/extensions/cached-compaction/summary.js +13 -16
  280. package/dist/extensions/cached-compaction/summary.js.map +1 -1
  281. package/dist/extensions/codemode/renderer.d.ts.map +1 -1
  282. package/dist/extensions/codemode/renderer.js +6 -2
  283. package/dist/extensions/codemode/renderer.js.map +1 -1
  284. package/dist/extensions/codemode/tool.d.ts +2 -1
  285. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  286. package/dist/extensions/codemode/tool.js +33 -8
  287. package/dist/extensions/codemode/tool.js.map +1 -1
  288. package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
  289. package/dist/extensions/deepwiki/schema.js +1 -1
  290. package/dist/extensions/deepwiki/schema.js.map +1 -1
  291. package/dist/extensions/llama/ui.d.ts.map +1 -1
  292. package/dist/extensions/llama/ui.js +16 -4
  293. package/dist/extensions/llama/ui.js.map +1 -1
  294. package/dist/extensions/mcp/cli.d.ts.map +1 -1
  295. package/dist/extensions/mcp/cli.js +34 -8
  296. package/dist/extensions/mcp/cli.js.map +1 -1
  297. package/dist/extensions/mcp/oauth.d.ts +1 -1
  298. package/dist/extensions/mcp/oauth.d.ts.map +1 -1
  299. package/dist/extensions/mcp/oauth.js +36 -13
  300. package/dist/extensions/mcp/oauth.js.map +1 -1
  301. package/dist/extensions/mcp/ui.d.ts +1 -0
  302. package/dist/extensions/mcp/ui.d.ts.map +1 -1
  303. package/dist/extensions/mcp/ui.js +33 -24
  304. package/dist/extensions/mcp/ui.js.map +1 -1
  305. package/dist/extensions/run-summary/index.d.ts +1 -1
  306. package/dist/extensions/run-summary/index.d.ts.map +1 -1
  307. package/dist/extensions/run-summary/index.js +11 -23
  308. package/dist/extensions/run-summary/index.js.map +1 -1
  309. package/dist/extensions/statusline/usage.d.ts.map +1 -1
  310. package/dist/extensions/statusline/usage.js +2 -1
  311. package/dist/extensions/statusline/usage.js.map +1 -1
  312. package/dist/extensions/tasks/tool/actions.d.ts +1 -2
  313. package/dist/extensions/tasks/tool/actions.d.ts.map +1 -1
  314. package/dist/extensions/tasks/tool/actions.js +7 -79
  315. package/dist/extensions/tasks/tool/actions.js.map +1 -1
  316. package/dist/extensions/tasks/tool/constants.d.ts +1 -3
  317. package/dist/extensions/tasks/tool/constants.d.ts.map +1 -1
  318. package/dist/extensions/tasks/tool/constants.js +1 -3
  319. package/dist/extensions/tasks/tool/constants.js.map +1 -1
  320. package/dist/extensions/tasks/tool/schema.d.ts +1 -2
  321. package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
  322. package/dist/extensions/tasks/tool/schema.js +7 -15
  323. package/dist/extensions/tasks/tool/schema.js.map +1 -1
  324. package/dist/extensions/tasks/tool/types.d.ts +1 -19
  325. package/dist/extensions/tasks/tool/types.d.ts.map +1 -1
  326. package/dist/extensions/tasks/tool/types.js.map +1 -1
  327. package/dist/extensions/tasks/tool.d.ts +1 -2
  328. package/dist/extensions/tasks/tool.d.ts.map +1 -1
  329. package/dist/extensions/tasks/tool.js +2 -4
  330. package/dist/extensions/tasks/tool.js.map +1 -1
  331. package/dist/extensions/tasks/ui/completion-render.d.ts +5 -1
  332. package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
  333. package/dist/extensions/tasks/ui/completion-render.js +25 -70
  334. package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
  335. package/dist/extensions/tasks/ui/inspector.d.ts +1 -1
  336. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
  337. package/dist/extensions/tasks/ui/inspector.js +0 -6
  338. package/dist/extensions/tasks/ui/inspector.js.map +1 -1
  339. package/dist/extensions/tasks/ui/manager.d.ts +1 -1
  340. package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
  341. package/dist/extensions/tasks/ui/manager.js.map +1 -1
  342. package/dist/extensions/tasks/ui/render.d.ts +2 -16
  343. package/dist/extensions/tasks/ui/render.d.ts.map +1 -1
  344. package/dist/extensions/tasks/ui/render.js +3 -79
  345. package/dist/extensions/tasks/ui/render.js.map +1 -1
  346. package/dist/extensions/tasks/ui/views.d.ts +2 -4
  347. package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
  348. package/dist/extensions/tasks/ui/views.js +3 -7
  349. package/dist/extensions/tasks/ui/views.js.map +1 -1
  350. package/dist/extensions/tool-presentation/fallback.d.ts.map +1 -0
  351. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/fallback.js +5 -5
  352. package/dist/extensions/tool-presentation/fallback.js.map +1 -0
  353. package/dist/extensions/tool-presentation/index.js +1 -1
  354. package/dist/extensions/tool-presentation/index.js.map +1 -1
  355. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/shell.d.ts +1 -1
  356. package/dist/extensions/tool-presentation/shell.d.ts.map +1 -0
  357. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/shell.js +3 -3
  358. package/dist/extensions/tool-presentation/shell.js.map +1 -0
  359. package/dist/extensions/tool-search/tool.d.ts +21 -6
  360. package/dist/extensions/tool-search/tool.d.ts.map +1 -1
  361. package/dist/extensions/tool-search/tool.js +104 -36
  362. package/dist/extensions/tool-search/tool.js.map +1 -1
  363. package/dist/index.d.ts +3 -3
  364. package/dist/index.d.ts.map +1 -1
  365. package/dist/index.js.map +1 -1
  366. package/dist/main.d.ts.map +1 -1
  367. package/dist/main.js +15 -8
  368. package/dist/main.js.map +1 -1
  369. package/dist/modes/interactive/components/assistant-message.d.ts +5 -3
  370. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  371. package/dist/modes/interactive/components/assistant-message.js +61 -45
  372. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  373. package/dist/modes/interactive/components/config-selector-skills.d.ts +54 -0
  374. package/dist/modes/interactive/components/config-selector-skills.d.ts.map +1 -0
  375. package/dist/modes/interactive/components/config-selector-skills.js +178 -0
  376. package/dist/modes/interactive/components/config-selector-skills.js.map +1 -0
  377. package/dist/modes/interactive/components/config-selector.d.ts +2 -11
  378. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  379. package/dist/modes/interactive/components/config-selector.js +31 -181
  380. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  381. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  382. package/dist/modes/interactive/components/custom-editor.js +7 -0
  383. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  384. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  385. package/dist/modes/interactive/components/custom-entry.js +2 -1
  386. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  387. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  388. package/dist/modes/interactive/components/custom-message.js +2 -1
  389. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  390. package/dist/modes/interactive/components/extension-editor.d.ts +2 -0
  391. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  392. package/dist/modes/interactive/components/extension-editor.js +4 -0
  393. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  394. package/dist/modes/interactive/components/login-dialog.d.ts +5 -0
  395. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  396. package/dist/modes/interactive/components/login-dialog.js +103 -10
  397. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  398. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -1
  399. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
  400. package/dist/modes/interactive/components/markdown-transform.js +3 -2
  401. package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
  402. package/dist/modes/interactive/components/model-selector.d.ts +1 -0
  403. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  404. package/dist/modes/interactive/components/model-selector.js +17 -6
  405. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  406. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -0
  407. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  408. package/dist/modes/interactive/components/oauth-selector.js +13 -4
  409. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  410. package/dist/modes/interactive/components/scoped-models-selector.d.ts +1 -0
  411. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  412. package/dist/modes/interactive/components/scoped-models-selector.js +14 -3
  413. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  414. package/dist/modes/interactive/components/session-selector-search.d.ts +4 -0
  415. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  416. package/dist/modes/interactive/components/session-selector-search.js +86 -22
  417. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  418. package/dist/modes/interactive/components/session-selector.d.ts +2 -1
  419. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  420. package/dist/modes/interactive/components/session-selector.js +15 -23
  421. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  422. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
  423. package/dist/modes/interactive/components/settings-submenu.js +2 -0
  424. package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
  425. package/dist/modes/interactive/components/tool-execution.d.ts +7 -0
  426. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  427. package/dist/modes/interactive/components/tool-execution.js +48 -9
  428. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  429. package/dist/modes/interactive/components/tree-selector.d.ts +1 -0
  430. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  431. package/dist/modes/interactive/components/tree-selector.js +5 -6
  432. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  433. package/dist/modes/interactive/components/user-message-selector.d.ts +1 -0
  434. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  435. package/dist/modes/interactive/components/user-message-selector.js +9 -1
  436. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  437. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  438. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  439. package/dist/modes/interactive/components/user-message.js +4 -2
  440. package/dist/modes/interactive/components/user-message.js.map +1 -1
  441. package/dist/modes/interactive/editor-host.d.ts.map +1 -1
  442. package/dist/modes/interactive/editor-host.js +3 -2
  443. package/dist/modes/interactive/editor-host.js.map +1 -1
  444. package/dist/modes/interactive/external-editor.d.ts +1 -0
  445. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  446. package/dist/modes/interactive/external-editor.js +17 -5
  447. package/dist/modes/interactive/external-editor.js.map +1 -1
  448. package/dist/modes/interactive/interactive-mode.d.ts +8 -12
  449. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  450. package/dist/modes/interactive/interactive-mode.js +169 -112
  451. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  452. package/dist/modes/interactive/model-search.d.ts +10 -0
  453. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  454. package/dist/modes/interactive/model-search.js +21 -0
  455. package/dist/modes/interactive/model-search.js.map +1 -1
  456. package/dist/modes/interactive/theme/theme.d.ts +10 -0
  457. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  458. package/dist/modes/interactive/theme/theme.js +30 -23
  459. package/dist/modes/interactive/theme/theme.js.map +1 -1
  460. package/dist/modes/interactive/tool-view/chat.d.ts +2 -2
  461. package/dist/modes/interactive/tool-view/chat.d.ts.map +1 -1
  462. package/dist/modes/interactive/tool-view/chat.js +22 -19
  463. package/dist/modes/interactive/tool-view/chat.js.map +1 -1
  464. package/dist/modes/interactive/transcript-layout.d.ts +2 -0
  465. package/dist/modes/interactive/transcript-layout.d.ts.map +1 -1
  466. package/dist/modes/interactive/transcript-layout.js +5 -2
  467. package/dist/modes/interactive/transcript-layout.js.map +1 -1
  468. package/dist/modes/print-mode.d.ts.map +1 -1
  469. package/dist/modes/print-mode.js +1 -0
  470. package/dist/modes/print-mode.js.map +1 -1
  471. package/dist/modes/rpc/rpc-client.d.ts +9 -1
  472. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  473. package/dist/modes/rpc/rpc-client.js +23 -23
  474. package/dist/modes/rpc/rpc-client.js.map +1 -1
  475. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  476. package/dist/modes/rpc/rpc-mode.js +1 -3
  477. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  478. package/dist/package-manager-cli.d.ts.map +1 -1
  479. package/dist/package-manager-cli.js +55 -4
  480. package/dist/package-manager-cli.js.map +1 -1
  481. package/dist/utils/ansi.d.ts.map +1 -1
  482. package/dist/utils/ansi.js +5 -2
  483. package/dist/utils/ansi.js.map +1 -1
  484. package/dist/utils/clipboard-command.d.ts.map +1 -1
  485. package/dist/utils/clipboard-command.js +4 -0
  486. package/dist/utils/clipboard-command.js.map +1 -1
  487. package/dist/utils/git.d.ts +1 -1
  488. package/dist/utils/git.d.ts.map +1 -1
  489. package/dist/utils/git.js.map +1 -1
  490. package/dist/utils/image-resize-core.d.ts.map +1 -1
  491. package/dist/utils/image-resize-core.js +5 -3
  492. package/dist/utils/image-resize-core.js.map +1 -1
  493. package/dist/utils/open-browser.d.ts.map +1 -1
  494. package/dist/utils/open-browser.js +4 -1
  495. package/dist/utils/open-browser.js.map +1 -1
  496. package/dist/utils/paths.d.ts +17 -0
  497. package/dist/utils/paths.d.ts.map +1 -1
  498. package/dist/utils/paths.js +42 -1
  499. package/dist/utils/paths.js.map +1 -1
  500. package/dist/utils/shell.d.ts.map +1 -1
  501. package/dist/utils/shell.js +14 -0
  502. package/dist/utils/shell.js.map +1 -1
  503. package/dist/utils/syntax-highlight.d.ts +5 -0
  504. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  505. package/dist/utils/syntax-highlight.js +7 -0
  506. package/dist/utils/syntax-highlight.js.map +1 -1
  507. package/dist/utils/tools-manager.d.ts.map +1 -1
  508. package/dist/utils/tools-manager.js +30 -35
  509. package/dist/utils/tools-manager.js.map +1 -1
  510. package/dist/utils/usage.d.ts +5 -0
  511. package/dist/utils/usage.d.ts.map +1 -0
  512. package/dist/utils/usage.js +16 -0
  513. package/dist/utils/usage.js.map +1 -0
  514. package/docs/bundled/README.md +1 -1
  515. package/docs/bundled/extensions/agent.md +7 -7
  516. package/docs/bundled/extensions/run-summary.md +4 -4
  517. package/docs/bundled/extensions/statusline.md +1 -1
  518. package/docs/bundled/tasks.md +12 -27
  519. package/docs/bundled/tool-presentation.md +2 -2
  520. package/docs/custom-provider.md +1 -1
  521. package/docs/environment-variables.md +2 -0
  522. package/docs/extensions.md +41 -28
  523. package/docs/keybindings.md +1 -1
  524. package/docs/llama-cpp.md +17 -12
  525. package/docs/mcp.md +6 -4
  526. package/docs/models-configuration.md +1 -1
  527. package/docs/models.md +7 -85
  528. package/docs/packages.md +26 -1
  529. package/docs/rpc.md +1 -1
  530. package/docs/sdk.md +10 -8
  531. package/docs/session-format.md +3 -3
  532. package/docs/sessions.md +10 -0
  533. package/docs/settings.md +5 -4
  534. package/docs/terminal-setup.md +2 -2
  535. package/docs/tmux.md +6 -0
  536. package/docs/tui.md +12 -7
  537. package/docs/usage.md +19 -9
  538. package/docs/windows.md +29 -0
  539. package/examples/extensions/README.md +2 -1
  540. package/examples/extensions/custom-provider-anthropic/index.ts +27 -31
  541. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  542. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  543. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  544. package/examples/extensions/debug-provider.ts +2 -2
  545. package/examples/extensions/gondolin/package-lock.json +19 -29
  546. package/examples/extensions/gondolin/package.json +2 -2
  547. package/examples/extensions/preset.ts +2 -0
  548. package/examples/extensions/reload-runtime.ts +17 -5
  549. package/examples/extensions/tools.ts +2 -0
  550. package/examples/extensions/with-deps/package-lock.json +2 -2
  551. package/examples/extensions/with-deps/package.json +1 -1
  552. package/package.json +11 -12
  553. package/schemas/models.schema.json +36 -36
  554. package/schemas/settings.schema.json +17 -0
  555. package/dist/bundle/chunks/anthropic-messages-HWL6AS7T.js +0 -6
  556. package/dist/bundle/chunks/azure-openai-responses-4YYPDYV5.js +0 -2
  557. package/dist/bundle/chunks/chunk-6GTUUUCJ.js +0 -1499
  558. package/dist/bundle/chunks/chunk-6JS2SOFO.js +0 -11
  559. package/dist/bundle/chunks/chunk-ANCZPKX7.js +0 -2
  560. package/dist/bundle/chunks/chunk-FEZ5RM2B.js +0 -2
  561. package/dist/bundle/chunks/chunk-LPF7HQ3S.js +0 -4
  562. package/dist/bundle/chunks/chunk-MMNIHCU7.js +0 -2
  563. package/dist/bundle/chunks/chunk-R267VV5T.js +0 -82
  564. package/dist/bundle/chunks/chunk-RVKT7OUB.js +0 -9
  565. package/dist/bundle/chunks/chunk-SA2AQYEI.js +0 -7
  566. package/dist/bundle/chunks/chunk-ZAIGBRV5.js +0 -16
  567. package/dist/bundle/chunks/mistral-conversations-V2JJTMJ5.js +0 -5
  568. package/dist/bundle/chunks/openai-completions-TXZXILJR.js +0 -7
  569. package/dist/bundle/chunks/pi-messages-LBJQ4NGP.js +0 -8
  570. package/dist/bundle/chunks/virtual-modules-6IJ6V2CG.js +0 -2
  571. package/dist/core/isolated-session.d.ts.map +0 -1
  572. package/dist/core/isolated-session.js.map +0 -1
  573. package/dist/core/tasks/wait.d.ts +0 -19
  574. package/dist/core/tasks/wait.d.ts.map +0 -1
  575. package/dist/core/tasks/wait.js +0 -45
  576. package/dist/core/tasks/wait.js.map +0 -1
  577. package/dist/modes/interactive/tool-view/fallback.d.ts.map +0 -1
  578. package/dist/modes/interactive/tool-view/fallback.js.map +0 -1
  579. package/dist/modes/interactive/tool-view/shell.d.ts.map +0 -1
  580. package/dist/modes/interactive/tool-view/shell.js.map +0 -1
  581. package/dist/modes/interactive/tool-view/tool-execution.d.ts +0 -14
  582. package/dist/modes/interactive/tool-view/tool-execution.d.ts.map +0 -1
  583. package/dist/modes/interactive/tool-view/tool-execution.js +0 -13
  584. package/dist/modes/interactive/tool-view/tool-execution.js.map +0 -1
  585. package/dist/utils/path-identity.d.ts +0 -12
  586. package/dist/utils/path-identity.d.ts.map +0 -1
  587. package/dist/utils/path-identity.js +0 -63
  588. package/dist/utils/path-identity.js.map +0 -1
  589. package/docs/images/doom-extension.png +0 -0
  590. package/docs/images/exy.png +0 -0
  591. package/examples/extensions/sandbox/index.ts +0 -321
  592. package/examples/extensions/sandbox/package-lock.json +0 -92
  593. package/examples/extensions/sandbox/package.json +0 -19
  594. package/npm-shrinkwrap.json +0 -4207
  595. /package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/fallback.d.ts +0 -0
@@ -1,214 +1,196 @@
1
+ /**
2
+ * Runs the native shell tool body (`bash.ts`) as one session task. The native body owns the
3
+ * process, progress, output formatting and structured result; this adapter only supplies the
4
+ * task's output log, its background limits and acceptance, and translates the native outcome
5
+ * into a task completion.
6
+ */
1
7
  import { unlink } from "node:fs/promises";
2
8
  import { boundText } from "../tasks/output.js";
9
+ import { resolveTimeoutMs } from "./bash.js";
3
10
  import { OutputAccumulator } from "./output-accumulator.js";
4
- import { BASH_UPDATE_THROTTLE_MS } from "./renderers/bash.js";
5
- import { formatSize } from "./truncate.js";
6
11
  export const MAX_BACKGROUND_OUTPUT_BYTES = 20 * 1024 * 1024;
7
- /** Interpret the documented BashOperations error markers once, before formatting output. */
8
- function shellFailure(error) {
9
- if (error instanceof Error && error.message === "aborted")
10
- return { status: "cancelled", error: "Command aborted" };
11
- if (error instanceof Error && error.message.startsWith("timeout:"))
12
- return { status: "timeout", error: `Command timed out after ${error.message.split(":")[1]} seconds` };
13
- return { status: "failed", error: boundText(error instanceof Error ? error.message : String(error), 4096) };
14
- }
15
- function formatOutput(output, snapshot, taskLog, emptyText) {
16
- const truncation = snapshot.truncation;
17
- let text = snapshot.content || emptyText;
18
- let details = taskLog ? { fullOutputPath: snapshot.fullOutputPath } : undefined;
19
- if (truncation.truncated) {
20
- details = { truncation, fullOutputPath: snapshot.fullOutputPath };
21
- const startLine = truncation.totalLines - truncation.outputLines + 1;
22
- const endLine = truncation.totalLines;
23
- if (truncation.lastLinePartial) {
24
- const lastLineSize = formatSize(output.getLastLineBytes());
25
- text += `\n\n[Showing last ${formatSize(truncation.outputBytes)} of line ${endLine} (line is ${lastLineSize}). Full output: ${snapshot.fullOutputPath}]`;
26
- }
27
- else if (truncation.truncatedBy === "lines") {
28
- text += `\n\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines}. Full output: ${snapshot.fullOutputPath}]`;
29
- }
30
- else {
31
- text += `\n\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines} (${formatSize(truncation.maxBytes)} limit). Full output: ${snapshot.fullOutputPath}]`;
32
- }
12
+ /** Background snapshots stay within the task result budget, so the bounded result keeps the newest output. */
13
+ const BACKGROUND_SNAPSHOT_BYTES = 40 * 1024;
14
+ const OUTPUT_LIMIT_ERROR = "Background command exceeded the 20 MiB output limit";
15
+ /**
16
+ * A session task's output: persisted from the first byte to the log attached to the task, and
17
+ * bounded once the task is background work. A write failure or the background cap cancels the
18
+ * task instead of throwing through the process's data observer.
19
+ */
20
+ class TaskOutput extends OutputAccumulator {
21
+ constructor(control, options) {
22
+ super({ ...options, persistFromStart: true });
23
+ this.control = control;
33
24
  }
34
- return { text, details };
35
- }
36
- /** One process and one output owner across foreground/background handoff. */
37
- export async function runShellCommand(options) {
38
- const { operations, context, control, taskLog, timeout } = options;
39
- const signal = control.signal;
40
- const output = new OutputAccumulator({ tempFilePrefix: options.tempFilePrefix, persistFromStart: taskLog });
41
- const startedAt = performance.now();
42
- let outputError;
43
- let acceptingOutput = true;
44
- let unsubscribe;
45
- let updateTimer;
46
- let updateDirty = false;
47
- let lastUpdateAt = 0;
48
- const failOutput = (error) => {
49
- if (outputError)
25
+ append(data) {
26
+ if (this.error)
50
27
  return;
51
- outputError = error instanceof Error ? error : new Error(String(error));
52
28
  try {
53
- control.cancel();
54
- }
55
- catch {
56
- // Late data must not throw through a process observer.
57
- }
58
- };
59
- const checkOutputLimit = () => {
60
- if (control.mode === "background" && output.getTotalBytes() > MAX_BACKGROUND_OUTPUT_BYTES) {
61
- failOutput(new Error("Background command exceeded the 20 MiB output limit"));
62
- }
63
- };
64
- const snapshot = () => output.snapshot({
65
- persistIfTruncated: true,
66
- maxBytes: control.mode === "background" ? 40 * 1024 : undefined,
67
- });
68
- const publish = (snapshot) => {
69
- const result = {
70
- content: snapshot ? [{ type: "text", text: snapshot.content }] : [],
71
- details: snapshot
72
- ? {
73
- truncation: snapshot.truncation.truncated ? snapshot.truncation : undefined,
74
- fullOutputPath: snapshot.fullOutputPath,
75
- }
76
- : undefined,
77
- };
78
- control.publish({ result });
79
- };
80
- const emitOutputUpdate = () => {
81
- if (!updateDirty)
82
- return;
83
- updateDirty = false;
84
- lastUpdateAt = Date.now();
85
- publish(snapshot());
86
- };
87
- const clearUpdateTimer = () => {
88
- if (updateTimer)
89
- clearTimeout(updateTimer);
90
- updateTimer = undefined;
91
- };
92
- const scheduleOutputUpdate = () => {
93
- updateDirty = true;
94
- const delay = BASH_UPDATE_THROTTLE_MS - (Date.now() - lastUpdateAt);
95
- if (delay <= 0) {
96
- clearUpdateTimer();
97
- emitOutputUpdate();
29
+ const room = MAX_BACKGROUND_OUTPUT_BYTES - this.getTotalBytes();
30
+ if (this.control.mode === "background" && data.length > room) {
31
+ super.append(data.subarray(0, Math.max(0, room)));
32
+ this.fail(new Error(OUTPUT_LIMIT_ERROR));
33
+ }
34
+ else
35
+ super.append(data);
98
36
  }
99
- else {
100
- updateTimer ??= setTimeout(() => {
101
- updateTimer = undefined;
102
- emitOutputUpdate();
103
- }, delay);
37
+ catch (error) {
38
+ this.fail(error);
104
39
  }
105
- };
106
- const handleData = (data) => {
107
- if (!acceptingOutput || outputError)
40
+ }
41
+ snapshot(options = {}) {
42
+ return super.snapshot(this.control.mode === "background" ? { ...options, maxBytes: BACKGROUND_SNAPSHOT_BYTES } : options);
43
+ }
44
+ /** A detach must check output written while in the foreground, preserving it. */
45
+ checkLimit() {
46
+ if (this.control.mode === "background" && this.getTotalBytes() > MAX_BACKGROUND_OUTPUT_BYTES)
47
+ this.fail(new Error(OUTPUT_LIMIT_ERROR));
48
+ }
49
+ fail(error) {
50
+ if (this.error)
108
51
  return;
52
+ this.error = error instanceof Error ? error : new Error(String(error));
109
53
  try {
110
- if (control.mode === "background" && output.getTotalBytes() + data.length > MAX_BACKGROUND_OUTPUT_BYTES) {
111
- const remaining = Math.max(0, MAX_BACKGROUND_OUTPUT_BYTES - output.getTotalBytes());
112
- output.append(data.subarray(0, remaining));
113
- failOutput(new Error("Background command exceeded the 20 MiB output limit"));
114
- }
115
- else
116
- output.append(data);
117
- scheduleOutputUpdate();
54
+ this.control.cancel();
118
55
  }
119
- catch (error) {
120
- failOutput(error);
56
+ catch {
57
+ // Late data must not throw through a process observer.
121
58
  }
59
+ }
60
+ }
61
+ /** Interpret the documented BashOperations error markers and exit codes as the native body states them. */
62
+ function processFailure(outcome) {
63
+ const { error, exitCode } = outcome;
64
+ if (error instanceof Error && error.message === "aborted")
65
+ return { status: "cancelled", error: "Command aborted" };
66
+ if (error instanceof Error && error.message.startsWith("timeout:"))
67
+ return { status: "timeout", error: `Command timed out after ${error.message.split(":")[1]} seconds` };
68
+ if (error !== undefined)
69
+ return { status: "failed", error: errorMessage(error) };
70
+ if (exitCode === null)
71
+ return { status: "failed", error: "Command terminated without an exit code" };
72
+ if (exitCode !== undefined && exitCode !== 0)
73
+ return { status: "failed", error: `Command exited with code ${exitCode}` };
74
+ return undefined;
75
+ }
76
+ function errorMessage(error) {
77
+ return boundText(error instanceof Error ? error.message : String(error), 4096);
78
+ }
79
+ /** The native body appends its failure status to the output; a task keeps them apart. */
80
+ function withoutStatus(text, status) {
81
+ if (text === status)
82
+ return "";
83
+ const suffix = `\n\n${status}`;
84
+ return text.endsWith(suffix) ? text.slice(0, -suffix.length) : text;
85
+ }
86
+ function resultText(result) {
87
+ return result.content
88
+ .filter((part) => part.type === "text")
89
+ .map((part) => part.text)
90
+ .join("\n");
91
+ }
92
+ /**
93
+ * One process and one output owner across foreground/background handoff. The task result holds
94
+ * the command's output only; its failure is the completion's `error`.
95
+ */
96
+ export async function runShellTask(options) {
97
+ const { control } = options;
98
+ if (control.signal.aborted)
99
+ throw new Error("Command aborted");
100
+ resolveTimeoutMs(options.timeout);
101
+ const output = new TaskOutput(control, { tempFilePrefix: options.tempFilePrefix });
102
+ const path = output.snapshot().fullOutputPath;
103
+ const cleanup = async () => {
104
+ await output.closeTempFile();
105
+ await unlink(path).catch((error) => {
106
+ if (error.code !== "ENOENT")
107
+ throw error;
108
+ });
122
109
  };
123
110
  try {
124
- if (taskLog) {
125
- const path = output.snapshot().fullOutputPath;
126
- const cleanup = async () => {
127
- await output.closeTempFile();
128
- await unlink(path).catch((error) => {
129
- if (error.code !== "ENOENT")
130
- throw error;
131
- });
132
- };
111
+ control.attachOutput(path, cleanup);
112
+ }
113
+ catch (error) {
114
+ await cleanup();
115
+ throw error;
116
+ }
117
+ const unsubscribe = control.onModeChange(() => output.checkLimit());
118
+ const spawned = {};
119
+ const operations = {
120
+ exec: (command, cwd, execOptions) => {
121
+ let running;
133
122
  try {
134
- control.attachOutput(path, cleanup);
123
+ running = options.operations.exec(command, cwd, execOptions);
135
124
  }
136
125
  catch (error) {
137
- await cleanup();
126
+ spawned.error = error;
138
127
  throw error;
139
128
  }
140
- }
141
- // Detach must check a silent foreground log too, preserving bytes already written.
142
- unsubscribe = control.onModeChange(checkOutputLimit);
143
- publish();
144
- let failure;
145
- let exitCode;
129
+ // The process exists, so a handoff can no longer start it twice.
130
+ control.accept();
131
+ return running.then((result) => {
132
+ spawned.exitCode = result.exitCode;
133
+ return result;
134
+ }, (error) => {
135
+ spawned.error = error;
136
+ throw error;
137
+ });
138
+ },
139
+ };
140
+ let result;
141
+ let thrown;
142
+ try {
146
143
  try {
147
- if (signal?.aborted)
148
- throw new Error("aborted");
149
- const execution = operations.exec(context.command, context.cwd, {
150
- onData: handleData,
151
- signal,
152
- timeout,
153
- env: context.env,
144
+ result = await options.execute({
145
+ createOutput: () => output,
146
+ operations,
147
+ onUpdate: (update) => control.publish({ result: update }),
154
148
  });
155
- control.accept();
156
- ({ exitCode } = await execution);
157
- if (exitCode === null) {
158
- failure = { status: "failed", error: "Command terminated without an exit code" };
159
- }
160
- else if (exitCode !== 0) {
161
- failure = { status: "failed", error: `Command exited with code ${exitCode}` };
162
- }
163
149
  }
164
150
  catch (error) {
165
- failure = shellFailure(error);
151
+ thrown = error;
166
152
  }
167
- acceptingOutput = false;
168
- output.finish();
169
- clearUpdateTimer();
170
- if (taskLog)
171
- publish(snapshot());
172
- else
173
- emitOutputUpdate();
174
- const final = snapshot();
175
- await output.closeTempFile();
176
- // Final progress/cleanup can re-enter handoff. Classify policy cancellation
177
- // after those callbacks, independently of the process's abort marker.
178
- if (outputError)
179
- failure = { status: "failed", error: boundText(outputError.message, 4096) };
180
- const { text, details } = formatOutput(output, final, taskLog, failure ? "" : "(no output)");
181
- const fullOutput = typeof exitCode === "number" && !outputError ? await output.readFullOutput(1024 * 1024) : undefined;
182
- return {
183
- status: failure?.status,
184
- error: failure?.error,
185
- ...(exitCode !== undefined ? { facts: [["Exit", exitCode === null ? "signal" : String(exitCode)]] } : {}),
186
- result: {
187
- ...(fullOutput && typeof exitCode === "number"
188
- ? {
189
- structuredContent: {
190
- output: fullOutput.content,
191
- truncated: fullOutput.truncated,
192
- ...(fullOutput.truncated && final.fullOutputPath
193
- ? { full_output_path: final.fullOutputPath }
194
- : {}),
195
- exit_code: exitCode,
196
- wall_time_seconds: Math.round((performance.now() - startedAt) / 100) / 10,
197
- },
198
- ...(failure ? { isError: true } : {}),
199
- }
200
- : {}),
201
- // The command's output only: its failure is the completion's `error`, composed where a result is shown.
202
- content: [{ type: "text", text }],
203
- details,
204
- },
205
- };
206
153
  }
207
154
  finally {
208
- acceptingOutput = false;
209
- unsubscribe?.();
210
- clearUpdateTimer();
155
+ unsubscribe();
211
156
  await output.closeTempFile();
212
157
  }
158
+ return shellCompletion(output, path, spawned, result, thrown);
159
+ }
160
+ function shellCompletion(output, path, spawned, result, thrown) {
161
+ const started = "exitCode" in spawned || "error" in spawned;
162
+ const failure = processFailure(spawned) ?? (thrown === undefined ? undefined : { status: "failed", error: errorMessage(thrown) });
163
+ // The native result or error carries the formatted output; a raw operations error carries none.
164
+ const formatted = result !== undefined
165
+ ? resultText(result)
166
+ : thrown instanceof Error && thrown !== spawned.error && started
167
+ ? thrown.message
168
+ : started
169
+ ? output.snapshot().content
170
+ : "";
171
+ const text = failure ? withoutStatus(formatted, failure.error) : formatted;
172
+ const truncation = output.snapshot().truncation;
173
+ const details = {
174
+ ...(result?.details ?? (truncation.truncated ? { truncation } : {})),
175
+ fullOutputPath: path,
176
+ };
177
+ // A cancellation the output policy caused is that policy's failure, not the process's abort.
178
+ const policy = output.error ? { status: "failed", error: errorMessage(output.error) } : undefined;
179
+ const settled = policy ?? failure;
180
+ const keepStructured = result?.structuredContent !== undefined && !policy;
181
+ return {
182
+ status: settled?.status,
183
+ error: settled?.error,
184
+ ...(spawned.exitCode !== undefined
185
+ ? { facts: [["Exit", spawned.exitCode === null ? "signal" : String(spawned.exitCode)]] }
186
+ : {}),
187
+ result: {
188
+ ...(keepStructured
189
+ ? { structuredContent: result.structuredContent, ...(settled ? { isError: true } : {}) }
190
+ : {}),
191
+ content: [{ type: "text", text }],
192
+ details,
193
+ },
194
+ };
213
195
  }
214
196
  //# sourceMappingURL=shell-execution.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shell-execution.js","sourceRoot":"","sources":["../../../src/core/tools/shell-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import { unlink } from \"node:fs/promises\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport { boundText } from \"../tasks/output.ts\";\nimport type { TaskCompletion, TaskControl } from \"../tasks/types.ts\";\nimport type { BashOperations, BashSpawnContext } from \"./bash.ts\";\nimport { OutputAccumulator, type OutputSnapshot } from \"./output-accumulator.ts\";\nimport { BASH_UPDATE_THROTTLE_MS } from \"./renderers/bash.ts\";\nimport type { BashToolDetails } from \"./shell-tool.ts\";\nimport { formatSize } from \"./truncate.ts\";\n\nexport const MAX_BACKGROUND_OUTPUT_BYTES = 20 * 1024 * 1024;\n\ninterface ShellExecutionOptions {\n\toperations: BashOperations;\n\tcontext: BashSpawnContext;\n\ttempFilePrefix: string;\n\ttimeout?: number;\n\t/** The task this command runs as; its signal cancels the process. */\n\tcontrol: TaskControl<BashToolDetails | undefined>;\n\t/**\n\t * The command belongs to a session task, which may leave the foreground: its output log is\n\t * created and attached to the task from the first byte, and a final snapshot is always\n\t * published. Otherwise the log is created only if output is truncated.\n\t */\n\ttaskLog: boolean;\n}\n\ninterface ShellFailure {\n\tstatus: \"failed\" | \"cancelled\" | \"timeout\";\n\terror: string;\n}\n\n/** Interpret the documented BashOperations error markers once, before formatting output. */\nfunction shellFailure(error: unknown): ShellFailure {\n\tif (error instanceof Error && error.message === \"aborted\") return { status: \"cancelled\", error: \"Command aborted\" };\n\tif (error instanceof Error && error.message.startsWith(\"timeout:\"))\n\t\treturn { status: \"timeout\", error: `Command timed out after ${error.message.split(\":\")[1]} seconds` };\n\treturn { status: \"failed\", error: boundText(error instanceof Error ? error.message : String(error), 4096) };\n}\n\nfunction formatOutput(\n\toutput: OutputAccumulator,\n\tsnapshot: OutputSnapshot,\n\ttaskLog: boolean,\n\temptyText: string,\n): { text: string; details: BashToolDetails | undefined } {\n\tconst truncation = snapshot.truncation;\n\tlet text = snapshot.content || emptyText;\n\tlet details: BashToolDetails | undefined = taskLog ? { fullOutputPath: snapshot.fullOutputPath } : undefined;\n\tif (truncation.truncated) {\n\t\tdetails = { truncation, fullOutputPath: snapshot.fullOutputPath };\n\t\tconst startLine = truncation.totalLines - truncation.outputLines + 1;\n\t\tconst endLine = truncation.totalLines;\n\t\tif (truncation.lastLinePartial) {\n\t\t\tconst lastLineSize = formatSize(output.getLastLineBytes());\n\t\t\ttext += `\\n\\n[Showing last ${formatSize(truncation.outputBytes)} of line ${endLine} (line is ${lastLineSize}). Full output: ${snapshot.fullOutputPath}]`;\n\t\t} else if (truncation.truncatedBy === \"lines\") {\n\t\t\ttext += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines}. Full output: ${snapshot.fullOutputPath}]`;\n\t\t} else {\n\t\t\ttext += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines} (${formatSize(truncation.maxBytes)} limit). Full output: ${snapshot.fullOutputPath}]`;\n\t\t}\n\t}\n\treturn { text, details };\n}\n\n/** One process and one output owner across foreground/background handoff. */\nexport async function runShellCommand(\n\toptions: ShellExecutionOptions,\n): Promise<TaskCompletion<BashToolDetails | undefined>> {\n\tconst { operations, context, control, taskLog, timeout } = options;\n\tconst signal = control.signal;\n\tconst output = new OutputAccumulator({ tempFilePrefix: options.tempFilePrefix, persistFromStart: taskLog });\n\tconst startedAt = performance.now();\n\tlet outputError: Error | undefined;\n\tlet acceptingOutput = true;\n\tlet unsubscribe: (() => void) | undefined;\n\tlet updateTimer: NodeJS.Timeout | undefined;\n\tlet updateDirty = false;\n\tlet lastUpdateAt = 0;\n\n\tconst failOutput = (error: unknown) => {\n\t\tif (outputError) return;\n\t\toutputError = error instanceof Error ? error : new Error(String(error));\n\t\ttry {\n\t\t\tcontrol.cancel();\n\t\t} catch {\n\t\t\t// Late data must not throw through a process observer.\n\t\t}\n\t};\n\tconst checkOutputLimit = () => {\n\t\tif (control.mode === \"background\" && output.getTotalBytes() > MAX_BACKGROUND_OUTPUT_BYTES) {\n\t\t\tfailOutput(new Error(\"Background command exceeded the 20 MiB output limit\"));\n\t\t}\n\t};\n\tconst snapshot = () =>\n\t\toutput.snapshot({\n\t\t\tpersistIfTruncated: true,\n\t\t\tmaxBytes: control.mode === \"background\" ? 40 * 1024 : undefined,\n\t\t});\n\tconst publish = (snapshot?: OutputSnapshot) => {\n\t\tconst result: AgentToolResult<BashToolDetails | undefined> = {\n\t\t\tcontent: snapshot ? [{ type: \"text\", text: snapshot.content }] : [],\n\t\t\tdetails: snapshot\n\t\t\t\t? {\n\t\t\t\t\t\ttruncation: snapshot.truncation.truncated ? snapshot.truncation : undefined,\n\t\t\t\t\t\tfullOutputPath: snapshot.fullOutputPath,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t};\n\t\tcontrol.publish({ result });\n\t};\n\tconst emitOutputUpdate = () => {\n\t\tif (!updateDirty) return;\n\t\tupdateDirty = false;\n\t\tlastUpdateAt = Date.now();\n\t\tpublish(snapshot());\n\t};\n\tconst clearUpdateTimer = () => {\n\t\tif (updateTimer) clearTimeout(updateTimer);\n\t\tupdateTimer = undefined;\n\t};\n\tconst scheduleOutputUpdate = () => {\n\t\tupdateDirty = true;\n\t\tconst delay = BASH_UPDATE_THROTTLE_MS - (Date.now() - lastUpdateAt);\n\t\tif (delay <= 0) {\n\t\t\tclearUpdateTimer();\n\t\t\temitOutputUpdate();\n\t\t} else {\n\t\t\tupdateTimer ??= setTimeout(() => {\n\t\t\t\tupdateTimer = undefined;\n\t\t\t\temitOutputUpdate();\n\t\t\t}, delay);\n\t\t}\n\t};\n\tconst handleData = (data: Buffer) => {\n\t\tif (!acceptingOutput || outputError) return;\n\t\ttry {\n\t\t\tif (control.mode === \"background\" && output.getTotalBytes() + data.length > MAX_BACKGROUND_OUTPUT_BYTES) {\n\t\t\t\tconst remaining = Math.max(0, MAX_BACKGROUND_OUTPUT_BYTES - output.getTotalBytes());\n\t\t\t\toutput.append(data.subarray(0, remaining));\n\t\t\t\tfailOutput(new Error(\"Background command exceeded the 20 MiB output limit\"));\n\t\t\t} else output.append(data);\n\t\t\tscheduleOutputUpdate();\n\t\t} catch (error) {\n\t\t\tfailOutput(error);\n\t\t}\n\t};\n\n\ttry {\n\t\tif (taskLog) {\n\t\t\tconst path = output.snapshot().fullOutputPath!;\n\t\t\tconst cleanup = async () => {\n\t\t\t\tawait output.closeTempFile();\n\t\t\t\tawait unlink(path).catch((error: NodeJS.ErrnoException) => {\n\t\t\t\t\tif (error.code !== \"ENOENT\") throw error;\n\t\t\t\t});\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tcontrol.attachOutput(path, cleanup);\n\t\t\t} catch (error) {\n\t\t\t\tawait cleanup();\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\t// Detach must check a silent foreground log too, preserving bytes already written.\n\t\tunsubscribe = control.onModeChange(checkOutputLimit);\n\t\tpublish();\n\t\tlet failure: ShellFailure | undefined;\n\t\tlet exitCode: number | null | undefined;\n\t\ttry {\n\t\t\tif (signal?.aborted) throw new Error(\"aborted\");\n\t\t\tconst execution = operations.exec(context.command, context.cwd, {\n\t\t\t\tonData: handleData,\n\t\t\t\tsignal,\n\t\t\t\ttimeout,\n\t\t\t\tenv: context.env,\n\t\t\t});\n\t\t\tcontrol.accept();\n\t\t\t({ exitCode } = await execution);\n\t\t\tif (exitCode === null) {\n\t\t\t\tfailure = { status: \"failed\", error: \"Command terminated without an exit code\" };\n\t\t\t} else if (exitCode !== 0) {\n\t\t\t\tfailure = { status: \"failed\", error: `Command exited with code ${exitCode}` };\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tfailure = shellFailure(error);\n\t\t}\n\t\tacceptingOutput = false;\n\t\toutput.finish();\n\t\tclearUpdateTimer();\n\t\tif (taskLog) publish(snapshot());\n\t\telse emitOutputUpdate();\n\t\tconst final = snapshot();\n\t\tawait output.closeTempFile();\n\t\t// Final progress/cleanup can re-enter handoff. Classify policy cancellation\n\t\t// after those callbacks, independently of the process's abort marker.\n\t\tif (outputError) failure = { status: \"failed\", error: boundText(outputError.message, 4096) };\n\t\tconst { text, details } = formatOutput(output, final, taskLog, failure ? \"\" : \"(no output)\");\n\t\tconst fullOutput =\n\t\t\ttypeof exitCode === \"number\" && !outputError ? await output.readFullOutput(1024 * 1024) : undefined;\n\t\treturn {\n\t\t\tstatus: failure?.status,\n\t\t\terror: failure?.error,\n\t\t\t...(exitCode !== undefined ? { facts: [[\"Exit\", exitCode === null ? \"signal\" : String(exitCode)]] } : {}),\n\t\t\tresult: {\n\t\t\t\t...(fullOutput && typeof exitCode === \"number\"\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tstructuredContent: {\n\t\t\t\t\t\t\t\toutput: fullOutput.content,\n\t\t\t\t\t\t\t\ttruncated: fullOutput.truncated,\n\t\t\t\t\t\t\t\t...(fullOutput.truncated && final.fullOutputPath\n\t\t\t\t\t\t\t\t\t? { full_output_path: final.fullOutputPath }\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\texit_code: exitCode,\n\t\t\t\t\t\t\t\twall_time_seconds: Math.round((performance.now() - startedAt) / 100) / 10,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t...(failure ? { isError: true } : {}),\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\t// The command's output only: its failure is the completion's `error`, composed where a result is shown.\n\t\t\t\tcontent: [{ type: \"text\", text }],\n\t\t\t\tdetails,\n\t\t\t},\n\t\t};\n\t} finally {\n\t\tacceptingOutput = false;\n\t\tunsubscribe?.();\n\t\tclearUpdateTimer();\n\t\tawait output.closeTempFile();\n\t}\n}\n"]}
1
+ {"version":3,"file":"shell-execution.js","sourceRoot":"","sources":["../../../src/core/tools/shell-execution.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Runs the native shell tool body (`bash.ts`) as one session task. The native body owns the\n * process, progress, output formatting and structured result; this adapter only supplies the\n * task's output log, its background limits and acceptance, and translates the native outcome\n * into a task completion.\n */\nimport { unlink } from \"node:fs/promises\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport { boundText } from \"../tasks/output.ts\";\nimport type { TaskCompletion, TaskControl, TaskTerminalStatus } from \"../tasks/types.ts\";\nimport { type BashOperations, resolveTimeoutMs } from \"./bash.ts\";\nimport { OutputAccumulator, type OutputAccumulatorOptions, type OutputSnapshot } from \"./output-accumulator.ts\";\nimport type { BashToolDetails } from \"./shell-tool.ts\";\n\nexport const MAX_BACKGROUND_OUTPUT_BYTES = 20 * 1024 * 1024;\n/** Background snapshots stay within the task result budget, so the bounded result keeps the newest output. */\nconst BACKGROUND_SNAPSHOT_BYTES = 40 * 1024;\nconst OUTPUT_LIMIT_ERROR = \"Background command exceeded the 20 MiB output limit\";\n\ntype ShellDetails = BashToolDetails | undefined;\ntype ShellControl = TaskControl<ShellDetails>;\n\n/**\n * A session task's output: persisted from the first byte to the log attached to the task, and\n * bounded once the task is background work. A write failure or the background cap cancels the\n * task instead of throwing through the process's data observer.\n */\nclass TaskOutput extends OutputAccumulator {\n\terror?: Error;\n\tprivate readonly control: ShellControl;\n\n\tconstructor(control: ShellControl, options: OutputAccumulatorOptions) {\n\t\tsuper({ ...options, persistFromStart: true });\n\t\tthis.control = control;\n\t}\n\n\toverride append(data: Buffer): void {\n\t\tif (this.error) return;\n\t\ttry {\n\t\t\tconst room = MAX_BACKGROUND_OUTPUT_BYTES - this.getTotalBytes();\n\t\t\tif (this.control.mode === \"background\" && data.length > room) {\n\t\t\t\tsuper.append(data.subarray(0, Math.max(0, room)));\n\t\t\t\tthis.fail(new Error(OUTPUT_LIMIT_ERROR));\n\t\t\t} else super.append(data);\n\t\t} catch (error) {\n\t\t\tthis.fail(error);\n\t\t}\n\t}\n\n\toverride snapshot(options: Parameters<OutputAccumulator[\"snapshot\"]>[0] = {}): OutputSnapshot {\n\t\treturn super.snapshot(\n\t\t\tthis.control.mode === \"background\" ? { ...options, maxBytes: BACKGROUND_SNAPSHOT_BYTES } : options,\n\t\t);\n\t}\n\n\t/** A detach must check output written while in the foreground, preserving it. */\n\tcheckLimit(): void {\n\t\tif (this.control.mode === \"background\" && this.getTotalBytes() > MAX_BACKGROUND_OUTPUT_BYTES)\n\t\t\tthis.fail(new Error(OUTPUT_LIMIT_ERROR));\n\t}\n\n\tprivate fail(error: unknown): void {\n\t\tif (this.error) return;\n\t\tthis.error = error instanceof Error ? error : new Error(String(error));\n\t\ttry {\n\t\t\tthis.control.cancel();\n\t\t} catch {\n\t\t\t// Late data must not throw through a process observer.\n\t\t}\n\t}\n}\n\ninterface ShellFailure {\n\tstatus: Extract<TaskTerminalStatus, \"failed\" | \"cancelled\" | \"timeout\">;\n\terror: string;\n}\n\n/** What the process itself reported, recorded before the native body formats it. */\ninterface ProcessOutcome {\n\texitCode?: number | null;\n\terror?: unknown;\n}\n\n/** Interpret the documented BashOperations error markers and exit codes as the native body states them. */\nfunction processFailure(outcome: ProcessOutcome): ShellFailure | undefined {\n\tconst { error, exitCode } = outcome;\n\tif (error instanceof Error && error.message === \"aborted\") return { status: \"cancelled\", error: \"Command aborted\" };\n\tif (error instanceof Error && error.message.startsWith(\"timeout:\"))\n\t\treturn { status: \"timeout\", error: `Command timed out after ${error.message.split(\":\")[1]} seconds` };\n\tif (error !== undefined) return { status: \"failed\", error: errorMessage(error) };\n\tif (exitCode === null) return { status: \"failed\", error: \"Command terminated without an exit code\" };\n\tif (exitCode !== undefined && exitCode !== 0)\n\t\treturn { status: \"failed\", error: `Command exited with code ${exitCode}` };\n\treturn undefined;\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn boundText(error instanceof Error ? error.message : String(error), 4096);\n}\n\n/** The native body appends its failure status to the output; a task keeps them apart. */\nfunction withoutStatus(text: string, status: string): string {\n\tif (text === status) return \"\";\n\tconst suffix = `\\n\\n${status}`;\n\treturn text.endsWith(suffix) ? text.slice(0, -suffix.length) : text;\n}\n\nfunction resultText(result: AgentToolResult<ShellDetails>): string {\n\treturn result.content\n\t\t.filter((part) => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\n/** The parts the native body runs with when it executes as a task. */\nexport interface ShellTaskParts {\n\tcreateOutput: () => OutputAccumulator;\n\toperations: BashOperations;\n\tonUpdate: (result: AgentToolResult<ShellDetails>) => void;\n}\n\nexport interface ShellTaskOptions {\n\tcontrol: ShellControl;\n\toperations: BashOperations;\n\ttempFilePrefix: string;\n\ttimeout?: number;\n\t/** Runs the native tool body once with the task's parts. */\n\texecute: (parts: ShellTaskParts) => Promise<AgentToolResult<ShellDetails>>;\n}\n\n/**\n * One process and one output owner across foreground/background handoff. The task result holds\n * the command's output only; its failure is the completion's `error`.\n */\nexport async function runShellTask(options: ShellTaskOptions): Promise<TaskCompletion<ShellDetails>> {\n\tconst { control } = options;\n\tif (control.signal.aborted) throw new Error(\"Command aborted\");\n\tresolveTimeoutMs(options.timeout);\n\tconst output = new TaskOutput(control, { tempFilePrefix: options.tempFilePrefix });\n\tconst path = output.snapshot().fullOutputPath!;\n\tconst cleanup = async () => {\n\t\tawait output.closeTempFile();\n\t\tawait unlink(path).catch((error: NodeJS.ErrnoException) => {\n\t\t\tif (error.code !== \"ENOENT\") throw error;\n\t\t});\n\t};\n\ttry {\n\t\tcontrol.attachOutput(path, cleanup);\n\t} catch (error) {\n\t\tawait cleanup();\n\t\tthrow error;\n\t}\n\tconst unsubscribe = control.onModeChange(() => output.checkLimit());\n\tconst spawned: ProcessOutcome = {};\n\tconst operations: BashOperations = {\n\t\texec: (command, cwd, execOptions) => {\n\t\t\tlet running: ReturnType<BashOperations[\"exec\"]>;\n\t\t\ttry {\n\t\t\t\trunning = options.operations.exec(command, cwd, execOptions);\n\t\t\t} catch (error) {\n\t\t\t\tspawned.error = error;\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\t// The process exists, so a handoff can no longer start it twice.\n\t\t\tcontrol.accept();\n\t\t\treturn running.then(\n\t\t\t\t(result) => {\n\t\t\t\t\tspawned.exitCode = result.exitCode;\n\t\t\t\t\treturn result;\n\t\t\t\t},\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tspawned.error = error;\n\t\t\t\t\tthrow error;\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t};\n\tlet result: AgentToolResult<ShellDetails> | undefined;\n\tlet thrown: unknown;\n\ttry {\n\t\ttry {\n\t\t\tresult = await options.execute({\n\t\t\t\tcreateOutput: () => output,\n\t\t\t\toperations,\n\t\t\t\tonUpdate: (update) => control.publish({ result: update }),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrown = error;\n\t\t}\n\t} finally {\n\t\tunsubscribe();\n\t\tawait output.closeTempFile();\n\t}\n\treturn shellCompletion(output, path, spawned, result, thrown);\n}\n\nfunction shellCompletion(\n\toutput: TaskOutput,\n\tpath: string,\n\tspawned: ProcessOutcome,\n\tresult: AgentToolResult<ShellDetails> | undefined,\n\tthrown: unknown,\n): TaskCompletion<ShellDetails> {\n\tconst started = \"exitCode\" in spawned || \"error\" in spawned;\n\tconst failure =\n\t\tprocessFailure(spawned) ?? (thrown === undefined ? undefined : { status: \"failed\", error: errorMessage(thrown) });\n\t// The native result or error carries the formatted output; a raw operations error carries none.\n\tconst formatted =\n\t\tresult !== undefined\n\t\t\t? resultText(result)\n\t\t\t: thrown instanceof Error && thrown !== spawned.error && started\n\t\t\t\t? thrown.message\n\t\t\t\t: started\n\t\t\t\t\t? output.snapshot().content\n\t\t\t\t\t: \"\";\n\tconst text = failure ? withoutStatus(formatted, failure.error) : formatted;\n\tconst truncation = output.snapshot().truncation;\n\tconst details: BashToolDetails = {\n\t\t...(result?.details ?? (truncation.truncated ? { truncation } : {})),\n\t\tfullOutputPath: path,\n\t};\n\t// A cancellation the output policy caused is that policy's failure, not the process's abort.\n\tconst policy = output.error ? { status: \"failed\" as const, error: errorMessage(output.error) } : undefined;\n\tconst settled = policy ?? failure;\n\tconst keepStructured = result?.structuredContent !== undefined && !policy;\n\treturn {\n\t\tstatus: settled?.status,\n\t\terror: settled?.error,\n\t\t...(spawned.exitCode !== undefined\n\t\t\t? { facts: [[\"Exit\", spawned.exitCode === null ? \"signal\" : String(spawned.exitCode)]] }\n\t\t\t: {}),\n\t\tresult: {\n\t\t\t...(keepStructured\n\t\t\t\t? { structuredContent: result!.structuredContent, ...(settled ? { isError: true } : {}) }\n\t\t\t\t: {}),\n\t\t\tcontent: [{ type: \"text\", text }],\n\t\t\tdetails,\n\t\t},\n\t};\n}\n"]}
@@ -1,37 +1,32 @@
1
+ /**
2
+ * The managed shell tools: the native shell definition (`bash.ts`) plus a `background` parameter,
3
+ * adapted to the session's Tasks. The native body stays the one owner of execution, progress,
4
+ * output formatting and results; outside a session it runs unchanged.
5
+ */
1
6
  import { type Static, Type } from "typebox";
2
7
  import type { ToolDefinition } from "../extensions/types.ts";
3
- import { type BashOperations, type BashToolOptions, type ShellToolConfig } from "./bash.ts";
4
- import { type TruncationResult } from "./truncate.ts";
8
+ import { type BashOperations, type BashRenderState, type BashToolOptions, type BashToolDetails as NativeBashToolDetails, type ShellToolConfig } from "./bash.ts";
5
9
  declare const bashSchema: Type.TObject<{
10
+ background: Type.TOptional<Type.TBoolean>;
6
11
  command: Type.TString;
7
12
  timeout: Type.TOptional<Type.TNumber>;
8
- background: Type.TOptional<Type.TBoolean>;
9
13
  }>;
10
14
  export declare const bashToolSystemPromptContribution: {
11
15
  readonly snippet: "Execute bash commands, foreground or background";
12
16
  readonly guidelines: readonly ["You can inspect PI_* environment variables for current model and session details."];
13
17
  };
14
18
  export type BashToolInput = Static<typeof bashSchema>;
15
- export interface BashToolDetails {
16
- truncation?: TruncationResult;
17
- fullOutputPath?: string;
19
+ export interface BashToolDetails extends NativeBashToolDetails {
18
20
  /** Settled handoff snapshot, not a command completion or exit code. */
19
21
  background?: {
20
22
  kind: "background";
21
23
  taskId: string;
22
24
  };
23
25
  }
24
- export type BashRenderState = {
25
- dispose?: () => void;
26
- };
27
26
  export declare function createShellToolDefinition(cwd: string, config: ShellToolConfig, options: BashToolOptions & {
28
27
  operations: BashOperations;
29
28
  }): ToolDefinition<typeof bashSchema, BashToolDetails | undefined, BashRenderState>;
30
29
  export declare function createBashToolDefinition(cwd: string, options?: BashToolOptions): ReturnType<typeof createShellToolDefinition>;
31
- export declare function createBashTool(cwd: string, options?: BashToolOptions): import("@earendil-works/pi-agent-core").AgentTool<Type.TObject<{
32
- command: Type.TString;
33
- timeout: Type.TOptional<Type.TNumber>;
34
- background: Type.TOptional<Type.TBoolean>;
35
- }>, BashToolDetails | undefined>;
30
+ export declare function createBashTool(cwd: string, options?: BashToolOptions): import("@earendil-works/pi-agent-core").AgentTool<any, BashToolDetails | undefined>;
36
31
  export {};
37
32
  //# sourceMappingURL=shell-tool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shell-tool.d.ts","sourceRoot":"","sources":["../../../src/core/tools/shell-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG/E,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,eAAe,EAGpB,KAAK,eAAe,EACpB,MAAM,WAAW,CAAC;AAKnB,OAAO,EAAwC,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE5F,QAAA,MAAM,UAAU;;;;EASd,CAAC;AAEH,eAAO,MAAM,gCAAgC;;;CAGnC,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAetD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD;AAED,MAAM,MAAM,eAAe,GAAG;IAC7B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAyBF,wBAAgB,yBAAyB,CACxC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,eAAe,GAAG;IAAE,UAAU,EAAE,cAAc,CAAA;CAAE,GACvD,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,EAAE,eAAe,CAAC,CA4FjF;AAYD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAK9C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe;;;;iCAQpE"}
1
+ {"version":3,"file":"shell-tool.d.ts","sourceRoot":"","sources":["../../../src/core/tools/shell-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAO7D,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,eAAe,EAEpB,KAAK,eAAe,IAAI,qBAAqB,EAG7C,KAAK,eAAe,EACpB,MAAM,WAAW,CAAC;AAKnB,QAAA,MAAM,UAAU;;;;EAQd,CAAC;AAEH,eAAO,MAAM,gCAAgC;;;CAGnC,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAOtD,MAAM,WAAW,eAAgB,SAAQ,qBAAqB;IAC7D,uEAAuE;IACvE,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD;AA2BD,wBAAgB,yBAAyB,CACxC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,eAAe,GAAG;IAAE,UAAU,EAAE,cAAc,CAAA;CAAE,GACvD,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,EAAE,eAAe,CAAC,CAiEjF;AAYD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAK9C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,uFAQpE"}