zidane 9.1.1 → 9.1.3

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 (279) hide show
  1. package/dist/{acp-Di9WvMDF.js → acp-CeCavNlg.js} +7 -7
  2. package/dist/{acp-Di9WvMDF.js.map → acp-CeCavNlg.js.map} +1 -1
  3. package/dist/acp-cli.js +5 -5
  4. package/dist/acp.d.ts +2 -2
  5. package/dist/acp.js +1 -1
  6. package/dist/{agent-DJhpTS-B.js → agent-Dh_XZ7fj.js} +74 -19
  7. package/dist/agent-Dh_XZ7fj.js.map +1 -0
  8. package/dist/agent.d.ts +1 -1
  9. package/dist/agent.js +1 -1
  10. package/dist/{auth-store-port-DFgf22oo.js → auth-store-port-BKpjlJ8a.js} +2 -2
  11. package/dist/{auth-store-port-DFgf22oo.js.map → auth-store-port-BKpjlJ8a.js.map} +1 -1
  12. package/dist/{auto-update-restart-BFB7Ek87.js → auto-update-restart-CQJtndMG.js} +277 -41
  13. package/dist/auto-update-restart-CQJtndMG.js.map +1 -0
  14. package/dist/{browser-BcoCCB_n.js → browser-BkdeKnxO.js} +56 -2
  15. package/dist/browser-BkdeKnxO.js.map +1 -0
  16. package/dist/{browser-entry-ypi8CyE-.d.ts → browser-entry-BCwruqNa.d.ts} +10 -10
  17. package/dist/{browser-entry-ypi8CyE-.d.ts.map → browser-entry-BCwruqNa.d.ts.map} +1 -1
  18. package/dist/channels.d.ts +5 -5
  19. package/dist/chat/browser.d.ts +4 -4
  20. package/dist/chat/browser.js +6 -6
  21. package/dist/chat/pure.d.ts +5 -5
  22. package/dist/chat/pure.js +8 -8
  23. package/dist/chat.d.ts +5 -5
  24. package/dist/chat.js +55 -55
  25. package/dist/chat.js.map +1 -1
  26. package/dist/{cli-shared-CabruH8Z.js → cli-shared-DeRHgYvl.js} +4 -4
  27. package/dist/{cli-shared-CabruH8Z.js.map → cli-shared-DeRHgYvl.js.map} +1 -1
  28. package/dist/cli-style-DBEm6CyT.js +105 -0
  29. package/dist/cli-style-DBEm6CyT.js.map +1 -0
  30. package/dist/{client-core-CIixwznM.d.ts → client-core-C_4m_oL6.d.ts} +4 -4
  31. package/dist/{client-core-CIixwznM.d.ts.map → client-core-C_4m_oL6.d.ts.map} +1 -1
  32. package/dist/{client-CCaIXWue.d.ts → client-ygTASGis.d.ts} +2 -2
  33. package/dist/{client-CCaIXWue.d.ts.map → client-ygTASGis.d.ts.map} +1 -1
  34. package/dist/codemode-worker.js +8 -5
  35. package/dist/codemode-worker.js.map +1 -1
  36. package/dist/codemode.d.ts +16 -0
  37. package/dist/codemode.d.ts.map +1 -1
  38. package/dist/codemode.js +2 -2
  39. package/dist/{connection-loop-QmWL-fJf.d.ts → connection-loop-D_pRONCr.d.ts} +4 -4
  40. package/dist/{connection-loop-QmWL-fJf.d.ts.map → connection-loop-D_pRONCr.d.ts.map} +1 -1
  41. package/dist/contexts/daytona.d.ts +3 -3
  42. package/dist/contexts/docker.d.ts +1 -1
  43. package/dist/contexts/e2b.d.ts +2 -2
  44. package/dist/contexts/sandbox.d.ts +1 -1
  45. package/dist/{contexts-C72b0mMa.js → contexts-DLZTSRHU.js} +17 -106
  46. package/dist/contexts-DLZTSRHU.js.map +1 -0
  47. package/dist/contexts.d.ts +4 -4
  48. package/dist/contexts.js +2 -2
  49. package/dist/{credentials-wwETW8rI.js → credentials-Bqg-qNBM.js} +2 -2
  50. package/dist/{credentials-wwETW8rI.js.map → credentials-Bqg-qNBM.js.map} +1 -1
  51. package/dist/{cwd-picker-CcekODCt.js → cwd-picker-BsHA6HKv.js} +4 -4
  52. package/dist/{cwd-picker-CcekODCt.js.map → cwd-picker-BsHA6HKv.js.map} +1 -1
  53. package/dist/daemon-cli.js +4 -3
  54. package/dist/daemon-cli.js.map +1 -1
  55. package/dist/{decisions-CXmK0nz9.js → decisions-hsw5XS2g.js} +3 -1
  56. package/dist/decisions-hsw5XS2g.js.map +1 -0
  57. package/dist/{discovery-DycXFxdA.js → discovery-CX7nbMCn.js} +4 -4
  58. package/dist/{discovery-DycXFxdA.js.map → discovery-CX7nbMCn.js.map} +1 -1
  59. package/dist/durable/sqlite.d.ts +2 -2
  60. package/dist/durable.d.ts +1 -1
  61. package/dist/{engine-VQ86XGdG.js → engine-CxBGgU94.js} +6 -6
  62. package/dist/{engine-VQ86XGdG.js.map → engine-CxBGgU94.js.map} +1 -1
  63. package/dist/{eval-Bod0I1W_.js → eval-CfGUDAkN.js} +3 -3
  64. package/dist/{eval-Bod0I1W_.js.map → eval-CfGUDAkN.js.map} +1 -1
  65. package/dist/eval.d.ts +1 -1
  66. package/dist/eval.js +1 -1
  67. package/dist/{executor-C7RQrkEq.js → executor-j_LFRBwS.js} +4 -4
  68. package/dist/{executor-C7RQrkEq.js.map → executor-j_LFRBwS.js.map} +1 -1
  69. package/dist/{extension-mark-BqKdEZwF.js → extension-mark-_rhkDWL5.js} +9 -6
  70. package/dist/extension-mark-_rhkDWL5.js.map +1 -0
  71. package/dist/extensions/testing.d.ts +1 -1
  72. package/dist/extensions/testing.js +2 -2
  73. package/dist/{extensions-BCx4QuGB.js → extensions-ADlhBQ_1.js} +8 -8
  74. package/dist/{extensions-BCx4QuGB.js.map → extensions-ADlhBQ_1.js.map} +1 -1
  75. package/dist/{extensions-client-D8tEAcMw.d.ts → extensions-client-D4Q2XRKV.d.ts} +31 -5
  76. package/dist/extensions-client-D4Q2XRKV.d.ts.map +1 -0
  77. package/dist/extensions.d.ts +1 -1
  78. package/dist/extensions.js +6 -6
  79. package/dist/{fold-rules-DvLK8pbf.d.ts → fold-rules-1DpDwG9h.d.ts} +2 -2
  80. package/dist/{fold-rules-DvLK8pbf.d.ts.map → fold-rules-1DpDwG9h.d.ts.map} +1 -1
  81. package/dist/{google-Crva32sk.js → google-B-Dhmzzf.js} +2 -2
  82. package/dist/{google-Crva32sk.js.map → google-B-Dhmzzf.js.map} +1 -1
  83. package/dist/{headless-CCm-jLLT.js → headless-CQm19BL0.js} +4 -4
  84. package/dist/{headless-CCm-jLLT.js.map → headless-CQm19BL0.js.map} +1 -1
  85. package/dist/headless.d.ts +1 -1
  86. package/dist/headless.js +1 -1
  87. package/dist/history-worker.js +1 -1
  88. package/dist/{host-wO_6GW0y.js → host-C61ntFBC.js} +276 -103
  89. package/dist/host-C61ntFBC.js.map +1 -0
  90. package/dist/{host-BHMs9jsN.js → host-DEoEzQal.js} +13 -4
  91. package/dist/host-DEoEzQal.js.map +1 -0
  92. package/dist/{host-scoped-settings-CrbcqOkP.js → host-scoped-settings-WBYaCork.js} +2 -2
  93. package/dist/{host-scoped-settings-CrbcqOkP.js.map → host-scoped-settings-WBYaCork.js.map} +1 -1
  94. package/dist/{host-signals-Jsjd_-4g.js → host-signals-Cb2TlGtN.js} +5 -5
  95. package/dist/{host-signals-Jsjd_-4g.js.map → host-signals-Cb2TlGtN.js.map} +1 -1
  96. package/dist/{host-version-CNAr9pov.js → host-version-BIx4CuBM.js} +2 -2
  97. package/dist/{host-version-CNAr9pov.js.map → host-version-BIx4CuBM.js.map} +1 -1
  98. package/dist/{index-C6nnKu32.d.ts → index-B0PLo9jn.d.ts} +4 -4
  99. package/dist/{index-C6nnKu32.d.ts.map → index-B0PLo9jn.d.ts.map} +1 -1
  100. package/dist/{index-Djnc8Peh.d.ts → index-De4x-s76.d.ts} +14 -14
  101. package/dist/{index-Djnc8Peh.d.ts.map → index-De4x-s76.d.ts.map} +1 -1
  102. package/dist/{index-CGbOWa7y.d.ts → index-WlE93Q6d.d.ts} +411 -3
  103. package/dist/index-WlE93Q6d.d.ts.map +1 -0
  104. package/dist/{index-CCf_WeTQ.d.ts → index-f-XWIoYo.d.ts} +2 -2
  105. package/dist/{index-CCf_WeTQ.d.ts.map → index-f-XWIoYo.d.ts.map} +1 -1
  106. package/dist/index.d.ts +5 -5
  107. package/dist/index.js +17 -17
  108. package/dist/ipc/browser-types.d.ts +304 -7
  109. package/dist/ipc/browser-types.d.ts.map +1 -1
  110. package/dist/ipc/browser.d.ts +4 -4
  111. package/dist/ipc/browser.js +2 -2
  112. package/dist/ipc/remote.d.ts +6 -6
  113. package/dist/ipc/remote.js +3 -3
  114. package/dist/{ipc-BzWhIybr.js → ipc-DiH_P-wr.js} +4 -4
  115. package/dist/{ipc-BzWhIybr.js.map → ipc-DiH_P-wr.js.map} +1 -1
  116. package/dist/ipc.d.ts +10 -10
  117. package/dist/ipc.js +8 -8
  118. package/dist/{json-Dj-YATkZ.js → json-BjClr43H.js} +2 -20
  119. package/dist/json-BjClr43H.js.map +1 -0
  120. package/dist/{links-CJG_rFvf.js → links-BbC_lOnn.js} +9 -9
  121. package/dist/{links-CJG_rFvf.js.map → links-BbC_lOnn.js.map} +1 -1
  122. package/dist/{loaded-entry-DTURJo_R.js → loaded-entry-C0vkCVNQ.js} +2 -2
  123. package/dist/{loaded-entry-DTURJo_R.js.map → loaded-entry-C0vkCVNQ.js.map} +1 -1
  124. package/dist/mcp.d.ts +1 -1
  125. package/dist/{media-type-BtA0cbfI.d.ts → media-type-ZSmAGHvg.d.ts} +188 -7
  126. package/dist/media-type-ZSmAGHvg.d.ts.map +1 -0
  127. package/dist/{memory-DuVGrzbl.js → memory-C3w8nO8f.js} +132 -31
  128. package/dist/memory-C3w8nO8f.js.map +1 -0
  129. package/dist/model-test-CAtJ76kM.js.map +1 -1
  130. package/dist/{move-session-kylExJ5H.js → move-session-D7ILECs-.js} +4 -4
  131. package/dist/{move-session-kylExJ5H.js.map → move-session-D7ILECs-.js.map} +1 -1
  132. package/dist/{nested-call-record-DlzPeTB7.js → nested-call-record-OayszZBQ.js} +4 -3
  133. package/dist/nested-call-record-OayszZBQ.js.map +1 -0
  134. package/dist/output/stream-json.d.ts +1 -1
  135. package/dist/output/terminal.d.ts +1 -1
  136. package/dist/{path-display-COVV71Yu.js → path-display-DRAEpKOU.js} +3 -3
  137. package/dist/{path-display-COVV71Yu.js.map → path-display-DRAEpKOU.js.map} +1 -1
  138. package/dist/plugins.d.ts +1 -1
  139. package/dist/{prelude-CVKoUzV8.js → prelude-BwiSR1uA.js} +16 -5
  140. package/dist/prelude-BwiSR1uA.js.map +1 -0
  141. package/dist/{presets-CBt6rFfS.js → presets-CMY43nUP.js} +3 -3
  142. package/dist/{presets-CBt6rFfS.js.map → presets-CMY43nUP.js.map} +1 -1
  143. package/dist/presets.d.ts +1 -1
  144. package/dist/presets.js +1 -1
  145. package/dist/{protocol-CEVqBO-q.d.ts → protocol-C2lqKuMd.d.ts} +50 -7
  146. package/dist/protocol-C2lqKuMd.d.ts.map +1 -0
  147. package/dist/protocol-DOGyHgLQ.js.map +1 -1
  148. package/dist/protocol-NSllElLw.js.map +1 -1
  149. package/dist/providers/anthropic.d.ts +1 -1
  150. package/dist/providers/arcee.d.ts +1 -1
  151. package/dist/providers/baseten.d.ts +1 -1
  152. package/dist/providers/cerebras.d.ts +1 -1
  153. package/dist/providers/google.d.ts +1 -1
  154. package/dist/providers/google.js +1 -1
  155. package/dist/providers/local.d.ts +1 -1
  156. package/dist/providers/neuralwatt.d.ts +1 -1
  157. package/dist/providers/openai-compat.d.ts +1 -1
  158. package/dist/providers/openai.d.ts +1 -1
  159. package/dist/providers/openrouter.d.ts +1 -1
  160. package/dist/providers/xai.d.ts +1 -1
  161. package/dist/{providers-Z0TaBp1O.js → providers-CpXV_uLE.js} +5 -5
  162. package/dist/providers-CpXV_uLE.js.map +1 -0
  163. package/dist/providers.d.ts +1 -1
  164. package/dist/providers.js +1 -1
  165. package/dist/{readonly-db-D7Z-k0pQ.js → readonly-db-DrbT8tX6.js} +2 -2
  166. package/dist/{readonly-db-D7Z-k0pQ.js.map → readonly-db-DrbT8tX6.js.map} +1 -1
  167. package/dist/{registry-BKjeBnoy.js → registry-CJHvmvaP.js} +2 -2
  168. package/dist/{registry-BKjeBnoy.js.map → registry-CJHvmvaP.js.map} +1 -1
  169. package/dist/{registry-B6Ww76iW.js → registry-CN6JlZKj.js} +2 -2
  170. package/dist/{registry-B6Ww76iW.js.map → registry-CN6JlZKj.js.map} +1 -1
  171. package/dist/{registry-B9INJwJR.js → registry-CnnKaY9s.js} +324 -39
  172. package/dist/registry-CnnKaY9s.js.map +1 -0
  173. package/dist/{remote-hosts-BMWoHCWO.js → remote-hosts-DoO9CJUQ.js} +4 -4
  174. package/dist/{remote-hosts-BMWoHCWO.js.map → remote-hosts-DoO9CJUQ.js.map} +1 -1
  175. package/dist/{repo-url-D4Dr8NfZ.js → repo-url-DLjjuVk_.js} +169 -2
  176. package/dist/repo-url-DLjjuVk_.js.map +1 -0
  177. package/dist/restate.d.ts +2 -2
  178. package/dist/{sandbox-BwiPGKF7.d.ts → sandbox-B4OW6oNx.d.ts} +2 -2
  179. package/dist/{sandbox-BwiPGKF7.d.ts.map → sandbox-B4OW6oNx.d.ts.map} +1 -1
  180. package/dist/script-progress-CrZ507Qq.js +900 -0
  181. package/dist/script-progress-CrZ507Qq.js.map +1 -0
  182. package/dist/session/sqlite.d.ts +1 -1
  183. package/dist/session.d.ts +1 -1
  184. package/dist/{setting-BQBSyUq0.js → setting-D_FpKFMw.js} +6 -6
  185. package/dist/{setting-BQBSyUq0.js.map → setting-D_FpKFMw.js.map} +1 -1
  186. package/dist/{settings-catalog-4IU2i_jG.js → settings-catalog-DEZlXP51.js} +14 -2
  187. package/dist/settings-catalog-DEZlXP51.js.map +1 -0
  188. package/dist/{settings-keys-iI_Y-7MC.js → settings-keys-CW2UgHgb.js} +3 -3
  189. package/dist/{settings-keys-iI_Y-7MC.js.map → settings-keys-CW2UgHgb.js.map} +1 -1
  190. package/dist/{skills-CFXRItJ6.js → skills-CEbosUlM.js} +2 -2
  191. package/dist/{skills-CFXRItJ6.js.map → skills-CEbosUlM.js.map} +1 -1
  192. package/dist/skills.d.ts +1 -1
  193. package/dist/skills.js +1 -1
  194. package/dist/{source-Bl1Z501r.js → source-3ZnEPOSa.js} +3 -2
  195. package/dist/source-3ZnEPOSa.js.map +1 -0
  196. package/dist/{sqlite-runtime-BZ2L4RaG.d.ts → sqlite-runtime-CS_LBaAN.d.ts} +2 -2
  197. package/dist/sqlite-runtime-CS_LBaAN.d.ts.map +1 -0
  198. package/dist/{src-BY_ND2xn.js → src-BmTXDta8.js} +2 -2
  199. package/dist/{src-BY_ND2xn.js.map → src-BmTXDta8.js.map} +1 -1
  200. package/dist/{store-C6gI7FfZ.js → store-ByCDaKgJ.js} +14 -3
  201. package/dist/store-ByCDaKgJ.js.map +1 -0
  202. package/dist/{system-freeze-m5o1sGIM.js → system-freeze-XgDPIwQS.js} +3 -3
  203. package/dist/{system-freeze-m5o1sGIM.js.map → system-freeze-XgDPIwQS.js.map} +1 -1
  204. package/dist/{todo-edits-CbukbjyV.js → todo-edits-Dyj32ds6.js} +4 -3
  205. package/dist/todo-edits-Dyj32ds6.js.map +1 -0
  206. package/dist/tools/fetch-url.d.ts +1 -1
  207. package/dist/tools/web-search.d.ts +1 -1
  208. package/dist/{tools-CVTGhggj.js → tools-BsrGQ8K4.js} +2 -2
  209. package/dist/{tools-CVTGhggj.js.map → tools-BsrGQ8K4.js.map} +1 -1
  210. package/dist/tools.d.ts +1 -1
  211. package/dist/tools.js +3 -3
  212. package/dist/{transcript-anchors-CiSi_UBn.js → transcript-anchors-DMjvyUjk.js} +3 -3
  213. package/dist/{transcript-anchors-CiSi_UBn.js.map → transcript-anchors-DMjvyUjk.js.map} +1 -1
  214. package/dist/{transcript-reconcile-jbSBjLq2.js → transcript-reconcile-DpQO85wl.js} +3 -3
  215. package/dist/{transcript-reconcile-jbSBjLq2.js.map → transcript-reconcile-DpQO85wl.js.map} +1 -1
  216. package/dist/tui.d.ts +9 -9
  217. package/dist/tui.d.ts.map +1 -1
  218. package/dist/tui.js +289 -38
  219. package/dist/tui.js.map +1 -1
  220. package/dist/{types-bDQagoiL.d.ts → types-2HrgolQz.d.ts} +20 -8
  221. package/dist/types-2HrgolQz.d.ts.map +1 -0
  222. package/dist/types-4q1bFG53.js +122 -0
  223. package/dist/types-4q1bFG53.js.map +1 -0
  224. package/dist/{types-DnRd9_cA.d.ts → types-SXqk6hLD.d.ts} +3 -3
  225. package/dist/{types-DnRd9_cA.d.ts.map → types-SXqk6hLD.d.ts.map} +1 -1
  226. package/dist/types-myxheQkw.js.map +1 -1
  227. package/dist/types.d.ts +3 -3
  228. package/dist/{usage-summary-BfcXjiSM.js → usage-summary-BM7B3JdI.js} +2 -2
  229. package/dist/{usage-summary-BfcXjiSM.js.map → usage-summary-BM7B3JdI.js.map} +1 -1
  230. package/dist/{version-DqqqvHDP.js → version-szdW1Od9.js} +2 -2
  231. package/dist/{version-DqqqvHDP.js.map → version-szdW1Od9.js.map} +1 -1
  232. package/dist/{wait-task-BX4NcOOm.js → wait-task-BiI5UaZQ.js} +13 -3
  233. package/dist/wait-task-BiI5UaZQ.js.map +1 -0
  234. package/dist/{wire-CLm2rMK0.js → wire-C3l9jl9x.js} +2 -2
  235. package/dist/{wire-CLm2rMK0.js.map → wire-C3l9jl9x.js.map} +1 -1
  236. package/dist/{write-file-0E6TUJ9A.js → write-file-Dquu7MzB.js} +5 -3
  237. package/dist/write-file-Dquu7MzB.js.map +1 -0
  238. package/dist/{ws-DfGGYQ4W.js → ws-CEHi0CiB.js} +4 -4
  239. package/dist/{ws-DfGGYQ4W.js.map → ws-CEHi0CiB.js.map} +1 -1
  240. package/dist/{ws-client-CFMbhsNq.js → ws-client-t8XNWxcq.js} +2 -2
  241. package/dist/{ws-client-CFMbhsNq.js.map → ws-client-t8XNWxcq.js.map} +1 -1
  242. package/docs/CHAT.md +55 -0
  243. package/docs/CODEMODE.md +37 -0
  244. package/docs/EXTENSIONS.md +8 -6
  245. package/docs/RELEASE-NOTES-NEXT.md +48 -1
  246. package/docs/RELEASE.md +9 -1
  247. package/package.json +2 -3
  248. package/dist/agent-DJhpTS-B.js.map +0 -1
  249. package/dist/auto-update-restart-BFB7Ek87.js.map +0 -1
  250. package/dist/browser-BcoCCB_n.js.map +0 -1
  251. package/dist/contexts-C72b0mMa.js.map +0 -1
  252. package/dist/decisions-CXmK0nz9.js.map +0 -1
  253. package/dist/extension-mark-BqKdEZwF.js.map +0 -1
  254. package/dist/extensions-client-D8tEAcMw.d.ts.map +0 -1
  255. package/dist/host-BHMs9jsN.js.map +0 -1
  256. package/dist/host-wO_6GW0y.js.map +0 -1
  257. package/dist/index-CGbOWa7y.d.ts.map +0 -1
  258. package/dist/json-Dj-YATkZ.js.map +0 -1
  259. package/dist/media-type-BtA0cbfI.d.ts.map +0 -1
  260. package/dist/memory-DuVGrzbl.js.map +0 -1
  261. package/dist/nested-call-events-BYk8XvGX.js +0 -182
  262. package/dist/nested-call-events-BYk8XvGX.js.map +0 -1
  263. package/dist/nested-call-record-DlzPeTB7.js.map +0 -1
  264. package/dist/prelude-CVKoUzV8.js.map +0 -1
  265. package/dist/protocol-CEVqBO-q.d.ts.map +0 -1
  266. package/dist/providers-Z0TaBp1O.js.map +0 -1
  267. package/dist/registry-B9INJwJR.js.map +0 -1
  268. package/dist/repo-url-D4Dr8NfZ.js.map +0 -1
  269. package/dist/settings-catalog-4IU2i_jG.js.map +0 -1
  270. package/dist/source-Bl1Z501r.js.map +0 -1
  271. package/dist/sqlite-runtime-BZ2L4RaG.d.ts.map +0 -1
  272. package/dist/store-C6gI7FfZ.js.map +0 -1
  273. package/dist/todo-edits-CbukbjyV.js.map +0 -1
  274. package/dist/types-DTMEhKJO.js +0 -14
  275. package/dist/types-DTMEhKJO.js.map +0 -1
  276. package/dist/types-bDQagoiL.d.ts.map +0 -1
  277. package/dist/wait-task-BX4NcOOm.js.map +0 -1
  278. package/dist/write-file-0E6TUJ9A.js.map +0 -1
  279. package/scripts/eval.ts +0 -179
