@namzu/cli 36.1.2 → 36.3.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 (314) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/chunks/{acp-QXCMYZW7.js → acp-2DS2IECT.js} +129 -37
  4. package/dist/chunks/acp-2DS2IECT.js.map +6 -0
  5. package/dist/chunks/{activity-command-HK7YJTXV.js → activity-command-MCYEK4Z4.js} +10 -10
  6. package/dist/chunks/{add-UYIKY4OE.js → add-ZQ3YWP4F.js} +16 -16
  7. package/dist/chunks/{agent-Y2WYEXWC.js → agent-PAGVUATH.js} +24 -22
  8. package/dist/chunks/agent-session-PLIPF3XG.js +46 -0
  9. package/dist/chunks/{archive-C4A3HPLF.js → archive-VPREZOGC.js} +8 -8
  10. package/dist/chunks/{bin-main-VQKMQICY.js → bin-main-MWFKUXP2.js} +3 -3
  11. package/dist/chunks/{browser-CRX4HM4C.js → browser-FZWYOIIJ.js} +6 -6
  12. package/dist/chunks/{chat-5MWPKAET.js → chat-W355SFNQ.js} +13 -13
  13. package/dist/chunks/{chunk-TLTJ2KTW.js → chunk-2BZOT2CT.js} +2 -2
  14. package/dist/chunks/{chunk-MJMDPZ6G.js → chunk-2O7KYX4V.js} +19 -9
  15. package/dist/chunks/chunk-2O7KYX4V.js.map +6 -0
  16. package/dist/chunks/{chunk-JELVHU7X.js → chunk-2TGQ2B53.js} +259 -3
  17. package/dist/chunks/{chunk-JELVHU7X.js.map → chunk-2TGQ2B53.js.map} +3 -3
  18. package/dist/chunks/{chunk-AN7FO7NS.js → chunk-3F5DGROG.js} +2 -2
  19. package/dist/chunks/{chunk-YMKYJ4DI.js → chunk-3M3PMQ3I.js} +7 -7
  20. package/dist/chunks/{chunk-WATMFOHB.js → chunk-46B7KRXY.js} +6 -6
  21. package/dist/chunks/{chunk-GMCOZ3CU.js → chunk-52OVP5BG.js} +4 -4
  22. package/dist/chunks/{chunk-HFJHHCTY.js → chunk-56OUKG5W.js} +3 -3
  23. package/dist/chunks/{chunk-N5IF64K3.js → chunk-5H4LJ4AN.js} +27 -9
  24. package/dist/chunks/chunk-5H4LJ4AN.js.map +6 -0
  25. package/dist/chunks/{chunk-4BZMQ2VD.js → chunk-5URT3ZM2.js} +4 -4
  26. package/dist/chunks/{chunk-7Z7CAVIN.js → chunk-6CGC72OA.js} +12 -10
  27. package/dist/chunks/{chunk-7Z7CAVIN.js.map → chunk-6CGC72OA.js.map} +1 -1
  28. package/dist/chunks/{chunk-AIY4PCDR.js → chunk-6TDJXZ5W.js} +4 -4
  29. package/dist/chunks/{chunk-ZKEWE6K4.js → chunk-AHYHR5DY.js} +3 -3
  30. package/dist/chunks/{chunk-3P5PF6XE.js → chunk-AP5KD43Y.js} +2 -2
  31. package/dist/chunks/{chunk-OLPOM3DR.js → chunk-AS7UWXMN.js} +4 -4
  32. package/dist/chunks/{chunk-Q24K7536.js → chunk-BOV53LZO.js} +2 -2
  33. package/dist/chunks/{chunk-HQM2WSQT.js → chunk-BUCICQWG.js} +2 -2
  34. package/dist/chunks/{chunk-5PQVJBIO.js → chunk-CZVHXYGD.js} +6 -3
  35. package/dist/chunks/{chunk-5PQVJBIO.js.map → chunk-CZVHXYGD.js.map} +1 -1
  36. package/dist/chunks/{chunk-YXLD46UI.js → chunk-DYUOXP5Q.js} +13 -13
  37. package/dist/chunks/{chunk-UOOQPODR.js → chunk-E7HLYLD7.js} +3 -3
  38. package/dist/chunks/{chunk-TIGWWAJI.js → chunk-EKUJUPFA.js} +4 -4
  39. package/dist/chunks/{chunk-L2T4O6S3.js → chunk-EZ6ZSHYX.js} +35 -26
  40. package/dist/chunks/{chunk-L2T4O6S3.js.map → chunk-EZ6ZSHYX.js.map} +1 -1
  41. package/dist/chunks/{chunk-HV4LJFNV.js → chunk-F3YQ2CSZ.js} +4 -4
  42. package/dist/chunks/{chunk-HBBB2CAC.js → chunk-FU4GQ7K2.js} +2 -2
  43. package/dist/chunks/{chunk-IJH7J5NJ.js → chunk-GQN64E36.js} +3 -3
  44. package/dist/chunks/{chunk-NQY5P2EB.js → chunk-HKDPP2JF.js} +2 -2
  45. package/dist/chunks/{chunk-WM2JEUGV.js → chunk-HSEJGSXE.js} +2 -2
  46. package/dist/chunks/{chunk-KU3W6IHV.js → chunk-I6CDUPVR.js} +2 -2
  47. package/dist/chunks/{chunk-O7DBCVNY.js → chunk-IQBR45AU.js} +2 -2
  48. package/dist/chunks/{chunk-FXS3AG6B.js → chunk-JCDTR2ZU.js} +4 -4
  49. package/dist/chunks/{chunk-AXIGFKJF.js → chunk-KMHLON54.js} +2 -2
  50. package/dist/chunks/{chunk-EIYM6TY7.js → chunk-KOG2WB66.js} +4 -4
  51. package/dist/chunks/{chunk-5GRV6P5C.js → chunk-LBH5WVXU.js} +2 -2
  52. package/dist/chunks/{chunk-RC6X3ZY6.js → chunk-LYDXPWAZ.js} +204 -7
  53. package/dist/chunks/chunk-LYDXPWAZ.js.map +6 -0
  54. package/dist/chunks/{chunk-K76WV7TN.js → chunk-MBBFX64S.js} +2 -2
  55. package/dist/chunks/{chunk-JPPC4LJF.js → chunk-MJO6CH5F.js} +3 -3
  56. package/dist/chunks/{chunk-SRU3MDHZ.js → chunk-NATYSTPM.js} +2 -2
  57. package/dist/chunks/{chunk-X2FWNSZ7.js → chunk-NBD5MAGK.js} +9 -9
  58. package/dist/chunks/{chunk-NROIHI6L.js → chunk-PINPSIJ5.js} +5 -5
  59. package/dist/chunks/{chunk-YTESW44T.js → chunk-PLKJKF32.js} +12 -12
  60. package/dist/chunks/chunk-QBAISLAD.js +750 -0
  61. package/dist/chunks/chunk-QBAISLAD.js.map +6 -0
  62. package/dist/chunks/{chunk-UDBEU2FR.js → chunk-QRT3N2K3.js} +2 -2
  63. package/dist/chunks/{chunk-Q5YM2GCX.js → chunk-QXDKRJZ5.js} +3 -3
  64. package/dist/chunks/{chunk-V7TQR6AR.js → chunk-RBX6RVYO.js} +6 -6
  65. package/dist/chunks/{chunk-J72CRUNX.js → chunk-RM6HTBJK.js} +2 -2
  66. package/dist/chunks/{chunk-A5UXODFL.js → chunk-S6MZK4LD.js} +2 -2
  67. package/dist/chunks/{chunk-TJJUB7VQ.js → chunk-SFUUN6B3.js} +1547 -280
  68. package/dist/chunks/chunk-SFUUN6B3.js.map +6 -0
  69. package/dist/chunks/{chunk-EWKJGHRO.js → chunk-V3ZLK3XQ.js} +3245 -1041
  70. package/dist/chunks/chunk-V3ZLK3XQ.js.map +6 -0
  71. package/dist/chunks/{chunk-C5WBEO3X.js → chunk-VUOS5SQ3.js} +2 -2
  72. package/dist/chunks/{chunk-LQMHASKR.js → chunk-XCWZZZOW.js} +3 -3
  73. package/dist/chunks/{chunk-2NJ2XUXJ.js → chunk-YYQFUKI7.js} +3 -3
  74. package/dist/chunks/{chunk-7WJOQ6EA.js → chunk-YYVDLVUM.js} +2 -2
  75. package/dist/chunks/{chunk-UWWGSDZ5.js → chunk-ZB5ETOVE.js} +3 -3
  76. package/dist/chunks/{chunk-CG65NUSJ.js → chunk-ZG6NVROB.js} +2 -2
  77. package/dist/chunks/{chunk-TWMKJ6BE.js → chunk-ZHBHRMCI.js} +4 -4
  78. package/dist/chunks/{cli-runtime-FXV35STX.js → cli-runtime-NG23IVRM.js} +8 -8
  79. package/dist/chunks/{commands-QPVRB3RK.js → commands-LQISMOPF.js} +5 -5
  80. package/dist/chunks/{crash-report-S3BTEPYR.js → crash-report-EYK56MJJ.js} +6 -6
  81. package/dist/chunks/{dist-BFC7XUCT.js → dist-3AMBKAG4.js} +2 -2
  82. package/dist/chunks/{dist-SKRHHPUR.js → dist-AUDNCB3F.js} +2 -2
  83. package/dist/chunks/{dist-3GJFRS2X.js → dist-AZJ56DQJ.js} +2 -2
  84. package/dist/chunks/{dist-EY3OJBQH.js → dist-DWB5AYXB.js} +2 -2
  85. package/dist/chunks/{dist-ERN5DRKK.js → dist-EDKLCZY4.js} +2 -2
  86. package/dist/chunks/{dist-LVG2TYZT.js → dist-PZXF5NU3.js} +2 -2
  87. package/dist/chunks/{dist-G42HPNIE.js → dist-XT4V74YL.js} +2 -2
  88. package/dist/chunks/{doctor-KMTPPEWG.js → doctor-3EOUWDYB.js} +6 -6
  89. package/dist/chunks/{drain-PL5VSYUQ.js → drain-IMNF2CDN.js} +11 -10
  90. package/dist/chunks/{drain-PL5VSYUQ.js.map → drain-IMNF2CDN.js.map} +1 -1
  91. package/dist/chunks/{eval-53UONRWR.js → eval-VHWEJ4GG.js} +2 -2
  92. package/dist/chunks/{exec-5ZXTX5XC.js → exec-2KM6DH56.js} +152 -41
  93. package/dist/chunks/exec-2KM6DH56.js.map +6 -0
  94. package/dist/chunks/{home-QS7RBP34.js → home-H4GTIYO5.js} +3 -3
  95. package/dist/chunks/{host-queries-A55WPD4R.js → host-queries-5C4TCX6J.js} +13 -13
  96. package/dist/chunks/{lifecycle-VR36VUPC.js → lifecycle-IHW4P636.js} +23 -23
  97. package/dist/chunks/{list-DQZU7NEF.js → list-JJZ7I5OF.js} +12 -12
  98. package/dist/chunks/{login-6OFDFHD6.js → login-T2RKNHK2.js} +8 -8
  99. package/dist/chunks/{logs-KSG7SFAB.js → logs-J6D4SEDY.js} +4 -4
  100. package/dist/chunks/{mcp-CHPFRT2Y.js → mcp-WONRVJ26.js} +15 -15
  101. package/dist/chunks/{message-command-AJFVZ5EY.js → message-command-F3TFROMK.js} +29 -29
  102. package/dist/chunks/{operator-tools-LTPV3CH5.js → operator-tools-H4MYC5PE.js} +11 -11
  103. package/dist/chunks/{output-schema-UM3P5AOR.js → output-schema-RFJUTQ2N.js} +3 -3
  104. package/dist/chunks/{pal-CWO3HUXQ.js → pal-UCYGJN75.js} +11 -11
  105. package/dist/chunks/{providers-7P5CTPHT.js → providers-BHF65IUG.js} +6 -6
  106. package/dist/chunks/{resident-3K7SI2UP.js → resident-CNS3XQRU.js} +18 -18
  107. package/dist/chunks/{resume-command-XZWGUXRK.js → resume-command-Y3NYDSI4.js} +4 -4
  108. package/dist/chunks/{schedule-GKM3RRIU.js → schedule-KN5YGOSJ.js} +8 -8
  109. package/dist/chunks/{service-CIWTUMRI.js → service-OEOHUGM6.js} +22 -22
  110. package/dist/chunks/session-step-AYHFVVX6.js +26 -0
  111. package/dist/chunks/{skills-HV2MOBEW.js → skills-K3JRZ3IR.js} +8 -8
  112. package/dist/chunks/{state-6HV3D3O4.js → state-QPSQI7U7.js} +2 -2
  113. package/dist/chunks/{store-GDP2EW27.js → store-7WZWQXKX.js} +6 -6
  114. package/dist/chunks/{store-6J2MUGON.js → store-PSQKDEPY.js} +8 -8
  115. package/dist/chunks/{store-VXNKMMNW.js → store-Z3PS6LUZ.js} +4 -4
  116. package/dist/chunks/{tui-ZURFLJQB.js → tui-JKZOXURU.js} +2626 -1331
  117. package/dist/chunks/tui-JKZOXURU.js.map +6 -0
  118. package/dist/chunks/{upgrade-MC5JB7DK.js → upgrade-C6QUXRLB.js} +3 -3
  119. package/dist/chunks/{worktree-6YPRX6SU.js → worktree-KLD2PAMU.js} +10 -10
  120. package/dist/cli.d.ts.map +1 -1
  121. package/dist/commands/acp-harness.d.ts.map +1 -1
  122. package/dist/commands/acp.d.ts +6 -0
  123. package/dist/commands/acp.d.ts.map +1 -1
  124. package/dist/commands/desktop-host-pr.d.ts +14 -0
  125. package/dist/commands/desktop-host-pr.d.ts.map +1 -0
  126. package/dist/commands/desktop-host.d.ts +6 -0
  127. package/dist/commands/desktop-host.d.ts.map +1 -1
  128. package/dist/commands/drain.d.ts.map +1 -1
  129. package/dist/commands/exec-json.d.ts.map +1 -1
  130. package/dist/commands/exec-workflows.d.ts +50 -0
  131. package/dist/commands/exec-workflows.d.ts.map +1 -0
  132. package/dist/commands/exec.d.ts.map +1 -1
  133. package/dist/config/load.d.ts.map +1 -1
  134. package/dist/config/schema.d.ts +96 -0
  135. package/dist/config/schema.d.ts.map +1 -1
  136. package/dist/index.js +9 -9
  137. package/dist/integrations/decision/model.d.ts +26 -0
  138. package/dist/integrations/decision/model.d.ts.map +1 -0
  139. package/dist/integrations/decision/routing.d.ts +75 -0
  140. package/dist/integrations/decision/routing.d.ts.map +1 -0
  141. package/dist/integrations/resident/runner-worker.js +16 -16
  142. package/dist/integrations/resident/session-step.d.ts.map +1 -1
  143. package/dist/integrations/subagents/activity.d.ts +19 -0
  144. package/dist/integrations/subagents/activity.d.ts.map +1 -1
  145. package/dist/integrations/subagents/runtime.d.ts +52 -0
  146. package/dist/integrations/subagents/runtime.d.ts.map +1 -1
  147. package/dist/integrations/workflows/doctrine.d.ts +7 -0
  148. package/dist/integrations/workflows/doctrine.d.ts.map +1 -0
  149. package/dist/integrations/workflows/history.d.ts +13 -0
  150. package/dist/integrations/workflows/history.d.ts.map +1 -0
  151. package/dist/integrations/workflows/host.d.ts +59 -0
  152. package/dist/integrations/workflows/host.d.ts.map +1 -0
  153. package/dist/integrations/workflows/notice.d.ts +19 -0
  154. package/dist/integrations/workflows/notice.d.ts.map +1 -0
  155. package/dist/integrations/workflows/offering.d.ts +40 -0
  156. package/dist/integrations/workflows/offering.d.ts.map +1 -0
  157. package/dist/integrations/workflows/registry.d.ts +73 -0
  158. package/dist/integrations/workflows/registry.d.ts.map +1 -0
  159. package/dist/integrations/workflows/view.d.ts +97 -0
  160. package/dist/integrations/workflows/view.d.ts.map +1 -0
  161. package/dist/pals/agent-session.d.ts.map +1 -1
  162. package/dist/tui/AgentExplorer.d.ts +179 -32
  163. package/dist/tui/AgentExplorer.d.ts.map +1 -1
  164. package/dist/tui/App.d.ts.map +1 -1
  165. package/dist/tui/BackgroundJobsPanel.d.ts.map +1 -1
  166. package/dist/tui/BrandHeader.d.ts +3 -1
  167. package/dist/tui/BrandHeader.d.ts.map +1 -1
  168. package/dist/tui/Composer.d.ts +23 -1
  169. package/dist/tui/Composer.d.ts.map +1 -1
  170. package/dist/tui/ComposerFrame.d.ts +10 -3
  171. package/dist/tui/ComposerFrame.d.ts.map +1 -1
  172. package/dist/tui/LiveActivity.d.ts +4 -0
  173. package/dist/tui/LiveActivity.d.ts.map +1 -1
  174. package/dist/tui/PendingInputPanel.d.ts +14 -11
  175. package/dist/tui/PendingInputPanel.d.ts.map +1 -1
  176. package/dist/tui/PermissionOverlay.d.ts.map +1 -1
  177. package/dist/tui/Picker.d.ts +11 -1
  178. package/dist/tui/Picker.d.ts.map +1 -1
  179. package/dist/tui/StatusBar.d.ts +61 -36
  180. package/dist/tui/StatusBar.d.ts.map +1 -1
  181. package/dist/tui/Transcript.d.ts +14 -0
  182. package/dist/tui/Transcript.d.ts.map +1 -1
  183. package/dist/tui/agent-transcript-rows.d.ts +34 -12
  184. package/dist/tui/agent-transcript-rows.d.ts.map +1 -1
  185. package/dist/tui/agent.d.ts +71 -1
  186. package/dist/tui/agent.d.ts.map +1 -1
  187. package/dist/tui/job-exit-row.d.ts +19 -0
  188. package/dist/tui/job-exit-row.d.ts.map +1 -0
  189. package/dist/tui/model-choices.d.ts +20 -0
  190. package/dist/tui/model-choices.d.ts.map +1 -1
  191. package/dist/tui/model-selection-intent.d.ts +25 -0
  192. package/dist/tui/model-selection-intent.d.ts.map +1 -1
  193. package/dist/tui/permission-review.d.ts +26 -0
  194. package/dist/tui/permission-review.d.ts.map +1 -1
  195. package/dist/tui/pr-status.d.ts +112 -0
  196. package/dist/tui/pr-status.d.ts.map +1 -0
  197. package/dist/tui/shell-cell.d.ts +86 -0
  198. package/dist/tui/shell-cell.d.ts.map +1 -0
  199. package/dist/tui/shorten-path.d.ts +10 -0
  200. package/dist/tui/shorten-path.d.ts.map +1 -0
  201. package/dist/tui/slashCommands.d.ts +4 -0
  202. package/dist/tui/slashCommands.d.ts.map +1 -1
  203. package/dist/tui/theme.d.ts +6 -0
  204. package/dist/tui/theme.d.ts.map +1 -1
  205. package/dist/tui/tidy-tool-output.d.ts +5 -0
  206. package/dist/tui/tidy-tool-output.d.ts.map +1 -1
  207. package/dist/tui/types.d.ts +23 -1
  208. package/dist/tui/types.d.ts.map +1 -1
  209. package/dist/tui/use-pr-status.d.ts +15 -0
  210. package/dist/tui/use-pr-status.d.ts.map +1 -0
  211. package/dist/tui/workflow-runs.d.ts +38 -0
  212. package/dist/tui/workflow-runs.d.ts.map +1 -0
  213. package/package.json +7 -6
  214. package/dist/chunks/acp-QXCMYZW7.js.map +0 -6
  215. package/dist/chunks/agent-session-UNUZAMRW.js +0 -46
  216. package/dist/chunks/chunk-EWKJGHRO.js.map +0 -6
  217. package/dist/chunks/chunk-MJMDPZ6G.js.map +0 -6
  218. package/dist/chunks/chunk-N5IF64K3.js.map +0 -6
  219. package/dist/chunks/chunk-PYG7DZ2D.js +0 -380
  220. package/dist/chunks/chunk-PYG7DZ2D.js.map +0 -6
  221. package/dist/chunks/chunk-RC6X3ZY6.js.map +0 -6
  222. package/dist/chunks/chunk-TJJUB7VQ.js.map +0 -6
  223. package/dist/chunks/exec-5ZXTX5XC.js.map +0 -6
  224. package/dist/chunks/session-step-XATOSLSM.js +0 -26
  225. package/dist/chunks/tui-ZURFLJQB.js.map +0 -6
  226. /package/dist/chunks/{activity-command-HK7YJTXV.js.map → activity-command-MCYEK4Z4.js.map} +0 -0
  227. /package/dist/chunks/{add-UYIKY4OE.js.map → add-ZQ3YWP4F.js.map} +0 -0
  228. /package/dist/chunks/{agent-Y2WYEXWC.js.map → agent-PAGVUATH.js.map} +0 -0
  229. /package/dist/chunks/{agent-session-UNUZAMRW.js.map → agent-session-PLIPF3XG.js.map} +0 -0
  230. /package/dist/chunks/{archive-C4A3HPLF.js.map → archive-VPREZOGC.js.map} +0 -0
  231. /package/dist/chunks/{bin-main-VQKMQICY.js.map → bin-main-MWFKUXP2.js.map} +0 -0
  232. /package/dist/chunks/{browser-CRX4HM4C.js.map → browser-FZWYOIIJ.js.map} +0 -0
  233. /package/dist/chunks/{chat-5MWPKAET.js.map → chat-W355SFNQ.js.map} +0 -0
  234. /package/dist/chunks/{chunk-TLTJ2KTW.js.map → chunk-2BZOT2CT.js.map} +0 -0
  235. /package/dist/chunks/{chunk-AN7FO7NS.js.map → chunk-3F5DGROG.js.map} +0 -0
  236. /package/dist/chunks/{chunk-YMKYJ4DI.js.map → chunk-3M3PMQ3I.js.map} +0 -0
  237. /package/dist/chunks/{chunk-WATMFOHB.js.map → chunk-46B7KRXY.js.map} +0 -0
  238. /package/dist/chunks/{chunk-GMCOZ3CU.js.map → chunk-52OVP5BG.js.map} +0 -0
  239. /package/dist/chunks/{chunk-HFJHHCTY.js.map → chunk-56OUKG5W.js.map} +0 -0
  240. /package/dist/chunks/{chunk-4BZMQ2VD.js.map → chunk-5URT3ZM2.js.map} +0 -0
  241. /package/dist/chunks/{chunk-AIY4PCDR.js.map → chunk-6TDJXZ5W.js.map} +0 -0
  242. /package/dist/chunks/{chunk-ZKEWE6K4.js.map → chunk-AHYHR5DY.js.map} +0 -0
  243. /package/dist/chunks/{chunk-3P5PF6XE.js.map → chunk-AP5KD43Y.js.map} +0 -0
  244. /package/dist/chunks/{chunk-OLPOM3DR.js.map → chunk-AS7UWXMN.js.map} +0 -0
  245. /package/dist/chunks/{chunk-Q24K7536.js.map → chunk-BOV53LZO.js.map} +0 -0
  246. /package/dist/chunks/{chunk-HQM2WSQT.js.map → chunk-BUCICQWG.js.map} +0 -0
  247. /package/dist/chunks/{chunk-YXLD46UI.js.map → chunk-DYUOXP5Q.js.map} +0 -0
  248. /package/dist/chunks/{chunk-UOOQPODR.js.map → chunk-E7HLYLD7.js.map} +0 -0
  249. /package/dist/chunks/{chunk-TIGWWAJI.js.map → chunk-EKUJUPFA.js.map} +0 -0
  250. /package/dist/chunks/{chunk-HV4LJFNV.js.map → chunk-F3YQ2CSZ.js.map} +0 -0
  251. /package/dist/chunks/{chunk-HBBB2CAC.js.map → chunk-FU4GQ7K2.js.map} +0 -0
  252. /package/dist/chunks/{chunk-IJH7J5NJ.js.map → chunk-GQN64E36.js.map} +0 -0
  253. /package/dist/chunks/{chunk-NQY5P2EB.js.map → chunk-HKDPP2JF.js.map} +0 -0
  254. /package/dist/chunks/{chunk-WM2JEUGV.js.map → chunk-HSEJGSXE.js.map} +0 -0
  255. /package/dist/chunks/{chunk-KU3W6IHV.js.map → chunk-I6CDUPVR.js.map} +0 -0
  256. /package/dist/chunks/{chunk-O7DBCVNY.js.map → chunk-IQBR45AU.js.map} +0 -0
  257. /package/dist/chunks/{chunk-FXS3AG6B.js.map → chunk-JCDTR2ZU.js.map} +0 -0
  258. /package/dist/chunks/{chunk-AXIGFKJF.js.map → chunk-KMHLON54.js.map} +0 -0
  259. /package/dist/chunks/{chunk-EIYM6TY7.js.map → chunk-KOG2WB66.js.map} +0 -0
  260. /package/dist/chunks/{chunk-5GRV6P5C.js.map → chunk-LBH5WVXU.js.map} +0 -0
  261. /package/dist/chunks/{chunk-K76WV7TN.js.map → chunk-MBBFX64S.js.map} +0 -0
  262. /package/dist/chunks/{chunk-JPPC4LJF.js.map → chunk-MJO6CH5F.js.map} +0 -0
  263. /package/dist/chunks/{chunk-SRU3MDHZ.js.map → chunk-NATYSTPM.js.map} +0 -0
  264. /package/dist/chunks/{chunk-X2FWNSZ7.js.map → chunk-NBD5MAGK.js.map} +0 -0
  265. /package/dist/chunks/{chunk-NROIHI6L.js.map → chunk-PINPSIJ5.js.map} +0 -0
  266. /package/dist/chunks/{chunk-YTESW44T.js.map → chunk-PLKJKF32.js.map} +0 -0
  267. /package/dist/chunks/{chunk-UDBEU2FR.js.map → chunk-QRT3N2K3.js.map} +0 -0
  268. /package/dist/chunks/{chunk-Q5YM2GCX.js.map → chunk-QXDKRJZ5.js.map} +0 -0
  269. /package/dist/chunks/{chunk-V7TQR6AR.js.map → chunk-RBX6RVYO.js.map} +0 -0
  270. /package/dist/chunks/{chunk-J72CRUNX.js.map → chunk-RM6HTBJK.js.map} +0 -0
  271. /package/dist/chunks/{chunk-A5UXODFL.js.map → chunk-S6MZK4LD.js.map} +0 -0
  272. /package/dist/chunks/{chunk-C5WBEO3X.js.map → chunk-VUOS5SQ3.js.map} +0 -0
  273. /package/dist/chunks/{chunk-LQMHASKR.js.map → chunk-XCWZZZOW.js.map} +0 -0
  274. /package/dist/chunks/{chunk-2NJ2XUXJ.js.map → chunk-YYQFUKI7.js.map} +0 -0
  275. /package/dist/chunks/{chunk-7WJOQ6EA.js.map → chunk-YYVDLVUM.js.map} +0 -0
  276. /package/dist/chunks/{chunk-UWWGSDZ5.js.map → chunk-ZB5ETOVE.js.map} +0 -0
  277. /package/dist/chunks/{chunk-CG65NUSJ.js.map → chunk-ZG6NVROB.js.map} +0 -0
  278. /package/dist/chunks/{chunk-TWMKJ6BE.js.map → chunk-ZHBHRMCI.js.map} +0 -0
  279. /package/dist/chunks/{cli-runtime-FXV35STX.js.map → cli-runtime-NG23IVRM.js.map} +0 -0
  280. /package/dist/chunks/{commands-QPVRB3RK.js.map → commands-LQISMOPF.js.map} +0 -0
  281. /package/dist/chunks/{crash-report-S3BTEPYR.js.map → crash-report-EYK56MJJ.js.map} +0 -0
  282. /package/dist/chunks/{dist-BFC7XUCT.js.map → dist-3AMBKAG4.js.map} +0 -0
  283. /package/dist/chunks/{dist-SKRHHPUR.js.map → dist-AUDNCB3F.js.map} +0 -0
  284. /package/dist/chunks/{dist-3GJFRS2X.js.map → dist-AZJ56DQJ.js.map} +0 -0
  285. /package/dist/chunks/{dist-EY3OJBQH.js.map → dist-DWB5AYXB.js.map} +0 -0
  286. /package/dist/chunks/{dist-ERN5DRKK.js.map → dist-EDKLCZY4.js.map} +0 -0
  287. /package/dist/chunks/{dist-LVG2TYZT.js.map → dist-PZXF5NU3.js.map} +0 -0
  288. /package/dist/chunks/{dist-G42HPNIE.js.map → dist-XT4V74YL.js.map} +0 -0
  289. /package/dist/chunks/{doctor-KMTPPEWG.js.map → doctor-3EOUWDYB.js.map} +0 -0
  290. /package/dist/chunks/{eval-53UONRWR.js.map → eval-VHWEJ4GG.js.map} +0 -0
  291. /package/dist/chunks/{home-QS7RBP34.js.map → home-H4GTIYO5.js.map} +0 -0
  292. /package/dist/chunks/{host-queries-A55WPD4R.js.map → host-queries-5C4TCX6J.js.map} +0 -0
  293. /package/dist/chunks/{lifecycle-VR36VUPC.js.map → lifecycle-IHW4P636.js.map} +0 -0
  294. /package/dist/chunks/{list-DQZU7NEF.js.map → list-JJZ7I5OF.js.map} +0 -0
  295. /package/dist/chunks/{login-6OFDFHD6.js.map → login-T2RKNHK2.js.map} +0 -0
  296. /package/dist/chunks/{logs-KSG7SFAB.js.map → logs-J6D4SEDY.js.map} +0 -0
  297. /package/dist/chunks/{mcp-CHPFRT2Y.js.map → mcp-WONRVJ26.js.map} +0 -0
  298. /package/dist/chunks/{message-command-AJFVZ5EY.js.map → message-command-F3TFROMK.js.map} +0 -0
  299. /package/dist/chunks/{operator-tools-LTPV3CH5.js.map → operator-tools-H4MYC5PE.js.map} +0 -0
  300. /package/dist/chunks/{output-schema-UM3P5AOR.js.map → output-schema-RFJUTQ2N.js.map} +0 -0
  301. /package/dist/chunks/{pal-CWO3HUXQ.js.map → pal-UCYGJN75.js.map} +0 -0
  302. /package/dist/chunks/{providers-7P5CTPHT.js.map → providers-BHF65IUG.js.map} +0 -0
  303. /package/dist/chunks/{resident-3K7SI2UP.js.map → resident-CNS3XQRU.js.map} +0 -0
  304. /package/dist/chunks/{resume-command-XZWGUXRK.js.map → resume-command-Y3NYDSI4.js.map} +0 -0
  305. /package/dist/chunks/{schedule-GKM3RRIU.js.map → schedule-KN5YGOSJ.js.map} +0 -0
  306. /package/dist/chunks/{service-CIWTUMRI.js.map → service-OEOHUGM6.js.map} +0 -0
  307. /package/dist/chunks/{session-step-XATOSLSM.js.map → session-step-AYHFVVX6.js.map} +0 -0
  308. /package/dist/chunks/{skills-HV2MOBEW.js.map → skills-K3JRZ3IR.js.map} +0 -0
  309. /package/dist/chunks/{state-6HV3D3O4.js.map → state-QPSQI7U7.js.map} +0 -0
  310. /package/dist/chunks/{store-6J2MUGON.js.map → store-7WZWQXKX.js.map} +0 -0
  311. /package/dist/chunks/{store-GDP2EW27.js.map → store-PSQKDEPY.js.map} +0 -0
  312. /package/dist/chunks/{store-VXNKMMNW.js.map → store-Z3PS6LUZ.js.map} +0 -0
  313. /package/dist/chunks/{upgrade-MC5JB7DK.js.map → upgrade-C6QUXRLB.js.map} +0 -0
  314. /package/dist/chunks/{worktree-6YPRX6SU.js.map → worktree-KLD2PAMU.js.map} +0 -0