@@ -1 +0,0 @@
1
- {"version":3,"file":"wait-task-BX4NcOOm.js","names":[],"sources":["../src/agent-extension-wiring.ts","../src/attachment-handle.ts","../src/tools/truncate.ts","../src/persisted-blob-io.ts","../src/tools/shell-classify.ts","../src/tools/shell-semantics.ts","../src/tools/shell-reads.ts","../src/tools/shell.ts","../src/tools/shell-kill.ts","../src/tools/wait-task.ts"],"sourcesContent":["/**\n * Which extension runtime an agent's hook bus belongs to. `createAgent`\n * records it when it is given `extensionRuntime`; the spawn tool reads it to\n * hand the same runtime (and approval flow) to a child agent, and\n * `createTracingHooks` reads it to run the `tracing.redact` chain.\n *\n * Kept free of runtime imports so the tracer and the spawn tool can read it\n * without pulling in the agent loop.\n */\n\nimport type { Hookable } from 'hookable'\nimport type { AgentHooks } from './agent-hooks'\nimport type { AgentExtensionRuntime, ExtensionCallScope, ToolCallApprover } from './agent-interceptors'\nimport type { ToolsCatalog } from './extensions/catalog'\n\n/** What a child agent inherits of its parent's extension wiring. */\nexport interface AgentExtensionWiring {\n /** The parent's extension runtime (interceptors, tools catalog). */\n readonly extensionRuntime: AgentExtensionRuntime\n /** The parent's approval flow for a `tool.call` `'ask'`, when it has one. */\n readonly approveToolCall?: ToolCallApprover\n /** The session interceptor inputs name for this agent's calls. */\n readonly sessionId: () => string | undefined\n}\n\nconst wirings = new WeakMap<Hookable<AgentHooks>, AgentExtensionWiring>()\n\n/**\n * Records the extension wiring of the agent that owns `hooks`.\n *\n * @param hooks - The agent's hook bus.\n * @param wiring - Its runtime, approval flow and session.\n */\nexport function recordAgentExtensionWiring(hooks: Hookable<AgentHooks>, wiring: AgentExtensionWiring): void {\n wirings.set(hooks, wiring)\n}\n\n/**\n * The extension wiring of the agent that owns `hooks`.\n *\n * @param hooks - An agent's hook bus.\n * @returns Its wiring, or `undefined` for an agent built without an extension runtime.\n */\nexport function agentExtensionWiringOf(hooks: Hookable<AgentHooks>): AgentExtensionWiring | undefined {\n return wirings.get(hooks)\n}\n\n/** The options a subagent gets from its parent's extension wiring (see {@link childExtensionOptions}). */\nexport interface ChildExtensionOptions {\n extensionRuntime: AgentExtensionRuntime\n approveToolCall?: ToolCallApprover\n extensionScope: ExtensionCallScope\n}\n\n/**\n * The extension options of a subagent: its parent's runtime, so the parent's\n * interceptors (`tool.call` among them) and tools catalog apply to the\n * child's calls too; the parent's approval flow, told which child asks; and\n * the parent's session and run for interceptor inputs.\n *\n * A subagent whose tools a subagent type narrowed (`tools`, `readonly`)\n * gets a tools catalog that can edit and remove its tools but not add any:\n * the type's filter stays the upper bound.\n *\n * @param wiring - The parent agent's wiring (`agentExtensionWiringOf(ctx.hooks)`).\n * @param child - The child's spawn id, the spawning run, and whether its tools were narrowed.\n * @param child.childId - Spawn id (`child-1`), passed to the approval flow.\n * @param child.parentRunId - The run that spawned it.\n * @param child.narrowed - Whether a subagent type filtered the child's tools.\n * @returns Options to spread into the child's `createAgent`.\n */\nexport function childExtensionOptions(wiring: AgentExtensionWiring, child: { childId: string, parentRunId?: string, narrowed?: boolean }): ChildExtensionOptions {\n const { extensionRuntime, approveToolCall } = wiring\n const tools = extensionRuntime.catalogs?.tools\n const runtime: AgentExtensionRuntime = child.narrowed && tools\n ? { ...extensionRuntime, catalogs: { ...extensionRuntime.catalogs, tools: { read: context => onlyBaseTools(tools.read(context), context) } } }\n : extensionRuntime\n return {\n extensionRuntime: runtime,\n // A grandchild's approver is wrapped again: the innermost child names itself.\n ...(approveToolCall ? { approveToolCall: (call, origin) => approveToolCall(call, origin ?? { childId: child.childId }) } : {}),\n extensionScope: {\n sessionId: wiring.sessionId,\n ...(child.parentRunId !== undefined ? { parentRunId: child.parentRunId } : {}),\n },\n }\n}\n\n/** A catalog read cut down to the tools of its base: edits and removals stay, additions go. */\nfunction onlyBaseTools(value: ReturnType<ToolsCatalog['read']>, context: Parameters<ToolsCatalog['read']>[0]): ReturnType<ToolsCatalog['read']> {\n if (!context?.base)\n return value\n const names = new Set(context.base.map(sourced => sourced.item.name))\n return { ...value, items: value.items.filter(tool => names.has(tool.name)) }\n}\n","/**\n * Attachment re-resolve handles + the media age-out marker.\n *\n * zidane keeps attachment bytes inline in `session.turns` (browsable history),\n * but ages old base64 OFF THE WIRE so a long session doesn't carry every\n * screenshot / pasted image forever (`behavior.mediaKeepTurns`). An aged-out\n * media block is replaced on the wire with a short text marker carrying a\n * stable `attachment://<hash>` handle; `read_file` resolves that handle back to\n * the original bytes from `session.turns` on demand, so nothing is ever lost -\n * a strict improvement over a dead \"[content cleared]\" stub.\n *\n * The handle is a content digest of the full base64 payload. It's stable across\n * turns (so markers stay byte-identical and the prompt cache holds), needs no\n * schema change / id threading at ingest, and avoids re-serving the wrong image\n * when two attachments share a prefix and length.\n */\n\nimport type { SessionContentBlock, ToolResultContent } from './types'\nimport { Buffer } from 'node:buffer'\nimport { createHash } from 'node:crypto'\nimport { humanBytes } from './format-bytes'\n\nexport const ATTACHMENT_HANDLE_SCHEME = 'attachment://'\n\n/**\n * Stable digest of the full base64 payload. We keep the visible handle short\n * (128-bit hex prefix) but hash the whole payload so same-size images with\n * identical headers / early pixels cannot alias.\n */\nfunction hashAttachmentData(data: string): string {\n return createHash('sha256').update(data).digest('hex').slice(0, 32)\n}\n\n/** Stable re-resolve handle for a base64 media payload. */\nexport function attachmentHandleFor(data: string): string {\n return `${ATTACHMENT_HANDLE_SCHEME}${hashAttachmentData(data)}`\n}\n\n/**\n * Parse an `attachment://<hash>` path back to its hash, or `null` when the path\n * isn't an attachment handle (i.e. a normal filesystem path). Used by\n * `read_file` to branch into the session re-resolve path.\n */\nexport function parseAttachmentHandle(path: string): string | null {\n if (!path.startsWith(ATTACHMENT_HANDLE_SCHEME))\n return null\n const hash = path.slice(ATTACHMENT_HANDLE_SCHEME.length).trim()\n return hash.length > 0 ? hash : null\n}\n\n/**\n * Payload byte length of a media block's `data` — raw text length for\n * text-encoded documents, decoded (padding-accurate) length for base64.\n */\nexport function mediaPayloadBytes(data: string, encoding?: 'base64' | 'text'): number {\n if (encoding === 'text')\n return Buffer.byteLength(data)\n return decodedBase64Bytes(data)\n}\n\n/** Decoded byte length of a base64 string (padding-accurate). */\nfunction decodedBase64Bytes(b64: string): number {\n if (b64.length === 0)\n return 0\n const pad = b64.endsWith('==') ? 2 : b64.endsWith('=') ? 1 : 0\n return Math.max(0, Math.floor((b64.length * 3) / 4) - pad)\n}\n\ninterface MediaLike {\n type: 'image' | 'document'\n mediaType: string\n data: string\n name?: string\n encoding?: 'base64' | 'text'\n}\n\n/**\n * Build the wire marker that replaces an aged-out media block. Stable for a\n * given payload (handle + size + mediaType) so the elided prefix stays\n * byte-identical across turns and the prompt cache holds.\n *\n * `readFileToolName` is the WIRE name of the file-read tool (e.g. `Read` when\n * the host aliases `read_file`), so the re-read hint names the tool the model\n * actually sees. Defaults to the canonical `read_file`. Pass `null` when the\n * media was stripped for emergency overflow recovery but no re-resolving tool\n * is available in this run.\n */\nexport function mediaAgeoutMarker(block: MediaLike, readFileToolName: string | null = 'read_file'): string {\n const handle = attachmentHandleFor(block.data)\n const size = humanBytes(mediaPayloadBytes(block.data, block.encoding))\n const named = block.name ? ` \"${block.name}\"` : ''\n const resolveHint = readFileToolName\n ? `Still saved in this session; re-read with ${readFileToolName} path=\"${handle}\" to view it again.`\n : `Still saved in this session as ${handle}, but no file-read tool is available in this run to re-open it.`\n return `[${block.type} aged out of context to save tokens -${named} ${block.mediaType}, ${size}. ${resolveHint}]`\n}\n\nexport interface ResolvedAttachment {\n kind: 'image' | 'document'\n mediaType: string\n data: string\n name?: string\n encoding?: 'base64' | 'text'\n}\n\nfunction matchMediaBlock(\n block: SessionContentBlock | ToolResultContent,\n hash: string,\n): ResolvedAttachment | null {\n if (block.type === 'image' && typeof (block as { data?: unknown }).data === 'string') {\n const data = (block as { data: string }).data\n if (attachmentHandleFor(data) !== `${ATTACHMENT_HANDLE_SCHEME}${hash}`)\n return null\n return { kind: 'image', mediaType: block.mediaType, data, ...(block.name ? { name: block.name } : {}) }\n }\n if (block.type === 'document' && typeof (block as { data?: unknown }).data === 'string') {\n const data = (block as { data: string }).data\n if (attachmentHandleFor(data) !== `${ATTACHMENT_HANDLE_SCHEME}${hash}`)\n return null\n const encoding = (block as { encoding?: 'base64' | 'text' }).encoding ?? 'base64'\n return { kind: 'document', mediaType: block.mediaType, data, encoding, ...(block.name ? { name: block.name } : {}) }\n }\n return null\n}\n\n/**\n * Find the original bytes for an `attachment://<hash>` handle by scanning\n * persisted turns. Walks newest-to-oldest so a re-pasted image resolves to its\n * latest copy. Searches both top-level `image`/`document` blocks and\n * image/document parts nested in `tool_result` outputs.\n *\n * Returns `null` when no match - the bytes were never present, or only ever\n * lived as an unresolved `ref` (host-offloaded; not recoverable from turns\n * alone).\n */\nexport function resolveAttachmentFromTurns(\n turns: readonly { content: readonly SessionContentBlock[] }[],\n hash: string,\n): ResolvedAttachment | null {\n for (let i = turns.length - 1; i >= 0; i--) {\n for (const block of turns[i].content) {\n const direct = matchMediaBlock(block, hash)\n if (direct)\n return direct\n if (block.type === 'tool_result' && Array.isArray(block.output)) {\n for (const part of block.output) {\n const nested = matchMediaBlock(part, hash)\n if (nested)\n return nested\n }\n }\n }\n }\n return null\n}\n","/**\n * Byte-budgeted truncation shared across tools: keep the end (`tailTruncate`,\n * for command output whose errors and summaries come last), the start and end\n * (`middleTruncate`, for content read for its structure), or the start\n * (`headSlice`, for previews).\n *\n * Budgets are UTF-8 *byte* counts, not character counts — wire/output\n * accounting is bytes, and a naive `String.prototype.slice` (UTF-16 code\n * units) under-counts multibyte text badly. Every cut lands on a whole code\n * point: the walks step by code point (surrogate pairs included), so an emoji\n * or CJK glyph is never split into a lone surrogate. Pure: no `node:buffer`.\n */\n\nimport { utf8ByteLength } from '../compact/utils'\n\n/** Options for {@link tailTruncate}. */\nexport interface TailTruncateOptions {\n /**\n * Build the marker inserted before the kept tail, given the number of\n * UTF-8 bytes dropped from the head. Defaults to\n * `…(<n> bytes truncated from head)…\\n`. Return an empty string to keep\n * the tail with no marker at all.\n */\n marker?: (droppedBytes: number) => string\n}\n\n/** Options for {@link middleTruncate}. */\nexport interface MiddleTruncateOptions {\n /**\n * Build the marker inserted between the kept start and end, given what was\n * dropped. Defaults to `\\n…(<n> bytes truncated from the middle)…\\n`.\n */\n marker?: (omitted: { bytes: number, chars: number }) => string\n /** Share of the budget kept from the start. Default 0.6. */\n headShare?: number\n}\n\nfunction defaultTailMarker(droppedBytes: number): string {\n return `…(${droppedBytes} bytes truncated from head)…\\n`\n}\n\nfunction defaultMiddleMarker(omitted: { bytes: number }): string {\n return `\\n…(${omitted.bytes} bytes truncated from the middle)…\\n`\n}\n\n/**\n * The longest start of `text` that fits in `maxBytes` UTF-8 bytes, with its\n * size. Returns `text` itself when it already fits.\n *\n * @param text - Text to slice.\n * @param maxBytes - UTF-8 bytes to keep. Zero or less keeps nothing.\n */\nexport function headSlice(text: string, maxBytes: number): { slice: string, bytes: number } {\n if (maxBytes <= 0)\n return { slice: '', bytes: 0 }\n const total = utf8ByteLength(text)\n if (total <= maxBytes)\n return { slice: text, bytes: total }\n let bytes = 0\n let end = 0\n // `for...of` yields whole code points, so a surrogate pair is never split.\n for (const ch of text) {\n const chBytes = utf8ByteLength(ch)\n if (bytes + chBytes > maxBytes)\n break\n bytes += chBytes\n end += ch.length\n }\n return { slice: text.slice(0, end), bytes }\n}\n\n/** The longest end of `text` that fits in `maxBytes` UTF-8 bytes. */\nfunction tailSlice(text: string, maxBytes: number): string {\n let bytes = 0\n let cut = text.length\n while (cut > 0) {\n let start = cut - 1\n const code = text.charCodeAt(start)\n // Low surrogate at the boundary → step back to include its high\n // surrogate so the pair stays intact.\n if (code >= 0xDC00 && code <= 0xDFFF && start > 0) {\n const high = text.charCodeAt(start - 1)\n if (high >= 0xD800 && high <= 0xDBFF)\n start -= 1\n }\n const codePointBytes = utf8ByteLength(text.slice(start, cut))\n if (bytes + codePointBytes > maxBytes)\n break\n bytes += codePointBytes\n cut = start\n }\n return text.slice(cut)\n}\n\n/**\n * Keep the last `maxBytes` UTF-8 bytes of `text`, dropping the head and\n * prefixing a marker. A non-positive `maxBytes` disables truncation and\n * returns `text` unchanged.\n *\n * `maxBytes` budgets the kept tail only; the marker is added on top and may\n * push the returned string slightly past `maxBytes`. That tradeoff is\n * intentional — folding the marker into the budget would shrink the content\n * actually shown. A leading run of U+FFFD (left by an upstream raw-byte slice\n * that landed mid-codepoint) is stripped from the kept tail.\n *\n * @param text - Text to truncate.\n * @param maxBytes - UTF-8 bytes of tail to keep. Zero or less disables truncation.\n * @param options - Marker override. See {@link TailTruncateOptions}.\n */\nexport function tailTruncate(text: string, maxBytes: number, options: TailTruncateOptions = {}): string {\n if (!Number.isFinite(maxBytes) || maxBytes <= 0)\n return text\n const totalBytes = utf8ByteLength(text)\n if (totalBytes <= maxBytes)\n return text\n const tail = tailSlice(text, maxBytes).replace(/^\\uFFFD+/, '')\n const marker = options.marker ?? defaultTailMarker\n return `${marker(totalBytes - utf8ByteLength(tail))}${tail}`\n}\n\n/**\n * Keep the start and the end of `text` within `maxBytes` UTF-8 bytes, with a\n * marker in the gap. A non-positive `maxBytes` disables truncation. As with\n * {@link tailTruncate}, the marker comes on top of the budget.\n *\n * @param text - Text to truncate.\n * @param maxBytes - UTF-8 bytes of start and end to keep. Zero or less disables truncation.\n * @param options - Marker and split. See {@link MiddleTruncateOptions}.\n */\nexport function middleTruncate(text: string, maxBytes: number, options: MiddleTruncateOptions = {}): string {\n if (!Number.isFinite(maxBytes) || maxBytes <= 0)\n return text\n const totalBytes = utf8ByteLength(text)\n if (totalBytes <= maxBytes)\n return text\n const head = headSlice(text, Math.floor(maxBytes * (options.headShare ?? 0.6)))\n const tail = tailSlice(text.slice(head.slice.length), maxBytes - head.bytes)\n const omitted = {\n bytes: totalBytes - head.bytes - utf8ByteLength(tail),\n chars: text.length - head.slice.length - tail.length,\n }\n return `${head.slice}${(options.marker ?? defaultMiddleMarker)(omitted)}${tail}`\n}\n","/**\n * Spilled tool results (`behavior.persistDir`) are zidane's own files, not the\n * workspace's. They are written and read through the execution context, so a\n * docker or sandbox run keeps them on its own filesystem. A process context\n * confined to a workspace root (`workspaceRoot`) or to writable roots refuses\n * them, though: the stub would point the model at a file it cannot write or\n * read back. On a process handle, these helpers fall back to the host\n * filesystem when the context refuses. Internal module.\n */\n\nimport type { ExecutionContext, ExecutionHandle } from './contexts/types'\nimport { mkdir, readFile, realpath, writeFile } from 'node:fs/promises'\nimport { dirname, isAbsolute, relative, resolve } from 'node:path'\nimport { errorMessage } from './errors'\n\nfunction isInside(root: string, target: string): boolean {\n const rel = relative(root, target)\n return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel)\n}\n\n/**\n * Write a spilled blob through the execution context, or on the host when an\n * in-process context refuses it.\n * @param execution - The run's execution context.\n * @param handle - The run's execution handle.\n * @param path - Blob path, inside `persistDir` (or the temp dir for codemode spills).\n * @param content - Blob text.\n * @param shouldRethrow - Errors to rethrow as-is instead of falling back (the run's durable runtime `isControlError`).\n */\nexport async function writePersistedBlob(execution: ExecutionContext, handle: ExecutionHandle, path: string, content: string, shouldRethrow?: (err: unknown) => boolean): Promise<void> {\n try {\n await execution.writeFile(handle, path, content)\n }\n catch (error) {\n if (handle.type !== 'process' || shouldRethrow?.(error))\n throw error\n const full = resolve(handle.cwd, path)\n try {\n await mkdir(dirname(full), { recursive: true })\n await writeFile(full, content, 'utf-8')\n }\n catch (hostError) {\n throw new Error(`${errorMessage(error)}; the host write failed too: ${errorMessage(hostError)}`)\n }\n }\n}\n\n/**\n * Read a file inside `persistDir` on the host. Used by `read_file` after an\n * in-process context refused the path. Symlinks are resolved first, so the\n * file must really live in `persistDir`.\n * @param persistDir - The run's `behavior.persistDir`.\n * @param handle - The run's execution handle.\n * @param path - Path the model asked for.\n * @returns The text, or `undefined` when this is not a blob the host may read.\n */\nexport async function readPersistedBlobOnHost(persistDir: string | undefined, handle: ExecutionHandle, path: string): Promise<string | undefined> {\n if (handle.type !== 'process' || !persistDir || !isAbsolute(persistDir))\n return undefined\n if (!isInside(resolve(persistDir), resolve(handle.cwd, path)))\n return undefined\n try {\n const [root, target] = await Promise.all([realpath(persistDir), realpath(resolve(handle.cwd, path))])\n return isInside(root, target) ? await readFile(target, 'utf-8') : undefined\n }\n catch {\n return undefined\n }\n}\n","/**\n * What a shell command does, read from its text. The one place that\n * classifies commands for the shell tool (scheduling, output truncation),\n * shell read tracking, the shell nudges, the evals and the usage report.\n * Pure string work: nothing is run.\n */\n\n// ---------------------------------------------------------------------------\n// Segments and tokens\n// ---------------------------------------------------------------------------\n\n/** One `&&` / `;` / newline-joined segment, with the separator after it (`null` after the last). */\nexport interface ShellSegment {\n /** The trimmed segment text. */\n text: string\n /** The separator that follows the segment, or `null` after the last one. */\n next: '&&' | ';' | null\n}\n\n/**\n * Split a command into `&&` / `;` / newline-joined segments, ignoring\n * separators inside single or double quotes (`sed -n '1,5p;9p' f` is one\n * segment). `||` is not a separator here: it stays inside the segment, whose\n * `|` then marks it as piped/compound.\n */\nexport function splitShellSegments(command: string): string[] {\n return splitShellSegmentsWithSeparators(command).map(seg => seg.text)\n}\n\n/** {@link splitShellSegments}, with the separator that follows each segment (`null` after the last). */\nexport function splitShellSegmentsWithSeparators(command: string): ShellSegment[] {\n const segments: ShellSegment[] = []\n let current = ''\n let quote: '\\'' | '\"' | null = null\n for (let i = 0; i < command.length; i++) {\n const ch = command[i]\n if (quote) {\n if (ch === quote)\n quote = null\n current += ch\n continue\n }\n if (ch === '\\'' || ch === '\"') {\n quote = ch\n current += ch\n continue\n }\n if (ch === ';' || ch === '\\n' || (ch === '&' && command[i + 1] === '&')) {\n segments.push({ text: current.trim(), next: ch === '&' ? '&&' : ';' })\n current = ''\n if (ch === '&')\n i++\n continue\n }\n current += ch\n }\n segments.push({ text: current.trim(), next: null })\n return segments.filter(seg => seg.text.length > 0)\n}\n\n/** A `&` outside quotes that isn't part of `&&` (backgrounding, `|&`). */\nexport function hasLoneAmpersand(command: string): boolean {\n let quote: '\\'' | '\"' | null = null\n for (let i = 0; i < command.length; i++) {\n const ch = command[i]\n if (quote) {\n if (ch === quote)\n quote = null\n continue\n }\n if (ch === '\\'' || ch === '\"') {\n quote = ch\n continue\n }\n if (ch === '&') {\n if (command[i + 1] === '&') {\n i++\n continue\n }\n return true\n }\n }\n return false\n}\n\n/**\n * Split on whitespace, honoring single and double quotes. Returns `null` on\n * an unbalanced quote or any backslash escape (not worth modelling).\n */\nexport function tokenizeShellSegment(segment: string): string[] | null {\n const tokens: string[] = []\n let current = ''\n let quote: '\\'' | '\"' | null = null\n let inToken = false\n for (const ch of segment) {\n if (quote) {\n if (ch === quote)\n quote = null\n else\n current += ch\n continue\n }\n if (ch === '\\\\')\n return null\n if (ch === '\\'' || ch === '\"') {\n quote = ch\n inToken = true\n continue\n }\n if (/\\s/.test(ch)) {\n if (inToken)\n tokens.push(current)\n current = ''\n inToken = false\n continue\n }\n current += ch\n inToken = true\n }\n if (quote)\n return null\n if (inToken)\n tokens.push(current)\n return tokens\n}\n\n// ---------------------------------------------------------------------------\n// Read-only verdict (scheduling)\n// ---------------------------------------------------------------------------\n\n/**\n * Best-effort read-only allow-list for the leading command token. Members\n * are commands that do not write to the workspace in ordinary use — `ls`,\n * `cat`, `pwd`, etc. Commands that *can*\n * mutate depending on flags (`find -delete`, `git tag <name>`, `tar -x`)\n * are intentionally excluded; the input-aware {@link isReadOnlyShellCommand}\n * predicate falls back to the conservative \"not safe\" answer for them, so\n * the scheduler barriers them.\n */\nconst SHELL_READ_ONLY_COMMANDS: ReadonlySet<string> = new Set([\n 'ls',\n 'cat',\n 'head',\n 'tail',\n 'wc',\n 'pwd',\n 'whoami',\n 'id',\n 'date',\n 'uname',\n 'hostname',\n 'tty',\n 'echo',\n 'printf',\n 'printenv',\n 'which',\n 'type',\n 'file',\n 'stat',\n 'grep',\n 'rg',\n 'ag',\n 'true',\n 'false',\n 'test',\n // Intentionally NOT included: `sed`, `awk`, `find`, `tar`, `xargs`,\n // `tee` — all can write to disk depending on flags / script body\n // (`sed -i`, `awk 'BEGIN { print > \"f\" }'`, `find -delete`, `tar\n // -x`). Conservative omission keeps the predicate fail-closed.\n //\n // `env` and `command` are also NOT here: they are wrappers that execute\n // their trailing argument (`env rm -rf x`, `command rm foo`), so listing\n // them would launder mutating commands through the read-only fleet. They\n // are handled as wrappers in {@link isReadOnlyShellCommand} instead.\n])\n\n/**\n * `git` subcommands that are pure reads regardless of arguments. Excludes\n * `branch`/`tag`/`remote` (which can mutate when given a name) and\n * `config` (which writes when given a value).\n */\nconst GIT_READ_ONLY_SUBCOMMANDS: ReadonlySet<string> = new Set([\n 'status',\n 'log',\n 'diff',\n 'show',\n 'blame',\n 'rev-parse',\n 'ls-files',\n 'ls-tree',\n 'cat-file',\n 'reflog',\n 'shortlog',\n 'describe',\n 'rev-list',\n 'name-rev',\n 'whatchanged',\n 'merge-base',\n 'symbolic-ref',\n])\n\n/**\n * Conservative read-only verdict for a shell command — used to opt a\n * `shell` invocation into the scheduler's concurrent fleet. Returns\n * `false` (fail-closed) on anything ambiguous so the scheduler barriers\n * it. Specifically:\n *\n * - Rejects compound commands (`;`, `&&`, `||`, `|`) and redirects (`>`,\n * `>>`, `<`) — even a pipe to a read-only sink is treated as too\n * complex to analyze.\n * - Rejects subshell / process substitution (`$(...)`, `` `...` ``,\n * `<(...)`, `>(...)`).\n * - Skips leading `VAR=value` env assignments to find the real\n * command token.\n * - Unwraps the `env` / `command` wrappers and classifies the wrapped\n * verb instead (`env rm -rf x` is NOT read-only; bare `env` is).\n * - Strips a possible absolute path on the command (`/usr/bin/ls` → `ls`).\n * - Allows the command iff its base name is in\n * {@link SHELL_READ_ONLY_COMMANDS} OR it's `git <subcmd>` where\n * `<subcmd>` is in {@link GIT_READ_ONLY_SUBCOMMANDS}.\n *\n * Cheap (no spawned process; regex + token scan). Safe to call from the\n * hot scheduler path.\n */\nexport function isReadOnlyShellCommand(command: unknown): boolean {\n if (typeof command !== 'string')\n return false\n const trimmed = command.trim()\n if (trimmed === '')\n return false\n\n // Shell metacharacters that could enable mutation, command chaining,\n // or backgrounding — any of these takes the command out of the\n // \"single read invocation\" shape we can analyze safely. Pipes (`|`)\n // are rejected even when piping to a read-only sink because parsing\n // both sides is more complexity than the win.\n //\n // >, <, >> — redirects\n // ;, &, \\n — command separators (and `&` covers backgrounding)\n // |, ||, && — pipes + boolean chains\n // `…`, $(…) — command substitution\n // <(…), >(…) — process substitution\n if (/[<>;&|`\\n]/.test(trimmed))\n return false\n if (trimmed.includes('$(') || trimmed.includes('<(') || trimmed.includes('>('))\n return false\n\n const tokens = trimmed.split(/\\s+/)\n let i = 0\n while (i < tokens.length) {\n // Skip leading VAR=value env assignments (e.g. `FOO=bar ls`,\n // `env FOO=bar ls`).\n while (i < tokens.length && /^[A-Z_]\\w*=/i.test(tokens[i]))\n i++\n const head = tokens[i]\n if (!head)\n return false\n\n // Strip a leading path: `/usr/bin/ls` → `ls`.\n const base = head.split('/').pop() ?? head\n\n // `env` / `command` execute their trailing argument — classify by the\n // wrapped verb, not the wrapper (`env rm -rf x` mutates). Skip the\n // wrapper plus its flags (`env -i`, `command -p`) and loop on what's\n // left. A bare `env` with no trailing command just prints the\n // environment — read-only. Anything else (`command -v rm` etc.) falls\n // through to the conservative verb check.\n if (base === 'env' || base === 'command') {\n i++\n while (i < tokens.length && tokens[i].startsWith('-'))\n i++\n if (i >= tokens.length)\n return base === 'env'\n continue\n }\n\n if (SHELL_READ_ONLY_COMMANDS.has(base))\n return true\n if (base === 'git') {\n const sub = tokens[i + 1]\n return typeof sub === 'string' && GIT_READ_ONLY_SUBCOMMANDS.has(sub)\n }\n return false\n }\n return false\n}\n\n// ---------------------------------------------------------------------------\n// Kind\n// ---------------------------------------------------------------------------\n\n/**\n * What a command does: `edit` writes files by script, `build` runs a build,\n * test, package or script tool, `git` runs git, `read` / `search` / `list`\n * only explore, `other` is anything else.\n */\nexport type ShellCommandKind = 'read' | 'search' | 'list' | 'edit' | 'build' | 'git' | 'other'\n\nconst READ_VERBS: ReadonlySet<string> = new Set(['cat', 'head', 'tail', 'nl'])\nconst SEARCH_VERBS: ReadonlySet<string> = new Set(['rg', 'grep', 'ag'])\nconst LIST_VERBS: ReadonlySet<string> = new Set(['ls', 'find', 'tree', 'wc', 'du', 'stat', 'file'])\n/** Segments that only decorate exploration output (`echo ---` separators, `cd`). */\nconst NEUTRAL_VERBS: ReadonlySet<string> = new Set(['cd', 'echo', 'printf', 'pwd'])\n/** Build, test, package and script runners, whose output ends with what matters. */\nconst BUILD_VERBS: ReadonlySet<string> = new Set(['bun', 'bunx', 'npm', 'npx', 'pnpm', 'yarn', 'node', 'deno', 'tsc', 'vitest', 'jest', 'eslint', 'make', 'cargo', 'go', 'python', 'python3', 'pytest', 'uv', 'pip', 'docker', 'vite', 'turbo'])\n/** `find` actions that delete or run commands. */\nconst FIND_ACTIONS = /\\s-(?:delete|exec|execdir|ok|okdir)\\b/\n\n/**\n * Scripted file writes: in-place sed/perl, python/node writing files,\n * `cat >` / heredoc-to-file, `tee`.\n */\nconst SCRIPTED_EDIT = /\\bsed\\s+(?:-[a-z]*\\s+)*-i\\b|\\bsed\\s+-[a-z]*i|\\bperl\\s+-[a-z]*i|\\.write_text\\(|\\.write\\(|open\\([^)]*,\\s*['\"][wa]\\+?['\"]|writeFileSync\\(|\\bcat\\s*>|<<-?\\s*['\"]?\\w+['\"]?\\s*>|\\btee\\s/\n\n/** Precedence once every segment is known: one unknown verb makes the whole command `other`. */\nconst KIND_PRECEDENCE: readonly ShellCommandKind[] = ['other', 'git', 'list', 'read', 'search']\n\n/**\n * Classify a command. A scripted write anywhere makes it `edit`, a build verb\n * anywhere `build`. Otherwise each segment is classified by its verb (`cd` and\n * `echo` separators are neutral, pipes count by their first command), and the\n * command takes the first kind of {@link KIND_PRECEDENCE} it contains, so\n * `rg x && sed -n 1,9p f` is a read and a build chained after a read never is.\n */\nexport function classifyShellCommand(command: string): ShellCommandKind {\n if (SCRIPTED_EDIT.test(command))\n return 'edit'\n const seen = new Set<ShellCommandKind>()\n for (const segment of splitShellSegments(command)) {\n const head = (segment.split('|')[0] ?? '').trim()\n const verb = head.split(/\\s+/)[0] ?? ''\n if (NEUTRAL_VERBS.has(verb))\n continue\n if (BUILD_VERBS.has(verb))\n return 'build'\n if (READ_VERBS.has(verb) || (verb === 'sed' && /\\s-n\\b/.test(segment)))\n seen.add('read')\n else if (SEARCH_VERBS.has(verb))\n seen.add('search')\n else if (LIST_VERBS.has(verb) && !(verb === 'find' && FIND_ACTIONS.test(head)))\n seen.add('list')\n else if (verb === 'git')\n seen.add('git')\n else\n seen.add('other')\n }\n return KIND_PRECEDENCE.find(kind => seen.has(kind)) ?? 'other'\n}\n\n/** Filters that only reshape exploration output piped into them. */\nconst FILTER_VERBS: ReadonlySet<string> = new Set(['sort', 'uniq', 'cut', 'tr', 'column', 'jq', 'awk'])\n\n/** The git subcommand of `git [-C dir] [-c k=v] [--flag] <sub> …`. */\nfunction gitSubcommand(tokens: string[]): string | undefined {\n for (let i = 1; i < tokens.length; i++) {\n if (tokens[i] === '-C' || tokens[i] === '-c')\n i++\n else if (!tokens[i].startsWith('-'))\n return tokens[i]\n }\n return undefined\n}\n\n/**\n * Whether a command only explores, so its output is read for its structure:\n * every stage of every pipe is a read, search, list, filter or read-only git\n * verb (`git push`, `cat in | python x.py` are not).\n */\nexport function isExploringShellCommand(command: string): boolean {\n const kind = classifyShellCommand(command)\n if (kind !== 'read' && kind !== 'search' && kind !== 'list' && kind !== 'git')\n return false\n return splitShellSegments(command).every(segment => segment.split('|').every((stage) => {\n const tokens = stage.trim().split(/\\s+/)\n const verb = tokens[0] ?? ''\n if (verb === 'git') {\n const sub = gitSubcommand(tokens)\n return sub !== undefined && GIT_READ_ONLY_SUBCOMMANDS.has(sub)\n }\n return NEUTRAL_VERBS.has(verb) || READ_VERBS.has(verb) || SEARCH_VERBS.has(verb) || FILTER_VERBS.has(verb)\n || (verb === 'sed' && /\\s-n\\b/.test(stage))\n || (LIST_VERBS.has(verb) && !(verb === 'find' && FIND_ACTIONS.test(stage)))\n }))\n}\n\n/**\n * Whether a command sends output into a file: a `>` / `>>` outside quotes\n * whose target is neither a file descriptor (`2>&1`) nor `/dev/null`.\n */\nexport function redirectsToFile(command: string): boolean {\n let quote: '\\'' | '\"' | null = null\n for (let i = 0; i < command.length; i++) {\n const ch = command[i]\n if (quote) {\n if (ch === quote)\n quote = null\n continue\n }\n if (ch === '\\'' || ch === '\"') {\n quote = ch\n continue\n }\n if (ch !== '>')\n continue\n let j = command[i + 1] === '>' ? i + 2 : i + 1\n while (command[j] === ' ')\n j++\n const target = /^[^\\s;&|]*/.exec(command.slice(j))?.[0] ?? ''\n if (command[j] !== '&' && target !== '/dev/null')\n return true\n i = j\n }\n return false\n}\n","/**\n * Per-command exit-code interpretation for the `shell` tool.\n *\n * Many command-line tools use non-zero exit codes to signal information that\n * is *not* an error — `grep` returns 1 for \"no matches found\", `diff` returns\n * 1 for \"files differ\", `find` returns 1 when some directories were\n * inaccessible, and `test`/`[` return 1 for \"condition false\". Treating\n * those uniformly as failures wastes turns: models retry or pivot when there\n * is nothing wrong.\n *\n * Mirrors `claude-code/tools/BashTool/commandSemantics.ts`.\n */\n\nexport interface CommandSemanticResult {\n /** Whether to surface this as an error to the model (`Exit code N` prefix). */\n isError: boolean\n /** Optional human-readable footer appended after the body, e.g. \"No matches found\". */\n message?: string\n}\n\ntype CommandSemantic = (exitCode: number) => CommandSemanticResult\n\nconst DEFAULT_SEMANTIC: CommandSemantic = exitCode => ({\n isError: exitCode !== 0,\n message: exitCode !== 0 ? `Command failed with exit code ${exitCode}` : undefined,\n})\n\nconst COMMAND_SEMANTICS: ReadonlyMap<string, CommandSemantic> = new Map<string, CommandSemantic>([\n // grep / ripgrep: 0 = matches, 1 = no matches, ≥2 = error.\n ['grep', exit => ({ isError: exit >= 2, message: exit === 1 ? 'No matches found' : undefined })],\n ['rg', exit => ({ isError: exit >= 2, message: exit === 1 ? 'No matches found' : undefined })],\n // diff: 0 = identical, 1 = differ, ≥2 = error.\n ['diff', exit => ({ isError: exit >= 2, message: exit === 1 ? 'Files differ' : undefined })],\n // find: 0 = ok, 1 = some dirs inaccessible (warning), ≥2 = error.\n ['find', exit => ({ isError: exit >= 2, message: exit === 1 ? 'Some directories were inaccessible' : undefined })],\n // test / [: 0 = condition true, 1 = condition false, ≥2 = error.\n ['test', exit => ({ isError: exit >= 2, message: exit === 1 ? 'Condition is false' : undefined })],\n ['[', exit => ({ isError: exit >= 2, message: exit === 1 ? 'Condition is false' : undefined })],\n])\n\n/**\n * Pick the semantic for a command line. Best-effort: walks the command from\n * right to left, taking the last segment after `|` / `&&` / `||` / `;` —\n * that's the segment whose exit code propagates. Don't depend on this for\n * security; it's a heuristic, not a parser.\n */\nexport function interpretShellResult(\n command: string,\n exitCode: number,\n): CommandSemanticResult {\n const base = extractTrailingCommand(command)\n const semantic = COMMAND_SEMANTICS.get(base) ?? DEFAULT_SEMANTIC\n return semantic(exitCode)\n}\n\nfunction extractTrailingCommand(command: string): string {\n // Split on the common chain operators. The exit code we see is the trailing\n // segment's. Quoted operators escape the split, but we don't try to be\n // perfect — false positives just fall back to default semantics.\n const segments = command.split(/\\|\\||&&|[;|\\n]/)\n const last = segments[segments.length - 1]?.trim() ?? command\n // First whitespace-delimited token of the trailing segment, sans leading\n // env assignments (`FOO=bar baz` → `baz`).\n const tokens = last.split(/\\s+/).filter(t => !/^[A-Z_]\\w*=/i.test(t))\n return tokens[0] ?? ''\n}\n","/**\n * `behavior.trackShellReads`: count simple shell file reads (`cat`, `head`,\n * `tail`, `nl`, `sed -n '<range>p'`) as reads in the per-session read-state,\n * so the `requireReadBeforeEdit` gate accepts a file the model inspected\n * through `shell`.\n *\n * The parser is deliberately narrow and fail-closed: anything it can't\n * classify registers nothing. Segments joined by `&&` / `;` are read\n * independently (a leading `cd dir &&` shifts the base for later segments;\n * a `cd` followed by `;` or a newline registers nothing, as it may have failed).\n * Any other segment, piped ones included, registers nothing for the whole\n * command: hashing happens after it ran, so a same-command write would be\n * recorded as content the model saw. A lone `&` (backgrounding) likewise.\n */\n\nimport type { ToolContext } from './types'\nimport { isAbsolute, join } from 'node:path'\nimport { hashContent, readStateKey, resolveReadStateMap } from './read-state'\nimport { hasLoneAmpersand, splitShellSegmentsWithSeparators, tokenizeShellSegment } from './shell-classify'\n\n/** Files above this size are not hashed (one whole read per file). */\nconst MAX_TRACKED_BYTES = 16 * 1024 * 1024\n\nconst SED_PRINT_SCRIPT = /^(?:(?:\\d+|\\$)(?:,(?:\\d+|\\$))?p;?)+$/\n\n/** `nl` options whose value may come as the next token (`nl -b a f`). */\nconst NL_VALUE_OPTIONS = new Set(['-b', '-s', '-w', '-v', '-i', '-n', '-d', '-h', '-f'])\n\n/** File operands of one read command, or `null` when it isn't a plain read. */\nfunction readOperands(tokens: string[]): string[] | null {\n const [verb, ...rest] = tokens\n const files: string[] = []\n if (verb === 'cat' || verb === 'nl') {\n for (const t of rest) {\n if (verb === 'nl' && (NL_VALUE_OPTIONS.has(t) || (t.startsWith('--') && !t.includes('='))))\n return null\n if (t.startsWith('-'))\n continue\n files.push(t)\n }\n return files\n }\n if (verb === 'head' || verb === 'tail') {\n for (let i = 0; i < rest.length; i++) {\n const t = rest[i]\n if (t === '-f' || t === '-F' || t === '--follow' || t.startsWith('--follow'))\n return null\n if (t === '-n' || t === '-c') {\n i++\n continue\n }\n if (t.startsWith('-'))\n continue\n files.push(t)\n }\n return files\n }\n if (verb === 'sed') {\n let quiet = false\n let script: string | undefined\n for (let i = 0; i < rest.length; i++) {\n const t = rest[i]\n if (t === '-n') {\n quiet = true\n continue\n }\n if (t === '-e') {\n if (script !== undefined)\n return null\n script = rest[++i]\n continue\n }\n if (t.startsWith('-'))\n return null // `-i` and friends can write\n if (script === undefined) {\n script = t\n continue\n }\n files.push(t)\n }\n if (!quiet || script === undefined || !SED_PRINT_SCRIPT.test(script))\n return null\n return files\n }\n return null\n}\n\n/**\n * Paths (relative to the shell's start directory, or absolute) that a\n * command reads in full view of the model. Empty when nothing qualifies.\n */\nexport function shellReadTargets(command: string): string[] {\n if (/[`<>]|\\$\\(/.test(command) || hasLoneAmpersand(command))\n return []\n const targets: string[] = []\n let base = ''\n for (const { text: segment, next } of splitShellSegmentsWithSeparators(command)) {\n if (segment.includes('|'))\n return []\n const tokens = tokenizeShellSegment(segment)\n if (!tokens || tokens.length === 0)\n return []\n if (tokens[0] === 'cd') {\n const dir = tokens[1]\n if (tokens.length !== 2 || dir === '-' || dir.startsWith('~') || dir.includes('$'))\n return []\n // After `;` / newline the rest runs even when the `cd` failed: the base is unknown.\n if (next === ';')\n return []\n base = isAbsolute(dir) ? dir : join(base, dir)\n continue\n }\n const files = readOperands(tokens)\n if (!files)\n return []\n for (const file of files) {\n if (/[*?[\\]$~]/.test(file))\n continue\n const path = isAbsolute(file) || base === '' ? file : join(base, file)\n if (!targets.includes(path))\n targets.push(path)\n }\n }\n return targets\n}\n\n/**\n * Record the files a successful shell command read. Each entry stores the\n * file's current hash (so the read-before-edit gate passes and drift is\n * still detected) and is marked `elided`, so `read_file` dedup never claims\n * the shell output is an already-visible read. An existing entry with the\n * same hash is left alone.\n */\nexport async function registerShellReads(command: string, ctx: ToolContext): Promise<void> {\n const targets = shellReadTargets(command)\n if (targets.length === 0)\n return\n const readState = resolveReadStateMap(ctx)\n if (!readState)\n return\n for (const path of targets) {\n try {\n const size = await ctx.execution.fileSize?.(ctx.handle, path) ?? null\n if (size !== null && size > MAX_TRACKED_BYTES)\n continue\n const raw = await ctx.execution.readFile(ctx.handle, path)\n const key = readStateKey(ctx.handle.cwd, path)\n const contentHash = hashContent(raw)\n if (readState.get(key)?.contentHash === contentHash)\n continue\n readState.set(key, { contentHash, offset: 1, limit: 0, maxBytes: 0, lineNumbers: false, mtimeMs: Date.now(), elided: true })\n }\n catch {\n // Unreadable or vanished: nothing to record.\n }\n }\n}\n","import type { TaskStallInfo } from '../contexts'\nimport type { ToolContext, ToolDef } from './types'\nimport { previewLine } from '../chat/format'\nimport { ToolFailure } from './failure'\nimport { toolPrompts } from './prompts'\nimport { isExploringShellCommand, isReadOnlyShellCommand } from './shell-classify'\nimport { registerShellReads } from './shell-reads'\nimport { interpretShellResult } from './shell-semantics'\nimport { middleTruncate, tailTruncate } from './truncate'\n\n/** Default cap on combined stdout and stderr, in bytes (32 KiB). */\nconst DEFAULT_MAX_OUTPUT_BYTES = 32_768\n\n/**\n * Build the `shell` tool's description text from `toolPrompts.shell`.\n *\n * - The background-mode paragraphs are appended only when `allowBackground`\n * is true so the model isn't pointed at a feature the agent has disabled.\n * - The \"prefer the dedicated tool\" swap block is appended only for siblings\n * actually present in `registeredCanonicals` — re-running `ls`/`cat` to\n * \"verify\" a path the model already inspected through a dedicated tool is\n * a measurable Kimi/Sonnet failure mode. Hosts that ship `shell` without\n * `read_file`/`glob`/etc. don't see misleading nudges. Aliased names are\n * rendered via `toolAliases` so the printed name matches what the model\n * sees in the tool spec.\n */\nfunction buildShellDescription({\n allowBackground,\n registeredCanonicals,\n toolAliases,\n}: {\n allowBackground: boolean\n registeredCanonicals?: ReadonlySet<string>\n toolAliases?: Record<string, string>\n}): string {\n const prompt = toolPrompts.shell\n const lines = [prompt.core]\n\n if (registeredCanonicals && registeredCanonicals.size > 0) {\n const swaps: string[] = []\n for (const { canonical, label, instead } of prompt.swapHints) {\n if (!registeredCanonicals.has(canonical))\n continue\n const wireName = toolAliases?.[canonical] ?? canonical\n swaps.push(`- ${label}: use \\`${wireName}\\` (not ${instead})`)\n }\n if (swaps.length > 0) {\n lines.push('', prompt.preferDedicated, ...swaps, '', prompt.reminder)\n }\n }\n\n if (allowBackground)\n lines.push('', prompt.background)\n return lines.join('\\n')\n}\n\n/**\n * Build the `shell` tool's JSON-schema. The `run_in_background` field\n * is included only when `allowBackground` is true; the `timeout` /\n * `maxOutputBytes` / `metadata` field descriptions also drop their\n * \"Ignored in background mode\" qualifier when there's no background\n * mode to ignore.\n */\nfunction buildShellInputSchema({ allowBackground }: { allowBackground: boolean }): Record<string, unknown> {\n const bgQualifier = allowBackground ? ' Ignored in background mode.' : ''\n const bgQualifierOutput = allowBackground ? ' Ignored in background mode (output streams to disk).' : ''\n const properties: Record<string, unknown> = {\n command: { type: 'string', description: 'Shell command to run.' },\n description: { type: 'string', description: 'Short (5-10 words) human-readable intent of the command, in sentence case, e.g. \"List TypeScript sources in src\" or \"Install project dependencies\". Shown to the user as the call\\'s label in the transcript, next to the command, so they can follow the agent\\'s reasoning.' },\n timeout: { type: 'integer', description: `Per-call timeout in milliseconds. Enforced at whole-second granularity: values are rounded UP to the next second (e.g. 500 → 1s).${bgQualifier}` },\n maxOutputBytes: { type: 'integer', description: `Truncate combined stdout+stderr beyond this many bytes. Default: 32768. Set 0 for unlimited.${bgQualifierOutput}` },\n metadata: { type: 'boolean', description: `Append \\`(exit N, Nms)\\` footer and surface non-empty stderr on success. Default: true.${bgQualifier}` },\n }\n if (allowBackground) {\n properties.run_in_background = { type: 'boolean', description: 'Start the command in the background, returning a task handle. See the tool description for the full flow.' }\n }\n return {\n type: 'object',\n properties,\n required: ['command'],\n }\n}\n\n/** Options for {@link createShellTool}. */\nexport interface CreateShellToolOptions {\n /**\n * Whether to expose the `run_in_background` flag in the input schema +\n * the background-mode paragraphs in the description. When `false`, the\n * model never sees the flag and won't try to use it. The execute path\n * still has a defensive fallback: an explicit `run_in_background: true`\n * call (e.g. from a hand-crafted message) returns a clean error rather\n * than silently running foreground.\n *\n * Default: `true`.\n */\n allowBackground?: boolean\n\n /**\n * Canonical names of tools registered alongside `shell` on the same\n * agent. When non-empty, the description gains a \"prefer the dedicated\n * tool\" block for each known sibling (`read_file`, `glob`, `grep`,\n * `list_files`, `edit`, `write_file`) — useful against the\n * `ls`/`cat`-to-re-verify loop some models fall into when both a\n * dedicated tool AND `shell` are visible. Unknown / unrecognized names\n * are ignored.\n *\n * Set by `createAgent` per-run from the tool registry; hosts that\n * construct a `shell` directly can pass it explicitly. Omit to suppress\n * the block entirely (no nudge for shell-only agents, no nudge for\n * hosts that prefer to author their own anti-loop prose).\n */\n registeredCanonicals?: ReadonlySet<string>\n\n /**\n * The agent's `toolAliases` map, used to render the wire-level name of\n * each sibling in the swap block. Without this, the block always prints\n * canonical names — fine for the default preset, wrong for hosts that\n * alias-rename (the model would be told to call a name it doesn't see\n * in the tool spec).\n */\n toolAliases?: Record<string, string>\n}\n\n/**\n * Cap on `stdout` / `stderr` in the structured result. Larger than the\n * model-facing cap on purpose: a calling tool (codemode) filters the output\n * before anything reaches the model.\n */\nexport const SHELL_STRUCTURED_MAX_BYTES = 1024 * 1024\n\n/** Shape of {@link shellStructuredResult}, documented to calling tools as `outputSchema`. */\nconst SHELL_OUTPUT_SCHEMA: Record<string, unknown> = {\n anyOf: [\n {\n type: 'object',\n properties: {\n stdout: { type: 'string', description: `Standard output, cut to ${SHELL_STRUCTURED_MAX_BYTES} bytes when longer (start and end for reads, the end otherwise).` },\n stderr: { type: 'string', description: `Standard error, cut to ${SHELL_STRUCTURED_MAX_BYTES} bytes when longer (start and end for reads, the end otherwise).` },\n exit_code: { type: 'number' },\n duration_ms: { type: 'number' },\n truncated: { type: 'boolean', description: 'Whether stdout or stderr was cut.' },\n },\n required: ['stdout', 'stderr', 'exit_code', 'duration_ms', 'truncated'],\n },\n {\n // `run_in_background: true`\n type: 'object',\n properties: {\n task_id: { type: 'string', description: 'Pass to wait_task / shell_kill.' },\n output_path: { type: 'string' },\n pid: { type: 'number' },\n },\n required: ['task_id', 'output_path', 'pid'],\n },\n ],\n}\n\n/** Cut output to `cap` bytes: start and end for exploring commands, the end for the rest. */\nfunction truncateOutput(command: string, text: string, cap: number): string {\n return isExploringShellCommand(command) ? middleTruncate(text, cap) : tailTruncate(text, cap)\n}\n\n/** What a nested caller gets for a foreground run, for any exit code. */\nfunction shellStructuredResult(command: string, result: { stdout: string, stderr: string, exitCode: number }, durationMs: number) {\n const stdout = truncateOutput(command, result.stdout, SHELL_STRUCTURED_MAX_BYTES)\n const stderr = tailTruncate(result.stderr, SHELL_STRUCTURED_MAX_BYTES)\n return {\n stdout,\n stderr,\n exit_code: result.exitCode,\n duration_ms: durationMs,\n truncated: stdout !== result.stdout || stderr !== result.stderr,\n }\n}\n\n/**\n * Creates the `shell` tool, which runs a command in the execution context, in the foreground or as a background task.\n *\n * The default exported `shell` is equivalent to `createShellTool({ allowBackground: true })`.\n * Hosts that use `createAgent` typically do not call this directly: when\n * `behavior.tasksDir` is unset or `behavior.disableBackgroundTasks: true` is\n * set, the agent rewrites the registered built-in `shell` using this factory.\n *\n * Truncation is **tail-priority**: when stdout+stderr combined exceeds\n * `maxOutputBytes`, the head is dropped and a marker `…(N bytes truncated\n * from head)…` is inserted before the tail. Errors and exit summaries\n * usually live at the end of output, so keeping the tail preserves the\n * model's most useful signal. Commands that only explore (`cat`, `sed -n`,\n * `grep`, `ls`, `git log`…) keep their start and end instead: what a read\n * shows first is what it was run for.\n *\n * The combined cap defaults to 32 KiB and the per-call timeout follows the\n * execution context's own default (30 s for in-process).\n *\n * Read-only commands run in parallel with other safe tool calls. Anything else runs alone.\n *\n * @param opts - Background support and sibling tool names. See {@link CreateShellToolOptions}.\n * @example\n * ```ts\n * import { createShellTool } from 'zidane/tools'\n *\n * const shell = createShellTool({ allowBackground: false })\n * ```\n */\nexport function createShellTool(opts: CreateShellToolOptions = {}): ToolDef {\n const allowBackground = opts.allowBackground !== false\n const { registeredCanonicals, toolAliases } = opts\n return {\n // Conditional concurrency safety. Read-only commands (`ls`, `cat`,\n // `git status`, `rg`, …) fan out with other safe siblings; anything\n // mutating or ambiguous barriers. See {@link isReadOnlyShellCommand}\n // for the exact allow-list.\n isConcurrencySafe: input => isReadOnlyShellCommand(input.command),\n spec: {\n name: 'shell',\n description: buildShellDescription({ allowBackground, registeredCanonicals, toolAliases }),\n inputSchema: buildShellInputSchema({ allowBackground }),\n outputSchema: SHELL_OUTPUT_SCHEMA,\n },\n async execute({ command, timeout, maxOutputBytes, metadata, run_in_background }, ctx: ToolContext) {\n const cmd = command as string\n\n // Background mode — dispatches via `execBackground` and returns\n // immediately. The model gets a structured one-liner naming the\n // task id + output path; the actual completion notification arrives\n // on the next turn via the agent's `<task-notification>` injection\n // (see `pendingTaskNotifications` in `src/agent-task-notifications.ts`).\n //\n // Defense-in-depth: when this tool variant has `allowBackground:\n // false` the field isn't in the schema, but a forged input could\n // still set it — surface a clean error instead of silently\n // running foreground (which would surprise the caller).\n if (run_in_background === true) {\n if (!allowBackground)\n throw new ToolFailure('shell error: background mode is disabled for this agent (no `behavior.tasksDir` set, or `behavior.disableBackgroundTasks: true`). Fall back to foreground (drop `run_in_background`).')\n return runBackground(cmd, ctx)\n }\n\n // Long-timeout steering — see `behavior.shellLongTimeoutMs`. A\n // blocking call that pins the turn to a multi-minute transport\n // timeout is almost always a background task the model failed to\n // recognize as one. Refuse with a re-issue instruction, but ONLY\n // when background mode is actually available — otherwise the\n // blocking call is the model's only option and refusing it strands\n // the task.\n const steerThresholdMs = ctx.behavior?.shellLongTimeoutMs\n if (\n typeof steerThresholdMs === 'number' && Number.isFinite(steerThresholdMs) && steerThresholdMs > 0\n && typeof timeout === 'number' && Number.isFinite(timeout) && timeout > steerThresholdMs\n && allowBackground\n && typeof ctx.behavior?.tasksDir === 'string' && ctx.behavior.tasksDir.length > 0\n && ctx.execution.execBackground\n ) {\n throw new ToolFailure(`shell error: this blocking call requested a ${timeout}ms timeout, above the agent's ${steerThresholdMs}ms foreground ceiling. Re-issue with \\`run_in_background: true\\` (drop \\`timeout\\`): you'll get a task_id + output log immediately, and a <task-notification> when it finishes. If your very next step depends on the result, follow up with \\`wait_task({ task_id })\\` instead of polling.`)\n }\n\n // `ExecutionContext.exec` accepts a timeout in seconds; the tool surface\n // takes it in milliseconds so the value lines up with the rest of zidane's\n // ms-based timing. Round up so a 500ms request doesn't collapse to 0.\n //\n // `signal` is what makes `agent.cancelTool(callId)` actually reach\n // the underlying OS process. The loop hands us a unioned signal\n // (`AbortSignal.any([ctx.signal_run, perCallAbort.signal])`) via\n // `ctx.signal`; forwarding it into `exec` lets `child_process.exec`\n // send SIGTERM the moment any of the three layers (run abort,\n // per-call cancel, sibling-cascade) aborts. Without this, a\n // `sleep 60` survived its own cancellation message — orphaned\n // process, observable via `ps` after the run had supposedly\n // finished.\n const execOpts: { timeout?: number, signal?: AbortSignal } = { signal: ctx.signal }\n if (typeof timeout === 'number' && Number.isFinite(timeout) && timeout > 0)\n execOpts.timeout = Math.max(1, Math.ceil(timeout / 1000))\n\n const wantMetadata = metadata !== false\n const startedAt = Date.now()\n const result = await ctx.execution.exec(ctx.handle, cmd, execOpts)\n const durationMs = Date.now() - startedAt\n\n const cap = normalizeCap(maxOutputBytes)\n const semantic = interpretShellResult(cmd, result.exitCode)\n ctx.reportStructured?.(shellStructuredResult(cmd, result, durationMs))\n\n // True success (exit 0): stdout body, cut by `truncateOutput`. With metadata,\n // surface non-empty stderr in a separate section (warnings, deprecation\n // notices) and append an `(exit 0, Nms)` footer.\n if (result.exitCode === 0) {\n const stdoutBody = result.stdout || '(no output)'\n const stdoutShown = truncateOutput(cmd, stdoutBody, cap)\n // Count plain file reads (`cat`, `sed -n`, …) toward read-state so the\n // read-before-edit gate accepts files inspected through shell (on unless\n // `trackShellReads: false`; no work without the gate).\n // A truncated output means the model saw only part of it: register nothing.\n if (ctx.behavior?.requireReadBeforeEdit === true && ctx.behavior.trackShellReads !== false && stdoutShown === stdoutBody)\n await registerShellReads(cmd, ctx)\n if (!wantMetadata)\n return stdoutShown\n const stderrTrimmed = result.stderr.trim()\n const stderrSection = stderrTrimmed\n ? `\\n[stderr]\\n${tailTruncate(stderrTrimmed, Math.min(cap, 2048))}`\n : ''\n return `${stdoutShown}${stderrSection}${absoluteCdNote(cmd, ctx.handle.cwd)}\\n(exit 0, ${durationMs}ms)`\n }\n\n // Per-command semantic override: non-zero exit codes that are NOT errors\n // (grep no-match, diff differ, find partial, test false). Don't surface\n // `Exit code N` — that misleads the model into retrying. Append a short\n // footer with the semantic interpretation so the model sees the why.\n if (!semantic.isError) {\n const body = (result.stdout || result.stderr || '').trim()\n const shown = truncateOutput(cmd, body, cap)\n const semanticFooter = semantic.message ? `\\n(${semantic.message})` : ''\n const timingFooter = wantMetadata ? `\\n(exit ${result.exitCode}, ${durationMs}ms)` : ''\n const head = shown.length > 0 ? shown : (semantic.message ?? '(no output)')\n return `${head}${semanticFooter}${timingFooter}`\n }\n\n // Real failure → keep the `Exit code N` line outside the truncation budget.\n // Truncating the joined body otherwise drops the exit-code prefix (it sits at\n // the head) the moment stdout overflows, leaving the model unable to tell\n // success from failure on large-output commands.\n const combined = `${result.stdout}\\n${result.stderr}`.trim()\n const header = wantMetadata\n ? `Exit code ${result.exitCode} (${durationMs}ms)`\n : `Exit code ${result.exitCode}`\n return `${header}\\n${tailTruncate(combined, cap)}`\n },\n }\n}\n\n/**\n * Detect a `cd` whose absolute target is the workspace root itself or a\n * path under it. Every shell call already starts at the root, so the\n * absolute prefix is pure token noise — and once one absolute `cd`\n * appears in the transcript, models tend to keep imitating it. Returns\n * the relative form to suggest, `''` when the `cd` is a no-op (target\n * === root), or `null` when no redundant `cd` is present. Targets\n * OUTSIDE the workspace are legitimate and never flagged.\n */\nexport function redundantAbsoluteCd(command: string, cwd: string | undefined): string | null {\n if (!cwd || !cwd.startsWith('/') || cwd === '/')\n return null\n const root = cwd.replace(/\\/+$/, '')\n // `cd <target>` at the start of the command or after a separator\n // (`&&`, `||`, `;`). Quoted targets may contain spaces; bare targets\n // stop at whitespace/separators.\n const re = /(?:^|&&|\\|\\||;)\\s*cd\\s+(?:'(\\/[^']*)'|\"(\\/[^\"]*)\"|(\\/[^\\s'\";|&]*))/g\n for (const m of command.matchAll(re)) {\n const target = (m[1] ?? m[2] ?? m[3]).replace(/\\/+$/, '')\n if (target === root)\n return ''\n if (target.startsWith(`${root}/`))\n return target.slice(root.length + 1)\n }\n return null\n}\n\n/**\n * One-line steer appended to a successful call's metadata footer when\n * {@link redundantAbsoluteCd} fires. Deliberately gentle and\n * self-extinguishing: it only ever appears when the model actually\n * emits a redundant absolute `cd`, and disappears as soon as it stops.\n */\nfunction absoluteCdNote(command: string, cwd: string | undefined): string {\n const rel = redundantAbsoluteCd(command, cwd)\n if (rel === null)\n return ''\n return rel === ''\n ? '\\n(note: every call already runs at the workspace root; this `cd` is redundant)'\n : `\\n(note: every call already runs at the workspace root; \\`cd ${rel}\\` suffices)`\n}\n\n/**\n * Default `shell` tool with background mode enabled.\n *\n * Most hosts use this directly via `basicTools`. When the agent's\n * `behavior.tasksDir` is unset OR `behavior.disableBackgroundTasks:\n * true` is set, `createAgent` auto-rewrites this identity to a\n * `createShellTool({ allowBackground: false })` variant so the model\n * never sees a flag it can't use. Hosts who want to bypass that\n * auto-rewrite can register a `createShellTool({ allowBackground })`\n * directly — the rewrite only fires on identity-equal references to\n * this constant.\n */\nexport const shell: ToolDef = createShellTool({ allowBackground: true })\n\n/**\n * Background-mode entry point for the `shell` tool. Settles fast,\n * registers an `onExit` callback that fires `background:exit` on the\n * agent's hook bus, and returns a structured one-liner to the model.\n *\n * Reachable only via the `allowBackground: true` variant; the\n * `allowBackground: false` variant short-circuits before this is\n * called and `createAgent` auto-rewrites the built-in to the\n * `false` variant when `behavior.tasksDir` is unset or\n * `behavior.disableBackgroundTasks: true` is set. The runtime checks\n * below are defense-in-depth for hosts who skip the auto-rewrite\n * (custom shell tool, run-level tools override, etc.):\n *\n * - `behavior.tasksDir` unset → host opted into the schema but\n * forgot to wire the log dir. Clean error, model can fall back to\n * foreground.\n * - `ctx.execution.execBackground` undefined → the context doesn't\n * support it (some remote sandboxes).\n * - `mkdir` on the output dir fails → the underlying filesystem\n * can't accommodate. Surface the error verbatim.\n */\nasync function runBackground(command: string, ctx: ToolContext): Promise<string> {\n const tasksDir = ctx.behavior?.tasksDir\n if (typeof tasksDir !== 'string' || tasksDir.length === 0) {\n throw new ToolFailure('shell error: background mode requires `behavior.tasksDir` to be set on the agent. The host has not opted into background tasks: either fall back to foreground (drop `run_in_background`) or ask the user to enable it.')\n }\n if (!ctx.execution.execBackground) {\n throw new ToolFailure(`shell error: the active execution context (${ctx.execution.type}) does not support background tasks. Fall back to foreground (drop \\`run_in_background\\`).`)\n }\n\n try {\n const outputCap = ctx.behavior?.backgroundOutputCap\n const stallWatchdogMs = ctx.behavior?.backgroundStallWatchdogMs\n const handle = await ctx.execution.execBackground(ctx.handle, command, {\n outputDir: tasksDir,\n onExit: (info) => {\n // Fire-and-forget. `callHook` returns a Promise (it may run\n // async listeners); we don't await — the agent's listener is\n // sync map.set, and the lifecycle is \"task already exited;\n // notify whoever cares\". Surface unhandled rejections under\n // ZIDANE_DEBUG only.\n Promise.resolve(ctx.hooks.callHook('background:exit', info))\n .catch((err: unknown) => {\n if (process.env.ZIDANE_DEBUG)\n process.stderr.write(`[zidane/shell] background:exit hook rejected: ${err instanceof Error ? err.message : String(err)}\\n`)\n })\n },\n ...(typeof outputCap === 'number' && outputCap > 0 ? { maxOutputBytes: outputCap } : {}),\n ...(typeof stallWatchdogMs === 'number' && stallWatchdogMs > 0\n ? {\n stallTimeoutMs: stallWatchdogMs,\n onStall: (info: TaskStallInfo) => {\n // Same fire-and-forget contract as onExit above.\n Promise.resolve(ctx.hooks.callHook('background:stall', info))\n .catch((err: unknown) => {\n if (process.env.ZIDANE_DEBUG)\n process.stderr.write(`[zidane/shell] background:stall hook rejected: ${err instanceof Error ? err.message : String(err)}\\n`)\n })\n },\n }\n : {}),\n })\n\n // Fire `background:start` AFTER the handle is returned so listeners\n // see a usable id + pid + path. Observational only — no caller\n // depends on this hook for behavior, so we don't await it on the\n // critical path.\n Promise.resolve(ctx.hooks.callHook('background:start', {\n taskId: handle.taskId,\n pid: handle.pid,\n command,\n cwd: ctx.handle.cwd,\n outputPath: handle.outputPath,\n startedAt: Date.now(),\n })).catch((err: unknown) => {\n if (process.env.ZIDANE_DEBUG)\n process.stderr.write(`[zidane/shell] background:start hook rejected: ${err instanceof Error ? err.message : String(err)}\\n`)\n })\n\n const cmdPreview = previewLine(command, 60)\n // Depth-aware wake-up instruction. Subagents (depth > 0) get a\n // run-once `agent.run()` so there's no \"next turn\" for them to\n // observe the notification on; the notification ends up on the\n // PARENT's next user-turn after `spawn-child.ts`'s `reassignBackgroundTasks`\n // transfers ownership at child-destroy time. Telling a subagent to\n // \"wait for your next turn\" misleads it into polling, which blocks\n // the parent's spawn call until maxTurns hits.\n const inSubagent = (ctx.depth ?? 0) > 0\n const wakeupHint = inSubagent\n ? 'You are inside a `spawn`\\'d subagent: you have NO next user-turn to receive the notification on. Return a brief summary INCLUDING this task_id and end your turn now. Ownership of the task transfers to the parent agent when your run completes; the parent will see the `<task-notification>` on its next user-turn.'\n : 'The task is running in the background. You\\'ll receive a <task-notification> on your NEXT user-turn with the final status. End your current turn now; do NOT poll the output file in a loop, the notification IS the wake-up. To inspect progress, call `read_file({ path: <output> })` once. To terminate, use `shell_kill({ task_id })`.'\n // For scripts (codemode): the id to hand `wait_task` / `shell_kill`, not a sentence to parse.\n ctx.reportStructured?.({ task_id: handle.taskId, output_path: handle.outputPath, pid: handle.pid })\n return [\n `Started ${handle.taskId} (pid ${handle.pid}).`,\n ` command: ${cmdPreview}`,\n ` output: ${handle.outputPath}`,\n '',\n wakeupHint,\n ].join('\\n')\n }\n catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n throw new ToolFailure(`shell error: failed to start background task: ${msg}`)\n }\n}\n\nfunction normalizeCap(value: unknown): number {\n if (typeof value !== 'number' || !Number.isFinite(value))\n return DEFAULT_MAX_OUTPUT_BYTES\n if (value < 0)\n return DEFAULT_MAX_OUTPUT_BYTES\n return Math.floor(value)\n}\n","/**\n * `shell_kill` — terminate a running background task by id.\n *\n * Companion to the `shell` tool's `run_in_background: true` mode. The\n * model receives a `task_id` when it spawns a background task; this\n * tool routes a kill request through `ExecutionContext.killBackground`,\n * which SIGTERMs the whole process group (the foreground `exec`\n * implementation already documents the kill-tree rationale).\n *\n * The successful kill ALSO suppresses the would-be `<task-notification>`\n * on the next turn — the agent's `tool:after` listener (see\n * `src/agent-task-notifications.ts`) deletes the pending entry by\n * `task_id`. Without that, the model would get the kill result\n * inline AND a redundant notification on its next prompt.\n */\n\nimport type { ToolContext, ToolDef } from './types'\nimport { formatDuration, formatTaskStatus, previewLine } from '../chat/format'\nimport { ToolFailure } from './failure'\nimport { toolPrompts } from './prompts'\n\n/** The `shell_kill` tool. Sends SIGTERM to a background shell task by `task_id`. */\nexport const shellKill: ToolDef = {\n // Concurrency-safe — pure SIGTERM dispatch, no shared mutable state\n // beyond the per-context registry which is atomic.\n isConcurrencySafe: true,\n spec: {\n name: 'shell_kill',\n description: toolPrompts.shell_kill,\n inputSchema: {\n type: 'object',\n properties: {\n task_id: { type: 'string', description: 'The task id returned by a prior `shell({ run_in_background: true })` call.' },\n },\n required: ['task_id'],\n additionalProperties: false,\n },\n },\n async execute(input, ctx: ToolContext): Promise<string> {\n const taskId = input.task_id as string\n\n if (!ctx.execution.killBackground) {\n throw new ToolFailure(`shell_kill error: the active execution context (${ctx.execution.type}) does not support background tasks.`)\n }\n\n const info = await ctx.execution.killBackground(ctx.handle, taskId)\n if (!info) {\n return `shell_kill: no such task \"${taskId}\". It may have already exited and been cleaned up, or it was never started in this session.`\n }\n\n return [\n `Killed ${info.taskId}: ${formatTaskStatus(info)} after ${formatDuration(info.durationMs)}.`,\n ` command: ${previewLine(info.command, 60)}`,\n ` output: ${info.outputPath}`,\n ].join('\\n')\n },\n}\n","/**\n * `wait_task` — block until a background task exits (or a timeout elapses).\n *\n * Companion to `shell({ run_in_background: true })` for the cases where\n * the model genuinely needs the result before it can continue (a build\n * that gates a deploy, a migration that gates a test run) — without\n * burning turns polling the output file.\n *\n * The wait itself is delegated to `ExecutionContext.waitBackground`, an\n * injectable seam: the in-process context parks on its own `onExit`\n * machinery; durable hosts implement it as an awakeable park so a\n * crashed worker re-attaches to the same wait on replay.\n *\n * A successful wait ALSO suppresses the would-be `<task-notification>`\n * on the next turn — the agent's `tool:after` listener treats the\n * returned exit info as \"the model knows\". Timeouts do NOT suppress\n * (the task is still running; its eventual exit is still news).\n */\n\nimport type { ExecutionContext } from '../contexts/types'\nimport type { DurableToolDef, ToolContext, ToolDef } from './types'\nimport { formatDuration, formatTaskStatus, previewLine } from '../chat/format'\nimport { resolveDetachedTasksCapability } from '../contexts/types'\nimport { ToolFailure } from './failure'\nimport { toolPrompts } from './prompts'\n\n/**\n * Stable prefix on the timed-out result. The agent's notification\n * suppression keys on it: results carrying this prefix mean the task is\n * still running, so the pending `<task-notification>` must survive.\n */\nexport const WAIT_TASK_TIMED_OUT_PREFIX = 'wait_task: timed out'\n\nconst DEFAULT_TIMEOUT_MS = 120_000\nconst MAX_TIMEOUT_MS = 30 * 60_000\n\nconst waitTaskDef: DurableToolDef = {\n // NOT concurrency-safe: a parked wait can occupy a scheduler slot for\n // minutes; barrier semantics keep it from starving a sibling fleet.\n // Waiting has no effect of its own: a resumed durable run waits again.\n replay: 'safe',\n spec: {\n name: 'wait_task',\n description: toolPrompts.wait_task,\n inputSchema: {\n type: 'object',\n properties: {\n task_id: { type: 'string', description: 'The task id returned by a prior `shell({ run_in_background: true })` call.' },\n timeout_ms: { type: 'integer', description: `Max milliseconds to wait before giving up (task keeps running). Default: ${DEFAULT_TIMEOUT_MS}. Capped at ${MAX_TIMEOUT_MS}.` },\n },\n required: ['task_id'],\n additionalProperties: false,\n },\n },\n // A durable context's `waitBackground` parks on the runtime itself.\n durableBody: (execution: ExecutionContext) => (resolveDetachedTasksCapability(execution) === 'durable' ? 'composite' : undefined),\n async execute(input, ctx: ToolContext): Promise<string> {\n const taskId = input.task_id as string\n\n if (!ctx.execution.waitBackground) {\n throw new ToolFailure(`wait_task error: the active execution context (${ctx.execution.type}) does not support waiting on background tasks.`)\n }\n\n // Distinguish \"unknown task\" from \"still running\" up front —\n // `waitBackground` collapses both into `null` on its miss path.\n //\n // Skipped on DURABLE contexts. There `wait_task` is not a step of a\n // replaying run (its awakeable park can't nest in a recorded step, see\n // `durableBody` above), so its body re-runs in full on every replay.\n // This `listBackground` read is un-journaled, and branching on it gates\n // whether the *journaled* `waitBackground` (e.g. its register/probe/settle\n // entries) runs. If the runner's registry flips across attempts (a\n // restart mid-park drops the task), the branch flips and the journal\n // diverges (a journal mismatch). Durable hosts get the existence decision from\n // `waitBackground`'s own journaled probe instead (missing → `null` → the\n // timeout branch below). On non-durable contexts there's no journal to\n // diverge, so the more precise \"no such task\" message is kept.\n if (resolveDetachedTasksCapability(ctx.execution) !== 'durable' && ctx.execution.listBackground) {\n const entries = await ctx.execution.listBackground(ctx.handle)\n if (!entries.some(e => e.taskId === taskId)) {\n return `wait_task: no such task \"${taskId}\". It may have already exited and been cleaned up, or it was never started in this session.`\n }\n }\n\n const requested = typeof input.timeout_ms === 'number' && Number.isFinite(input.timeout_ms) && input.timeout_ms > 0\n ? input.timeout_ms\n : DEFAULT_TIMEOUT_MS\n const timeoutMs = Math.min(requested, MAX_TIMEOUT_MS)\n\n const info = await ctx.execution.waitBackground(ctx.handle, taskId, {\n timeoutMs,\n signal: ctx.signal,\n })\n\n if (!info) {\n return [\n `${WAIT_TASK_TIMED_OUT_PREFIX} after ${formatDuration(timeoutMs)}: ${taskId} is still running.`,\n 'You can wait again with a longer timeout, continue with other work (a `<task-notification>` arrives when it exits), or terminate it with `shell_kill`.',\n ].join('\\n')\n }\n\n return [\n `Task ${info.taskId} ${formatTaskStatus(info)} after ${formatDuration(info.durationMs)}.`,\n ` command: ${previewLine(info.command, 60)}`,\n ` output: ${info.outputPath}`,\n ].join('\\n')\n },\n}\n\n/**\n * The `wait_task` tool. Waits for a background shell task to exit and returns its final status. On timeout the task keeps running.\n */\nexport const waitTask: ToolDef = waitTaskDef\n"],"mappings":"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"}