@@ -2,24 +2,34 @@ import { createRequire as __namzuCreateRequire } from 'node:module';
2
2
  const require = __namzuCreateRequire(import.meta.url);
3
3
  import {
4
4
  openManagedWorktrees
5
- } from "./chunk-GMCOZ3CU.js";
5
+ } from "./chunk-52OVP5BG.js";
6
6
  import {
7
7
  createBrowserControl
8
8
  } from "./chunk-WHODOMXA.js";
9
9
  import {
10
10
  connectMcpServers
11
- } from "./chunk-FXS3AG6B.js";
11
+ } from "./chunk-JCDTR2ZU.js";
12
12
  import {
13
13
  createSessionSkillCatalog
14
- } from "./chunk-LQMHASKR.js";
14
+ } from "./chunk-XCWZZZOW.js";
15
15
  import {
16
16
  SAVE_SKILL_TOOL_NAME,
17
+ WORKFLOW_TOOL_DESCRIPTION,
18
+ WORKFLOW_TOOL_NAME,
19
+ attachAgentView,
20
+ closeOpenAgents,
21
+ initialRunView,
22
+ launchedText,
17
23
  readStoredTurnGuards,
18
- resolveTurnGuards
19
- } from "./chunk-PYG7DZ2D.js";
24
+ reduceRunView,
25
+ resolveTurnGuards,
26
+ viewFromJournal,
27
+ workflowOffered,
28
+ workflowRefusal
29
+ } from "./chunk-QBAISLAD.js";
20
30
  import {
21
31
  openInBrowser
22
- } from "./chunk-3P5PF6XE.js";
32
+ } from "./chunk-AP5KD43Y.js";
23
33
  import {
24
34
  CredentialRefreshRejectedError,
25
35
  CredentialWithdrawnError,
@@ -27,7 +37,7 @@ import {
27
37
  ensureFreshStoredCodexCredential,
28
38
  readSubscriptionCredential,
29
39
  sameOAuthCredential
30
- } from "./chunk-4BZMQ2VD.js";
40
+ } from "./chunk-5URT3ZM2.js";
31
41
  import {
32
42
  debugRequested
33
43
  } from "./chunk-GNBMKISG.js";
@@ -35,7 +45,7 @@ import {
35
45
  configuredPassthroughTools,
36
46
  resolveToolResultScreens,
37
47
  unmatchedPassthroughTools
38
- } from "./chunk-K76WV7TN.js";
48
+ } from "./chunk-MBBFX64S.js";
39
49
  import {
40
50
  formatSize,
41
51
  homePath,
@@ -63,7 +73,7 @@ import {
63
73
  requiresCredentialForModel,
64
74
  resolveChainCapabilities,
65
75
  unresolvedMembers
66
- } from "./chunk-YXLD46UI.js";
76
+ } from "./chunk-DYUOXP5Q.js";
67
77
  import {
68
78
  PROVIDER_REGISTRY,
69
79
  missingCredentialMessage,
@@ -71,11 +81,11 @@ import {
71
81
  } from "./chunk-6LLJQ3KY.js";
72
82
  import {
73
83
  cliLogger
74
- } from "./chunk-HBBB2CAC.js";
84
+ } from "./chunk-FU4GQ7K2.js";
75
85
  import {
76
86
  isPermissionMode,
77
87
  permissionModeLabel
78
- } from "./chunk-5GRV6P5C.js";
88
+ } from "./chunk-LBH5WVXU.js";
79
89
  import {
80
90
  probeCapabilities
81
91
  } from "./chunk-OH6TB27S.js";
@@ -86,7 +96,7 @@ import {
86
96
  import {
87
97
  conversationLogPath,
88
98
  ensureSessionStarted
89
- } from "./chunk-TIGWWAJI.js";
99
+ } from "./chunk-EKUJUPFA.js";
90
100
  import {
91
101
  INSTRUCTIONS_FILENAME,
92
102
  MAX_CHARS_PER_FILE,
@@ -96,13 +106,13 @@ import {
96
106
  } from "./chunk-H6B6AROX.js";
97
107
  import {
98
108
  ensurePrivateStateDirectory
99
- } from "./chunk-A5UXODFL.js";
109
+ } from "./chunk-S6MZK4LD.js";
100
110
  import {
101
111
  restrictToOwner
102
- } from "./chunk-Q24K7536.js";
112
+ } from "./chunk-BOV53LZO.js";
103
113
  import {
104
114
  namzuHomePath
105
- } from "./chunk-NQY5P2EB.js";
115
+ } from "./chunk-HKDPP2JF.js";
106
116
  import {
107
117
  AgentManager,
108
118
  AgentRegistry,
@@ -111,6 +121,7 @@ import {
111
121
  CODING_AGENT_DELEGATION_DOCTRINE,
112
122
  CODING_AGENT_HYPERMODE_DOCTRINE,
113
123
  CODING_AGENT_WORKING_DOCTRINE,
124
+ COMPUTER_USE_TOOL_NAME,
114
125
  CompletionInbox,
115
126
  DefaultCapacityValidator,
116
127
  DiskMemoryStore,
@@ -123,6 +134,7 @@ import {
123
134
  EXPLORE_AGENT_DESCRIPTION,
124
135
  EXPLORE_AGENT_ID,
125
136
  EXPLORE_AGENT_PROMPT,
137
+ FileWorkflowJournal,
126
138
  GitWorktreeDriver,
127
139
  GuardedFetchProvider,
128
140
  InMemorySessionLog,
@@ -155,6 +167,8 @@ import {
155
167
  TopicManager,
156
168
  TurnCancelled,
157
169
  WebFetchTool,
170
+ WorkflowRuntime,
171
+ WorkflowScriptError,
158
172
  WorkspaceBackendRegistry,
159
173
  abandonTurn,
160
174
  asSessionId,
@@ -190,6 +204,7 @@ import {
190
204
  discoverAgentDefinitions,
191
205
  discoverAllPluginDirs,
192
206
  ensureProject,
207
+ external_exports,
193
208
  filtered,
194
209
  generateSessionId,
195
210
  generateSummaryId,
@@ -211,6 +226,7 @@ import {
211
226
  mapTools,
212
227
  mcpJsonSchemaToZod,
213
228
  openSessionTokenBudget,
229
+ parseWorkflowMeta,
214
230
  query,
215
231
  readSessionLog,
216
232
  readyWhen,
@@ -228,9 +244,10 @@ import {
228
244
  toolset,
229
245
  untrustedEnvelopeBody,
230
246
  webGuidanceContribution,
247
+ windowsShellNotice,
231
248
  withProviderFallback,
232
249
  wrapUntrusted
233
- } from "./chunk-EWKJGHRO.js";
250
+ } from "./chunk-V3ZLK3XQ.js";
234
251
  import {
235
252
  __name
236
253
  } from "./chunk-76FLAFCG.js";
@@ -619,6 +636,7 @@ __name(isAuthoredSentence, "isAuthoredSentence");
619
636
 
620
637
  // src/tui/tidy-tool-output.ts
621
638
  import { stripVTControlCharacters } from "node:util";
639
+ var BACKGROUND_NOTE = "Running in the background (\u2193 to manage)";
622
640
  function looksBinary(text) {
623
641
  if (text.includes("\0")) return true;
624
642
  if (text.length === 0) return false;
@@ -632,7 +650,8 @@ function looksBinary(text) {
632
650
  __name(looksBinary, "looksBinary");
633
651
  function tidyTerminalOutput(raw) {
634
652
  if (looksBinary(raw)) {
635
- return { output: "The command printed binary data, which is not shown." };
653
+ const output2 = "The command printed binary data, which is not shown.";
654
+ return { output: output2, shell: { stdout: [], stderr: [], failed: false, note: output2 } };
636
655
  }
637
656
  let failure;
638
657
  const kept = [];
@@ -646,7 +665,18 @@ function tidyTerminalOutput(raw) {
646
665
  kept.push(line);
647
666
  }
648
667
  while (kept.length > 0 && kept[kept.length - 1]?.trim() === "") kept.pop();
649
- return { output: kept.join("\n"), ...failure ? { failure } : {} };
668
+ const output = kept.join("\n");
669
+ const background = /^Started background job /.test(output);
670
+ const code = failure ? /\d+/.exec(failure)?.[0] : void 0;
671
+ const shell = {
672
+ stdout: background || output.length === 0 ? [] : kept,
673
+ stderr: [],
674
+ failed: failure !== void 0,
675
+ ...background ? { note: BACKGROUND_NOTE } : {},
676
+ ...failure ? { note: code ? `Exit code ${code}` : failure } : {},
677
+ ...failure && output.length > 0 && !background ? { status: code ? `Exit code ${code}` : failure } : {}
678
+ };
679
+ return { output, ...failure ? { failure } : {}, shell };
650
680
  }
651
681
  __name(tidyTerminalOutput, "tidyTerminalOutput");
652
682
  function shortCommand(command) {
@@ -682,21 +712,33 @@ function tidyCommandOutput(facts, raw) {
682
712
  const how = endedHow(facts);
683
713
  const label = shortCommand(facts.command);
684
714
  const failure = how ? label ? `Ran ${label} \xB7 ${how}` : `${how.charAt(0).toUpperCase()}${how.slice(1)}` : void 0;
685
- const withFailure = /* @__PURE__ */ __name((output) => ({ output, ...failure ? { failure } : {} }), "withFailure");
715
+ const status = !how ? void 0 : facts.timedOut ? "Timed out" : facts.signal ? "Stopped before it finished" : `Exit code ${facts.exitCode}`;
716
+ const cell = /* @__PURE__ */ __name((stdout2, stderr2, note) => ({
717
+ stdout: stdout2,
718
+ stderr: stderr2,
719
+ failed: how !== void 0,
720
+ ...status && (stdout2.length > 0 || stderr2.length > 0) ? { status } : {},
721
+ ...status ? { note: status } : note ? { note } : {}
722
+ }), "cell");
723
+ const withFailure = /* @__PURE__ */ __name((output, shell) => ({
724
+ output,
725
+ ...failure ? { failure } : {},
726
+ shell
727
+ }), "withFailure");
686
728
  if (facts.binary) {
687
- return withFailure(
688
- `The command printed binary data (${formatSize(facts.binary.bytes)}), which is not shown.`
689
- );
690
- }
691
- const streams = [facts.stdout, facts.stderr].filter(
692
- (w) => w !== void 0 && w.totalBytes > 0
729
+ const sentence = `The command printed binary data (${formatSize(facts.binary.bytes)}), which is not shown.`;
730
+ return withFailure(sentence, cell([], [], sentence));
731
+ }
732
+ const clean = /* @__PURE__ */ __name((window) => window && window.totalBytes > 0 ? windowLines(window).map((line) => stripVTControlCharacters(line)) : [], "clean");
733
+ const stdout = clean(facts.stdout);
734
+ const stderr = clean(facts.stderr);
735
+ if (stdout.length > 0 || stderr.length > 0) {
736
+ return withFailure([...stdout, ...stderr].join("\n"), cell(stdout, stderr));
737
+ }
738
+ return withFailure(
739
+ tidyTerminalOutput(raw).output,
740
+ cell([], [], facts.background ? BACKGROUND_NOTE : void 0)
693
741
  );
694
- if (streams.length > 0) {
695
- return withFailure(
696
- streams.flatMap(windowLines).map((line) => stripVTControlCharacters(line)).join("\n")
697
- );
698
- }
699
- return withFailure(tidyTerminalOutput(raw).output);
700
742
  }
701
743
  __name(tidyCommandOutput, "tidyCommandOutput");
702
744
  function unknownToolNotice(result) {
@@ -820,14 +862,14 @@ function formatCompactCount(value) {
820
862
  __name(formatCompactCount, "formatCompactCount");
821
863
 
822
864
  // src/tui/web-activity.ts
823
- function webActivityKind(toolName) {
824
- if (toolName === "web_search") return "search";
825
- if (toolName === "web_fetch") return "fetch";
865
+ function webActivityKind(toolName2) {
866
+ if (toolName2 === "web_search") return "search";
867
+ if (toolName2 === "web_fetch") return "fetch";
826
868
  return void 0;
827
869
  }
828
870
  __name(webActivityKind, "webActivityKind");
829
- function webActivityFromInput(toolName, input) {
830
- const kind = webActivityKind(toolName);
871
+ function webActivityFromInput(toolName2, input) {
872
+ const kind = webActivityKind(toolName2);
831
873
  if (!kind) return void 0;
832
874
  const field = kind === "search" ? "query" : "url";
833
875
  const value = input !== null && typeof input === "object" ? input[field] : void 0;
@@ -882,7 +924,7 @@ __name(oneLine, "oneLine");
882
924
  // src/tui/agent.ts
883
925
  import { SubprocessComputerUseHost } from "@namzu/computer-use";
884
926
  import { realpath as realpath4, stat as stat4 } from "node:fs/promises";
885
- import { parse, resolve as resolve8 } from "node:path";
927
+ import { join as join13, parse, resolve as resolve8 } from "node:path";
886
928
 
887
929
  // src/checkpoints/store.ts
888
930
  import { randomUUID as randomUUID2 } from "node:crypto";
@@ -2626,6 +2668,499 @@ function composeTurnSnapshot(snapshot) {
2626
2668
  }
2627
2669
  __name(composeTurnSnapshot, "composeTurnSnapshot");
2628
2670
 
2671
+ // ../decision/dist/contract.js
2672
+ var DecisionError = class extends Error {
2673
+ static {
2674
+ __name(this, "DecisionError");
2675
+ }
2676
+ status;
2677
+ code;
2678
+ constructor(message2, status, code) {
2679
+ super(message2);
2680
+ this.status = status;
2681
+ this.code = code;
2682
+ this.name = "DecisionError";
2683
+ }
2684
+ };
2685
+
2686
+ // ../decision/dist/drivers/wire.js
2687
+ function isRecord(v) {
2688
+ return typeof v === "object" && v !== null && !Array.isArray(v);
2689
+ }
2690
+ __name(isRecord, "isRecord");
2691
+ function numberRecord(v) {
2692
+ const out = {};
2693
+ if (isRecord(v)) {
2694
+ for (const [k, val] of Object.entries(v))
2695
+ if (typeof val === "number")
2696
+ out[k] = val;
2697
+ }
2698
+ return out;
2699
+ }
2700
+ __name(numberRecord, "numberRecord");
2701
+ async function postDecision(post) {
2702
+ const res = await post.fetch(post.url, {
2703
+ method: "POST",
2704
+ headers: { "Content-Type": "application/json", ...post.headers },
2705
+ body: JSON.stringify(post.body),
2706
+ signal: post.signal
2707
+ });
2708
+ let json;
2709
+ try {
2710
+ json = await res.json();
2711
+ } catch {
2712
+ json = void 0;
2713
+ }
2714
+ if (!res.ok) {
2715
+ const err = isRecord(json) && isRecord(json.error) ? json.error : {};
2716
+ throw new DecisionError(typeof err.message === "string" ? err.message : `Decision request failed (${res.status})`, res.status, typeof err.code === "string" ? err.code : void 0);
2717
+ }
2718
+ const answers = isRecord(json) ? json.answers : void 0;
2719
+ return isRecord(answers) ? answers.q : void 0;
2720
+ }
2721
+ __name(postDecision, "postDecision");
2722
+ function yesnoQuestion(instructions) {
2723
+ return { type: "noul", instructions };
2724
+ }
2725
+ __name(yesnoQuestion, "yesnoQuestion");
2726
+ function choiceQuestion(instructions, options) {
2727
+ return { type: "choice", instructions, options: [...options] };
2728
+ }
2729
+ __name(choiceQuestion, "choiceQuestion");
2730
+ function scoreQuestion(instructions, levels2) {
2731
+ return { type: "score", instructions, levels: [...levels2] };
2732
+ }
2733
+ __name(scoreQuestion, "scoreQuestion");
2734
+ function parseYesNo(answer) {
2735
+ const noul = isRecord(answer) ? answer.noul : void 0;
2736
+ if (typeof noul !== "number") {
2737
+ throw new DecisionError('Decision response carried no "noul" probability');
2738
+ }
2739
+ return { p: noul };
2740
+ }
2741
+ __name(parseYesNo, "parseYesNo");
2742
+ function parseChoice(answer) {
2743
+ const body = isRecord(answer) && isRecord(answer.choice) ? answer.choice : answer;
2744
+ const probabilities = numberRecord(isRecord(body) ? body.probabilities : void 0);
2745
+ let option = isRecord(body) ? body.option : void 0;
2746
+ if (typeof option !== "string") {
2747
+ option = Object.entries(probabilities).sort((a, b) => b[1] - a[1])[0]?.[0];
2748
+ }
2749
+ if (typeof option !== "string") {
2750
+ throw new DecisionError('Decision response carried no "choice" answer');
2751
+ }
2752
+ return { option, probabilities };
2753
+ }
2754
+ __name(parseChoice, "parseChoice");
2755
+ function parseScore(answer) {
2756
+ const body = isRecord(answer) && isRecord(answer.score) ? answer.score : answer;
2757
+ const raw = isRecord(body) ? body : {};
2758
+ const probabilities = Array.isArray(raw.probabilities) ? raw.probabilities.filter((x) => typeof x === "number") : [];
2759
+ let level = raw.level;
2760
+ if (typeof level !== "number") {
2761
+ let best = -1;
2762
+ probabilities.forEach((p, i) => {
2763
+ if (best < 0 || p > (probabilities[best] ?? 0))
2764
+ best = i;
2765
+ });
2766
+ level = best >= 0 ? best : void 0;
2767
+ }
2768
+ if (typeof level !== "number") {
2769
+ throw new DecisionError('Decision response carried no "score" answer');
2770
+ }
2771
+ return { level, probabilities };
2772
+ }
2773
+ __name(parseScore, "parseScore");
2774
+
2775
+ // ../decision/dist/drivers/azure-foundry.js
2776
+ var AzureFoundryDecisionModel = class {
2777
+ static {
2778
+ __name(this, "AzureFoundryDecisionModel");
2779
+ }
2780
+ config;
2781
+ constructor(config) {
2782
+ this.config = config;
2783
+ }
2784
+ async yesno(state, instructions, opts) {
2785
+ return parseYesNo(await this.ask(state, yesnoQuestion(instructions), opts));
2786
+ }
2787
+ async choice(state, instructions, options, opts) {
2788
+ return parseChoice(await this.ask(state, choiceQuestion(instructions, options), opts));
2789
+ }
2790
+ async score(state, instructions, levels2, opts) {
2791
+ return parseScore(await this.ask(state, scoreQuestion(instructions, levels2), opts));
2792
+ }
2793
+ async ask(state, question, opts) {
2794
+ const token = await this.config.getToken();
2795
+ return postDecision({
2796
+ url: `${this.config.endpoint.replace(/\/$/, "")}/providers/microsoft/v1/systemone`,
2797
+ headers: { Authorization: `Bearer ${token}` },
2798
+ body: { model: this.config.deployment, state, questions: { q: question } },
2799
+ fetch: this.config.fetch ?? globalThis.fetch,
2800
+ ...opts?.signal ? { signal: opts.signal } : {}
2801
+ });
2802
+ }
2803
+ };
2804
+
2805
+ // ../decision/dist/drivers/http.js
2806
+ var HttpDecisionModel = class {
2807
+ static {
2808
+ __name(this, "HttpDecisionModel");
2809
+ }
2810
+ config;
2811
+ constructor(config) {
2812
+ this.config = config;
2813
+ }
2814
+ async yesno(state, instructions, opts) {
2815
+ return parseYesNo(await this.ask(state, yesnoQuestion(instructions), opts));
2816
+ }
2817
+ async choice(state, instructions, options, opts) {
2818
+ return parseChoice(await this.ask(state, choiceQuestion(instructions, options), opts));
2819
+ }
2820
+ async score(state, instructions, levels2, opts) {
2821
+ return parseScore(await this.ask(state, scoreQuestion(instructions, levels2), opts));
2822
+ }
2823
+ async ask(state, question, opts) {
2824
+ return postDecision({
2825
+ url: this.config.url,
2826
+ headers: {
2827
+ ...this.config.apiKey ? { Authorization: `Bearer ${this.config.apiKey}` } : {},
2828
+ ...this.config.headers
2829
+ },
2830
+ body: {
2831
+ ...this.config.model ? { model: this.config.model } : {},
2832
+ state,
2833
+ questions: { q: question }
2834
+ },
2835
+ fetch: this.config.fetch ?? globalThis.fetch,
2836
+ ...opts?.signal ? { signal: opts.signal } : {}
2837
+ });
2838
+ }
2839
+ };
2840
+
2841
+ // ../decision/dist/create.js
2842
+ function createDecisionModel(config) {
2843
+ switch (config.provider) {
2844
+ case "azure":
2845
+ return new AzureFoundryDecisionModel({
2846
+ endpoint: config.endpoint,
2847
+ deployment: config.deployment,
2848
+ getToken: config.getToken,
2849
+ ...config.fetch ? { fetch: config.fetch } : {}
2850
+ });
2851
+ case "http":
2852
+ return new HttpDecisionModel({
2853
+ url: config.url,
2854
+ ...config.model ? { model: config.model } : {},
2855
+ ...config.apiKey ? { apiKey: config.apiKey } : {},
2856
+ ...config.headers ? { headers: config.headers } : {},
2857
+ ...config.fetch ? { fetch: config.fetch } : {}
2858
+ });
2859
+ default: {
2860
+ const unknown = config;
2861
+ throw new Error(`Unknown decision provider: ${JSON.stringify(unknown.provider)}`);
2862
+ }
2863
+ }
2864
+ }
2865
+ __name(createDecisionModel, "createDecisionModel");
2866
+
2867
+ // ../decision/dist/tool.js
2868
+ var DECIDE_TOOL_NAME = "decide";
2869
+ var inputSchema3 = external_exports.object({
2870
+ kind: external_exports.enum(["yesno", "choice", "score"]).describe("yesno = probability a statement is true; choice = pick one of `options`; score = pick one of ordered `levels`."),
2871
+ context: external_exports.string().describe("The situation to judge: the state, the evidence, whatever the decision turns on."),
2872
+ question: external_exports.string().describe("What to decide, phrased for the chosen kind (a yes/no claim, a pick instruction, a scoring rubric)."),
2873
+ options: external_exports.array(external_exports.string()).optional().describe('kind="choice" only: the options to pick exactly one of (2 or more).'),
2874
+ levels: external_exports.array(external_exports.string()).optional().describe('kind="score" only: the ordered levels, lowest first (2 or more).')
2875
+ });
2876
+ function round(n) {
2877
+ return n.toFixed(4);
2878
+ }
2879
+ __name(round, "round");
2880
+ function distribution(probabilities) {
2881
+ return Object.entries(probabilities).sort((a, b) => b[1] - a[1]).map(([k, v]) => `${k}=${round(v)}`).join(", ");
2882
+ }
2883
+ __name(distribution, "distribution");
2884
+ var ADVISORY = "This is a fast, advisory System-1 judgment \u2014 you remain responsible for hard constraints; weigh low-confidence results with your own reasoning.";
2885
+ function createDecisionTool(model, options = {}) {
2886
+ return defineTool({
2887
+ name: options.name ?? DECIDE_TOOL_NAME,
2888
+ description: "Ask a fast System-1 decision model for a typed judgment: a yes/no probability, a choice among options, or a score across ordered levels. Optional and advisory \u2014 reach for it when a quick, well-scoped classification, routing, safety pre-screen, element pick or ranking would help, then act on your own reasoning. If the model is unavailable the tool says so and you simply proceed.",
2889
+ inputSchema: inputSchema3,
2890
+ category: "analysis",
2891
+ permissions: [],
2892
+ readOnly: true,
2893
+ destructive: false,
2894
+ concurrencySafe: true,
2895
+ async execute(input, context) {
2896
+ const opts = context.abortSignal ? { signal: context.abortSignal } : void 0;
2897
+ try {
2898
+ if (input.kind === "yesno") {
2899
+ const { p } = await model.yesno(input.context, input.question, opts);
2900
+ return {
2901
+ success: true,
2902
+ output: `P(true) = ${round(p)}. ${ADVISORY}`,
2903
+ data: { kind: "yesno", p }
2904
+ };
2905
+ }
2906
+ if (input.kind === "choice") {
2907
+ const choices = input.options ?? [];
2908
+ if (choices.length < 2) {
2909
+ return {
2910
+ success: true,
2911
+ output: "decide(choice) needs 2 or more `options`. None judged \u2014 decide with your own reasoning."
2912
+ };
2913
+ }
2914
+ const { option, probabilities: probabilities2 } = await model.choice(input.context, input.question, choices, opts);
2915
+ return {
2916
+ success: true,
2917
+ output: `Pick: ${option} (${distribution(probabilities2)}). ${ADVISORY}`,
2918
+ data: { kind: "choice", option, probabilities: probabilities2 }
2919
+ };
2920
+ }
2921
+ const levels2 = input.levels ?? [];
2922
+ if (levels2.length < 2) {
2923
+ return {
2924
+ success: true,
2925
+ output: "decide(score) needs 2 or more `levels`. None judged \u2014 decide with your own reasoning."
2926
+ };
2927
+ }
2928
+ const { level, probabilities } = await model.score(input.context, input.question, levels2, opts);
2929
+ const name = levels2[level] ?? `level ${level}`;
2930
+ return {
2931
+ success: true,
2932
+ output: `Score: ${name} (index ${level}) [${probabilities.map(round).join(", ")}]. ${ADVISORY}`,
2933
+ data: { kind: "score", level, name, probabilities }
2934
+ };
2935
+ } catch (error) {
2936
+ const why = error instanceof DecisionError ? error.message : String(error);
2937
+ return {
2938
+ success: true,
2939
+ output: `The decision model is unavailable (${why}). Decide using your own reasoning; this tool is advisory only.`,
2940
+ data: { kind: "unavailable", reason: why }
2941
+ };
2942
+ }
2943
+ }
2944
+ });
2945
+ }
2946
+ __name(createDecisionTool, "createDecisionTool");
2947
+
2948
+ // src/integrations/decision/model.ts
2949
+ function buildDecisionProviderConfig(cfg, env) {
2950
+ if (cfg.provider === "azure") {
2951
+ return {
2952
+ provider: "azure",
2953
+ endpoint: cfg.endpoint,
2954
+ deployment: cfg.deployment,
2955
+ getToken: /* @__PURE__ */ __name(async () => env[cfg.tokenEnv ?? "AZURE_FOUNDRY_TOKEN"] ?? "", "getToken")
2956
+ };
2957
+ }
2958
+ return {
2959
+ provider: "http",
2960
+ url: cfg.url,
2961
+ ...cfg.model !== void 0 ? { model: cfg.model } : {},
2962
+ ...cfg.apiKeyEnv ? { apiKey: env[cfg.apiKeyEnv] } : {}
2963
+ };
2964
+ }
2965
+ __name(buildDecisionProviderConfig, "buildDecisionProviderConfig");
2966
+ function maybeCreateDecisionTool(cfg, env) {
2967
+ if (!cfg) return void 0;
2968
+ return createDecisionTool(createDecisionModel(buildDecisionProviderConfig(cfg, env)));
2969
+ }
2970
+ __name(maybeCreateDecisionTool, "maybeCreateDecisionTool");
2971
+ function maybeCreateDecisionModel(cfg, env) {
2972
+ if (!cfg) return void 0;
2973
+ return createDecisionModel(buildDecisionProviderConfig(cfg, env));
2974
+ }
2975
+ __name(maybeCreateDecisionModel, "maybeCreateDecisionModel");
2976
+
2977
+ // src/integrations/decision/routing.ts
2978
+ var DEFAULT_ROUTING_TIMEOUT_MS = 1500;
2979
+ var DEFAULT_ROUTING_THRESHOLD = 0.7;
2980
+ var ROUTING_TASK_CHARS = 1500;
2981
+ var FAST_MAX_CONVERSATION = 40;
2982
+ var ROUTING_FAST_QUESTION = "Is this task simple enough for a small, fast model to complete correctly? Answer yes only for short chat, a lookup, or a single small step.";
2983
+ var ROUTING_BIG_QUESTION = "Does this task need deep multi-step reasoning or large-scale code changes across many files?";
2984
+ var ROUTING_SCORE_LEVELS = [
2985
+ "trivial: chat, lookup, or one step",
2986
+ "small: a single-file or single-tool task",
2987
+ "medium: multi-step work across several files",
2988
+ "large: open-ended, architectural, or long-horizon work"
2989
+ ];
2990
+ function truncate(task) {
2991
+ return task.length > ROUTING_TASK_CHARS ? task.slice(0, ROUTING_TASK_CHARS) : task;
2992
+ }
2993
+ __name(truncate, "truncate");
2994
+ function describeState(task, features) {
2995
+ const facts = [];
2996
+ if (features?.attachmentCount) facts.push(`attachments: ${features.attachmentCount}`);
2997
+ if (features?.usesComputerUse) facts.push("drives the desktop");
2998
+ if (features?.usesPal) facts.push("runs in a Pal");
2999
+ if (features?.conversationLength) facts.push(`messages so far: ${features.conversationLength}`);
3000
+ if (features?.voice) facts.push("spoken");
3001
+ return facts.length > 0 ? `${truncate(task)}
3002
+
3003
+ [${facts.join("; ")}]` : truncate(task);
3004
+ }
3005
+ __name(describeState, "describeState");
3006
+ function probability(value) {
3007
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 1) {
3008
+ throw new RangeError("malformed probability");
3009
+ }
3010
+ return value;
3011
+ }
3012
+ __name(probability, "probability");
3013
+ function massAtOrBelow(probabilities, last) {
3014
+ const total = probabilities.reduce((sum, p) => sum + p, 0);
3015
+ if (!(total > 0)) throw new RangeError("malformed probabilities");
3016
+ return probabilities.slice(0, last + 1).reduce((sum, p) => sum + p, 0) / total;
3017
+ }
3018
+ __name(massAtOrBelow, "massAtOrBelow");
3019
+ var RouteInterrupted = class extends Error {
3020
+ constructor(reason) {
3021
+ super(reason);
3022
+ this.reason = reason;
3023
+ }
3024
+ reason;
3025
+ static {
3026
+ __name(this, "RouteInterrupted");
3027
+ }
3028
+ };
3029
+ async function withinBudget(run2, timeoutMs, outer) {
3030
+ const controller = new AbortController();
3031
+ let timer;
3032
+ let onOuterAbort;
3033
+ const interrupted = new Promise((_, reject) => {
3034
+ timer = setTimeout(() => {
3035
+ controller.abort();
3036
+ reject(new RouteInterrupted("timeout"));
3037
+ }, timeoutMs);
3038
+ onOuterAbort = /* @__PURE__ */ __name(() => {
3039
+ controller.abort();
3040
+ reject(new RouteInterrupted("aborted"));
3041
+ }, "onOuterAbort");
3042
+ if (outer?.aborted) onOuterAbort();
3043
+ else outer?.addEventListener("abort", onOuterAbort, { once: true });
3044
+ });
3045
+ try {
3046
+ return await Promise.race([run2(controller.signal), interrupted]);
3047
+ } finally {
3048
+ if (timer !== void 0) clearTimeout(timer);
3049
+ if (onOuterAbort) outer?.removeEventListener("abort", onOuterAbort);
3050
+ }
3051
+ }
3052
+ __name(withinBudget, "withinBudget");
3053
+ async function askOnce(call, signal) {
3054
+ try {
3055
+ return await call(signal);
3056
+ } catch (err) {
3057
+ if (signal.aborted) throw err;
3058
+ return await call(signal);
3059
+ }
3060
+ }
3061
+ __name(askOnce, "askOnce");
3062
+ async function routeModel(input, deps = {}) {
3063
+ const now = deps.now ?? Date.now;
3064
+ const started = now();
3065
+ const { config } = input;
3066
+ const result = /* @__PURE__ */ __name((tier, target, confidence, reason, error) => {
3067
+ const routed = {
3068
+ tier,
3069
+ provider: target.provider,
3070
+ model: target.model,
3071
+ confidence,
3072
+ reason
3073
+ };
3074
+ try {
3075
+ deps.logger?.debug("auto model routed", {
3076
+ "namzu.routing.tier": tier,
3077
+ "namzu.routing.reason": reason,
3078
+ "namzu.routing.confidence": confidence,
3079
+ "namzu.routing.duration_ms": Math.max(0, now() - started),
3080
+ "gen_ai.request.model": target.model,
3081
+ "namzu.provider.id": target.provider,
3082
+ // The class of what made it fall back, never its message: that can carry an endpoint.
3083
+ ...error instanceof Error ? { "error.type": error.name } : {}
3084
+ });
3085
+ } catch {
3086
+ }
3087
+ return routed;
3088
+ }, "result");
3089
+ const fallback = /* @__PURE__ */ __name((reason, error) => result("default", config.default, 0, reason, error), "fallback");
3090
+ try {
3091
+ if (input.pin) return result("default", input.pin, 1, "pinned");
3092
+ const usable = /* @__PURE__ */ __name((target) => target && (deps.isAvailable?.(target) ?? true) ? target : void 0, "usable");
3093
+ const features = input.features;
3094
+ const failedOn = features?.previousTurnFailedOnTier;
3095
+ const big = usable(config.tiers?.big);
3096
+ const fastBarred = features?.usesComputerUse === true || features?.usesPal === true || (features?.attachmentCount ?? 0) > 0 || (features?.conversationLength ?? 0) > FAST_MAX_CONVERSATION || failedOn === "fast" || failedOn === "default";
3097
+ const fast = fastBarred ? void 0 : usable(config.tiers?.fast);
3098
+ if (failedOn === "fast") return result("default", config.default, 1, "escalated-after-failure");
3099
+ if (failedOn === "default") {
3100
+ return big ? result("big", big, 1, "escalated-after-failure") : fallback("failed-no-bigger-tier");
3101
+ }
3102
+ if (!fast && !big) return fallback(fastBarred ? "fast-tier-barred" : "no-tier-available");
3103
+ if (!deps.model) return fallback("no-decision-model");
3104
+ const model = deps.model;
3105
+ const timeoutMs = config.timeoutMs ?? DEFAULT_ROUTING_TIMEOUT_MS;
3106
+ const fastThreshold = config.thresholds?.fast ?? DEFAULT_ROUTING_THRESHOLD;
3107
+ const bigThreshold = config.thresholds?.big ?? DEFAULT_ROUTING_THRESHOLD;
3108
+ const state = describeState(input.task, features);
3109
+ let pFast;
3110
+ let pBig;
3111
+ if (config.strategy === "score") {
3112
+ const decision = await withinBudget(
3113
+ (signal) => askOnce(
3114
+ (inner) => model.score(state, "", ROUTING_SCORE_LEVELS, { signal: inner }),
3115
+ signal
3116
+ ),
3117
+ timeoutMs,
3118
+ input.signal
3119
+ );
3120
+ const { probabilities } = decision;
3121
+ if (!Array.isArray(probabilities) || probabilities.length !== ROUTING_SCORE_LEVELS.length) {
3122
+ throw new RangeError("malformed probabilities");
3123
+ }
3124
+ for (const p of probabilities) probability(p);
3125
+ if (fast) pFast = massAtOrBelow(probabilities, 1);
3126
+ if (big) pBig = 1 - massAtOrBelow(probabilities, 2);
3127
+ } else {
3128
+ const [fastDecision, bigDecision] = await withinBudget(
3129
+ (signal) => Promise.all([
3130
+ fast ? askOnce(
3131
+ (inner) => model.yesno(state, ROUTING_FAST_QUESTION, { signal: inner }),
3132
+ signal
3133
+ ) : Promise.resolve(void 0),
3134
+ big ? askOnce(
3135
+ (inner) => model.yesno(state, ROUTING_BIG_QUESTION, { signal: inner }),
3136
+ signal
3137
+ ) : Promise.resolve(void 0)
3138
+ ]),
3139
+ timeoutMs,
3140
+ input.signal
3141
+ );
3142
+ if (fastDecision) pFast = probability(fastDecision.p);
3143
+ if (bigDecision) pBig = probability(bigDecision.p);
3144
+ }
3145
+ const wantsFast = fast !== void 0 && pFast !== void 0 && pFast >= fastThreshold;
3146
+ const wantsBig = big !== void 0 && pBig !== void 0 && pBig >= bigThreshold;
3147
+ if (wantsFast && wantsBig) return fallback("contradictory-decision");
3148
+ if (wantsFast && fast) return result("fast", fast, pFast ?? 0, "simple-task");
3149
+ if (wantsBig && big) return result("big", big, pBig ?? 0, "demanding-task");
3150
+ const leaning = Math.max(pFast ?? 0, pBig ?? 0);
3151
+ return result("default", config.default, Math.max(0, 1 - leaning), "ordinary-task");
3152
+ } catch (err) {
3153
+ if (err instanceof RouteInterrupted) return fallback(err.reason);
3154
+ if (err instanceof RangeError) return fallback("malformed-decision", err);
3155
+ return fallback("decision-unavailable", err);
3156
+ }
3157
+ }
3158
+ __name(routeModel, "routeModel");
3159
+ function resolveAutoDefault(config, isAvailable) {
3160
+ return isAvailable(config.default) ? config.default : void 0;
3161
+ }
3162
+ __name(resolveAutoDefault, "resolveAutoDefault");
3163
+
2629
3164
  // src/integrations/plugins/settings.ts
2630
3165
  import { createHash as createHash3, randomUUID as randomUUID3 } from "node:crypto";
2631
3166
  import {
@@ -4163,6 +4698,27 @@ var SubagentActivityMonitor = class {
4163
4698
  getNarration() {
4164
4699
  return [...this.narration];
4165
4700
  }
4701
+ /**
4702
+ * The cheap facts a progress line needs about one child, without copying
4703
+ * its transcript: spend, tool executions and the tool it ran last.
4704
+ */
4705
+ progressOf(viewId) {
4706
+ const record = this.records.get(viewId);
4707
+ if (!record) return void 0;
4708
+ let lastTool;
4709
+ for (let index = record.rows.length - 1; index >= 0; index -= 1) {
4710
+ const row = record.rows[index];
4711
+ if (row?.kind === "tool") {
4712
+ lastTool = row.text;
4713
+ break;
4714
+ }
4715
+ }
4716
+ return {
4717
+ ...record.tokens !== void 0 ? { tokens: record.tokens } : {},
4718
+ ...record.toolCalls !== void 0 ? { toolCalls: record.toolCalls } : {},
4719
+ ...lastTool !== void 0 ? { lastTool } : {}
4720
+ };
4721
+ }
4166
4722
  getSnapshot() {
4167
4723
  return [...this.records.values()].sort((left, right) => {
4168
4724
  const live = Number(isTerminal(left.status)) - Number(isTerminal(right.status));
@@ -5250,6 +5806,7 @@ var SUBAGENT_PROMPT = [
5250
5806
  // the parent does not is the same defect in the other direction.
5251
5807
  CODING_AGENT_WORKING_DOCTRINE
5252
5808
  ].join("\n");
5809
+ var WORKFLOW_RUN_GROUP_PREFIX = "wf:";
5253
5810
  var ParentTaskScheduler = class extends LocalTaskScheduler {
5254
5811
  constructor(manager, context, onEvent, validateParent) {
5255
5812
  super(manager, context, onEvent);
@@ -5545,6 +6102,194 @@ async function createSubagentRuntime(opts) {
5545
6102
  }, "completionInboxForTurn");
5546
6103
  const activity = new SubagentActivityMonitor();
5547
6104
  let dynCounter = 0;
6105
+ const launchChild = /* @__PURE__ */ __name(async (input, context, hooks = {}) => {
6106
+ const {
6107
+ description,
6108
+ prompt,
6109
+ subagent_type,
6110
+ role,
6111
+ workflow,
6112
+ phase,
6113
+ phase_order,
6114
+ phase_detail,
6115
+ run_in_background,
6116
+ workspace,
6117
+ model: requestedModel,
6118
+ provider: requestedProvider,
6119
+ effort: requestedEffort
6120
+ } = input;
6121
+ if (!requestedModel && (requestedProvider || requestedEffort))
6122
+ throw new Error("Supply model when selecting a child provider or effort.");
6123
+ const explore = subagent_type === EXPLORE_SUBAGENT;
6124
+ const fileAgent = subagent_type !== void 0 ? fileAgents.get(subagent_type) : void 0;
6125
+ const inherited = opts.resolveTurnModel?.(context.turnId);
6126
+ const parentModel = inherited?.model ?? opts.model;
6127
+ const selects = requestedModel !== void 0 && (requestedModel !== parentModel || requestedProvider !== void 0 || requestedEffort !== void 0 || fileAgent?.model !== void 0 && fileAgent.model !== parentModel);
6128
+ if (selects && !opts.resolveModel)
6129
+ throw new Error("Child model selection is unavailable in this host.");
6130
+ const selection = selects ? await opts.resolveModel?.(
6131
+ {
6132
+ model: requestedModel,
6133
+ provider: requestedProvider,
6134
+ effort: requestedEffort
6135
+ },
6136
+ context.abortSignal
6137
+ ) : (
6138
+ // A file agent that pins its own model keeps it; any other child
6139
+ // of a turn on another model than the session's runs on that one.
6140
+ fileAgent?.model === void 0 ? inherited : void 0
6141
+ );
6142
+ let agentId = fileAgent?.name ?? (explore ? EXPLORE_SUBAGENT : GENERAL_PURPOSE_SUBAGENT);
6143
+ const persona = typeof role === "string" ? role.trim() : "";
6144
+ const dynamic = persona.length > 0 || selection !== void 0;
6145
+ if (dynamic) {
6146
+ agentId = `dyn-${++dynCounter}`;
6147
+ registry.register(
6148
+ buildDefinition(
6149
+ agentId,
6150
+ `Dynamic specialist: ${agentId}`,
6151
+ fileAgent ? `${fileAgent.prompt}
6152
+
6153
+ ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6154
+ opts,
6155
+ fileAgent ? fileAgentTools(fileAgent, opts) : explore ? () => opts.buildTools().map(
6156
+ (ts) => filtered(
6157
+ ts,
6158
+ (tool) => isTrustedReadOnly(tool, void 0, toToolSourceRef(ts.source))
6159
+ )
6160
+ ) : opts.buildTools,
6161
+ selection?.model ?? fileAgent?.model ?? parentModel,
6162
+ selection
6163
+ )
6164
+ );
6165
+ }
6166
+ const seed = {
6167
+ agentId,
6168
+ model: selection?.model ?? fileAgent?.model ?? parentModel,
6169
+ description,
6170
+ prompt,
6171
+ batchId: context.toolBatchId,
6172
+ toolUseId: context.toolUseId,
6173
+ workflowId: hooks.workflowId ?? String(context.turnId),
6174
+ workflow,
6175
+ phase,
6176
+ phaseOrder: phase_order,
6177
+ phaseDetail: phase_detail
6178
+ };
6179
+ const tracker = activity.begin(seed);
6180
+ hooks.onView?.(tracker.viewId);
6181
+ const resumeHandler = opts.resolveResumeHandler?.(context.turnId) ?? refuseUnownedChildReview;
6182
+ const configOverrides = {
6183
+ ...resolveTurnGuards(opts, opts.resolveLimits?.(context.turnId)),
6184
+ ...selection ? { model: selection.model, effort: selection.effort } : {},
6185
+ ...Object.keys(context.env ?? {}).length > 0 ? { env: context.env } : {},
6186
+ // The parent turn's tool-result screens, so a sub-agent judges a
6187
+ // connected answer the way the turn that asked for the work
6188
+ // does. Without it the child's executor installs the shipped
6189
+ // default, and `toolResultScreens: []` — the operator's off
6190
+ // switch — would hold for the parent and not for anything it
6191
+ // delegated to, which is the half an operator does not watch.
6192
+ //
6193
+ // `[]` is carried rather than skipped: empty is a decision, and
6194
+ // a `length` test — which is the shape that gets this wrong,
6195
+ // since `[]` is truthy — would turn it back into absent.
6196
+ ...context.toolResultGuardrails ? { toolResultGuardrails: context.toolResultGuardrails } : {},
6197
+ resumeHandler
6198
+ };
6199
+ let taskOwnsCleanup = false;
6200
+ let retained;
6201
+ const cleanupDefinition = /* @__PURE__ */ __name(() => {
6202
+ if (dynamic && !retained) registry.unregister(agentId);
6203
+ }, "cleanupDefinition");
6204
+ try {
6205
+ const parentKey = sessionKey(await resolveParent(context.turnId));
6206
+ const gateway = await gatewayForTurn(context.turnId);
6207
+ const completionInbox = await completionInboxForTurn(context.turnId);
6208
+ const subdirectory = workspace === "worktree" ? await worktreeDriver.selectedSubdirectory() : void 0;
6209
+ const outcome = await runBlockingAgentTask({
6210
+ gateway: await gatewayForTurn(context.turnId),
6211
+ signal: context.abortSignal,
6212
+ waitForInbound: opts.resolveWaitForInbound?.(context.turnId),
6213
+ background: run_in_background === true,
6214
+ ...hooks.cancelCause ? { cancelCause: hooks.cancelCause } : {},
6215
+ completionInbox,
6216
+ onCreated: /* @__PURE__ */ __name((task) => {
6217
+ taskOwnsCleanup = true;
6218
+ retained = {
6219
+ parentKey,
6220
+ agentId,
6221
+ dynamic,
6222
+ seed,
6223
+ config: {
6224
+ ...selection ? { model: selection.model, effort: selection.effort } : {},
6225
+ ...configOverrides.env ? { env: configOverrides.env } : {},
6226
+ ...configOverrides.toolResultGuardrails ? {
6227
+ toolResultGuardrails: configOverrides.toolResultGuardrails
6228
+ } : {}
6229
+ },
6230
+ workspace: workspace ?? "shared",
6231
+ gateway,
6232
+ task,
6233
+ turnId: context.turnId,
6234
+ busy: false
6235
+ };
6236
+ conversations.set(tracker.viewId, retained);
6237
+ const visible = new Set(activity.getSnapshot().map((value) => value.viewId));
6238
+ for (const [id, previous] of conversations) {
6239
+ if (visible.has(id) || previous.busy || !isTerminalAgentTaskState(previous.task.state))
6240
+ continue;
6241
+ conversations.delete(id);
6242
+ if (previous.dynamic) registry.unregister(previous.agentId);
6243
+ }
6244
+ tracker.settle(task);
6245
+ }, "onCreated"),
6246
+ onSettled: /* @__PURE__ */ __name((completed) => {
6247
+ if (retained) retained.task = completed;
6248
+ tracker.settle(completed);
6249
+ }, "onSettled"),
6250
+ onFailed: /* @__PURE__ */ __name((error) => tracker.fail(error), "onFailed"),
6251
+ onFinished: cleanupDefinition,
6252
+ create: {
6253
+ agentId,
6254
+ prompt,
6255
+ workingDirectory: opts.cwd,
6256
+ workspace: workspace === "worktree" ? {
6257
+ mode: "isolated",
6258
+ backend: "git-worktree",
6259
+ retention: "retain",
6260
+ ...subdirectory ? { subdirectory } : {}
6261
+ } : { mode: "shared" },
6262
+ // The same labels the monitor was seeded with, sent down so the
6263
+ // child's `agent_pending` carries them: a listener or SSE
6264
+ // consumer outside this process then groups the child the way
6265
+ // the operator sees it here, instead of the grouping living
6266
+ // only in the closure above. Display-only on both paths — no
6267
+ // dependency, barrier or serial execution follows from any.
6268
+ ...workflow ? { workflow } : {},
6269
+ ...phase ? { phase } : {},
6270
+ ...phase_detail ? { phaseDetail: phase_detail } : {},
6271
+ ...phase_order !== void 0 ? { phaseOrder: phase_order } : {},
6272
+ // Hang the child session off THIS tool's span, so the delegation
6273
+ // shows up inside the turn that asked for it. Without it a
6274
+ // sub-agent opens its OWN root trace, and the one structure
6275
+ // a delegation trace exists to record — who dispatched whom
6276
+ // — is the thing that goes missing.
6277
+ ...context.parentSpan ? { parentSpan: context.parentSpan } : {},
6278
+ configOverrides,
6279
+ onEvent: hooks.onEvent ? (event) => {
6280
+ tracker.onEvent(event);
6281
+ hooks.onEvent?.(event);
6282
+ } : tracker.onEvent
6283
+ }
6284
+ });
6285
+ return { outcome, agentId };
6286
+ } catch (error) {
6287
+ tracker.fail(error);
6288
+ throw error;
6289
+ } finally {
6290
+ if (!taskOwnsCleanup) cleanupDefinition();
6291
+ }
6292
+ }, "launchChild");
5548
6293
  const agentTool = defineTool({
5549
6294
  name: "Agent",
5550
6295
  description: [
@@ -5558,7 +6303,7 @@ async function createSubagentRuntime(opts) {
5558
6303
  "Omit `role` for the plain sub-agent.",
5559
6304
  "The sub-agent runs in its own context with its own tools and cannot see this conversation \u2014 put everything it needs in `prompt`.",
5560
6305
  "Call this multiple times in one response to run specialists in parallel. Tasks beyond the project's live-agent capacity wait in a queue and start as slots become available. Queued tasks have not started execution; do not relaunch them.",
5561
- "When coordinating several specialists, give them the same `workflow` label and an explicit `phase` plus `phase_order` so the operator can follow the work in the agent cockpit.",
6306
+ "When coordinating several specialists, give them the same `workflow` label and an explicit `phase` plus `phase_order` so the operator can follow the work in the agent cockpit. For work with several phases or many agents, use the `workflow` tool instead when it is in your tool list, and keep these labels for a small fan-out.",
5562
6307
  "These fields are display annotations only; they do not create dependencies, barriers, or serial execution.",
5563
6308
  fileAgentSummary.length > 0 ? `Project-defined types: ${fileAgentSummary}.` : ""
5564
6309
  ].filter((part) => part.length > 0).join(" "),
@@ -5642,202 +6387,116 @@ async function createSubagentRuntime(opts) {
5642
6387
  concurrencySafe: true,
5643
6388
  timeoutMs: opts.resolveLimits ? 0 : opts.timeoutMs ?? CLI_INTERACTIVE_TURN_TIMEOUT_MS,
5644
6389
  async execute(input, context) {
5645
- const {
5646
- description,
5647
- prompt,
5648
- subagent_type,
5649
- role,
5650
- workflow,
5651
- phase,
5652
- phase_order,
5653
- phase_detail,
5654
- run_in_background,
5655
- workspace,
5656
- model: requestedModel,
5657
- provider: requestedProvider,
5658
- effort: requestedEffort
5659
- } = input;
5660
- if (!requestedModel && (requestedProvider || requestedEffort))
5661
- throw new Error("Supply model when selecting a child provider or effort.");
5662
- const explore = subagent_type === EXPLORE_SUBAGENT;
5663
- const fileAgent = subagent_type !== void 0 ? fileAgents.get(subagent_type) : void 0;
5664
- const inherited = opts.resolveTurnModel?.(context.turnId);
5665
- const parentModel = inherited?.model ?? opts.model;
5666
- const selects = requestedModel !== void 0 && (requestedModel !== parentModel || requestedProvider !== void 0 || requestedEffort !== void 0 || fileAgent?.model !== void 0 && fileAgent.model !== parentModel);
5667
- if (selects && !opts.resolveModel)
5668
- throw new Error("Child model selection is unavailable in this host.");
5669
- const selection = selects ? await opts.resolveModel?.(
6390
+ const { description, run_in_background } = input;
6391
+ const { outcome, agentId } = await launchChild(input, context);
6392
+ if (outcome.kind === "yielded") {
6393
+ const progress = outcome.handle.state === "pending" ? "queued for an available slot" : "still running";
6394
+ return {
6395
+ success: true,
6396
+ output: `Sub-agent ${agentId} for task ${JSON.stringify(description)} is ${progress} as task ${outcome.handle.taskId}; it has not completed.${workspaceNote(outcome.handle)} ${run_in_background ? "Continue independent work while this task runs in the background." : "Waiting was released because the operator sent a message. Answer their question or status request before making further tool calls; preserve existing work unless they ask to cancel or change it."} Its actual result will arrive as a task notification; do not launch the same work again.`,
6397
+ data: {
6398
+ task_id: outcome.handle.taskId,
6399
+ state: outcome.handle.state,
6400
+ ...workspaceData(outcome.handle),
6401
+ wait_released: run_in_background ? "background" : "operator_input"
6402
+ }
6403
+ };
6404
+ }
6405
+ return completedAgentResult(outcome.handle);
6406
+ }
6407
+ });
6408
+ const launchWorkflowAgent = /* @__PURE__ */ __name(async (launch) => {
6409
+ if (launch.agentType !== void 0 && !agentTypeIds.includes(launch.agentType)) {
6410
+ throw new Error(
6411
+ `Unknown agent type "${launch.agentType}". Available: ${agentTypeIds.join(", ")}.`
6412
+ );
6413
+ }
6414
+ if (launch.effort !== void 0 && launch.model === void 0) {
6415
+ throw new Error("Supply model when selecting an agent effort.");
6416
+ }
6417
+ const prompt = launch.schema === void 0 ? launch.prompt : `${launch.prompt}
6418
+
6419
+ Answer with one JSON value that satisfies this JSON Schema and nothing else:
6420
+ ${JSON.stringify(launch.schema)}`;
6421
+ const label = launch.workflowName === DEFAULT_AGENT_WORKFLOW ? "Workflow" : launch.workflowName;
6422
+ let viewId;
6423
+ let lastReport = 0;
6424
+ const report = /* @__PURE__ */ __name((force) => {
6425
+ if (!viewId || !launch.onProgress) return;
6426
+ const at = Date.now();
6427
+ if (!force && at - lastReport < 250) return;
6428
+ lastReport = at;
6429
+ const progress = activity.progressOf(viewId);
6430
+ if (progress) launch.onProgress(progress);
6431
+ }, "report");
6432
+ try {
6433
+ const { outcome } = await launchChild(
5670
6434
  {
5671
- model: requestedModel,
5672
- provider: requestedProvider,
5673
- effort: requestedEffort
6435
+ description: launch.label,
6436
+ prompt,
6437
+ run_in_background: false,
6438
+ ...launch.agentType !== void 0 ? { subagent_type: launch.agentType } : {},
6439
+ ...launch.model !== void 0 ? { model: launch.model } : {},
6440
+ ...launch.effort !== void 0 ? { effort: launch.effort } : {},
6441
+ workflow: label,
6442
+ ...launch.phaseTitle !== void 0 ? { phase: launch.phaseTitle } : {},
6443
+ ...launch.phaseIndex !== void 0 ? { phase_order: launch.phaseIndex } : {},
6444
+ ...launch.phaseDetail !== void 0 ? { phase_detail: launch.phaseDetail } : {}
5674
6445
  },
5675
- context.abortSignal
5676
- ) : (
5677
- // A file agent that pins its own model keeps it; any other child
5678
- // of a turn on another model than the session's runs on that one.
5679
- fileAgent?.model === void 0 ? inherited : void 0
6446
+ {
6447
+ turnId: launch.turnId,
6448
+ abortSignal: launch.signal,
6449
+ toolBatchId: launch.runId,
6450
+ ...launch.inherit?.env ? { env: launch.inherit.env } : {},
6451
+ ...launch.inherit?.toolResultGuardrails ? { toolResultGuardrails: launch.inherit.toolResultGuardrails } : {}
6452
+ },
6453
+ {
6454
+ workflowId: `${WORKFLOW_RUN_GROUP_PREFIX}${launch.runId}`,
6455
+ cancelCause: "user",
6456
+ onView: /* @__PURE__ */ __name((id) => {
6457
+ viewId = id;
6458
+ launch.onView?.(id);
6459
+ }, "onView"),
6460
+ onEvent: /* @__PURE__ */ __name(() => report(false), "onEvent")
6461
+ }
5680
6462
  );
5681
- let agentId = fileAgent?.name ?? (explore ? EXPLORE_SUBAGENT : GENERAL_PURPOSE_SUBAGENT);
5682
- const persona = typeof role === "string" ? role.trim() : "";
5683
- const dynamic = persona.length > 0 || selection !== void 0;
5684
- if (dynamic) {
5685
- agentId = `dyn-${++dynCounter}`;
5686
- registry.register(
5687
- buildDefinition(
5688
- agentId,
5689
- `Dynamic specialist: ${agentId}`,
5690
- fileAgent ? `${fileAgent.prompt}
5691
-
5692
- ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
5693
- opts,
5694
- fileAgent ? fileAgentTools(fileAgent, opts) : explore ? () => opts.buildTools().map(
5695
- (ts) => filtered(
5696
- ts,
5697
- (tool) => isTrustedReadOnly(tool, void 0, toToolSourceRef(ts.source))
5698
- )
5699
- ) : opts.buildTools,
5700
- selection?.model ?? fileAgent?.model ?? parentModel,
5701
- selection
5702
- )
5703
- );
6463
+ report(true);
6464
+ const stats = viewId ? activity.progressOf(viewId) : void 0;
6465
+ const tokens = stats?.tokens ?? 0;
6466
+ const toolCalls = stats?.toolCalls ?? 0;
6467
+ if (outcome.kind !== "completed") {
6468
+ return {
6469
+ state: "error",
6470
+ tokens,
6471
+ toolCalls,
6472
+ error: "The agent did not finish."
6473
+ };
5704
6474
  }
5705
- const seed = {
5706
- agentId,
5707
- model: selection?.model ?? fileAgent?.model ?? parentModel,
5708
- description,
5709
- prompt,
5710
- batchId: context.toolBatchId,
5711
- toolUseId: context.toolUseId,
5712
- workflowId: String(context.turnId),
5713
- workflow,
5714
- phase,
5715
- phaseOrder: phase_order,
5716
- phaseDetail: phase_detail
5717
- };
5718
- const tracker = activity.begin(seed);
5719
- const resumeHandler = opts.resolveResumeHandler?.(context.turnId) ?? refuseUnownedChildReview;
5720
- const configOverrides = {
5721
- ...resolveTurnGuards(opts, opts.resolveLimits?.(context.turnId)),
5722
- ...selection ? { model: selection.model, effort: selection.effort } : {},
5723
- ...Object.keys(context.env ?? {}).length > 0 ? { env: context.env } : {},
5724
- // The parent turn's tool-result screens, so a sub-agent judges a
5725
- // connected answer the way the turn that asked for the work
5726
- // does. Without it the child's executor installs the shipped
5727
- // default, and `toolResultScreens: []` — the operator's off
5728
- // switch — would hold for the parent and not for anything it
5729
- // delegated to, which is the half an operator does not watch.
5730
- //
5731
- // `[]` is carried rather than skipped: empty is a decision, and
5732
- // a `length` test — which is the shape that gets this wrong,
5733
- // since `[]` is truthy — would turn it back into absent.
5734
- ...context.toolResultGuardrails ? { toolResultGuardrails: context.toolResultGuardrails } : {},
5735
- resumeHandler
5736
- };
5737
- let taskOwnsCleanup = false;
5738
- let retained;
5739
- const cleanupDefinition = /* @__PURE__ */ __name(() => {
5740
- if (dynamic && !retained) registry.unregister(agentId);
5741
- }, "cleanupDefinition");
5742
- try {
5743
- const parentKey = sessionKey(await resolveParent(context.turnId));
5744
- const gateway = await gatewayForTurn(context.turnId);
5745
- const completionInbox = await completionInboxForTurn(context.turnId);
5746
- const subdirectory = workspace === "worktree" ? await worktreeDriver.selectedSubdirectory() : void 0;
5747
- const outcome = await runBlockingAgentTask({
5748
- gateway: await gatewayForTurn(context.turnId),
5749
- signal: context.abortSignal,
5750
- waitForInbound: opts.resolveWaitForInbound?.(context.turnId),
5751
- background: run_in_background === true,
5752
- completionInbox,
5753
- onCreated: /* @__PURE__ */ __name((task) => {
5754
- taskOwnsCleanup = true;
5755
- retained = {
5756
- parentKey,
5757
- agentId,
5758
- dynamic,
5759
- seed,
5760
- config: {
5761
- ...selection ? { model: selection.model, effort: selection.effort } : {},
5762
- ...configOverrides.env ? { env: configOverrides.env } : {},
5763
- ...configOverrides.toolResultGuardrails ? {
5764
- toolResultGuardrails: configOverrides.toolResultGuardrails
5765
- } : {}
5766
- },
5767
- workspace: workspace ?? "shared",
5768
- gateway,
5769
- task,
5770
- turnId: context.turnId,
5771
- busy: false
5772
- };
5773
- conversations.set(tracker.viewId, retained);
5774
- const visible = new Set(activity.getSnapshot().map((value) => value.viewId));
5775
- for (const [id, previous] of conversations) {
5776
- if (visible.has(id) || previous.busy || !isTerminalAgentTaskState(previous.task.state))
5777
- continue;
5778
- conversations.delete(id);
5779
- if (previous.dynamic) registry.unregister(previous.agentId);
5780
- }
5781
- tracker.settle(task);
5782
- }, "onCreated"),
5783
- onSettled: /* @__PURE__ */ __name((completed) => {
5784
- if (retained) retained.task = completed;
5785
- tracker.settle(completed);
5786
- }, "onSettled"),
5787
- onFailed: /* @__PURE__ */ __name((error) => tracker.fail(error), "onFailed"),
5788
- onFinished: cleanupDefinition,
5789
- create: {
5790
- agentId,
5791
- prompt,
5792
- workingDirectory: opts.cwd,
5793
- workspace: workspace === "worktree" ? {
5794
- mode: "isolated",
5795
- backend: "git-worktree",
5796
- retention: "retain",
5797
- ...subdirectory ? { subdirectory } : {}
5798
- } : { mode: "shared" },
5799
- // The same labels the monitor was seeded with, sent down so the
5800
- // child's `agent_pending` carries them: a listener or SSE
5801
- // consumer outside this process then groups the child the way
5802
- // the operator sees it here, instead of the grouping living
5803
- // only in the closure above. Display-only on both paths — no
5804
- // dependency, barrier or serial execution follows from any.
5805
- ...workflow ? { workflow } : {},
5806
- ...phase ? { phase } : {},
5807
- ...phase_detail ? { phaseDetail: phase_detail } : {},
5808
- ...phase_order !== void 0 ? { phaseOrder: phase_order } : {},
5809
- // Hang the child session off THIS tool's span, so the delegation
5810
- // shows up inside the turn that asked for it. Without it a
5811
- // sub-agent opens its OWN root trace, and the one structure
5812
- // a delegation trace exists to record — who dispatched whom
5813
- // — is the thing that goes missing.
5814
- ...context.parentSpan ? { parentSpan: context.parentSpan } : {},
5815
- configOverrides,
5816
- onEvent: tracker.onEvent
5817
- }
5818
- });
5819
- if (outcome.kind === "yielded") {
5820
- const progress = outcome.handle.state === "pending" ? "queued for an available slot" : "still running";
5821
- return {
5822
- success: true,
5823
- output: `Sub-agent ${agentId} for task ${JSON.stringify(description)} is ${progress} as task ${outcome.handle.taskId}; it has not completed.${workspaceNote(outcome.handle)} ${run_in_background ? "Continue independent work while this task runs in the background." : "Waiting was released because the operator sent a message. Answer their question or status request before making further tool calls; preserve existing work unless they ask to cancel or change it."} Its actual result will arrive as a task notification; do not launch the same work again.`,
5824
- data: {
5825
- task_id: outcome.handle.taskId,
5826
- state: outcome.handle.state,
5827
- ...workspaceData(outcome.handle),
5828
- wait_released: run_in_background ? "background" : "operator_input"
5829
- }
5830
- };
5831
- }
5832
- return completedAgentResult(outcome.handle);
5833
- } catch (error) {
5834
- tracker.fail(error);
5835
- throw error;
5836
- } finally {
5837
- if (!taskOwnsCleanup) cleanupDefinition();
6475
+ const handle = outcome.handle;
6476
+ const status = agentTaskOutcome(handle);
6477
+ const turn = handle.result;
6478
+ const value = turn?.structuredOutput ?? turn?.result;
6479
+ const text = typeof value === "string" ? value : value === void 0 ? "" : JSON.stringify(value);
6480
+ if (status !== "completed") {
6481
+ return {
6482
+ state: "error",
6483
+ tokens,
6484
+ toolCalls,
6485
+ error: `The agent ended as ${status}${turn?.lastError ? `: ${turn.lastError}` : "."}`
6486
+ };
5838
6487
  }
6488
+ return { state: "done", text, tokens, toolCalls };
6489
+ } catch (error) {
6490
+ if (launch.signal.aborted) throw error;
6491
+ const stats = viewId ? activity.progressOf(viewId) : void 0;
6492
+ return {
6493
+ state: "error",
6494
+ tokens: stats?.tokens ?? 0,
6495
+ toolCalls: stats?.toolCalls ?? 0,
6496
+ error: error instanceof Error ? error.message : String(error)
6497
+ };
5839
6498
  }
5840
- });
6499
+ }, "launchWorkflowAgent");
5841
6500
  const agentTaskListTool = defineTool({
5842
6501
  name: "agent_task_list",
5843
6502
  description: "List the agent invocations launched by this turn and their current status, without waiting or starting work. Use this for agent progress questions. task_list contains planning items, not agent invocations. Use wait_for_task with a live ID for its result. Set history: true to inspect agents saved from earlier turns of this conversation, optionally session_id for one saved result; saved agents are not live.",
@@ -6324,10 +6983,21 @@ ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6324
6983
  };
6325
6984
  }
6326
6985
  }) : void 0;
6986
+ const stopChild = /* @__PURE__ */ __name((viewId) => {
6987
+ if (closed) return false;
6988
+ const owned = conversations.get(viewId);
6989
+ const shown = activity.getSnapshot().find((value) => value.viewId === viewId);
6990
+ if (!owned || !shown || shown.replayed) return false;
6991
+ const current = owned.gateway.getTask(owned.task.taskId) ?? owned.task;
6992
+ if (isTerminalAgentTaskState(current.state)) return false;
6993
+ owned.gateway.cancelTask(owned.task.taskId, "user");
6994
+ return true;
6995
+ }, "stopChild");
6327
6996
  return {
6328
6997
  cancelAgentTool,
6329
6998
  modelCatalogueTool,
6330
6999
  messageChild,
7000
+ stopChild,
6331
7001
  gatewayForTurn,
6332
7002
  completionInboxForTurn,
6333
7003
  releaseTurn,
@@ -6351,6 +7021,7 @@ ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6351
7021
  return type === EXPLORE_SUBAGENT;
6352
7022
  },
6353
7023
  activity,
7024
+ launchWorkflowAgent,
6354
7025
  close
6355
7026
  };
6356
7027
  }
@@ -6371,7 +7042,7 @@ async function runBlockingAgentTask(input) {
6371
7042
  if (taskCancellationAttempted) return;
6372
7043
  taskCancellationAttempted = true;
6373
7044
  try {
6374
- gateway.cancelTask(task.taskId, "parent");
7045
+ gateway.cancelTask(task.taskId, input.cancelCause ?? "parent");
6375
7046
  } catch {
6376
7047
  }
6377
7048
  }, "cancel");
@@ -6568,9 +7239,403 @@ ${SUBAGENT_PROMPT}`;
6568
7239
  }
6569
7240
  __name(buildDefinition, "buildDefinition");
6570
7241
 
7242
+ // src/integrations/workflows/doctrine.ts
7243
+ var WORKFLOW_DOCTRINE = [
7244
+ "The `workflow` tool is available this turn because the operator asked for orchestration.",
7245
+ "Use it for work with several phases or many agents: write the script once, call `workflow`, and the runtime schedules the agents and groups them by phase. Keep `Agent` calls (with a `workflow` label and a `phase`) for a small fan-out of a few agents, and for a single subagent.",
7246
+ "A workflow runs in the background and the operator approves the script before it starts. After you start one, tell the operator in one sentence that it is running; its result reaches you in a single message when it ends, and you then report the outcome."
7247
+ ].join("\n");
7248
+
7249
+ // src/integrations/workflows/history.ts
7250
+ import { readFile as readFile3, readdir as readdir2 } from "node:fs/promises";
7251
+ import { join as join8 } from "node:path";
7252
+ var RUN_ID = /^w[0-9a-z]{8}$/;
7253
+ async function readWorkflowJournal(file) {
7254
+ let text;
7255
+ try {
7256
+ text = await readFile3(file, "utf8");
7257
+ } catch (error) {
7258
+ if (error.code === "ENOENT") return [];
7259
+ throw error;
7260
+ }
7261
+ const records = [];
7262
+ for (const line of text.split("\n")) {
7263
+ if (line.trim().length === 0) continue;
7264
+ try {
7265
+ const parsed = JSON.parse(line);
7266
+ if (typeof parsed === "object" && parsed !== null && "type" in parsed) {
7267
+ records.push(parsed);
7268
+ }
7269
+ } catch {
7270
+ }
7271
+ }
7272
+ return records;
7273
+ }
7274
+ __name(readWorkflowJournal, "readWorkflowJournal");
7275
+ async function readWorkflowRun(runsDirectory, runId) {
7276
+ if (!RUN_ID.test(runId)) return void 0;
7277
+ const records = await readWorkflowJournal(join8(runsDirectory, runId, "workflow", "journal.jsonl"));
7278
+ return viewFromJournal(records);
7279
+ }
7280
+ __name(readWorkflowRun, "readWorkflowRun");
7281
+ async function listWorkflowRuns(runsDirectory) {
7282
+ let entries;
7283
+ try {
7284
+ entries = await readdir2(runsDirectory);
7285
+ } catch (error) {
7286
+ if (error.code === "ENOENT") return [];
7287
+ throw error;
7288
+ }
7289
+ const views = await Promise.all(
7290
+ entries.filter((name) => RUN_ID.test(name)).map((name) => readWorkflowRun(runsDirectory, name))
7291
+ );
7292
+ return views.filter((view) => view !== void 0).sort((a, b) => b.startedAt - a.startedAt);
7293
+ }
7294
+ __name(listWorkflowRuns, "listWorkflowRuns");
7295
+
7296
+ // src/integrations/workflows/host.ts
7297
+ import { randomBytes as randomBytes3 } from "node:crypto";
7298
+ import { join as join9 } from "node:path";
7299
+
7300
+ // src/integrations/workflows/registry.ts
7301
+ var WorkflowRunRegistry = class {
7302
+ static {
7303
+ __name(this, "WorkflowRunRegistry");
7304
+ }
7305
+ runs = /* @__PURE__ */ new Map();
7306
+ listeners = /* @__PURE__ */ new Set();
7307
+ runtime;
7308
+ now;
7309
+ notifyTimer;
7310
+ closed = false;
7311
+ constructor(options = {}) {
7312
+ this.now = options.now ?? Date.now;
7313
+ this.runtime = options.runtime ?? new WorkflowRuntime();
7314
+ }
7315
+ list() {
7316
+ return [...this.runs.values()].map((run2) => run2.view);
7317
+ }
7318
+ get(runId) {
7319
+ return this.runs.get(runId)?.view;
7320
+ }
7321
+ subscribe(listener) {
7322
+ this.listeners.add(listener);
7323
+ return () => this.listeners.delete(listener);
7324
+ }
7325
+ /** Runs that have not ended. */
7326
+ running() {
7327
+ return this.list().filter((view) => view.status === "running");
7328
+ }
7329
+ /** Begin a run. Returns at once; the run goes on in the background. */
7330
+ start(input) {
7331
+ if (this.closed) throw new Error("Workflows are closed for this session.");
7332
+ const run2 = {
7333
+ view: initialRunView({
7334
+ runId: input.runId,
7335
+ name: input.meta.name,
7336
+ description: input.meta.description,
7337
+ phases: input.meta.phases,
7338
+ at: this.now()
7339
+ }),
7340
+ abort: new AbortController(),
7341
+ finalized: false
7342
+ };
7343
+ this.runs.set(input.runId, run2);
7344
+ this.notifySoon(true);
7345
+ const settle = /* @__PURE__ */ __name(async (result, error) => {
7346
+ const at = this.now();
7347
+ if (run2.view.status === "running") {
7348
+ run2.view = {
7349
+ ...run2.view,
7350
+ status: run2.abort.signal.aborted ? "stopped" : "failed",
7351
+ endedAt: at,
7352
+ ...error !== void 0 ? { error } : {}
7353
+ };
7354
+ }
7355
+ run2.view = closeOpenAgents(run2.view, at);
7356
+ try {
7357
+ await input.onEnd?.({ view: run2.view, ...result ? { result } : {} });
7358
+ } catch {
7359
+ }
7360
+ run2.finalized = true;
7361
+ this.notifySoon(true);
7362
+ }, "settle");
7363
+ void this.runtime.run({
7364
+ script: input.script,
7365
+ ...input.args !== void 0 ? { args: input.args } : {},
7366
+ ...input.limits ? { limits: input.limits } : {},
7367
+ ...input.journal ? { journal: input.journal } : {},
7368
+ runId: input.runId,
7369
+ signal: run2.abort.signal,
7370
+ onControl: /* @__PURE__ */ __name((control) => {
7371
+ run2.control = control;
7372
+ }, "onControl"),
7373
+ onEvent: /* @__PURE__ */ __name((event) => {
7374
+ run2.view = reduceRunView(run2.view, event);
7375
+ this.notifySoon(event.type !== "workflow_agent" || event.state !== "progress");
7376
+ }, "onEvent"),
7377
+ spawnAgent: /* @__PURE__ */ __name((request, signal) => input.spawn(request, signal, (viewId) => {
7378
+ run2.view = attachAgentView(run2.view, request.index, viewId);
7379
+ this.notifySoon(false);
7380
+ }), "spawnAgent")
7381
+ }).then(
7382
+ (result) => settle(result),
7383
+ (error) => settle(void 0, error instanceof Error ? error.message : String(error))
7384
+ );
7385
+ return run2.view;
7386
+ }
7387
+ /**
7388
+ * Resolves once no run is going, or when `signal` aborts (whichever is first).
7389
+ * A run's own limits bound the wait: the runtime stops one at its duration cap.
7390
+ */
7391
+ whenIdle(signal) {
7392
+ const going = /* @__PURE__ */ __name(() => [...this.runs.values()].some((run2) => !run2.finalized), "going");
7393
+ if (!going() || signal?.aborted) return Promise.resolve();
7394
+ return new Promise((resolve9) => {
7395
+ const done = /* @__PURE__ */ __name(() => {
7396
+ off();
7397
+ signal?.removeEventListener("abort", done);
7398
+ resolve9();
7399
+ }, "done");
7400
+ const off = this.subscribe(() => {
7401
+ if (!going()) done();
7402
+ });
7403
+ signal?.addEventListener("abort", done, { once: true });
7404
+ });
7405
+ }
7406
+ /** Stop a run: queued agents never start, running ones are aborted. False when it is not running. */
7407
+ stop(runId) {
7408
+ const run2 = this.runs.get(runId);
7409
+ if (!run2 || run2.view.status !== "running") return false;
7410
+ run2.abort.abort(new Error("The operator stopped this workflow."));
7411
+ return true;
7412
+ }
7413
+ /** Skip one agent of a run. False when it is not running or already settled. */
7414
+ skipAgent(runId, index) {
7415
+ const run2 = this.runs.get(runId);
7416
+ if (!run2 || run2.view.status !== "running") return false;
7417
+ return run2.control?.skipAgent(index) ?? false;
7418
+ }
7419
+ /** Which run and agent a monitor row stands for, if any. */
7420
+ agentOf(viewId) {
7421
+ for (const run2 of this.runs.values()) {
7422
+ const agent = run2.view.agents.find((item) => item.viewId === viewId);
7423
+ if (agent) return { runId: run2.view.runId, index: agent.index };
7424
+ }
7425
+ return void 0;
7426
+ }
7427
+ /** Forget runs that have ended (a new conversation). Running ones are stopped first. */
7428
+ reset() {
7429
+ for (const run2 of this.runs.values()) run2.abort.abort(new Error("The conversation changed."));
7430
+ this.runs.clear();
7431
+ this.notifySoon(true);
7432
+ }
7433
+ close() {
7434
+ this.closed = true;
7435
+ for (const run2 of this.runs.values()) run2.abort.abort(new Error("The session ended."));
7436
+ if (this.notifyTimer) clearTimeout(this.notifyTimer);
7437
+ this.notifyTimer = void 0;
7438
+ this.listeners.clear();
7439
+ }
7440
+ notifySoon(now) {
7441
+ if (this.closed) return;
7442
+ if (now) {
7443
+ if (this.notifyTimer) clearTimeout(this.notifyTimer);
7444
+ this.notifyTimer = void 0;
7445
+ for (const listener of [...this.listeners]) listener();
7446
+ return;
7447
+ }
7448
+ if (this.notifyTimer) return;
7449
+ this.notifyTimer = setTimeout(() => {
7450
+ this.notifyTimer = void 0;
7451
+ for (const listener of [...this.listeners]) listener();
7452
+ }, 100);
7453
+ this.notifyTimer.unref?.();
7454
+ }
7455
+ };
7456
+
7457
+ // src/integrations/workflows/host.ts
7458
+ var MAX_WORKFLOW_SCRIPT_CHARS = 262144;
7459
+ var MAX_WORKFLOW_ARGS_CHARS = 65536;
7460
+ var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
7461
+ function createWorkflowRunId(isTaken = () => false) {
7462
+ for (; ; ) {
7463
+ let body = "";
7464
+ while (body.length < 8) {
7465
+ for (const byte of randomBytes3(16)) {
7466
+ if (byte >= 252) continue;
7467
+ body += ALPHABET[byte % 36];
7468
+ if (body.length === 8) break;
7469
+ }
7470
+ }
7471
+ const id = `w${body}`;
7472
+ if (!isTaken(id)) return id;
7473
+ }
7474
+ }
7475
+ __name(createWorkflowRunId, "createWorkflowRunId");
7476
+ function toolName(label) {
7477
+ if (!label) return { name: "tool" };
7478
+ const open3 = label.indexOf("(");
7479
+ return open3 > 0 ? { name: label.slice(0, open3), summary: label } : { name: label, summary: label };
7480
+ }
7481
+ __name(toolName, "toolName");
7482
+ function describeWorkflowCall(input) {
7483
+ if (typeof input.description === "string" && input.description.trim().length > 0) {
7484
+ return input.description.trim().replace(/\s+/g, " ");
7485
+ }
7486
+ if (typeof input.script === "string") {
7487
+ try {
7488
+ return parseWorkflowMeta(input.script).description.replace(/\s+/g, " ");
7489
+ } catch {
7490
+ const first = input.script.split("\n").find((line) => line.trim().length > 0);
7491
+ if (first) return first.trim().slice(0, 80);
7492
+ }
7493
+ }
7494
+ return "workflow";
7495
+ }
7496
+ __name(describeWorkflowCall, "describeWorkflowCall");
7497
+ function createWorkflowHost(options) {
7498
+ const registry = options.registry ?? new WorkflowRunRegistry();
7499
+ const tool = defineTool({
7500
+ name: WORKFLOW_TOOL_NAME,
7501
+ description: WORKFLOW_TOOL_DESCRIPTION,
7502
+ inputSchema: mcpJsonSchemaToZod({
7503
+ type: "object",
7504
+ properties: {
7505
+ script: {
7506
+ type: "string",
7507
+ maxLength: MAX_WORKFLOW_SCRIPT_CHARS,
7508
+ description: "The workflow script: `export const meta = {...}` first, then the code. Plain JavaScript, not wrapped in a function or a code fence."
7509
+ },
7510
+ args: {
7511
+ description: "JSON the script reads as `args`. Keep it small; the operator reads it before the run starts."
7512
+ },
7513
+ description: {
7514
+ type: "string",
7515
+ maxLength: 200,
7516
+ description: "Optional one-line summary shown to the operator instead of meta.description."
7517
+ }
7518
+ },
7519
+ required: ["script"],
7520
+ additionalProperties: false
7521
+ }),
7522
+ largeStringArguments: { script: 2e4 },
7523
+ truncatedInputHint: "Write a shorter script: shared helpers, loops instead of repeated lines, and prompts built from args.",
7524
+ malformedInputHint: 'Every character of "script" goes inside a JSON string: write a newline as \\n, a tab as \\t, a double quote as \\" and a backslash as \\\\.',
7525
+ // The person reads `Workflow(<what it is for>)`, never the script.
7526
+ presentCall: /* @__PURE__ */ __name((input) => ({
7527
+ kind: "generic",
7528
+ label: `Workflow(${describeWorkflowCall(input)})`,
7529
+ presentation: "activity"
7530
+ }), "presentCall"),
7531
+ category: "custom",
7532
+ permissions: [],
7533
+ readOnly: false,
7534
+ destructive: false,
7535
+ concurrencySafe: false,
7536
+ async execute(input, context) {
7537
+ const { script, args } = input;
7538
+ const refused = options.refusal(context.turnId);
7539
+ if (refused !== void 0) return { success: false, output: "", error: refused };
7540
+ if (args !== void 0 && JSON.stringify(args).length > MAX_WORKFLOW_ARGS_CHARS) {
7541
+ return {
7542
+ success: false,
7543
+ output: "",
7544
+ error: `args is larger than ${MAX_WORKFLOW_ARGS_CHARS} characters. Pass less, or have the agents read a file.`
7545
+ };
7546
+ }
7547
+ let meta;
7548
+ try {
7549
+ meta = parseWorkflowMeta(script);
7550
+ } catch (error) {
7551
+ if (error instanceof WorkflowScriptError) {
7552
+ return { success: false, output: "", error: error.message };
7553
+ }
7554
+ throw error;
7555
+ }
7556
+ const runId = createWorkflowRunId((id) => registry.get(id) !== void 0);
7557
+ const turn = options.openRunTurn(context.turnId, runId);
7558
+ const runs = options.runsDirectory(context.turnId);
7559
+ const limits = options.limitsFor?.(context.turnId);
7560
+ const journal = runs === void 0 ? void 0 : new FileWorkflowJournal(join9(runs, runId, "workflow"));
7561
+ const phaseDetail = /* @__PURE__ */ __name((title) => title === void 0 ? void 0 : meta.phases.find((phase) => phase.title.trim() === title.trim())?.detail, "phaseDetail");
7562
+ try {
7563
+ const view = registry.start({
7564
+ runId,
7565
+ meta,
7566
+ script,
7567
+ ...args !== void 0 ? { args } : {},
7568
+ ...limits ? { limits } : {},
7569
+ ...journal ? { journal } : {},
7570
+ spawn: /* @__PURE__ */ __name(async (request, signal, viewed) => {
7571
+ const detail = phaseDetail(request.phaseTitle);
7572
+ const outcome = await options.subagents.launchWorkflowAgent({
7573
+ turnId: turn.turnId,
7574
+ runId,
7575
+ workflowName: meta.name,
7576
+ label: request.label,
7577
+ prompt: request.prompt,
7578
+ ...request.phaseTitle !== void 0 ? { phaseTitle: request.phaseTitle } : {},
7579
+ ...request.phaseIndex !== void 0 ? { phaseIndex: request.phaseIndex } : {},
7580
+ ...detail !== void 0 ? { phaseDetail: detail } : {},
7581
+ ...request.agentType !== void 0 ? { agentType: request.agentType } : {},
7582
+ ...request.model !== void 0 ? { model: request.model } : {},
7583
+ ...request.effort !== void 0 ? { effort: request.effort } : {},
7584
+ ...request.schema !== void 0 ? { schema: request.schema } : {},
7585
+ signal,
7586
+ inherit: {
7587
+ ...context.env ? { env: context.env } : {},
7588
+ ...context.toolResultGuardrails ? { toolResultGuardrails: context.toolResultGuardrails } : {}
7589
+ },
7590
+ onView: viewed,
7591
+ onProgress: /* @__PURE__ */ __name((progress) => {
7592
+ const last = toolName(progress.lastTool);
7593
+ request.onProgress({
7594
+ ...progress.tokens !== void 0 ? { tokens: progress.tokens } : {},
7595
+ ...progress.toolCalls !== void 0 ? { toolCalls: progress.toolCalls } : {},
7596
+ ...progress.lastTool !== void 0 ? {
7597
+ lastToolName: last.name,
7598
+ lastToolSummary: last.summary ?? last.name
7599
+ } : {}
7600
+ });
7601
+ }, "onProgress")
7602
+ });
7603
+ return {
7604
+ state: outcome.state,
7605
+ ...outcome.text !== void 0 ? { text: outcome.text } : {},
7606
+ tokens: outcome.tokens,
7607
+ toolCalls: outcome.toolCalls,
7608
+ ...outcome.error !== void 0 ? { error: outcome.error } : {}
7609
+ };
7610
+ }, "spawn"),
7611
+ onEnd: /* @__PURE__ */ __name(async (end) => {
7612
+ await turn.release().catch(() => void 0);
7613
+ options.onEnd?.(end);
7614
+ }, "onEnd")
7615
+ });
7616
+ return {
7617
+ success: true,
7618
+ output: launchedText(view),
7619
+ data: {
7620
+ run_id: runId,
7621
+ name: meta.name,
7622
+ description: input && typeof input.description === "string" ? input.description : meta.description,
7623
+ phases: meta.phases.map((phase) => phase.title)
7624
+ }
7625
+ };
7626
+ } catch (error) {
7627
+ await turn.release();
7628
+ throw error;
7629
+ }
7630
+ }
7631
+ });
7632
+ return { registry, tool };
7633
+ }
7634
+ __name(createWorkflowHost, "createWorkflowHost");
7635
+
6571
7636
  // src/memory/store.ts
6572
7637
  import { realpathSync as realpathSync3 } from "node:fs";
6573
- import { join as join9, resolve as resolve7 } from "node:path";
7638
+ import { join as join11, resolve as resolve7 } from "node:path";
6574
7639
 
6575
7640
  // src/memory/io.ts
6576
7641
  import {
@@ -6584,7 +7649,7 @@ import {
6584
7649
  realpathSync as realpathSync2,
6585
7650
  writeSync
6586
7651
  } from "node:fs";
6587
- import { isAbsolute as isAbsolute5, join as join8, relative as relative5, resolve as resolve6, sep as sep4 } from "node:path";
7652
+ import { isAbsolute as isAbsolute5, join as join10, relative as relative5, resolve as resolve6, sep as sep4 } from "node:path";
6588
7653
  var MEMORY_FILE_MAX_BYTES = 1024 * 1024;
6589
7654
  function missing(error) {
6590
7655
  return error.code === "ENOENT";
@@ -6617,7 +7682,7 @@ function resolveMemoryPath(location, createParents = false) {
6617
7682
  for (let i = 0; i < parts.length; i += 1) {
6618
7683
  const part = parts[i];
6619
7684
  if (part === void 0) throw new Error("Memory path has an invalid segment.");
6620
- candidate = join8(candidate, part);
7685
+ candidate = join10(candidate, part);
6621
7686
  const leaf = i === parts.length - 1;
6622
7687
  let stat5;
6623
7688
  try {
@@ -6747,11 +7812,11 @@ function memoryDir(home) {
6747
7812
  }
6748
7813
  __name(memoryDir, "memoryDir");
6749
7814
  function userFilePath(home) {
6750
- return join9(memoryDir(home), "USER.md");
7815
+ return join11(memoryDir(home), "USER.md");
6751
7816
  }
6752
7817
  __name(userFilePath, "userFilePath");
6753
7818
  function memoryFilePath(home) {
6754
- return join9(memoryDir(home), "MEMORY.md");
7819
+ return join11(memoryDir(home), "MEMORY.md");
6755
7820
  }
6756
7821
  __name(memoryFilePath, "memoryFilePath");
6757
7822
  function projectMemoryFilePath(cwd) {
@@ -6762,9 +7827,9 @@ function projectMemoryFilePath(cwd) {
6762
7827
  if (error.code !== "ENOENT") throw error;
6763
7828
  }
6764
7829
  const root = cliProjectRoot(directory);
6765
- const local = join9(directory, ".namzu", "MEMORY.md");
7830
+ const local = join11(directory, ".namzu", "MEMORY.md");
6766
7831
  if (resolveMemoryPath({ path: local, root }) !== null) return local;
6767
- return join9(root, ".namzu", "MEMORY.md");
7832
+ return join11(root, ".namzu", "MEMORY.md");
6768
7833
  }
6769
7834
  __name(projectMemoryFilePath, "projectMemoryFilePath");
6770
7835
  function projectMemoryLocation(cwd) {
@@ -6794,15 +7859,15 @@ function readMemory(home, cwd) {
6794
7859
  }
6795
7860
  }, "read");
6796
7861
  const userRoot = memoryDir(home);
6797
- const user = read(join9(userRoot, "USER.md"), () => ({
7862
+ const user = read(join11(userRoot, "USER.md"), () => ({
6798
7863
  root: userRoot,
6799
- path: join9(userRoot, "USER.md")
7864
+ path: join11(userRoot, "USER.md")
6800
7865
  }));
6801
- const memory = read(join9(userRoot, "MEMORY.md"), () => ({
7866
+ const memory = read(join11(userRoot, "MEMORY.md"), () => ({
6802
7867
  root: userRoot,
6803
- path: join9(userRoot, "MEMORY.md")
7868
+ path: join11(userRoot, "MEMORY.md")
6804
7869
  }));
6805
- const project = cwd && !isUserMemoryFile(join9(resolve7(cwd), ".namzu", "MEMORY.md"), userRoot) ? read(join9(resolve7(cwd), ".namzu", "MEMORY.md"), () => projectLocation(cwd)) : null;
7870
+ const project = cwd && !isUserMemoryFile(join11(resolve7(cwd), ".namzu", "MEMORY.md"), userRoot) ? read(join11(resolve7(cwd), ".namzu", "MEMORY.md"), () => projectLocation(cwd)) : null;
6806
7871
  return { user, memory, project, ...diagnostics.length > 0 ? { diagnostics } : {} };
6807
7872
  }
6808
7873
  __name(readMemory, "readMemory");
@@ -6814,7 +7879,7 @@ function isUserMemoryFile(projectPath, userRoot) {
6814
7879
  return resolve7(path);
6815
7880
  }
6816
7881
  }, "canonical");
6817
- return canonical(projectPath) === canonical(join9(userRoot, "MEMORY.md"));
7882
+ return canonical(projectPath) === canonical(join11(userRoot, "MEMORY.md"));
6818
7883
  }
6819
7884
  __name(isUserMemoryFile, "isUserMemoryFile");
6820
7885
  function capped(text, file) {
@@ -6963,8 +8028,8 @@ __name(renderStoredMemorySection, "renderStoredMemorySection");
6963
8028
 
6964
8029
  // src/memory/typed.ts
6965
8030
  import { createHash as createHash4 } from "node:crypto";
6966
- import { access, readFile as readFile3, rename as rename3, writeFile as writeFile2 } from "node:fs/promises";
6967
- import { join as join10 } from "node:path";
8031
+ import { access, readFile as readFile4, rename as rename3, writeFile as writeFile2 } from "node:fs/promises";
8032
+ import { join as join12 } from "node:path";
6968
8033
  function firstLine2(text, limit) {
6969
8034
  const line = (text.split(/\r?\n/).find((part) => part.trim()) ?? "").replace(/\s+/g, " ").trim();
6970
8035
  if (line.length <= limit) return line;
@@ -6988,7 +8053,7 @@ async function saveTypedNote(store, text, type = "project") {
6988
8053
  saved: false,
6989
8054
  duplicate: true,
6990
8055
  type: record.entry.type ?? type,
6991
- ...record.entry.name ? { name: record.entry.name, path: join10(store.path, `${record.entry.name}.md`) } : {}
8056
+ ...record.entry.name ? { name: record.entry.name, path: join12(store.path, `${record.entry.name}.md`) } : {}
6992
8057
  };
6993
8058
  }
6994
8059
  }
@@ -7003,7 +8068,7 @@ async function saveTypedNote(store, text, type = "project") {
7003
8068
  return {
7004
8069
  saved: true,
7005
8070
  type,
7006
- ...entry.name ? { name: entry.name, path: join10(store.path, `${entry.name}.md`) } : {}
8071
+ ...entry.name ? { name: entry.name, path: join12(store.path, `${entry.name}.md`) } : {}
7007
8072
  };
7008
8073
  }
7009
8074
  __name(saveTypedNote, "saveTypedNote");
@@ -7021,7 +8086,7 @@ __name(composeStoredMemoryPrompt, "composeStoredMemoryPrompt");
7021
8086
  var MARKER = "migration.json";
7022
8087
  async function readMarker(directory) {
7023
8088
  try {
7024
- const parsed = JSON.parse(await readFile3(join10(directory, MARKER), "utf8"));
8089
+ const parsed = JSON.parse(await readFile4(join12(directory, MARKER), "utf8"));
7025
8090
  return parsed !== null && typeof parsed === "object" ? parsed : {};
7026
8091
  } catch (error) {
7027
8092
  if (error.code === "ENOENT") return {};
@@ -7034,7 +8099,7 @@ async function markCuratedFile(directory, path, state) {
7034
8099
  const files = { ...marker.curatedFiles ?? {} };
7035
8100
  files[path] = { ...files[path] ?? {}, ...state };
7036
8101
  await writeFile2(
7037
- join10(directory, MARKER),
8102
+ join12(directory, MARKER),
7038
8103
  `${JSON.stringify({ ...marker, curatedFiles: files }, null, 2)}
7039
8104
  `,
7040
8105
  { mode: 384 }
@@ -7101,7 +8166,7 @@ async function migrateMemoryOnce(options) {
7101
8166
  const skippedRecords = [];
7102
8167
  let importedRecords = 0;
7103
8168
  let notesOffer;
7104
- const indexPath = join10(directory, "index.json");
8169
+ const indexPath = join12(directory, "index.json");
7105
8170
  if (await exists(indexPath)) {
7106
8171
  try {
7107
8172
  const disk = new DiskMemoryStore({ baseDir: directory, directory });
@@ -7124,11 +8189,11 @@ async function migrateMemoryOnce(options) {
7124
8189
  }
7125
8190
  }
7126
8191
  await retire(indexPath);
7127
- const content = join10(directory, "content");
8192
+ const content = join12(directory, "content");
7128
8193
  const retiredContent = await exists(content) ? await retire(content) : content;
7129
8194
  for (const record of refused) {
7130
8195
  skippedRecords.push(
7131
- `"${record.title}" (${record.id}) was not moved: ${record.reason} It is kept in ${join10(retiredContent, `${record.id}.json`)}.`
8196
+ `"${record.title}" (${record.id}) was not moved: ${record.reason} It is kept in ${join12(retiredContent, `${record.id}.json`)}.`
7132
8197
  );
7133
8198
  }
7134
8199
  } catch (error) {
@@ -7490,25 +8555,25 @@ __name(admitToolView, "admitToolView");
7490
8555
  function createCliToolPresenter(registry) {
7491
8556
  const log = cliLogger().child({ [SCOPE_ATTRIBUTE]: "cli/tool-presentation" });
7492
8557
  const presenter = createToolPresenter(registry, log);
7493
- const admit = /* @__PURE__ */ __name((toolName, hook, present) => {
8558
+ const admit = /* @__PURE__ */ __name((toolName2, hook, present) => {
7494
8559
  try {
7495
8560
  const view = admitToolView(present());
7496
8561
  if (view) return view;
7497
8562
  } catch {
7498
8563
  }
7499
8564
  log.warn("Tool presentation was invalid; using a plain view", {
7500
- "namzu.tool.name": toolName,
8565
+ "namzu.tool.name": toolName2,
7501
8566
  "namzu.tool.presenter_hook": hook
7502
8567
  });
7503
8568
  return void 0;
7504
8569
  }, "admit");
7505
8570
  return {
7506
- presentCall: /* @__PURE__ */ __name((toolName, input) => admit(toolName, "presentCall", () => presenter.presentCall(toolName, input)) ?? {
8571
+ presentCall: /* @__PURE__ */ __name((toolName2, input) => admit(toolName2, "presentCall", () => presenter.presentCall(toolName2, input)) ?? {
7507
8572
  kind: "generic",
7508
8573
  // Never stringify unreadable input as a replacement for a broken label.
7509
- label: toolName
8574
+ label: toolName2
7510
8575
  }, "presentCall"),
7511
- presentResult: /* @__PURE__ */ __name((toolName, input, result) => admit(toolName, "presentResult", () => presenter.presentResult(toolName, input, result)) ?? {
8576
+ presentResult: /* @__PURE__ */ __name((toolName2, input, result) => admit(toolName2, "presentResult", () => presenter.presentResult(toolName2, input, result)) ?? {
7512
8577
  kind: "terminal",
7513
8578
  output: (result.success ? result.output : result.error ?? result.output) ?? ""
7514
8579
  }, "presentResult")
@@ -7865,10 +8930,10 @@ function clipRequestContext(prompt, limit, kind) {
7865
8930
  __name(clipRequestContext, "clipRequestContext");
7866
8931
  async function createAgentSession(prefs, detected, options = {}) {
7867
8932
  if (options.palEnvironment) {
7868
- const { createPalAgentSession } = await import("./agent-session-UNUZAMRW.js");
8933
+ const { createPalAgentSession } = await import("./agent-session-PLIPF3XG.js");
7869
8934
  return createPalAgentSession(prefs, detected, options);
7870
8935
  }
7871
- const { palAtWorkspace } = await import("./store-GDP2EW27.js");
8936
+ const { palAtWorkspace } = await import("./store-7WZWQXKX.js");
7872
8937
  if (palAtWorkspace(options.cwd ?? process.cwd()))
7873
8938
  throw new Error("This Pal requires its owned virtual computer. Open it with namzu pal chat.");
7874
8939
  const fileObservations = /* @__PURE__ */ new Map();
@@ -8167,6 +9232,8 @@ async function createAgentSession(prefs, detected, options = {}) {
8167
9232
  }
8168
9233
  return readCurrentAuxiliaryCredential(found, signal);
8169
9234
  }, "currentCredentialFor");
9235
+ let turnRouteTarget;
9236
+ let lastAutoRoute;
8170
9237
  const providerForSession = /* @__PURE__ */ __name((sessionId) => primary.id === "zen" || primary.id === "zen-go" ? constructProvider(primary.id, det, model, { sessionId }) : provider, "providerForSession");
8171
9238
  const projectInstructions = new ProjectInstructionTracker(cwd);
8172
9239
  let sandbox;
@@ -8346,6 +9413,9 @@ async function createAgentSession(prefs, detected, options = {}) {
8346
9413
  const goalAuthorities = /* @__PURE__ */ new Map();
8347
9414
  const delegatedResumeHandlers = /* @__PURE__ */ new Map();
8348
9415
  const delegatedReviewAllowedCalls = /* @__PURE__ */ new Map();
9416
+ const delegatedWorkflowAuth = /* @__PURE__ */ new Map();
9417
+ let workflowHost;
9418
+ const workflowEndListeners = /* @__PURE__ */ new Set();
8349
9419
  const goalToolNames = new Set(SESSION_GOAL_TOOL_NAMES);
8350
9420
  if (options.sessionGoals) {
8351
9421
  toolsets.push(
@@ -8393,9 +9463,10 @@ async function createAgentSession(prefs, detected, options = {}) {
8393
9463
  const nativeSearchAvailable = provider.capabilities?.supportsHostedWebSearch === true && !options.structuredOutput && (provider.supportsHostedWebSearchFor?.(
8394
9464
  model,
8395
9465
  options.web?.search === "cached" ? "cached" : "live"
8396
- ) ?? true) && prefs.providers.length === 1;
9466
+ ) ?? true) && prefs.providers.length === 1 && !options.routing;
8397
9467
  const webSearch = resolveWebSearch(options.web, nativeSearchAvailable);
8398
9468
  const nativeWebSearch = webSearch.mode !== "off" && webSearch.backend === "native" ? { mode: webSearch.mode } : void 0;
9469
+ const routedWebSearch = /* @__PURE__ */ __name((routed) => nativeWebSearch && routed.provider.capabilities?.supportsHostedWebSearch === true && (routed.provider.supportsHostedWebSearchFor?.(routed.model, nativeWebSearch.mode) ?? true) ? nativeWebSearch : void 0, "routedWebSearch");
8399
9470
  let webSearchTool;
8400
9471
  if (webSearch.mode !== "off" && webSearch.backend === "exa") {
8401
9472
  webSearchTool = createWebSearchTool();
@@ -8607,8 +9678,8 @@ async function createAgentSession(prefs, detected, options = {}) {
8607
9678
  });
8608
9679
  }, "listModels"),
8609
9680
  buildProvider: /* @__PURE__ */ __name(async (invokingSessionId, selection) => {
8610
- const providerId = selection ? selection.provider : primary.id;
8611
- const selectedModel = selection?.model ?? model;
9681
+ const providerId = selection ? selection.provider : turnRouteTarget?.provider ?? primary.id;
9682
+ const selectedModel = selection?.model ?? turnRouteTarget?.model ?? model;
8612
9683
  if (!invokingSessionId && (providerId === "zen" || providerId === "zen-go"))
8613
9684
  throw new Error("A delegated provider requires its invoking conversation.");
8614
9685
  await ensureRegistered(providerId);
@@ -8654,6 +9725,73 @@ async function createAgentSession(prefs, detected, options = {}) {
8654
9725
  new ToolManager({ toolsets: agentToolsets, messages: /* @__PURE__ */ __name(() => [], "messages") }).dispose();
8655
9726
  toolsets.push(...agentToolsets);
8656
9727
  allowedAgentIds = sub.allowedAgentIds;
9728
+ workflowHost = createWorkflowHost({
9729
+ subagents: sub,
9730
+ runsDirectory: /* @__PURE__ */ __name((turnId) => {
9731
+ if (options.ephemeral) return void 0;
9732
+ const owner = delegationScopes.get(turnId) ?? scope;
9733
+ return join13(paths.sessionDir({ sessionId: owner.sessionId }), "runs");
9734
+ }, "runsDirectory"),
9735
+ refusal: /* @__PURE__ */ __name((turnId) => {
9736
+ const auth = delegatedWorkflowAuth.get(turnId);
9737
+ if (!auth) return "This turn cannot start a workflow.";
9738
+ return workflowRefusal({ interactive: auth.interactive, mode: auth.mode() });
9739
+ }, "refusal"),
9740
+ openRunTurn: /* @__PURE__ */ __name((originTurnId, runId) => {
9741
+ const runTurnId = generateTurnId();
9742
+ const origin = delegatedWorkflowAuth.get(originTurnId);
9743
+ const ownerScope = delegationScopes.get(originTurnId) ?? { ...scope };
9744
+ const control = createLiveModeControl({
9745
+ initial: origin?.mode() ?? "prompt",
9746
+ ...origin ? { read: origin.mode } : {},
9747
+ handlerFor: /* @__PURE__ */ __name((mode) => makeResumeHandler(
9748
+ approval,
9749
+ origin?.reviewer?.onPermission,
9750
+ mode,
9751
+ reviewExemptionFor(mode, manager, (input) => sub.launchesReadOnlyAgent(input)),
9752
+ { unattendedSandboxEscape },
9753
+ screenPolicyFor(() => manager)
9754
+ ), "handlerFor")
9755
+ });
9756
+ liveModeControls.add(control);
9757
+ delegationScopes.set(runTurnId, ownerScope);
9758
+ delegationLimits.set(
9759
+ runTurnId,
9760
+ delegationLimits.get(originTurnId) ?? resolveTurnGuards(options.limits, void 0)
9761
+ );
9762
+ delegatedResumeHandlers.set(runTurnId, control.handler);
9763
+ delegatedReviewAllowedCalls.set(runTurnId, control.reviewAllowedCalls);
9764
+ const model2 = delegationModels.get(originTurnId);
9765
+ if (model2) delegationModels.set(runTurnId, model2);
9766
+ void runId;
9767
+ let released;
9768
+ return {
9769
+ turnId: runTurnId,
9770
+ release: /* @__PURE__ */ __name(() => {
9771
+ released ??= (async () => {
9772
+ liveModeControls.delete(control);
9773
+ delegationScopes.delete(runTurnId);
9774
+ delegationLimits.delete(runTurnId);
9775
+ delegatedResumeHandlers.delete(runTurnId);
9776
+ delegatedReviewAllowedCalls.delete(runTurnId);
9777
+ delegationModels.delete(runTurnId);
9778
+ await sub.releaseTurn(runTurnId);
9779
+ })();
9780
+ return released;
9781
+ }, "release")
9782
+ };
9783
+ }, "openRunTurn"),
9784
+ limitsFor: /* @__PURE__ */ __name((turnId) => {
9785
+ const budget = delegationLimits.get(turnId)?.tokenBudget;
9786
+ return {
9787
+ ...budget !== void 0 && budget > 0 ? { tokenBudget: budget } : {},
9788
+ ...options.workflow
9789
+ };
9790
+ }, "limitsFor"),
9791
+ onEnd: /* @__PURE__ */ __name((end) => {
9792
+ for (const listener of [...workflowEndListeners]) listener(end);
9793
+ }, "onEnd")
9794
+ });
8657
9795
  } catch (err) {
8658
9796
  try {
8659
9797
  await subagentRuntime?.close();
@@ -8723,7 +9861,9 @@ async function createAgentSession(prefs, detected, options = {}) {
8723
9861
  toolsets.push(toolset("extra", options.extraTools));
8724
9862
  }
8725
9863
  if (options.openUrl) toolsets.push(toolset("open-url", [createOpenUrlTool()]));
8726
- const operatorPals = await import("./operator-tools-LTPV3CH5.js");
9864
+ const decisionTool = maybeCreateDecisionTool(options.decision, process.env);
9865
+ if (decisionTool) toolsets.push(toolset("decide", [decisionTool]));
9866
+ const operatorPals = await import("./operator-tools-H4MYC5PE.js");
8727
9867
  toolsets.push(
8728
9868
  readyWhen(
8729
9869
  toolset(
@@ -8856,6 +9996,7 @@ async function createAgentSession(prefs, detected, options = {}) {
8856
9996
  const reasoningLookup = new AbortController();
8857
9997
  const operations = new SessionOperationOwner(async () => {
8858
9998
  reasoningLookup.abort();
9999
+ workflowHost?.registry.close();
8859
10000
  const results = await Promise.allSettled([
8860
10001
  Promise.resolve().then(() => manager.dispose()),
8861
10002
  options.conversationSessions ? releaseConversationEvidence(options.conversationSessions, scope.sessionId) : void 0,
@@ -8914,6 +10055,58 @@ async function createAgentSession(prefs, detected, options = {}) {
8914
10055
  ...effort ? { effort } : {}
8915
10056
  };
8916
10057
  }, "pinnedResumeRoute");
10058
+ const routingDecisionModel = options.routing ? maybeCreateDecisionModel(options.decision, process.env) : void 0;
10059
+ const autoRouteFor = /* @__PURE__ */ __name(async (messages, sessionId, signal) => {
10060
+ const routing = options.routing;
10061
+ if (!routing) return void 0;
10062
+ try {
10063
+ const routed = await routeModel(
10064
+ {
10065
+ task: lastUserText(messages),
10066
+ config: routing,
10067
+ features: {
10068
+ conversationLength: messages.length,
10069
+ // Mounted is not used: the tool is on in every interactive session,
10070
+ // so only a conversation that has driven the desktop keeps the small
10071
+ // tier out.
10072
+ usesComputerUse: options.enableComputerUse === true && conversationDrovePc(messages),
10073
+ usesPal: false
10074
+ },
10075
+ signal
10076
+ },
10077
+ {
10078
+ ...routingDecisionModel ? { model: routingDecisionModel } : {},
10079
+ isAvailable: /* @__PURE__ */ __name((target) => {
10080
+ const found = findDetected(detected, target.provider);
10081
+ if (!found) return false;
10082
+ return found.entry.constructible && canSelectModel(found.entry, found.apiKey, target.model);
10083
+ }, "isAvailable"),
10084
+ logger: cliLogger()
10085
+ }
10086
+ );
10087
+ lastAutoRoute = { tier: routed.tier, model: routed.model };
10088
+ if (routed.provider === primary.id && routed.model === model) {
10089
+ turnRouteTarget = void 0;
10090
+ return void 0;
10091
+ }
10092
+ const route = await pinnedResumeRoute(
10093
+ { provider: routed.provider, model: routed.model },
10094
+ sessionId,
10095
+ signal
10096
+ );
10097
+ turnRouteTarget = route ? { provider: routed.provider, model: route.model } : void 0;
10098
+ return route;
10099
+ } catch (err) {
10100
+ signal.throwIfAborted();
10101
+ turnRouteTarget = void 0;
10102
+ lastAutoRoute = void 0;
10103
+ cliLogger().warn(
10104
+ "auto model routing failed, using the session model",
10105
+ exceptionAttributes(err)
10106
+ );
10107
+ return void 0;
10108
+ }
10109
+ }, "autoRouteFor");
8917
10110
  const kernelResume = /* @__PURE__ */ __name(({
8918
10111
  entry: entry2,
8919
10112
  sessionLog,
@@ -8935,6 +10128,7 @@ async function createAgentSession(prefs, detected, options = {}) {
8935
10128
  const resumedLimits = await readStoredTurnGuards(sessionLog, entry2.turnId) ?? resolveTurnGuards(options.limits);
8936
10129
  await prepareProviderCredential(ownedSignal);
8937
10130
  const route = await pinnedResumeRoute(pinned, entry2.sessionId, ownedSignal);
10131
+ const resumeWebSearch = route ? routedWebSearch(route) : nativeWebSearch;
8938
10132
  const turnSkills = await turnSkillsFor(route?.model ?? model);
8939
10133
  const curatedMemory = readMemory(void 0, cwd);
8940
10134
  for (const notice of formatMemoryDiagnostics(curatedMemory)) cliLogger().warn(notice);
@@ -9054,7 +10248,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9054
10248
  turnConfig: {
9055
10249
  model: route?.model ?? model,
9056
10250
  ...route?.effort ? { effort: route.effort } : {},
9057
- ...nativeWebSearch ? { webSearch: nativeWebSearch } : {},
10251
+ ...resumeWebSearch ? { webSearch: resumeWebSearch } : {},
9058
10252
  ...sandbox.provider ? { sandbox: { workspace: sandboxWorkspace } } : {},
9059
10253
  ...resumedLimits,
9060
10254
  maxResponseTokens: 8192,
@@ -9201,6 +10395,9 @@ async function createAgentSession(prefs, detected, options = {}) {
9201
10395
  },
9202
10396
  providerSummary: entry.label,
9203
10397
  modelSummary: model,
10398
+ get autoRoute() {
10399
+ return lastAutoRoute;
10400
+ },
9204
10401
  get imageAttachmentsSupported() {
9205
10402
  return providerForSession(scope.sessionId).capabilities?.supportsVision;
9206
10403
  },
@@ -9272,6 +10469,32 @@ async function createAgentSession(prefs, detected, options = {}) {
9272
10469
  if (job.owner === jobOwner) listener(job);
9273
10470
  }) ?? (() => {
9274
10471
  }), "onJobExit"),
10472
+ ...workflowHost ? {
10473
+ workflows: /* @__PURE__ */ ((host) => ({
10474
+ runs: /* @__PURE__ */ __name(() => host.registry.list(), "runs"),
10475
+ subscribe: /* @__PURE__ */ __name((listener) => host.registry.subscribe(listener), "subscribe"),
10476
+ stop: /* @__PURE__ */ __name((runId) => host.registry.stop(runId), "stop"),
10477
+ skipAgent: /* @__PURE__ */ __name((runId, index) => host.registry.skipAgent(runId, index), "skipAgent"),
10478
+ agentOf: /* @__PURE__ */ __name((viewId) => host.registry.agentOf(viewId), "agentOf"),
10479
+ history: /* @__PURE__ */ __name(async () => {
10480
+ const live = host.registry.list();
10481
+ const known = new Set(live.map((view) => view.runId));
10482
+ const saved = options.ephemeral ? [] : await listWorkflowRuns(
10483
+ join13(paths.sessionDir({ sessionId: scope.sessionId }), "runs")
10484
+ ).catch(() => []);
10485
+ return [
10486
+ ...[...live].sort((a, b) => b.startedAt - a.startedAt),
10487
+ ...saved.filter((view) => !known.has(view.runId))
10488
+ ];
10489
+ }, "history"),
10490
+ onEnd: /* @__PURE__ */ __name((listener) => {
10491
+ workflowEndListeners.add(listener);
10492
+ return () => workflowEndListeners.delete(listener);
10493
+ }, "onEnd"),
10494
+ idle: /* @__PURE__ */ __name((signal) => host.registry.whenIdle(signal), "idle"),
10495
+ reset: /* @__PURE__ */ __name(() => host.registry.reset(), "reset")
10496
+ }))(workflowHost)
10497
+ } : {},
9275
10498
  ...subagentRuntime ? {
9276
10499
  subagents: subagentRuntime.activity,
9277
10500
  onSubagentReport: /* @__PURE__ */ __name((listener) => {
@@ -9280,6 +10503,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9280
10503
  directChildReports.delete(listener);
9281
10504
  };
9282
10505
  }, "onSubagentReport"),
10506
+ stopSubagent: /* @__PURE__ */ __name((viewId) => subagentRuntime?.stopChild(viewId) ?? false, "stopSubagent"),
9283
10507
  messageSubagent: /* @__PURE__ */ __name((viewId, message2, opts) => operations.promise(opts?.signal, async (signal) => {
9284
10508
  const runtime = subagentRuntime;
9285
10509
  if (!runtime) throw new Error("Delegation is unavailable.");
@@ -9420,6 +10644,8 @@ async function createAgentSession(prefs, detected, options = {}) {
9420
10644
  mcpStatus: /* @__PURE__ */ __name(() => mcp.current(), "mcpStatus"),
9421
10645
  ...browserControl ? { browser: browserControl } : {},
9422
10646
  configNotices: [
10647
+ // Git for Windows is missing and the shell tool runs cmd.exe: said once, here.
10648
+ ...sandbox.provider === void 0 && windowsShellNotice() !== void 0 ? [windowsShellNotice()] : [],
9423
10649
  ...capabilityNotice ? [capabilityNotice] : [],
9424
10650
  ...effortNotice ? [effortNotice] : [],
9425
10651
  ...passthroughNotice ? [passthroughNotice] : [],
@@ -9528,6 +10754,11 @@ async function createAgentSession(prefs, detected, options = {}) {
9528
10754
  if (opts?.waitForInbound) delegatedInputWaiters.set(turnId2, opts.waitForInbound);
9529
10755
  delegationScopes.set(turnId2, turnScope);
9530
10756
  delegationLimits.set(turnId2, turnLimits);
10757
+ delegatedWorkflowAuth.set(turnId2, {
10758
+ interactive: opts?.workflowReview?.onPermission !== void 0,
10759
+ mode: /* @__PURE__ */ __name(() => modeControl.current(), "mode"),
10760
+ reviewer: opts?.workflowReview
10761
+ });
9531
10762
  if (capturedAuthority) {
9532
10763
  if (goalAuthorities.has(turnId2)) {
9533
10764
  throw new Error(`Turn ${turnId2} already owns goal-round authority.`);
@@ -9537,7 +10768,9 @@ async function createAgentSession(prefs, detected, options = {}) {
9537
10768
  }, "claimTurn");
9538
10769
  try {
9539
10770
  await prepareProviderCredential(signal);
9540
- const turnSkills = await turnSkillsFor(model);
10771
+ const autoRoute = await autoRouteFor(messages, turnScope.sessionId, signal);
10772
+ const turnWebSearch = autoRoute ? routedWebSearch(autoRoute) : nativeWebSearch;
10773
+ const turnSkills = await turnSkillsFor(autoRoute?.model ?? model);
9541
10774
  const curatedMemory = readMemory(void 0, cwd);
9542
10775
  for (const notice of formatMemoryDiagnostics(curatedMemory)) {
9543
10776
  yield { kind: "context", text: notice, shed: false };
@@ -9640,6 +10873,19 @@ async function createAgentSession(prefs, detected, options = {}) {
9640
10873
  render: /* @__PURE__ */ __name(() => invocationContext, "render")
9641
10874
  });
9642
10875
  }
10876
+ const workflowOffer = workflowHost !== void 0 && opts?.workflowReview !== void 0 && !residentContext && workflowOffered({
10877
+ hypermode: opts?.hypermode === true,
10878
+ userText: lastUserText(messages)
10879
+ });
10880
+ if (workflowOffer && workflowHost) {
10881
+ runToolsets = [...runToolsets, toolset("workflow", [workflowHost.tool])];
10882
+ if (runManager !== manager) runManager.dispose();
10883
+ runManager = new ToolManager({
10884
+ toolsets: runToolsets,
10885
+ ...screensConfig !== void 0 ? { resultGuardrails: screensConfig } : {},
10886
+ messages: /* @__PURE__ */ __name(() => [], "messages")
10887
+ });
10888
+ }
9643
10889
  const systemPrompt = [
9644
10890
  NAMZU_IDENTITY,
9645
10891
  residentContext ? void 0 : CODING_AGENT_WORKING_DOCTRINE,
@@ -9649,6 +10895,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9649
10895
  // to use a tool it was not sent.
9650
10896
  residentContext || options.withheldTools?.includes(AGENT_LAUNCH_TOOL) ? void 0 : CODING_AGENT_DELEGATION_DOCTRINE,
9651
10897
  !residentContext && opts?.hypermode ? CODING_AGENT_HYPERMODE_DOCTRINE : void 0,
10898
+ workflowOffer ? WORKFLOW_DOCTRINE : void 0,
9652
10899
  residentContext ? void 0 : palPromptBlock(),
9653
10900
  options.conversationSessions ? CONVERSATION_EVIDENCE_GUIDANCE : void 0,
9654
10901
  options.toolLoading === "deferred" ? DEFERRED_TOOL_GUIDANCE : void 0,
@@ -9700,7 +10947,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9700
10947
  }
9701
10948
  try {
9702
10949
  for await (const event of runTurn({
9703
- provider: providerForSession(turnScope.sessionId),
10950
+ provider: autoRoute?.provider ?? providerForSession(turnScope.sessionId),
9704
10951
  fileReadTracker: await observationsFor(turnScope.sessionId, messages),
9705
10952
  compactionConfig: compactionConfigFor(options.compaction),
9706
10953
  retainedToolPreviewChars: options.conversationSessions ? options.compaction?.retainedToolPreviewChars ?? 4e3 : void 0,
@@ -9716,8 +10963,9 @@ async function createAgentSession(prefs, detected, options = {}) {
9716
10963
  // that expired hours ago — and a chain whose own members are stale
9717
10964
  // is a fallback that fails for the reason the fallback exists to
9718
10965
  // survive. Building a driver is a client object, not a request.
9719
- fallbackProviders: fallbackPlan.build(currentToken, turnScope.sessionId),
9720
- model,
10966
+ // A routed turn has no fallback chain, like a pinned resume.
10967
+ fallbackProviders: autoRoute ? [] : fallbackPlan.build(currentToken, turnScope.sessionId),
10968
+ model: autoRoute?.model ?? model,
9721
10969
  toolsets: runToolsets,
9722
10970
  ...screensConfig !== void 0 ? { toolResultGuardrails: screensConfig } : {},
9723
10971
  pluginManager: pluginRuntime?.manager,
@@ -9769,7 +11017,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9769
11017
  completionInbox: await subagentRuntime?.completionInboxForTurn(turnId),
9770
11018
  promptContributions,
9771
11019
  ...webCapability ? { web: webCapability } : {},
9772
- ...nativeWebSearch ? { webSearch: nativeWebSearch } : {},
11020
+ ...turnWebSearch ? { webSearch: turnWebSearch } : {},
9773
11021
  // Tasks join this turn's registry inside query, after the fork.
9774
11022
  // Keep the existing eager path unless deferral was requested.
9775
11023
  runtimeToolOverrides: {
@@ -9815,6 +11063,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9815
11063
  delegatedInputWaiters.delete(turnId2);
9816
11064
  delegationScopes.delete(turnId2);
9817
11065
  delegationLimits.delete(turnId2);
11066
+ delegatedWorkflowAuth.delete(turnId2);
9818
11067
  await subagentRuntime?.releaseTurn(turnId2);
9819
11068
  }
9820
11069
  }
@@ -10153,6 +11402,16 @@ async function listProviderModels(id, det) {
10153
11402
  return listing.kind === "ok" ? [...listing.models] : [];
10154
11403
  }
10155
11404
  __name(listProviderModels, "listProviderModels");
11405
+ var DESKTOP_USE_LOOKBACK = 20;
11406
+ function conversationDrovePc(messages) {
11407
+ for (let i = messages.length - 1; i >= 0 && i >= messages.length - DESKTOP_USE_LOOKBACK; i--) {
11408
+ const m = messages[i];
11409
+ if (m?.role === "assistant" && m.toolCalls?.some((call) => call.function.name === COMPUTER_USE_TOOL_NAME))
11410
+ return true;
11411
+ }
11412
+ return false;
11413
+ }
11414
+ __name(conversationDrovePc, "conversationDrovePc");
10156
11415
  function lastUserText(messages) {
10157
11416
  for (let i = messages.length - 1; i >= 0; i--) {
10158
11417
  const m = messages[i];
@@ -10485,9 +11744,9 @@ function confirmsItself(name, input) {
10485
11744
  }
10486
11745
  __name(confirmsItself, "confirmsItself");
10487
11746
  function declaredReadOnly(manager) {
10488
- return (toolName, input) => {
11747
+ return (toolName2, input) => {
10489
11748
  try {
10490
- return manager.get(toolName)?.isReadOnly?.(input) === true;
11749
+ return manager.get(toolName2)?.isReadOnly?.(input) === true;
10491
11750
  } catch {
10492
11751
  return false;
10493
11752
  }
@@ -10558,6 +11817,10 @@ function toAgentEvent(event, presenter, readsOnly) {
10558
11817
  if (view.kind === "diff") rememberCallDiff(event.toolUseId, view);
10559
11818
  return {
10560
11819
  summary: viewToSummary(view),
11820
+ ...(() => {
11821
+ const command = view.kind === "terminal" ? view.command : view.kind === "generic" && view.facts?.kind === "command" ? view.facts.command : void 0;
11822
+ return command ? { command } : {};
11823
+ })(),
10561
11824
  ...view.kind === "generic" && view.activity ? { activity: view.activity } : {},
10562
11825
  detail: viewToLines(view),
10563
11826
  ...view.kind === "generic" && view.presentation === "activity" ? { standalone: true } : {}
@@ -10626,6 +11889,7 @@ function toAgentEvent(event, presenter, readsOnly) {
10626
11889
  summary: headline ?? summary,
10627
11890
  ...headline ? { headline } : {},
10628
11891
  ...plainFailure ? { plainFailure } : {},
11892
+ ...tidy?.shell ? { shell: tidy.shell } : {},
10629
11893
  ...event.durationMs !== void 0 ? { durationMs: event.durationMs } : {},
10630
11894
  ...view.kind === "generic" && view.visibility === "hidden" ? { hidden: true } : {},
10631
11895
  ...event.isError && view.kind === "generic" && view.outcome === "cancelled" ? { cancelled: true } : {},
@@ -10844,29 +12108,29 @@ __name(takeCallDiff, "takeCallDiff");
10844
12108
  function viewToSummary(view) {
10845
12109
  switch (view.kind) {
10846
12110
  case "generic":
10847
- return truncate(view.label, 120);
12111
+ return truncate2(view.label, 120);
10848
12112
  case "diff":
10849
- return truncate(view.label ?? view.path ?? view.after.split("\n")[0] ?? "", 120);
12113
+ return truncate2(view.label ?? view.path ?? view.after.split("\n")[0] ?? "", 120);
10850
12114
  case "terminal":
10851
- return truncate(view.command ?? view.output.split("\n")[0] ?? "", 120);
12115
+ return truncate2(view.command ?? view.output.split("\n")[0] ?? "", 120);
10852
12116
  }
10853
12117
  }
10854
12118
  __name(viewToSummary, "viewToSummary");
10855
12119
  var RESULT_SUMMARY_WHOLE_MAX = 300;
10856
12120
  function resultSummaryLine(line) {
10857
12121
  const flat = line.replace(/\s+/g, " ");
10858
- return flat.length <= RESULT_SUMMARY_WHOLE_MAX ? flat : truncate(line, 120);
12122
+ return flat.length <= RESULT_SUMMARY_WHOLE_MAX ? flat : truncate2(line, 120);
10859
12123
  }
10860
12124
  __name(resultSummaryLine, "resultSummaryLine");
10861
12125
  function summarySaysAll(line, summary) {
10862
12126
  return line === summary || line.replace(/\s+/g, " ") === summary;
10863
12127
  }
10864
12128
  __name(summarySaysAll, "summarySaysAll");
10865
- function truncate(value, max) {
12129
+ function truncate2(value, max) {
10866
12130
  const oneLine3 = value.replace(/\s+/g, " ");
10867
12131
  return oneLine3.length > max ? `${oneLine3.slice(0, max - 1)}\u2026` : oneLine3;
10868
12132
  }
10869
- __name(truncate, "truncate");
12133
+ __name(truncate2, "truncate");
10870
12134
  function diffContentLines(value) {
10871
12135
  if (value === "") return [];
10872
12136
  const lines = value.split("\n");
@@ -10913,16 +12177,16 @@ __name(resultToLines, "resultToLines");
10913
12177
  function firstLine3(result) {
10914
12178
  const payload = payloadString(result);
10915
12179
  if (payload !== null) {
10916
- return truncate(payload.split("\n").find((l) => l.trim().length > 0) ?? "", 120);
12180
+ return truncate2(payload.split("\n").find((l) => l.trim().length > 0) ?? "", 120);
10917
12181
  }
10918
12182
  const obj = parseJsonObject(result);
10919
12183
  if (obj) {
10920
- if (obj.success === false && typeof obj.error === "string") return truncate(obj.error, 120);
12184
+ if (obj.success === false && typeof obj.error === "string") return truncate2(obj.error, 120);
10921
12185
  const keys = Object.keys(obj);
10922
12186
  return keys.length > 0 ? `{ ${keys.slice(0, 6).join(", ")}${keys.length > 6 ? ", \u2026" : ""} }` : "{}";
10923
12187
  }
10924
12188
  const cleaned = cleanToolText(result.trim());
10925
- return truncate(cleaned.split("\n").find((l) => l.trim().length > 0) ?? "", 120);
12189
+ return truncate2(cleaned.split("\n").find((l) => l.trim().length > 0) ?? "", 120);
10926
12190
  }
10927
12191
  __name(firstLine3, "firstLine");
10928
12192
  function exceptionAttributes(err) {
@@ -11053,6 +12317,8 @@ export {
11053
12317
  renderRestoreNote,
11054
12318
  PluginSettingsStore,
11055
12319
  validateComposerSendSettings,
12320
+ maybeCreateDecisionTool,
12321
+ resolveAutoDefault,
11056
12322
  createCurrentCredentialReader,
11057
12323
  createTaskContextStep,
11058
12324
  createLiveModeControl,
@@ -11094,6 +12360,7 @@ export {
11094
12360
  computerUseHasControl,
11095
12361
  isCredentialRejection,
11096
12362
  listProviderModels,
12363
+ conversationDrovePc,
11097
12364
  makeResumeHandler,
11098
12365
  makeHoldingResumeHandler,
11099
12366
  isPromptExempt,
@@ -11108,4 +12375,4 @@ export {
11108
12375
  RESULT_SUMMARY_WHOLE_MAX,
11109
12376
  resultSummaryLine
11110
12377
  };
11111
- //# sourceMappingURL=chunk-TJJUB7VQ.js.map
12378
+ //# sourceMappingURL=chunk-SFUUN6B3.js.map