@namzu/cli 36.2.0 → 36.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/chunks/{acp-P22WRX3A.js → acp-CJ2TTGJD.js} +58 -34
  4. package/dist/chunks/acp-CJ2TTGJD.js.map +6 -0
  5. package/dist/chunks/{activity-command-OK463NV4.js → activity-command-MCYEK4Z4.js} +10 -10
  6. package/dist/chunks/{add-ML53TFN2.js → add-ZQ3YWP4F.js} +16 -16
  7. package/dist/chunks/{agent-3ST7Q6HZ.js → agent-UO62HZPI.js} +22 -22
  8. package/dist/chunks/agent-session-DU55LD4P.js +46 -0
  9. package/dist/chunks/{archive-WV2NBOHR.js → archive-VPREZOGC.js} +8 -8
  10. package/dist/chunks/{bin-main-FPJQMK33.js → bin-main-J5ULRXXN.js} +3 -3
  11. package/dist/chunks/{browser-JRWZ3PYX.js → browser-FZWYOIIJ.js} +6 -6
  12. package/dist/chunks/{chat-3IJFKDSN.js → chat-BGWKKQTT.js} +13 -13
  13. package/dist/chunks/{chunk-S7E42272.js → chunk-2BZOT2CT.js} +2 -2
  14. package/dist/chunks/{chunk-LIZPXS73.js → chunk-3F5DGROG.js} +2 -2
  15. package/dist/chunks/{chunk-KNNQHRZ4.js → chunk-46B7KRXY.js} +6 -6
  16. package/dist/chunks/{chunk-PT7TZNBV.js → chunk-52OVP5BG.js} +4 -4
  17. package/dist/chunks/{chunk-X2YRM3UE.js → chunk-56OUKG5W.js} +3 -3
  18. package/dist/chunks/{chunk-HJ42RG5U.js → chunk-5URT3ZM2.js} +4 -4
  19. package/dist/chunks/{chunk-GWOW3U2S.js → chunk-6TDJXZ5W.js} +4 -4
  20. package/dist/chunks/chunk-74KMYYM2.js +755 -0
  21. package/dist/chunks/chunk-74KMYYM2.js.map +6 -0
  22. package/dist/chunks/{chunk-43FBWINL.js → chunk-AEPAIDAA.js} +5 -5
  23. package/dist/chunks/{chunk-7WQV2FSF.js → chunk-AHYHR5DY.js} +3 -3
  24. package/dist/chunks/{chunk-XAKL7C7B.js → chunk-AP5KD43Y.js} +2 -2
  25. package/dist/chunks/{chunk-NRML7BIR.js → chunk-AS7UWXMN.js} +4 -4
  26. package/dist/chunks/{chunk-QQLB573I.js → chunk-BOV53LZO.js} +2 -2
  27. package/dist/chunks/{chunk-GPBUDMUF.js → chunk-BUCICQWG.js} +2 -2
  28. package/dist/chunks/{chunk-OS7IVIYH.js → chunk-CXSUA2PF.js} +242 -3
  29. package/dist/chunks/{chunk-OS7IVIYH.js.map → chunk-CXSUA2PF.js.map} +3 -3
  30. package/dist/chunks/{chunk-5PQVJBIO.js → chunk-CZVHXYGD.js} +6 -3
  31. package/dist/chunks/{chunk-5PQVJBIO.js.map → chunk-CZVHXYGD.js.map} +1 -1
  32. package/dist/chunks/{chunk-CFN7CUD3.js → chunk-DYUOXP5Q.js} +13 -13
  33. package/dist/chunks/{chunk-G5XTLTDR.js → chunk-E7HLYLD7.js} +3 -3
  34. package/dist/chunks/{chunk-ABD2DOO2.js → chunk-EKUJUPFA.js} +4 -4
  35. package/dist/chunks/{chunk-AABPCENY.js → chunk-F3YQ2CSZ.js} +4 -4
  36. package/dist/chunks/{chunk-2VXA7GZU.js → chunk-FU4GQ7K2.js} +2 -2
  37. package/dist/chunks/{chunk-VHKKPDL2.js → chunk-GQN64E36.js} +3 -3
  38. package/dist/chunks/{chunk-AL6ESCHD.js → chunk-GSHSAMZJ.js} +12 -12
  39. package/dist/chunks/{chunk-H7VJHF5S.js → chunk-H6MWKPHM.js} +1030 -264
  40. package/dist/chunks/chunk-H6MWKPHM.js.map +6 -0
  41. package/dist/chunks/{chunk-3OZ2OBGU.js → chunk-HKDPP2JF.js} +2 -2
  42. package/dist/chunks/{chunk-YZ675PG4.js → chunk-HSEJGSXE.js} +2 -2
  43. package/dist/chunks/{chunk-ZXWJ6G3J.js → chunk-I6CDUPVR.js} +2 -2
  44. package/dist/chunks/{chunk-27VZRJTG.js → chunk-IQBR45AU.js} +2 -2
  45. package/dist/chunks/{chunk-HIZ7F6BT.js → chunk-JCDTR2ZU.js} +4 -4
  46. package/dist/chunks/{chunk-53EZXXT4.js → chunk-KHF4IAIH.js} +27 -9
  47. package/dist/chunks/chunk-KHF4IAIH.js.map +6 -0
  48. package/dist/chunks/{chunk-ZNAH4EGP.js → chunk-KMHLON54.js} +2 -2
  49. package/dist/chunks/{chunk-CXLSM5SH.js → chunk-KOG2WB66.js} +4 -4
  50. package/dist/chunks/{chunk-AGHVC2IJ.js → chunk-LBH5WVXU.js} +2 -2
  51. package/dist/chunks/{chunk-NKEOCU52.js → chunk-LNQ6SCBF.js} +7 -7
  52. package/dist/chunks/{chunk-22P25PLK.js → chunk-LYDXPWAZ.js} +22 -4
  53. package/dist/chunks/{chunk-22P25PLK.js.map → chunk-LYDXPWAZ.js.map} +1 -1
  54. package/dist/chunks/{chunk-YEFJAE2B.js → chunk-M32YRERZ.js} +27 -26
  55. package/dist/chunks/{chunk-YEFJAE2B.js.map → chunk-M32YRERZ.js.map} +1 -1
  56. package/dist/chunks/{chunk-U5AWHJ7O.js → chunk-MBBFX64S.js} +2 -2
  57. package/dist/chunks/{chunk-PJ3UYK2K.js → chunk-MJO6CH5F.js} +3 -3
  58. package/dist/chunks/{chunk-AVIW5JJF.js → chunk-NATYSTPM.js} +2 -2
  59. package/dist/chunks/{chunk-KQOIPRZ5.js → chunk-QRT3N2K3.js} +2 -2
  60. package/dist/chunks/{chunk-DYBUCWAB.js → chunk-QXDKRJZ5.js} +3 -3
  61. package/dist/chunks/{chunk-EOO5AKO4.js → chunk-RBX6RVYO.js} +6 -6
  62. package/dist/chunks/{chunk-VSUHR44P.js → chunk-RM6HTBJK.js} +2 -2
  63. package/dist/chunks/{chunk-YLIKDPD6.js → chunk-S6DK2YOB.js} +9 -9
  64. package/dist/chunks/{chunk-WW4VKEBD.js → chunk-S6MZK4LD.js} +2 -2
  65. package/dist/chunks/{chunk-ZZ6Z2DO6.js → chunk-UFTNEQFN.js} +10 -10
  66. package/dist/chunks/{chunk-7OEK2NAO.js → chunk-UXGI3FE5.js} +8 -8
  67. package/dist/chunks/{chunk-ZKTLXAQK.js → chunk-V3ZLK3XQ.js} +3243 -1041
  68. package/dist/chunks/chunk-V3ZLK3XQ.js.map +6 -0
  69. package/dist/chunks/{chunk-WNMRETWS.js → chunk-VUOS5SQ3.js} +2 -2
  70. package/dist/chunks/{chunk-YTJO7G24.js → chunk-XCWZZZOW.js} +3 -3
  71. package/dist/chunks/{chunk-RPAHIOW6.js → chunk-YYQFUKI7.js} +3 -3
  72. package/dist/chunks/{chunk-5GARJ3CK.js → chunk-YYVDLVUM.js} +2 -2
  73. package/dist/chunks/{chunk-HQZSTYKY.js → chunk-ZB5ETOVE.js} +3 -3
  74. package/dist/chunks/{chunk-GFSD2D3M.js → chunk-ZG6NVROB.js} +2 -2
  75. package/dist/chunks/{chunk-MBGQS5YA.js → chunk-ZHBHRMCI.js} +4 -4
  76. package/dist/chunks/{cli-runtime-CQKITOHY.js → cli-runtime-NG23IVRM.js} +8 -8
  77. package/dist/chunks/{commands-UEPVSG33.js → commands-LQISMOPF.js} +5 -5
  78. package/dist/chunks/{crash-report-3GQ3SJML.js → crash-report-EYK56MJJ.js} +6 -6
  79. package/dist/chunks/{dist-YDFJ4YOH.js → dist-3AMBKAG4.js} +2 -2
  80. package/dist/chunks/{dist-SCEJQJFY.js → dist-AUDNCB3F.js} +2 -2
  81. package/dist/chunks/{dist-FFMNE5LK.js → dist-AZJ56DQJ.js} +2 -2
  82. package/dist/chunks/{dist-IPJVDPA3.js → dist-DWB5AYXB.js} +2 -2
  83. package/dist/chunks/{dist-VJ2UQYSX.js → dist-EDKLCZY4.js} +2 -2
  84. package/dist/chunks/{dist-Q37IZHCW.js → dist-PZXF5NU3.js} +2 -2
  85. package/dist/chunks/{dist-AMYVT2VT.js → dist-XT4V74YL.js} +2 -2
  86. package/dist/chunks/{doctor-YWK25HGQ.js → doctor-3EOUWDYB.js} +6 -6
  87. package/dist/chunks/{drain-5R73B66Y.js → drain-VKGTCFXC.js} +10 -10
  88. package/dist/chunks/{eval-GYPUHRIK.js → eval-VHWEJ4GG.js} +2 -2
  89. package/dist/chunks/{exec-AHAC6YBQ.js → exec-TBNI5CDH.js} +149 -41
  90. package/dist/chunks/exec-TBNI5CDH.js.map +6 -0
  91. package/dist/chunks/{home-GI6TRZAN.js → home-H4GTIYO5.js} +3 -3
  92. package/dist/chunks/{host-queries-MN57UTDU.js → host-queries-AIZVYFDQ.js} +13 -13
  93. package/dist/chunks/{lifecycle-7LD634AQ.js → lifecycle-UF7VDCOQ.js} +23 -23
  94. package/dist/chunks/{list-DSHTQRTP.js → list-JJZ7I5OF.js} +12 -12
  95. package/dist/chunks/{login-R5P2OAXZ.js → login-T2RKNHK2.js} +8 -8
  96. package/dist/chunks/{logs-SGPSXLBY.js → logs-J6D4SEDY.js} +4 -4
  97. package/dist/chunks/{mcp-MC6B34XH.js → mcp-WONRVJ26.js} +15 -15
  98. package/dist/chunks/{message-command-4MV2SVHP.js → message-command-BGQB2TFW.js} +29 -29
  99. package/dist/chunks/{operator-tools-GI63VOXH.js → operator-tools-H4MYC5PE.js} +11 -11
  100. package/dist/chunks/{output-schema-74VSN66J.js → output-schema-RFJUTQ2N.js} +3 -3
  101. package/dist/chunks/{pal-BWPYGQ4B.js → pal-AV7AD5MG.js} +11 -11
  102. package/dist/chunks/{providers-YV45XVWS.js → providers-BHF65IUG.js} +6 -6
  103. package/dist/chunks/{resident-OC2D5V5I.js → resident-YF3MIILM.js} +18 -18
  104. package/dist/chunks/{resume-command-DZBKOABY.js → resume-command-Y3NYDSI4.js} +4 -4
  105. package/dist/chunks/{schedule-GUD625PJ.js → schedule-6T2MNPKK.js} +8 -8
  106. package/dist/chunks/{service-67FZ3N75.js → service-2VASPD2V.js} +22 -22
  107. package/dist/chunks/session-step-LJ24HVLF.js +26 -0
  108. package/dist/chunks/{skills-DNNEKEOH.js → skills-K3JRZ3IR.js} +8 -8
  109. package/dist/chunks/{state-K7MMFNZC.js → state-QPSQI7U7.js} +2 -2
  110. package/dist/chunks/{store-2PDDGKYZ.js → store-7WZWQXKX.js} +6 -6
  111. package/dist/chunks/{store-NIBJFQOT.js → store-PSQKDEPY.js} +8 -8
  112. package/dist/chunks/{store-KYMOKW6X.js → store-Z3PS6LUZ.js} +4 -4
  113. package/dist/chunks/{tui-UY3ZLTMX.js → tui-GNG3YLGE.js} +2536 -1325
  114. package/dist/chunks/tui-GNG3YLGE.js.map +6 -0
  115. package/dist/chunks/{upgrade-2NO7NPPM.js → upgrade-C6QUXRLB.js} +3 -3
  116. package/dist/chunks/{worktree-ADQJ4AJ5.js → worktree-KLD2PAMU.js} +10 -10
  117. package/dist/cli.d.ts.map +1 -1
  118. package/dist/commands/acp-harness.d.ts.map +1 -1
  119. package/dist/commands/desktop-host-pr.d.ts +14 -0
  120. package/dist/commands/desktop-host-pr.d.ts.map +1 -0
  121. package/dist/commands/desktop-host.d.ts +3 -0
  122. package/dist/commands/desktop-host.d.ts.map +1 -1
  123. package/dist/commands/exec-json.d.ts.map +1 -1
  124. package/dist/commands/exec-workflows.d.ts +50 -0
  125. package/dist/commands/exec-workflows.d.ts.map +1 -0
  126. package/dist/commands/exec.d.ts.map +1 -1
  127. package/dist/config/load.d.ts.map +1 -1
  128. package/dist/config/schema.d.ts +13 -0
  129. package/dist/config/schema.d.ts.map +1 -1
  130. package/dist/index.js +9 -9
  131. package/dist/integrations/resident/runner-worker.js +16 -16
  132. package/dist/integrations/subagents/activity.d.ts +19 -0
  133. package/dist/integrations/subagents/activity.d.ts.map +1 -1
  134. package/dist/integrations/subagents/runtime.d.ts +52 -0
  135. package/dist/integrations/subagents/runtime.d.ts.map +1 -1
  136. package/dist/integrations/workflows/doctrine.d.ts +7 -0
  137. package/dist/integrations/workflows/doctrine.d.ts.map +1 -0
  138. package/dist/integrations/workflows/history.d.ts +13 -0
  139. package/dist/integrations/workflows/history.d.ts.map +1 -0
  140. package/dist/integrations/workflows/host.d.ts +59 -0
  141. package/dist/integrations/workflows/host.d.ts.map +1 -0
  142. package/dist/integrations/workflows/notice.d.ts +21 -0
  143. package/dist/integrations/workflows/notice.d.ts.map +1 -0
  144. package/dist/integrations/workflows/offering.d.ts +40 -0
  145. package/dist/integrations/workflows/offering.d.ts.map +1 -0
  146. package/dist/integrations/workflows/registry.d.ts +85 -0
  147. package/dist/integrations/workflows/registry.d.ts.map +1 -0
  148. package/dist/integrations/workflows/view.d.ts +97 -0
  149. package/dist/integrations/workflows/view.d.ts.map +1 -0
  150. package/dist/tui/AgentExplorer.d.ts +179 -32
  151. package/dist/tui/AgentExplorer.d.ts.map +1 -1
  152. package/dist/tui/App.d.ts.map +1 -1
  153. package/dist/tui/BackgroundJobsPanel.d.ts.map +1 -1
  154. package/dist/tui/BrandHeader.d.ts +3 -1
  155. package/dist/tui/BrandHeader.d.ts.map +1 -1
  156. package/dist/tui/Composer.d.ts +23 -1
  157. package/dist/tui/Composer.d.ts.map +1 -1
  158. package/dist/tui/ComposerFrame.d.ts +10 -3
  159. package/dist/tui/ComposerFrame.d.ts.map +1 -1
  160. package/dist/tui/LiveActivity.d.ts +4 -0
  161. package/dist/tui/LiveActivity.d.ts.map +1 -1
  162. package/dist/tui/PendingInputPanel.d.ts +14 -11
  163. package/dist/tui/PendingInputPanel.d.ts.map +1 -1
  164. package/dist/tui/PermissionOverlay.d.ts.map +1 -1
  165. package/dist/tui/StatusBar.d.ts +61 -36
  166. package/dist/tui/StatusBar.d.ts.map +1 -1
  167. package/dist/tui/Transcript.d.ts +14 -0
  168. package/dist/tui/Transcript.d.ts.map +1 -1
  169. package/dist/tui/agent-transcript-rows.d.ts +34 -12
  170. package/dist/tui/agent-transcript-rows.d.ts.map +1 -1
  171. package/dist/tui/agent.d.ts +49 -1
  172. package/dist/tui/agent.d.ts.map +1 -1
  173. package/dist/tui/job-exit-row.d.ts +19 -0
  174. package/dist/tui/job-exit-row.d.ts.map +1 -0
  175. package/dist/tui/permission-review.d.ts +26 -0
  176. package/dist/tui/permission-review.d.ts.map +1 -1
  177. package/dist/tui/pr-status.d.ts +112 -0
  178. package/dist/tui/pr-status.d.ts.map +1 -0
  179. package/dist/tui/shell-cell.d.ts +86 -0
  180. package/dist/tui/shell-cell.d.ts.map +1 -0
  181. package/dist/tui/shorten-path.d.ts +10 -0
  182. package/dist/tui/shorten-path.d.ts.map +1 -0
  183. package/dist/tui/slashCommands.d.ts +4 -0
  184. package/dist/tui/slashCommands.d.ts.map +1 -1
  185. package/dist/tui/theme.d.ts +6 -0
  186. package/dist/tui/theme.d.ts.map +1 -1
  187. package/dist/tui/tidy-tool-output.d.ts +5 -0
  188. package/dist/tui/tidy-tool-output.d.ts.map +1 -1
  189. package/dist/tui/types.d.ts +10 -1
  190. package/dist/tui/types.d.ts.map +1 -1
  191. package/dist/tui/use-pr-status.d.ts +15 -0
  192. package/dist/tui/use-pr-status.d.ts.map +1 -0
  193. package/dist/tui/workflow-runs.d.ts +42 -0
  194. package/dist/tui/workflow-runs.d.ts.map +1 -0
  195. package/package.json +7 -7
  196. package/dist/chunks/acp-P22WRX3A.js.map +0 -6
  197. package/dist/chunks/agent-session-C2HDOXK4.js +0 -46
  198. package/dist/chunks/chunk-53EZXXT4.js.map +0 -6
  199. package/dist/chunks/chunk-H7VJHF5S.js.map +0 -6
  200. package/dist/chunks/chunk-L6FMG3R6.js +0 -380
  201. package/dist/chunks/chunk-L6FMG3R6.js.map +0 -6
  202. package/dist/chunks/chunk-ZKTLXAQK.js.map +0 -6
  203. package/dist/chunks/exec-AHAC6YBQ.js.map +0 -6
  204. package/dist/chunks/session-step-YNMU75FQ.js +0 -26
  205. package/dist/chunks/tui-UY3ZLTMX.js.map +0 -6
  206. /package/dist/chunks/{activity-command-OK463NV4.js.map → activity-command-MCYEK4Z4.js.map} +0 -0
  207. /package/dist/chunks/{add-ML53TFN2.js.map → add-ZQ3YWP4F.js.map} +0 -0
  208. /package/dist/chunks/{agent-3ST7Q6HZ.js.map → agent-UO62HZPI.js.map} +0 -0
  209. /package/dist/chunks/{agent-session-C2HDOXK4.js.map → agent-session-DU55LD4P.js.map} +0 -0
  210. /package/dist/chunks/{archive-WV2NBOHR.js.map → archive-VPREZOGC.js.map} +0 -0
  211. /package/dist/chunks/{bin-main-FPJQMK33.js.map → bin-main-J5ULRXXN.js.map} +0 -0
  212. /package/dist/chunks/{browser-JRWZ3PYX.js.map → browser-FZWYOIIJ.js.map} +0 -0
  213. /package/dist/chunks/{chat-3IJFKDSN.js.map → chat-BGWKKQTT.js.map} +0 -0
  214. /package/dist/chunks/{chunk-S7E42272.js.map → chunk-2BZOT2CT.js.map} +0 -0
  215. /package/dist/chunks/{chunk-LIZPXS73.js.map → chunk-3F5DGROG.js.map} +0 -0
  216. /package/dist/chunks/{chunk-KNNQHRZ4.js.map → chunk-46B7KRXY.js.map} +0 -0
  217. /package/dist/chunks/{chunk-PT7TZNBV.js.map → chunk-52OVP5BG.js.map} +0 -0
  218. /package/dist/chunks/{chunk-X2YRM3UE.js.map → chunk-56OUKG5W.js.map} +0 -0
  219. /package/dist/chunks/{chunk-HJ42RG5U.js.map → chunk-5URT3ZM2.js.map} +0 -0
  220. /package/dist/chunks/{chunk-GWOW3U2S.js.map → chunk-6TDJXZ5W.js.map} +0 -0
  221. /package/dist/chunks/{chunk-43FBWINL.js.map → chunk-AEPAIDAA.js.map} +0 -0
  222. /package/dist/chunks/{chunk-7WQV2FSF.js.map → chunk-AHYHR5DY.js.map} +0 -0
  223. /package/dist/chunks/{chunk-XAKL7C7B.js.map → chunk-AP5KD43Y.js.map} +0 -0
  224. /package/dist/chunks/{chunk-NRML7BIR.js.map → chunk-AS7UWXMN.js.map} +0 -0
  225. /package/dist/chunks/{chunk-QQLB573I.js.map → chunk-BOV53LZO.js.map} +0 -0
  226. /package/dist/chunks/{chunk-GPBUDMUF.js.map → chunk-BUCICQWG.js.map} +0 -0
  227. /package/dist/chunks/{chunk-CFN7CUD3.js.map → chunk-DYUOXP5Q.js.map} +0 -0
  228. /package/dist/chunks/{chunk-G5XTLTDR.js.map → chunk-E7HLYLD7.js.map} +0 -0
  229. /package/dist/chunks/{chunk-ABD2DOO2.js.map → chunk-EKUJUPFA.js.map} +0 -0
  230. /package/dist/chunks/{chunk-AABPCENY.js.map → chunk-F3YQ2CSZ.js.map} +0 -0
  231. /package/dist/chunks/{chunk-2VXA7GZU.js.map → chunk-FU4GQ7K2.js.map} +0 -0
  232. /package/dist/chunks/{chunk-VHKKPDL2.js.map → chunk-GQN64E36.js.map} +0 -0
  233. /package/dist/chunks/{chunk-AL6ESCHD.js.map → chunk-GSHSAMZJ.js.map} +0 -0
  234. /package/dist/chunks/{chunk-3OZ2OBGU.js.map → chunk-HKDPP2JF.js.map} +0 -0
  235. /package/dist/chunks/{chunk-YZ675PG4.js.map → chunk-HSEJGSXE.js.map} +0 -0
  236. /package/dist/chunks/{chunk-ZXWJ6G3J.js.map → chunk-I6CDUPVR.js.map} +0 -0
  237. /package/dist/chunks/{chunk-27VZRJTG.js.map → chunk-IQBR45AU.js.map} +0 -0
  238. /package/dist/chunks/{chunk-HIZ7F6BT.js.map → chunk-JCDTR2ZU.js.map} +0 -0
  239. /package/dist/chunks/{chunk-ZNAH4EGP.js.map → chunk-KMHLON54.js.map} +0 -0
  240. /package/dist/chunks/{chunk-CXLSM5SH.js.map → chunk-KOG2WB66.js.map} +0 -0
  241. /package/dist/chunks/{chunk-AGHVC2IJ.js.map → chunk-LBH5WVXU.js.map} +0 -0
  242. /package/dist/chunks/{chunk-NKEOCU52.js.map → chunk-LNQ6SCBF.js.map} +0 -0
  243. /package/dist/chunks/{chunk-U5AWHJ7O.js.map → chunk-MBBFX64S.js.map} +0 -0
  244. /package/dist/chunks/{chunk-PJ3UYK2K.js.map → chunk-MJO6CH5F.js.map} +0 -0
  245. /package/dist/chunks/{chunk-AVIW5JJF.js.map → chunk-NATYSTPM.js.map} +0 -0
  246. /package/dist/chunks/{chunk-KQOIPRZ5.js.map → chunk-QRT3N2K3.js.map} +0 -0
  247. /package/dist/chunks/{chunk-DYBUCWAB.js.map → chunk-QXDKRJZ5.js.map} +0 -0
  248. /package/dist/chunks/{chunk-EOO5AKO4.js.map → chunk-RBX6RVYO.js.map} +0 -0
  249. /package/dist/chunks/{chunk-VSUHR44P.js.map → chunk-RM6HTBJK.js.map} +0 -0
  250. /package/dist/chunks/{chunk-YLIKDPD6.js.map → chunk-S6DK2YOB.js.map} +0 -0
  251. /package/dist/chunks/{chunk-WW4VKEBD.js.map → chunk-S6MZK4LD.js.map} +0 -0
  252. /package/dist/chunks/{chunk-ZZ6Z2DO6.js.map → chunk-UFTNEQFN.js.map} +0 -0
  253. /package/dist/chunks/{chunk-7OEK2NAO.js.map → chunk-UXGI3FE5.js.map} +0 -0
  254. /package/dist/chunks/{chunk-WNMRETWS.js.map → chunk-VUOS5SQ3.js.map} +0 -0
  255. /package/dist/chunks/{chunk-YTJO7G24.js.map → chunk-XCWZZZOW.js.map} +0 -0
  256. /package/dist/chunks/{chunk-RPAHIOW6.js.map → chunk-YYQFUKI7.js.map} +0 -0
  257. /package/dist/chunks/{chunk-5GARJ3CK.js.map → chunk-YYVDLVUM.js.map} +0 -0
  258. /package/dist/chunks/{chunk-HQZSTYKY.js.map → chunk-ZB5ETOVE.js.map} +0 -0
  259. /package/dist/chunks/{chunk-GFSD2D3M.js.map → chunk-ZG6NVROB.js.map} +0 -0
  260. /package/dist/chunks/{chunk-MBGQS5YA.js.map → chunk-ZHBHRMCI.js.map} +0 -0
  261. /package/dist/chunks/{cli-runtime-CQKITOHY.js.map → cli-runtime-NG23IVRM.js.map} +0 -0
  262. /package/dist/chunks/{commands-UEPVSG33.js.map → commands-LQISMOPF.js.map} +0 -0
  263. /package/dist/chunks/{crash-report-3GQ3SJML.js.map → crash-report-EYK56MJJ.js.map} +0 -0
  264. /package/dist/chunks/{dist-YDFJ4YOH.js.map → dist-3AMBKAG4.js.map} +0 -0
  265. /package/dist/chunks/{dist-SCEJQJFY.js.map → dist-AUDNCB3F.js.map} +0 -0
  266. /package/dist/chunks/{dist-FFMNE5LK.js.map → dist-AZJ56DQJ.js.map} +0 -0
  267. /package/dist/chunks/{dist-IPJVDPA3.js.map → dist-DWB5AYXB.js.map} +0 -0
  268. /package/dist/chunks/{dist-VJ2UQYSX.js.map → dist-EDKLCZY4.js.map} +0 -0
  269. /package/dist/chunks/{dist-Q37IZHCW.js.map → dist-PZXF5NU3.js.map} +0 -0
  270. /package/dist/chunks/{dist-AMYVT2VT.js.map → dist-XT4V74YL.js.map} +0 -0
  271. /package/dist/chunks/{doctor-YWK25HGQ.js.map → doctor-3EOUWDYB.js.map} +0 -0
  272. /package/dist/chunks/{drain-5R73B66Y.js.map → drain-VKGTCFXC.js.map} +0 -0
  273. /package/dist/chunks/{eval-GYPUHRIK.js.map → eval-VHWEJ4GG.js.map} +0 -0
  274. /package/dist/chunks/{home-GI6TRZAN.js.map → home-H4GTIYO5.js.map} +0 -0
  275. /package/dist/chunks/{host-queries-MN57UTDU.js.map → host-queries-AIZVYFDQ.js.map} +0 -0
  276. /package/dist/chunks/{lifecycle-7LD634AQ.js.map → lifecycle-UF7VDCOQ.js.map} +0 -0
  277. /package/dist/chunks/{list-DSHTQRTP.js.map → list-JJZ7I5OF.js.map} +0 -0
  278. /package/dist/chunks/{login-R5P2OAXZ.js.map → login-T2RKNHK2.js.map} +0 -0
  279. /package/dist/chunks/{logs-SGPSXLBY.js.map → logs-J6D4SEDY.js.map} +0 -0
  280. /package/dist/chunks/{mcp-MC6B34XH.js.map → mcp-WONRVJ26.js.map} +0 -0
  281. /package/dist/chunks/{message-command-4MV2SVHP.js.map → message-command-BGQB2TFW.js.map} +0 -0
  282. /package/dist/chunks/{operator-tools-GI63VOXH.js.map → operator-tools-H4MYC5PE.js.map} +0 -0
  283. /package/dist/chunks/{output-schema-74VSN66J.js.map → output-schema-RFJUTQ2N.js.map} +0 -0
  284. /package/dist/chunks/{pal-BWPYGQ4B.js.map → pal-AV7AD5MG.js.map} +0 -0
  285. /package/dist/chunks/{providers-YV45XVWS.js.map → providers-BHF65IUG.js.map} +0 -0
  286. /package/dist/chunks/{resident-OC2D5V5I.js.map → resident-YF3MIILM.js.map} +0 -0
  287. /package/dist/chunks/{resume-command-DZBKOABY.js.map → resume-command-Y3NYDSI4.js.map} +0 -0
  288. /package/dist/chunks/{schedule-GUD625PJ.js.map → schedule-6T2MNPKK.js.map} +0 -0
  289. /package/dist/chunks/{service-67FZ3N75.js.map → service-2VASPD2V.js.map} +0 -0
  290. /package/dist/chunks/{session-step-YNMU75FQ.js.map → session-step-LJ24HVLF.js.map} +0 -0
  291. /package/dist/chunks/{skills-DNNEKEOH.js.map → skills-K3JRZ3IR.js.map} +0 -0
  292. /package/dist/chunks/{state-K7MMFNZC.js.map → state-QPSQI7U7.js.map} +0 -0
  293. /package/dist/chunks/{store-2PDDGKYZ.js.map → store-7WZWQXKX.js.map} +0 -0
  294. /package/dist/chunks/{store-KYMOKW6X.js.map → store-PSQKDEPY.js.map} +0 -0
  295. /package/dist/chunks/{store-NIBJFQOT.js.map → store-Z3PS6LUZ.js.map} +0 -0
  296. /package/dist/chunks/{upgrade-2NO7NPPM.js.map → upgrade-C6QUXRLB.js.map} +0 -0
  297. /package/dist/chunks/{worktree-ADQJ4AJ5.js.map → worktree-KLD2PAMU.js.map} +0 -0
@@ -2,24 +2,35 @@ import { createRequire as __namzuCreateRequire } from 'node:module';
2
2
  const require = __namzuCreateRequire(import.meta.url);
3
3
  import {
4
4
  openManagedWorktrees
5
- } from "./chunk-PT7TZNBV.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-HIZ7F6BT.js";
11
+ } from "./chunk-JCDTR2ZU.js";
12
12
  import {
13
13
  createSessionSkillCatalog
14
- } from "./chunk-YTJO7G24.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
+ completionNotice,
22
+ initialRunView,
23
+ launchedText,
17
24
  readStoredTurnGuards,
18
- resolveTurnGuards
19
- } from "./chunk-L6FMG3R6.js";
25
+ reduceRunView,
26
+ resolveTurnGuards,
27
+ viewFromJournal,
28
+ workflowOffered,
29
+ workflowRefusal
30
+ } from "./chunk-74KMYYM2.js";
20
31
  import {
21
32
  openInBrowser
22
- } from "./chunk-XAKL7C7B.js";
33
+ } from "./chunk-AP5KD43Y.js";
23
34
  import {
24
35
  CredentialRefreshRejectedError,
25
36
  CredentialWithdrawnError,
@@ -27,7 +38,7 @@ import {
27
38
  ensureFreshStoredCodexCredential,
28
39
  readSubscriptionCredential,
29
40
  sameOAuthCredential
30
- } from "./chunk-HJ42RG5U.js";
41
+ } from "./chunk-5URT3ZM2.js";
31
42
  import {
32
43
  debugRequested
33
44
  } from "./chunk-GNBMKISG.js";
@@ -35,7 +46,7 @@ import {
35
46
  configuredPassthroughTools,
36
47
  resolveToolResultScreens,
37
48
  unmatchedPassthroughTools
38
- } from "./chunk-U5AWHJ7O.js";
49
+ } from "./chunk-MBBFX64S.js";
39
50
  import {
40
51
  formatSize,
41
52
  homePath,
@@ -63,7 +74,7 @@ import {
63
74
  requiresCredentialForModel,
64
75
  resolveChainCapabilities,
65
76
  unresolvedMembers
66
- } from "./chunk-CFN7CUD3.js";
77
+ } from "./chunk-DYUOXP5Q.js";
67
78
  import {
68
79
  PROVIDER_REGISTRY,
69
80
  missingCredentialMessage,
@@ -71,11 +82,11 @@ import {
71
82
  } from "./chunk-6LLJQ3KY.js";
72
83
  import {
73
84
  cliLogger
74
- } from "./chunk-2VXA7GZU.js";
85
+ } from "./chunk-FU4GQ7K2.js";
75
86
  import {
76
87
  isPermissionMode,
77
88
  permissionModeLabel
78
- } from "./chunk-AGHVC2IJ.js";
89
+ } from "./chunk-LBH5WVXU.js";
79
90
  import {
80
91
  probeCapabilities
81
92
  } from "./chunk-OH6TB27S.js";
@@ -86,7 +97,7 @@ import {
86
97
  import {
87
98
  conversationLogPath,
88
99
  ensureSessionStarted
89
- } from "./chunk-ABD2DOO2.js";
100
+ } from "./chunk-EKUJUPFA.js";
90
101
  import {
91
102
  INSTRUCTIONS_FILENAME,
92
103
  MAX_CHARS_PER_FILE,
@@ -96,13 +107,13 @@ import {
96
107
  } from "./chunk-H6B6AROX.js";
97
108
  import {
98
109
  ensurePrivateStateDirectory
99
- } from "./chunk-WW4VKEBD.js";
110
+ } from "./chunk-S6MZK4LD.js";
100
111
  import {
101
112
  restrictToOwner
102
- } from "./chunk-QQLB573I.js";
113
+ } from "./chunk-BOV53LZO.js";
103
114
  import {
104
115
  namzuHomePath
105
- } from "./chunk-3OZ2OBGU.js";
116
+ } from "./chunk-HKDPP2JF.js";
106
117
  import {
107
118
  AgentManager,
108
119
  AgentRegistry,
@@ -124,6 +135,7 @@ import {
124
135
  EXPLORE_AGENT_DESCRIPTION,
125
136
  EXPLORE_AGENT_ID,
126
137
  EXPLORE_AGENT_PROMPT,
138
+ FileWorkflowJournal,
127
139
  GitWorktreeDriver,
128
140
  GuardedFetchProvider,
129
141
  InMemorySessionLog,
@@ -156,6 +168,8 @@ import {
156
168
  TopicManager,
157
169
  TurnCancelled,
158
170
  WebFetchTool,
171
+ WorkflowRuntime,
172
+ WorkflowScriptError,
159
173
  WorkspaceBackendRegistry,
160
174
  abandonTurn,
161
175
  asSessionId,
@@ -213,6 +227,7 @@ import {
213
227
  mapTools,
214
228
  mcpJsonSchemaToZod,
215
229
  openSessionTokenBudget,
230
+ parseWorkflowMeta,
216
231
  query,
217
232
  readSessionLog,
218
233
  readyWhen,
@@ -230,9 +245,10 @@ import {
230
245
  toolset,
231
246
  untrustedEnvelopeBody,
232
247
  webGuidanceContribution,
248
+ windowsShellNotice,
233
249
  withProviderFallback,
234
250
  wrapUntrusted
235
- } from "./chunk-ZKTLXAQK.js";
251
+ } from "./chunk-V3ZLK3XQ.js";
236
252
  import {
237
253
  __name
238
254
  } from "./chunk-76FLAFCG.js";
@@ -621,6 +637,7 @@ __name(isAuthoredSentence, "isAuthoredSentence");
621
637
 
622
638
  // src/tui/tidy-tool-output.ts
623
639
  import { stripVTControlCharacters } from "node:util";
640
+ var BACKGROUND_NOTE = "Running in the background (\u2193 to manage)";
624
641
  function looksBinary(text) {
625
642
  if (text.includes("\0")) return true;
626
643
  if (text.length === 0) return false;
@@ -634,7 +651,8 @@ function looksBinary(text) {
634
651
  __name(looksBinary, "looksBinary");
635
652
  function tidyTerminalOutput(raw) {
636
653
  if (looksBinary(raw)) {
637
- return { output: "The command printed binary data, which is not shown." };
654
+ const output2 = "The command printed binary data, which is not shown.";
655
+ return { output: output2, shell: { stdout: [], stderr: [], failed: false, note: output2 } };
638
656
  }
639
657
  let failure;
640
658
  const kept = [];
@@ -648,7 +666,18 @@ function tidyTerminalOutput(raw) {
648
666
  kept.push(line);
649
667
  }
650
668
  while (kept.length > 0 && kept[kept.length - 1]?.trim() === "") kept.pop();
651
- return { output: kept.join("\n"), ...failure ? { failure } : {} };
669
+ const output = kept.join("\n");
670
+ const background = /^Started background job /.test(output);
671
+ const code = failure ? /\d+/.exec(failure)?.[0] : void 0;
672
+ const shell = {
673
+ stdout: background || output.length === 0 ? [] : kept,
674
+ stderr: [],
675
+ failed: failure !== void 0,
676
+ ...background ? { note: BACKGROUND_NOTE } : {},
677
+ ...failure ? { note: code ? `Exit code ${code}` : failure } : {},
678
+ ...failure && output.length > 0 && !background ? { status: code ? `Exit code ${code}` : failure } : {}
679
+ };
680
+ return { output, ...failure ? { failure } : {}, shell };
652
681
  }
653
682
  __name(tidyTerminalOutput, "tidyTerminalOutput");
654
683
  function shortCommand(command) {
@@ -684,21 +713,33 @@ function tidyCommandOutput(facts, raw) {
684
713
  const how = endedHow(facts);
685
714
  const label = shortCommand(facts.command);
686
715
  const failure = how ? label ? `Ran ${label} \xB7 ${how}` : `${how.charAt(0).toUpperCase()}${how.slice(1)}` : void 0;
687
- const withFailure = /* @__PURE__ */ __name((output) => ({ output, ...failure ? { failure } : {} }), "withFailure");
716
+ const status = !how ? void 0 : facts.timedOut ? "Timed out" : facts.signal ? "Stopped before it finished" : `Exit code ${facts.exitCode}`;
717
+ const cell = /* @__PURE__ */ __name((stdout2, stderr2, note) => ({
718
+ stdout: stdout2,
719
+ stderr: stderr2,
720
+ failed: how !== void 0,
721
+ ...status && (stdout2.length > 0 || stderr2.length > 0) ? { status } : {},
722
+ ...status ? { note: status } : note ? { note } : {}
723
+ }), "cell");
724
+ const withFailure = /* @__PURE__ */ __name((output, shell) => ({
725
+ output,
726
+ ...failure ? { failure } : {},
727
+ shell
728
+ }), "withFailure");
688
729
  if (facts.binary) {
689
- return withFailure(
690
- `The command printed binary data (${formatSize(facts.binary.bytes)}), which is not shown.`
691
- );
692
- }
693
- const streams = [facts.stdout, facts.stderr].filter(
694
- (w) => w !== void 0 && w.totalBytes > 0
730
+ const sentence = `The command printed binary data (${formatSize(facts.binary.bytes)}), which is not shown.`;
731
+ return withFailure(sentence, cell([], [], sentence));
732
+ }
733
+ const clean = /* @__PURE__ */ __name((window) => window && window.totalBytes > 0 ? windowLines(window).map((line) => stripVTControlCharacters(line)) : [], "clean");
734
+ const stdout = clean(facts.stdout);
735
+ const stderr = clean(facts.stderr);
736
+ if (stdout.length > 0 || stderr.length > 0) {
737
+ return withFailure([...stdout, ...stderr].join("\n"), cell(stdout, stderr));
738
+ }
739
+ return withFailure(
740
+ tidyTerminalOutput(raw).output,
741
+ cell([], [], facts.background ? BACKGROUND_NOTE : void 0)
695
742
  );
696
- if (streams.length > 0) {
697
- return withFailure(
698
- streams.flatMap(windowLines).map((line) => stripVTControlCharacters(line)).join("\n")
699
- );
700
- }
701
- return withFailure(tidyTerminalOutput(raw).output);
702
743
  }
703
744
  __name(tidyCommandOutput, "tidyCommandOutput");
704
745
  function unknownToolNotice(result) {
@@ -822,14 +863,14 @@ function formatCompactCount(value) {
822
863
  __name(formatCompactCount, "formatCompactCount");
823
864
 
824
865
  // src/tui/web-activity.ts
825
- function webActivityKind(toolName) {
826
- if (toolName === "web_search") return "search";
827
- if (toolName === "web_fetch") return "fetch";
866
+ function webActivityKind(toolName2) {
867
+ if (toolName2 === "web_search") return "search";
868
+ if (toolName2 === "web_fetch") return "fetch";
828
869
  return void 0;
829
870
  }
830
871
  __name(webActivityKind, "webActivityKind");
831
- function webActivityFromInput(toolName, input) {
832
- const kind = webActivityKind(toolName);
872
+ function webActivityFromInput(toolName2, input) {
873
+ const kind = webActivityKind(toolName2);
833
874
  if (!kind) return void 0;
834
875
  const field = kind === "search" ? "query" : "url";
835
876
  const value = input !== null && typeof input === "object" ? input[field] : void 0;
@@ -884,7 +925,7 @@ __name(oneLine, "oneLine");
884
925
  // src/tui/agent.ts
885
926
  import { SubprocessComputerUseHost } from "@namzu/computer-use";
886
927
  import { realpath as realpath4, stat as stat4 } from "node:fs/promises";
887
- import { parse, resolve as resolve8 } from "node:path";
928
+ import { join as join13, parse, resolve as resolve8 } from "node:path";
888
929
 
889
930
  // src/checkpoints/store.ts
890
931
  import { randomUUID as randomUUID2 } from "node:crypto";
@@ -4658,6 +4699,27 @@ var SubagentActivityMonitor = class {
4658
4699
  getNarration() {
4659
4700
  return [...this.narration];
4660
4701
  }
4702
+ /**
4703
+ * The cheap facts a progress line needs about one child, without copying
4704
+ * its transcript: spend, tool executions and the tool it ran last.
4705
+ */
4706
+ progressOf(viewId) {
4707
+ const record = this.records.get(viewId);
4708
+ if (!record) return void 0;
4709
+ let lastTool;
4710
+ for (let index = record.rows.length - 1; index >= 0; index -= 1) {
4711
+ const row = record.rows[index];
4712
+ if (row?.kind === "tool") {
4713
+ lastTool = row.text;
4714
+ break;
4715
+ }
4716
+ }
4717
+ return {
4718
+ ...record.tokens !== void 0 ? { tokens: record.tokens } : {},
4719
+ ...record.toolCalls !== void 0 ? { toolCalls: record.toolCalls } : {},
4720
+ ...lastTool !== void 0 ? { lastTool } : {}
4721
+ };
4722
+ }
4661
4723
  getSnapshot() {
4662
4724
  return [...this.records.values()].sort((left, right) => {
4663
4725
  const live = Number(isTerminal(left.status)) - Number(isTerminal(right.status));
@@ -5745,6 +5807,7 @@ var SUBAGENT_PROMPT = [
5745
5807
  // the parent does not is the same defect in the other direction.
5746
5808
  CODING_AGENT_WORKING_DOCTRINE
5747
5809
  ].join("\n");
5810
+ var WORKFLOW_RUN_GROUP_PREFIX = "wf:";
5748
5811
  var ParentTaskScheduler = class extends LocalTaskScheduler {
5749
5812
  constructor(manager, context, onEvent, validateParent) {
5750
5813
  super(manager, context, onEvent);
@@ -6040,6 +6103,194 @@ async function createSubagentRuntime(opts) {
6040
6103
  }, "completionInboxForTurn");
6041
6104
  const activity = new SubagentActivityMonitor();
6042
6105
  let dynCounter = 0;
6106
+ const launchChild = /* @__PURE__ */ __name(async (input, context, hooks = {}) => {
6107
+ const {
6108
+ description,
6109
+ prompt,
6110
+ subagent_type,
6111
+ role,
6112
+ workflow,
6113
+ phase,
6114
+ phase_order,
6115
+ phase_detail,
6116
+ run_in_background,
6117
+ workspace,
6118
+ model: requestedModel,
6119
+ provider: requestedProvider,
6120
+ effort: requestedEffort
6121
+ } = input;
6122
+ if (!requestedModel && (requestedProvider || requestedEffort))
6123
+ throw new Error("Supply model when selecting a child provider or effort.");
6124
+ const explore = subagent_type === EXPLORE_SUBAGENT;
6125
+ const fileAgent = subagent_type !== void 0 ? fileAgents.get(subagent_type) : void 0;
6126
+ const inherited = opts.resolveTurnModel?.(context.turnId);
6127
+ const parentModel = inherited?.model ?? opts.model;
6128
+ const selects = requestedModel !== void 0 && (requestedModel !== parentModel || requestedProvider !== void 0 || requestedEffort !== void 0 || fileAgent?.model !== void 0 && fileAgent.model !== parentModel);
6129
+ if (selects && !opts.resolveModel)
6130
+ throw new Error("Child model selection is unavailable in this host.");
6131
+ const selection = selects ? await opts.resolveModel?.(
6132
+ {
6133
+ model: requestedModel,
6134
+ provider: requestedProvider,
6135
+ effort: requestedEffort
6136
+ },
6137
+ context.abortSignal
6138
+ ) : (
6139
+ // A file agent that pins its own model keeps it; any other child
6140
+ // of a turn on another model than the session's runs on that one.
6141
+ fileAgent?.model === void 0 ? inherited : void 0
6142
+ );
6143
+ let agentId = fileAgent?.name ?? (explore ? EXPLORE_SUBAGENT : GENERAL_PURPOSE_SUBAGENT);
6144
+ const persona = typeof role === "string" ? role.trim() : "";
6145
+ const dynamic = persona.length > 0 || selection !== void 0;
6146
+ if (dynamic) {
6147
+ agentId = `dyn-${++dynCounter}`;
6148
+ registry.register(
6149
+ buildDefinition(
6150
+ agentId,
6151
+ `Dynamic specialist: ${agentId}`,
6152
+ fileAgent ? `${fileAgent.prompt}
6153
+
6154
+ ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6155
+ opts,
6156
+ fileAgent ? fileAgentTools(fileAgent, opts) : explore ? () => opts.buildTools().map(
6157
+ (ts) => filtered(
6158
+ ts,
6159
+ (tool) => isTrustedReadOnly(tool, void 0, toToolSourceRef(ts.source))
6160
+ )
6161
+ ) : opts.buildTools,
6162
+ selection?.model ?? fileAgent?.model ?? parentModel,
6163
+ selection
6164
+ )
6165
+ );
6166
+ }
6167
+ const seed = {
6168
+ agentId,
6169
+ model: selection?.model ?? fileAgent?.model ?? parentModel,
6170
+ description,
6171
+ prompt,
6172
+ batchId: context.toolBatchId,
6173
+ toolUseId: context.toolUseId,
6174
+ workflowId: hooks.workflowId ?? String(context.turnId),
6175
+ workflow,
6176
+ phase,
6177
+ phaseOrder: phase_order,
6178
+ phaseDetail: phase_detail
6179
+ };
6180
+ const tracker = activity.begin(seed);
6181
+ hooks.onView?.(tracker.viewId);
6182
+ const resumeHandler = opts.resolveResumeHandler?.(context.turnId) ?? refuseUnownedChildReview;
6183
+ const configOverrides = {
6184
+ ...resolveTurnGuards(opts, opts.resolveLimits?.(context.turnId)),
6185
+ ...selection ? { model: selection.model, effort: selection.effort } : {},
6186
+ ...Object.keys(context.env ?? {}).length > 0 ? { env: context.env } : {},
6187
+ // The parent turn's tool-result screens, so a sub-agent judges a
6188
+ // connected answer the way the turn that asked for the work
6189
+ // does. Without it the child's executor installs the shipped
6190
+ // default, and `toolResultScreens: []` — the operator's off
6191
+ // switch — would hold for the parent and not for anything it
6192
+ // delegated to, which is the half an operator does not watch.
6193
+ //
6194
+ // `[]` is carried rather than skipped: empty is a decision, and
6195
+ // a `length` test — which is the shape that gets this wrong,
6196
+ // since `[]` is truthy — would turn it back into absent.
6197
+ ...context.toolResultGuardrails ? { toolResultGuardrails: context.toolResultGuardrails } : {},
6198
+ resumeHandler
6199
+ };
6200
+ let taskOwnsCleanup = false;
6201
+ let retained;
6202
+ const cleanupDefinition = /* @__PURE__ */ __name(() => {
6203
+ if (dynamic && !retained) registry.unregister(agentId);
6204
+ }, "cleanupDefinition");
6205
+ try {
6206
+ const parentKey = sessionKey(await resolveParent(context.turnId));
6207
+ const gateway = await gatewayForTurn(context.turnId);
6208
+ const completionInbox = await completionInboxForTurn(context.turnId);
6209
+ const subdirectory = workspace === "worktree" ? await worktreeDriver.selectedSubdirectory() : void 0;
6210
+ const outcome = await runBlockingAgentTask({
6211
+ gateway: await gatewayForTurn(context.turnId),
6212
+ signal: context.abortSignal,
6213
+ waitForInbound: opts.resolveWaitForInbound?.(context.turnId),
6214
+ background: run_in_background === true,
6215
+ ...hooks.cancelCause ? { cancelCause: hooks.cancelCause } : {},
6216
+ completionInbox,
6217
+ onCreated: /* @__PURE__ */ __name((task) => {
6218
+ taskOwnsCleanup = true;
6219
+ retained = {
6220
+ parentKey,
6221
+ agentId,
6222
+ dynamic,
6223
+ seed,
6224
+ config: {
6225
+ ...selection ? { model: selection.model, effort: selection.effort } : {},
6226
+ ...configOverrides.env ? { env: configOverrides.env } : {},
6227
+ ...configOverrides.toolResultGuardrails ? {
6228
+ toolResultGuardrails: configOverrides.toolResultGuardrails
6229
+ } : {}
6230
+ },
6231
+ workspace: workspace ?? "shared",
6232
+ gateway,
6233
+ task,
6234
+ turnId: context.turnId,
6235
+ busy: false
6236
+ };
6237
+ conversations.set(tracker.viewId, retained);
6238
+ const visible = new Set(activity.getSnapshot().map((value) => value.viewId));
6239
+ for (const [id, previous] of conversations) {
6240
+ if (visible.has(id) || previous.busy || !isTerminalAgentTaskState(previous.task.state))
6241
+ continue;
6242
+ conversations.delete(id);
6243
+ if (previous.dynamic) registry.unregister(previous.agentId);
6244
+ }
6245
+ tracker.settle(task);
6246
+ }, "onCreated"),
6247
+ onSettled: /* @__PURE__ */ __name((completed) => {
6248
+ if (retained) retained.task = completed;
6249
+ tracker.settle(completed);
6250
+ }, "onSettled"),
6251
+ onFailed: /* @__PURE__ */ __name((error) => tracker.fail(error), "onFailed"),
6252
+ onFinished: cleanupDefinition,
6253
+ create: {
6254
+ agentId,
6255
+ prompt,
6256
+ workingDirectory: opts.cwd,
6257
+ workspace: workspace === "worktree" ? {
6258
+ mode: "isolated",
6259
+ backend: "git-worktree",
6260
+ retention: "retain",
6261
+ ...subdirectory ? { subdirectory } : {}
6262
+ } : { mode: "shared" },
6263
+ // The same labels the monitor was seeded with, sent down so the
6264
+ // child's `agent_pending` carries them: a listener or SSE
6265
+ // consumer outside this process then groups the child the way
6266
+ // the operator sees it here, instead of the grouping living
6267
+ // only in the closure above. Display-only on both paths — no
6268
+ // dependency, barrier or serial execution follows from any.
6269
+ ...workflow ? { workflow } : {},
6270
+ ...phase ? { phase } : {},
6271
+ ...phase_detail ? { phaseDetail: phase_detail } : {},
6272
+ ...phase_order !== void 0 ? { phaseOrder: phase_order } : {},
6273
+ // Hang the child session off THIS tool's span, so the delegation
6274
+ // shows up inside the turn that asked for it. Without it a
6275
+ // sub-agent opens its OWN root trace, and the one structure
6276
+ // a delegation trace exists to record — who dispatched whom
6277
+ // — is the thing that goes missing.
6278
+ ...context.parentSpan ? { parentSpan: context.parentSpan } : {},
6279
+ configOverrides,
6280
+ onEvent: hooks.onEvent ? (event) => {
6281
+ tracker.onEvent(event);
6282
+ hooks.onEvent?.(event);
6283
+ } : tracker.onEvent
6284
+ }
6285
+ });
6286
+ return { outcome, agentId };
6287
+ } catch (error) {
6288
+ tracker.fail(error);
6289
+ throw error;
6290
+ } finally {
6291
+ if (!taskOwnsCleanup) cleanupDefinition();
6292
+ }
6293
+ }, "launchChild");
6043
6294
  const agentTool = defineTool({
6044
6295
  name: "Agent",
6045
6296
  description: [
@@ -6053,7 +6304,7 @@ async function createSubagentRuntime(opts) {
6053
6304
  "Omit `role` for the plain sub-agent.",
6054
6305
  "The sub-agent runs in its own context with its own tools and cannot see this conversation \u2014 put everything it needs in `prompt`.",
6055
6306
  "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.",
6056
- "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.",
6307
+ "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.",
6057
6308
  "These fields are display annotations only; they do not create dependencies, barriers, or serial execution.",
6058
6309
  fileAgentSummary.length > 0 ? `Project-defined types: ${fileAgentSummary}.` : ""
6059
6310
  ].filter((part) => part.length > 0).join(" "),
@@ -6137,202 +6388,116 @@ async function createSubagentRuntime(opts) {
6137
6388
  concurrencySafe: true,
6138
6389
  timeoutMs: opts.resolveLimits ? 0 : opts.timeoutMs ?? CLI_INTERACTIVE_TURN_TIMEOUT_MS,
6139
6390
  async execute(input, context) {
6140
- const {
6141
- description,
6142
- prompt,
6143
- subagent_type,
6144
- role,
6145
- workflow,
6146
- phase,
6147
- phase_order,
6148
- phase_detail,
6149
- run_in_background,
6150
- workspace,
6151
- model: requestedModel,
6152
- provider: requestedProvider,
6153
- effort: requestedEffort
6154
- } = input;
6155
- if (!requestedModel && (requestedProvider || requestedEffort))
6156
- throw new Error("Supply model when selecting a child provider or effort.");
6157
- const explore = subagent_type === EXPLORE_SUBAGENT;
6158
- const fileAgent = subagent_type !== void 0 ? fileAgents.get(subagent_type) : void 0;
6159
- const inherited = opts.resolveTurnModel?.(context.turnId);
6160
- const parentModel = inherited?.model ?? opts.model;
6161
- const selects = requestedModel !== void 0 && (requestedModel !== parentModel || requestedProvider !== void 0 || requestedEffort !== void 0 || fileAgent?.model !== void 0 && fileAgent.model !== parentModel);
6162
- if (selects && !opts.resolveModel)
6163
- throw new Error("Child model selection is unavailable in this host.");
6164
- const selection = selects ? await opts.resolveModel?.(
6391
+ const { description, run_in_background } = input;
6392
+ const { outcome, agentId } = await launchChild(input, context);
6393
+ if (outcome.kind === "yielded") {
6394
+ const progress = outcome.handle.state === "pending" ? "queued for an available slot" : "still running";
6395
+ return {
6396
+ success: true,
6397
+ 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.`,
6398
+ data: {
6399
+ task_id: outcome.handle.taskId,
6400
+ state: outcome.handle.state,
6401
+ ...workspaceData(outcome.handle),
6402
+ wait_released: run_in_background ? "background" : "operator_input"
6403
+ }
6404
+ };
6405
+ }
6406
+ return completedAgentResult(outcome.handle);
6407
+ }
6408
+ });
6409
+ const launchWorkflowAgent = /* @__PURE__ */ __name(async (launch) => {
6410
+ if (launch.agentType !== void 0 && !agentTypeIds.includes(launch.agentType)) {
6411
+ throw new Error(
6412
+ `Unknown agent type "${launch.agentType}". Available: ${agentTypeIds.join(", ")}.`
6413
+ );
6414
+ }
6415
+ if (launch.effort !== void 0 && launch.model === void 0) {
6416
+ throw new Error("Supply model when selecting an agent effort.");
6417
+ }
6418
+ const prompt = launch.schema === void 0 ? launch.prompt : `${launch.prompt}
6419
+
6420
+ Answer with one JSON value that satisfies this JSON Schema and nothing else:
6421
+ ${JSON.stringify(launch.schema)}`;
6422
+ const label = launch.workflowName === DEFAULT_AGENT_WORKFLOW ? "Workflow" : launch.workflowName;
6423
+ let viewId;
6424
+ let lastReport = 0;
6425
+ const report = /* @__PURE__ */ __name((force) => {
6426
+ if (!viewId || !launch.onProgress) return;
6427
+ const at = Date.now();
6428
+ if (!force && at - lastReport < 250) return;
6429
+ lastReport = at;
6430
+ const progress = activity.progressOf(viewId);
6431
+ if (progress) launch.onProgress(progress);
6432
+ }, "report");
6433
+ try {
6434
+ const { outcome } = await launchChild(
6165
6435
  {
6166
- model: requestedModel,
6167
- provider: requestedProvider,
6168
- effort: requestedEffort
6436
+ description: launch.label,
6437
+ prompt,
6438
+ run_in_background: false,
6439
+ ...launch.agentType !== void 0 ? { subagent_type: launch.agentType } : {},
6440
+ ...launch.model !== void 0 ? { model: launch.model } : {},
6441
+ ...launch.effort !== void 0 ? { effort: launch.effort } : {},
6442
+ workflow: label,
6443
+ ...launch.phaseTitle !== void 0 ? { phase: launch.phaseTitle } : {},
6444
+ ...launch.phaseIndex !== void 0 ? { phase_order: launch.phaseIndex } : {},
6445
+ ...launch.phaseDetail !== void 0 ? { phase_detail: launch.phaseDetail } : {}
6169
6446
  },
6170
- context.abortSignal
6171
- ) : (
6172
- // A file agent that pins its own model keeps it; any other child
6173
- // of a turn on another model than the session's runs on that one.
6174
- fileAgent?.model === void 0 ? inherited : void 0
6447
+ {
6448
+ turnId: launch.turnId,
6449
+ abortSignal: launch.signal,
6450
+ toolBatchId: launch.runId,
6451
+ ...launch.inherit?.env ? { env: launch.inherit.env } : {},
6452
+ ...launch.inherit?.toolResultGuardrails ? { toolResultGuardrails: launch.inherit.toolResultGuardrails } : {}
6453
+ },
6454
+ {
6455
+ workflowId: `${WORKFLOW_RUN_GROUP_PREFIX}${launch.runId}`,
6456
+ cancelCause: "user",
6457
+ onView: /* @__PURE__ */ __name((id) => {
6458
+ viewId = id;
6459
+ launch.onView?.(id);
6460
+ }, "onView"),
6461
+ onEvent: /* @__PURE__ */ __name(() => report(false), "onEvent")
6462
+ }
6175
6463
  );
6176
- let agentId = fileAgent?.name ?? (explore ? EXPLORE_SUBAGENT : GENERAL_PURPOSE_SUBAGENT);
6177
- const persona = typeof role === "string" ? role.trim() : "";
6178
- const dynamic = persona.length > 0 || selection !== void 0;
6179
- if (dynamic) {
6180
- agentId = `dyn-${++dynCounter}`;
6181
- registry.register(
6182
- buildDefinition(
6183
- agentId,
6184
- `Dynamic specialist: ${agentId}`,
6185
- fileAgent ? `${fileAgent.prompt}
6186
-
6187
- ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6188
- opts,
6189
- fileAgent ? fileAgentTools(fileAgent, opts) : explore ? () => opts.buildTools().map(
6190
- (ts) => filtered(
6191
- ts,
6192
- (tool) => isTrustedReadOnly(tool, void 0, toToolSourceRef(ts.source))
6193
- )
6194
- ) : opts.buildTools,
6195
- selection?.model ?? fileAgent?.model ?? parentModel,
6196
- selection
6197
- )
6198
- );
6464
+ report(true);
6465
+ const stats = viewId ? activity.progressOf(viewId) : void 0;
6466
+ const tokens = stats?.tokens ?? 0;
6467
+ const toolCalls = stats?.toolCalls ?? 0;
6468
+ if (outcome.kind !== "completed") {
6469
+ return {
6470
+ state: "error",
6471
+ tokens,
6472
+ toolCalls,
6473
+ error: "The agent did not finish."
6474
+ };
6199
6475
  }
6200
- const seed = {
6201
- agentId,
6202
- model: selection?.model ?? fileAgent?.model ?? parentModel,
6203
- description,
6204
- prompt,
6205
- batchId: context.toolBatchId,
6206
- toolUseId: context.toolUseId,
6207
- workflowId: String(context.turnId),
6208
- workflow,
6209
- phase,
6210
- phaseOrder: phase_order,
6211
- phaseDetail: phase_detail
6212
- };
6213
- const tracker = activity.begin(seed);
6214
- const resumeHandler = opts.resolveResumeHandler?.(context.turnId) ?? refuseUnownedChildReview;
6215
- const configOverrides = {
6216
- ...resolveTurnGuards(opts, opts.resolveLimits?.(context.turnId)),
6217
- ...selection ? { model: selection.model, effort: selection.effort } : {},
6218
- ...Object.keys(context.env ?? {}).length > 0 ? { env: context.env } : {},
6219
- // The parent turn's tool-result screens, so a sub-agent judges a
6220
- // connected answer the way the turn that asked for the work
6221
- // does. Without it the child's executor installs the shipped
6222
- // default, and `toolResultScreens: []` — the operator's off
6223
- // switch — would hold for the parent and not for anything it
6224
- // delegated to, which is the half an operator does not watch.
6225
- //
6226
- // `[]` is carried rather than skipped: empty is a decision, and
6227
- // a `length` test — which is the shape that gets this wrong,
6228
- // since `[]` is truthy — would turn it back into absent.
6229
- ...context.toolResultGuardrails ? { toolResultGuardrails: context.toolResultGuardrails } : {},
6230
- resumeHandler
6231
- };
6232
- let taskOwnsCleanup = false;
6233
- let retained;
6234
- const cleanupDefinition = /* @__PURE__ */ __name(() => {
6235
- if (dynamic && !retained) registry.unregister(agentId);
6236
- }, "cleanupDefinition");
6237
- try {
6238
- const parentKey = sessionKey(await resolveParent(context.turnId));
6239
- const gateway = await gatewayForTurn(context.turnId);
6240
- const completionInbox = await completionInboxForTurn(context.turnId);
6241
- const subdirectory = workspace === "worktree" ? await worktreeDriver.selectedSubdirectory() : void 0;
6242
- const outcome = await runBlockingAgentTask({
6243
- gateway: await gatewayForTurn(context.turnId),
6244
- signal: context.abortSignal,
6245
- waitForInbound: opts.resolveWaitForInbound?.(context.turnId),
6246
- background: run_in_background === true,
6247
- completionInbox,
6248
- onCreated: /* @__PURE__ */ __name((task) => {
6249
- taskOwnsCleanup = true;
6250
- retained = {
6251
- parentKey,
6252
- agentId,
6253
- dynamic,
6254
- seed,
6255
- config: {
6256
- ...selection ? { model: selection.model, effort: selection.effort } : {},
6257
- ...configOverrides.env ? { env: configOverrides.env } : {},
6258
- ...configOverrides.toolResultGuardrails ? {
6259
- toolResultGuardrails: configOverrides.toolResultGuardrails
6260
- } : {}
6261
- },
6262
- workspace: workspace ?? "shared",
6263
- gateway,
6264
- task,
6265
- turnId: context.turnId,
6266
- busy: false
6267
- };
6268
- conversations.set(tracker.viewId, retained);
6269
- const visible = new Set(activity.getSnapshot().map((value) => value.viewId));
6270
- for (const [id, previous] of conversations) {
6271
- if (visible.has(id) || previous.busy || !isTerminalAgentTaskState(previous.task.state))
6272
- continue;
6273
- conversations.delete(id);
6274
- if (previous.dynamic) registry.unregister(previous.agentId);
6275
- }
6276
- tracker.settle(task);
6277
- }, "onCreated"),
6278
- onSettled: /* @__PURE__ */ __name((completed) => {
6279
- if (retained) retained.task = completed;
6280
- tracker.settle(completed);
6281
- }, "onSettled"),
6282
- onFailed: /* @__PURE__ */ __name((error) => tracker.fail(error), "onFailed"),
6283
- onFinished: cleanupDefinition,
6284
- create: {
6285
- agentId,
6286
- prompt,
6287
- workingDirectory: opts.cwd,
6288
- workspace: workspace === "worktree" ? {
6289
- mode: "isolated",
6290
- backend: "git-worktree",
6291
- retention: "retain",
6292
- ...subdirectory ? { subdirectory } : {}
6293
- } : { mode: "shared" },
6294
- // The same labels the monitor was seeded with, sent down so the
6295
- // child's `agent_pending` carries them: a listener or SSE
6296
- // consumer outside this process then groups the child the way
6297
- // the operator sees it here, instead of the grouping living
6298
- // only in the closure above. Display-only on both paths — no
6299
- // dependency, barrier or serial execution follows from any.
6300
- ...workflow ? { workflow } : {},
6301
- ...phase ? { phase } : {},
6302
- ...phase_detail ? { phaseDetail: phase_detail } : {},
6303
- ...phase_order !== void 0 ? { phaseOrder: phase_order } : {},
6304
- // Hang the child session off THIS tool's span, so the delegation
6305
- // shows up inside the turn that asked for it. Without it a
6306
- // sub-agent opens its OWN root trace, and the one structure
6307
- // a delegation trace exists to record — who dispatched whom
6308
- // — is the thing that goes missing.
6309
- ...context.parentSpan ? { parentSpan: context.parentSpan } : {},
6310
- configOverrides,
6311
- onEvent: tracker.onEvent
6312
- }
6313
- });
6314
- if (outcome.kind === "yielded") {
6315
- const progress = outcome.handle.state === "pending" ? "queued for an available slot" : "still running";
6316
- return {
6317
- success: true,
6318
- 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.`,
6319
- data: {
6320
- task_id: outcome.handle.taskId,
6321
- state: outcome.handle.state,
6322
- ...workspaceData(outcome.handle),
6323
- wait_released: run_in_background ? "background" : "operator_input"
6324
- }
6325
- };
6326
- }
6327
- return completedAgentResult(outcome.handle);
6328
- } catch (error) {
6329
- tracker.fail(error);
6330
- throw error;
6331
- } finally {
6332
- if (!taskOwnsCleanup) cleanupDefinition();
6476
+ const handle = outcome.handle;
6477
+ const status = agentTaskOutcome(handle);
6478
+ const turn = handle.result;
6479
+ const value = turn?.structuredOutput ?? turn?.result;
6480
+ const text = typeof value === "string" ? value : value === void 0 ? "" : JSON.stringify(value);
6481
+ if (status !== "completed") {
6482
+ return {
6483
+ state: "error",
6484
+ tokens,
6485
+ toolCalls,
6486
+ error: `The agent ended as ${status}${turn?.lastError ? `: ${turn.lastError}` : "."}`
6487
+ };
6333
6488
  }
6489
+ return { state: "done", text, tokens, toolCalls };
6490
+ } catch (error) {
6491
+ if (launch.signal.aborted) throw error;
6492
+ const stats = viewId ? activity.progressOf(viewId) : void 0;
6493
+ return {
6494
+ state: "error",
6495
+ tokens: stats?.tokens ?? 0,
6496
+ toolCalls: stats?.toolCalls ?? 0,
6497
+ error: error instanceof Error ? error.message : String(error)
6498
+ };
6334
6499
  }
6335
- });
6500
+ }, "launchWorkflowAgent");
6336
6501
  const agentTaskListTool = defineTool({
6337
6502
  name: "agent_task_list",
6338
6503
  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.",
@@ -6406,7 +6571,7 @@ ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6406
6571
  properties: {
6407
6572
  task_id: {
6408
6573
  type: "string",
6409
- description: "The task_id from the Agent launch receipt or task notification metadata."
6574
+ description: "The task_id from the Agent launch receipt or task notification metadata. A workflow run id is not a task id."
6410
6575
  }
6411
6576
  },
6412
6577
  required: ["task_id"]
@@ -6420,8 +6585,16 @@ ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6420
6585
  async execute(input, context) {
6421
6586
  const gateway = await gatewayForTurn(context.turnId);
6422
6587
  let taskId;
6588
+ const asked = input.task_id;
6589
+ if (typeof asked === "string" && /^w[0-9a-z]{8}$/.test(asked.trim())) {
6590
+ return {
6591
+ success: true,
6592
+ output: `${asked.trim()} is a workflow run, not a task, so there is nothing to wait for here. You get one message when it ends, with what it returned. End your turn or do other work; do not call wait_for_task for it.`,
6593
+ data: { run_id: asked.trim(), waited: false }
6594
+ };
6595
+ }
6423
6596
  try {
6424
- taskId = asTaskId(input.task_id);
6597
+ taskId = asTaskId(asked);
6425
6598
  } catch {
6426
6599
  return {
6427
6600
  success: false,
@@ -6819,10 +6992,21 @@ ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6819
6992
  };
6820
6993
  }
6821
6994
  }) : void 0;
6995
+ const stopChild = /* @__PURE__ */ __name((viewId) => {
6996
+ if (closed) return false;
6997
+ const owned = conversations.get(viewId);
6998
+ const shown = activity.getSnapshot().find((value) => value.viewId === viewId);
6999
+ if (!owned || !shown || shown.replayed) return false;
7000
+ const current = owned.gateway.getTask(owned.task.taskId) ?? owned.task;
7001
+ if (isTerminalAgentTaskState(current.state)) return false;
7002
+ owned.gateway.cancelTask(owned.task.taskId, "user");
7003
+ return true;
7004
+ }, "stopChild");
6822
7005
  return {
6823
7006
  cancelAgentTool,
6824
7007
  modelCatalogueTool,
6825
7008
  messageChild,
7009
+ stopChild,
6826
7010
  gatewayForTurn,
6827
7011
  completionInboxForTurn,
6828
7012
  releaseTurn,
@@ -6846,6 +7030,7 @@ ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6846
7030
  return type === EXPLORE_SUBAGENT;
6847
7031
  },
6848
7032
  activity,
7033
+ launchWorkflowAgent,
6849
7034
  close
6850
7035
  };
6851
7036
  }
@@ -6866,7 +7051,7 @@ async function runBlockingAgentTask(input) {
6866
7051
  if (taskCancellationAttempted) return;
6867
7052
  taskCancellationAttempted = true;
6868
7053
  try {
6869
- gateway.cancelTask(task.taskId, "parent");
7054
+ gateway.cancelTask(task.taskId, input.cancelCause ?? "parent");
6870
7055
  } catch {
6871
7056
  }
6872
7057
  }, "cancel");
@@ -7063,9 +7248,465 @@ ${SUBAGENT_PROMPT}`;
7063
7248
  }
7064
7249
  __name(buildDefinition, "buildDefinition");
7065
7250
 
7251
+ // src/integrations/workflows/doctrine.ts
7252
+ var WORKFLOW_DOCTRINE = [
7253
+ "The `workflow` tool is available this turn because the operator asked for orchestration.",
7254
+ "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.",
7255
+ "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."
7256
+ ].join("\n");
7257
+
7258
+ // src/integrations/workflows/history.ts
7259
+ import { readFile as readFile3, readdir as readdir2 } from "node:fs/promises";
7260
+ import { join as join8 } from "node:path";
7261
+ var RUN_ID = /^w[0-9a-z]{8}$/;
7262
+ async function readWorkflowJournal(file) {
7263
+ let text;
7264
+ try {
7265
+ text = await readFile3(file, "utf8");
7266
+ } catch (error) {
7267
+ if (error.code === "ENOENT") return [];
7268
+ throw error;
7269
+ }
7270
+ const records = [];
7271
+ for (const line of text.split("\n")) {
7272
+ if (line.trim().length === 0) continue;
7273
+ try {
7274
+ const parsed = JSON.parse(line);
7275
+ if (typeof parsed === "object" && parsed !== null && "type" in parsed) {
7276
+ records.push(parsed);
7277
+ }
7278
+ } catch {
7279
+ }
7280
+ }
7281
+ return records;
7282
+ }
7283
+ __name(readWorkflowJournal, "readWorkflowJournal");
7284
+ async function readWorkflowRun(runsDirectory, runId) {
7285
+ if (!RUN_ID.test(runId)) return void 0;
7286
+ const records = await readWorkflowJournal(join8(runsDirectory, runId, "workflow", "journal.jsonl"));
7287
+ return viewFromJournal(records);
7288
+ }
7289
+ __name(readWorkflowRun, "readWorkflowRun");
7290
+ async function listWorkflowRuns(runsDirectory) {
7291
+ let entries;
7292
+ try {
7293
+ entries = await readdir2(runsDirectory);
7294
+ } catch (error) {
7295
+ if (error.code === "ENOENT") return [];
7296
+ throw error;
7297
+ }
7298
+ const views = await Promise.all(
7299
+ entries.filter((name) => RUN_ID.test(name)).map((name) => readWorkflowRun(runsDirectory, name))
7300
+ );
7301
+ return views.filter((view) => view !== void 0).sort((a, b) => b.startedAt - a.startedAt);
7302
+ }
7303
+ __name(listWorkflowRuns, "listWorkflowRuns");
7304
+
7305
+ // src/integrations/workflows/host.ts
7306
+ import { randomBytes as randomBytes3 } from "node:crypto";
7307
+ import { join as join9 } from "node:path";
7308
+
7309
+ // src/integrations/workflows/registry.ts
7310
+ var WorkflowRunRegistry = class {
7311
+ static {
7312
+ __name(this, "WorkflowRunRegistry");
7313
+ }
7314
+ runs = /* @__PURE__ */ new Map();
7315
+ listeners = /* @__PURE__ */ new Set();
7316
+ runtime;
7317
+ now;
7318
+ notifyTimer;
7319
+ closed = false;
7320
+ constructor(options = {}) {
7321
+ this.now = options.now ?? Date.now;
7322
+ this.runtime = options.runtime ?? new WorkflowRuntime();
7323
+ }
7324
+ list() {
7325
+ return [...this.runs.values()].map((run2) => run2.view);
7326
+ }
7327
+ get(runId) {
7328
+ return this.runs.get(runId)?.view;
7329
+ }
7330
+ subscribe(listener) {
7331
+ this.listeners.add(listener);
7332
+ return () => this.listeners.delete(listener);
7333
+ }
7334
+ /** Runs that have not ended. */
7335
+ running() {
7336
+ return this.list().filter((view) => view.status === "running");
7337
+ }
7338
+ /** Begin a run. Returns at once; the run goes on in the background. */
7339
+ start(input) {
7340
+ if (this.closed) throw new Error("Workflows are closed for this session.");
7341
+ const run2 = {
7342
+ view: initialRunView({
7343
+ runId: input.runId,
7344
+ name: input.meta.name,
7345
+ description: input.meta.description,
7346
+ phases: input.meta.phases,
7347
+ at: this.now()
7348
+ }),
7349
+ abort: new AbortController(),
7350
+ finalized: false
7351
+ };
7352
+ this.runs.set(input.runId, run2);
7353
+ this.notifySoon(true);
7354
+ let firstAgentSeen = false;
7355
+ const settle = /* @__PURE__ */ __name(async (result, error) => {
7356
+ const at = this.now();
7357
+ if (run2.view.status === "running") {
7358
+ run2.view = {
7359
+ ...run2.view,
7360
+ status: run2.abort.signal.aborted ? "stopped" : "failed",
7361
+ endedAt: at,
7362
+ ...error !== void 0 ? { error } : {}
7363
+ };
7364
+ }
7365
+ run2.view = closeOpenAgents(run2.view, at);
7366
+ try {
7367
+ await input.onEnd?.({ view: run2.view, ...result ? { result } : {} });
7368
+ } catch {
7369
+ }
7370
+ run2.finalized = true;
7371
+ this.notifySoon(true);
7372
+ }, "settle");
7373
+ void this.runtime.run({
7374
+ script: input.script,
7375
+ ...input.args !== void 0 ? { args: input.args } : {},
7376
+ ...input.limits ? { limits: input.limits } : {},
7377
+ ...input.journal ? { journal: input.journal } : {},
7378
+ runId: input.runId,
7379
+ signal: run2.abort.signal,
7380
+ onControl: /* @__PURE__ */ __name((control) => {
7381
+ run2.control = control;
7382
+ }, "onControl"),
7383
+ onEvent: /* @__PURE__ */ __name((event) => {
7384
+ run2.view = reduceRunView(run2.view, event);
7385
+ if (event.type === "workflow_agent" && !firstAgentSeen) {
7386
+ firstAgentSeen = true;
7387
+ input.onFirstAgent?.();
7388
+ }
7389
+ this.notifySoon(event.type !== "workflow_agent" || event.state !== "progress");
7390
+ }, "onEvent"),
7391
+ spawnAgent: /* @__PURE__ */ __name((request, signal) => input.spawn(request, signal, (viewId) => {
7392
+ run2.view = attachAgentView(run2.view, request.index, viewId);
7393
+ this.notifySoon(false);
7394
+ }), "spawnAgent")
7395
+ }).then(
7396
+ (result) => settle(result),
7397
+ (error) => settle(void 0, error instanceof Error ? error.message : String(error))
7398
+ );
7399
+ return run2.view;
7400
+ }
7401
+ /**
7402
+ * Resolves once no run is going, or when `signal` aborts (whichever is first).
7403
+ * A run's own limits bound the wait: the runtime stops one at its duration cap.
7404
+ */
7405
+ whenIdle(signal) {
7406
+ const going = /* @__PURE__ */ __name(() => [...this.runs.values()].some((run2) => !run2.finalized), "going");
7407
+ if (!going() || signal?.aborted) return Promise.resolve();
7408
+ return new Promise((resolve9) => {
7409
+ const done = /* @__PURE__ */ __name(() => {
7410
+ off();
7411
+ signal?.removeEventListener("abort", done);
7412
+ resolve9();
7413
+ }, "done");
7414
+ const off = this.subscribe(() => {
7415
+ if (!going()) done();
7416
+ });
7417
+ signal?.addEventListener("abort", done, { once: true });
7418
+ });
7419
+ }
7420
+ /** Stop a run: queued agents never start, running ones are aborted. False when it is not running. */
7421
+ stop(runId) {
7422
+ const run2 = this.runs.get(runId);
7423
+ if (!run2 || run2.view.status !== "running") return false;
7424
+ run2.abort.abort(new Error("The operator stopped this workflow."));
7425
+ return true;
7426
+ }
7427
+ /** Skip one agent of a run. False when it is not running or already settled. */
7428
+ skipAgent(runId, index) {
7429
+ const run2 = this.runs.get(runId);
7430
+ if (!run2 || run2.view.status !== "running") return false;
7431
+ return run2.control?.skipAgent(index) ?? false;
7432
+ }
7433
+ /** Which run and agent a monitor row stands for, if any. */
7434
+ agentOf(viewId) {
7435
+ for (const run2 of this.runs.values()) {
7436
+ const agent = run2.view.agents.find((item) => item.viewId === viewId);
7437
+ if (agent) return { runId: run2.view.runId, index: agent.index };
7438
+ }
7439
+ return void 0;
7440
+ }
7441
+ /**
7442
+ * Forget one run that has ended, so nothing lists it. For a run the tool
7443
+ * answered inline: it never became background work. False when the run is
7444
+ * unknown or still going.
7445
+ */
7446
+ discard(runId) {
7447
+ const run2 = this.runs.get(runId);
7448
+ if (!run2 || run2.view.status === "running") return false;
7449
+ this.runs.delete(runId);
7450
+ this.notifySoon(true);
7451
+ return true;
7452
+ }
7453
+ /** Forget runs that have ended (a new conversation). Running ones are stopped first. */
7454
+ reset() {
7455
+ for (const run2 of this.runs.values()) run2.abort.abort(new Error("The conversation changed."));
7456
+ this.runs.clear();
7457
+ this.notifySoon(true);
7458
+ }
7459
+ close() {
7460
+ this.closed = true;
7461
+ for (const run2 of this.runs.values()) run2.abort.abort(new Error("The session ended."));
7462
+ if (this.notifyTimer) clearTimeout(this.notifyTimer);
7463
+ this.notifyTimer = void 0;
7464
+ this.listeners.clear();
7465
+ }
7466
+ notifySoon(now) {
7467
+ if (this.closed) return;
7468
+ if (now) {
7469
+ if (this.notifyTimer) clearTimeout(this.notifyTimer);
7470
+ this.notifyTimer = void 0;
7471
+ for (const listener of [...this.listeners]) listener();
7472
+ return;
7473
+ }
7474
+ if (this.notifyTimer) return;
7475
+ this.notifyTimer = setTimeout(() => {
7476
+ this.notifyTimer = void 0;
7477
+ for (const listener of [...this.listeners]) listener();
7478
+ }, 100);
7479
+ this.notifyTimer.unref?.();
7480
+ }
7481
+ };
7482
+
7483
+ // src/integrations/workflows/host.ts
7484
+ var MAX_WORKFLOW_SCRIPT_CHARS = 262144;
7485
+ var MAX_WORKFLOW_ARGS_CHARS = 65536;
7486
+ var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
7487
+ function createWorkflowRunId(isTaken = () => false) {
7488
+ for (; ; ) {
7489
+ let body = "";
7490
+ while (body.length < 8) {
7491
+ for (const byte of randomBytes3(16)) {
7492
+ if (byte >= 252) continue;
7493
+ body += ALPHABET[byte % 36];
7494
+ if (body.length === 8) break;
7495
+ }
7496
+ }
7497
+ const id = `w${body}`;
7498
+ if (!isTaken(id)) return id;
7499
+ }
7500
+ }
7501
+ __name(createWorkflowRunId, "createWorkflowRunId");
7502
+ function endedBeforeAgents(end, noArgs) {
7503
+ const { view } = end;
7504
+ if (view.status === "completed") {
7505
+ return {
7506
+ success: true,
7507
+ output: completionNotice(view),
7508
+ data: { run_id: view.runId, name: view.name, status: "completed", inline: true }
7509
+ };
7510
+ }
7511
+ const reason = view.error ?? "no reason was given";
7512
+ const hint = view.status === "failed" && noArgs ? '\nThis call passed no "args", so `args` was undefined in the script.' : "";
7513
+ return {
7514
+ success: false,
7515
+ output: "",
7516
+ error: view.status === "stopped" ? `Workflow "${view.name}" was stopped before it started any agent${view.error ? `: ${reason}` : "."}` : `${reason}${hint}`
7517
+ };
7518
+ }
7519
+ __name(endedBeforeAgents, "endedBeforeAgents");
7520
+ function toolName(label) {
7521
+ if (!label) return { name: "tool" };
7522
+ const open3 = label.indexOf("(");
7523
+ return open3 > 0 ? { name: label.slice(0, open3), summary: label } : { name: label, summary: label };
7524
+ }
7525
+ __name(toolName, "toolName");
7526
+ function describeWorkflowCall(input) {
7527
+ if (typeof input.description === "string" && input.description.trim().length > 0) {
7528
+ return input.description.trim().replace(/\s+/g, " ");
7529
+ }
7530
+ if (typeof input.script === "string") {
7531
+ try {
7532
+ return parseWorkflowMeta(input.script).description.replace(/\s+/g, " ");
7533
+ } catch {
7534
+ const first = input.script.split("\n").find((line) => line.trim().length > 0);
7535
+ if (first) return first.trim().slice(0, 80);
7536
+ }
7537
+ }
7538
+ return "workflow";
7539
+ }
7540
+ __name(describeWorkflowCall, "describeWorkflowCall");
7541
+ function createWorkflowHost(options) {
7542
+ const registry = options.registry ?? new WorkflowRunRegistry();
7543
+ const tool = defineTool({
7544
+ name: WORKFLOW_TOOL_NAME,
7545
+ description: WORKFLOW_TOOL_DESCRIPTION,
7546
+ inputSchema: mcpJsonSchemaToZod({
7547
+ type: "object",
7548
+ properties: {
7549
+ script: {
7550
+ type: "string",
7551
+ maxLength: MAX_WORKFLOW_SCRIPT_CHARS,
7552
+ description: "The workflow script: `export const meta = {...}` first, then the code. Plain JavaScript, not wrapped in a function or a code fence."
7553
+ },
7554
+ args: {
7555
+ description: "JSON the script reads as `args`; undefined when omitted, so pass it or hard-code the values. Keep it small; the operator reads it before the run starts."
7556
+ },
7557
+ description: {
7558
+ type: "string",
7559
+ maxLength: 200,
7560
+ description: "Optional one-line summary shown to the operator instead of meta.description."
7561
+ }
7562
+ },
7563
+ required: ["script"],
7564
+ additionalProperties: false
7565
+ }),
7566
+ largeStringArguments: { script: 2e4 },
7567
+ truncatedInputHint: "Write a shorter script: shared helpers, loops instead of repeated lines, and prompts built from args.",
7568
+ 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 \\\\.',
7569
+ // The person reads `Workflow(<what it is for>)`, never the script.
7570
+ presentCall: /* @__PURE__ */ __name((input) => ({
7571
+ kind: "generic",
7572
+ label: `Workflow(${describeWorkflowCall(input)})`,
7573
+ presentation: "activity"
7574
+ }), "presentCall"),
7575
+ category: "custom",
7576
+ permissions: [],
7577
+ readOnly: false,
7578
+ destructive: false,
7579
+ concurrencySafe: false,
7580
+ async execute(input, context) {
7581
+ const { script, args } = input;
7582
+ const refused = options.refusal(context.turnId);
7583
+ if (refused !== void 0) return { success: false, output: "", error: refused };
7584
+ if (args !== void 0 && JSON.stringify(args).length > MAX_WORKFLOW_ARGS_CHARS) {
7585
+ return {
7586
+ success: false,
7587
+ output: "",
7588
+ error: `args is larger than ${MAX_WORKFLOW_ARGS_CHARS} characters. Pass less, or have the agents read a file.`
7589
+ };
7590
+ }
7591
+ let meta;
7592
+ try {
7593
+ meta = parseWorkflowMeta(script);
7594
+ } catch (error) {
7595
+ if (error instanceof WorkflowScriptError) {
7596
+ return { success: false, output: "", error: error.message };
7597
+ }
7598
+ throw error;
7599
+ }
7600
+ const runId = createWorkflowRunId((id) => registry.get(id) !== void 0);
7601
+ const turn = options.openRunTurn(context.turnId, runId);
7602
+ const runs = options.runsDirectory(context.turnId);
7603
+ const limits = options.limitsFor?.(context.turnId);
7604
+ const journal = runs === void 0 ? void 0 : new FileWorkflowJournal(join9(runs, runId, "workflow"));
7605
+ const phaseDetail = /* @__PURE__ */ __name((title) => title === void 0 ? void 0 : meta.phases.find((phase) => phase.title.trim() === title.trim())?.detail, "phaseDetail");
7606
+ let launching = true;
7607
+ let settleLaunch = /* @__PURE__ */ __name(() => {
7608
+ }, "settleLaunch");
7609
+ const launch = new Promise((resolve9) => {
7610
+ settleLaunch = resolve9;
7611
+ });
7612
+ const detach = /* @__PURE__ */ __name(() => {
7613
+ if (!launching) return;
7614
+ launching = false;
7615
+ settleLaunch({ kind: "background" });
7616
+ }, "detach");
7617
+ const onAbort = /* @__PURE__ */ __name(() => detach(), "onAbort");
7618
+ context.abortSignal.addEventListener("abort", onAbort, { once: true });
7619
+ try {
7620
+ const view = registry.start({
7621
+ runId,
7622
+ meta,
7623
+ script,
7624
+ ...args !== void 0 ? { args } : {},
7625
+ ...limits ? { limits } : {},
7626
+ ...journal ? { journal } : {},
7627
+ spawn: /* @__PURE__ */ __name(async (request, signal, viewed) => {
7628
+ const detail = phaseDetail(request.phaseTitle);
7629
+ const outcome2 = await options.subagents.launchWorkflowAgent({
7630
+ turnId: turn.turnId,
7631
+ runId,
7632
+ workflowName: meta.name,
7633
+ label: request.label,
7634
+ prompt: request.prompt,
7635
+ ...request.phaseTitle !== void 0 ? { phaseTitle: request.phaseTitle } : {},
7636
+ ...request.phaseIndex !== void 0 ? { phaseIndex: request.phaseIndex } : {},
7637
+ ...detail !== void 0 ? { phaseDetail: detail } : {},
7638
+ ...request.agentType !== void 0 ? { agentType: request.agentType } : {},
7639
+ ...request.model !== void 0 ? { model: request.model } : {},
7640
+ ...request.effort !== void 0 ? { effort: request.effort } : {},
7641
+ ...request.schema !== void 0 ? { schema: request.schema } : {},
7642
+ signal,
7643
+ inherit: {
7644
+ ...context.env ? { env: context.env } : {},
7645
+ ...context.toolResultGuardrails ? { toolResultGuardrails: context.toolResultGuardrails } : {}
7646
+ },
7647
+ onView: viewed,
7648
+ onProgress: /* @__PURE__ */ __name((progress) => {
7649
+ const last = toolName(progress.lastTool);
7650
+ request.onProgress({
7651
+ ...progress.tokens !== void 0 ? { tokens: progress.tokens } : {},
7652
+ ...progress.toolCalls !== void 0 ? { toolCalls: progress.toolCalls } : {},
7653
+ ...progress.lastTool !== void 0 ? {
7654
+ lastToolName: last.name,
7655
+ lastToolSummary: last.summary ?? last.name
7656
+ } : {}
7657
+ });
7658
+ }, "onProgress")
7659
+ });
7660
+ return {
7661
+ state: outcome2.state,
7662
+ ...outcome2.text !== void 0 ? { text: outcome2.text } : {},
7663
+ tokens: outcome2.tokens,
7664
+ toolCalls: outcome2.toolCalls,
7665
+ ...outcome2.error !== void 0 ? { error: outcome2.error } : {}
7666
+ };
7667
+ }, "spawn"),
7668
+ onFirstAgent: detach,
7669
+ onEnd: /* @__PURE__ */ __name(async (end) => {
7670
+ await turn.release().catch(() => void 0);
7671
+ if (launching) {
7672
+ launching = false;
7673
+ settleLaunch({ kind: "ended", end });
7674
+ return;
7675
+ }
7676
+ options.onEnd?.(end);
7677
+ }, "onEnd")
7678
+ });
7679
+ void view;
7680
+ const outcome = await launch;
7681
+ context.abortSignal.removeEventListener("abort", onAbort);
7682
+ if (outcome.kind === "ended") {
7683
+ registry.discard(runId);
7684
+ return endedBeforeAgents(outcome.end, args === void 0);
7685
+ }
7686
+ return {
7687
+ success: true,
7688
+ output: launchedText(view),
7689
+ data: {
7690
+ run_id: runId,
7691
+ name: meta.name,
7692
+ description: input && typeof input.description === "string" ? input.description : meta.description,
7693
+ phases: meta.phases.map((phase) => phase.title)
7694
+ }
7695
+ };
7696
+ } catch (error) {
7697
+ context.abortSignal.removeEventListener("abort", onAbort);
7698
+ await turn.release();
7699
+ throw error;
7700
+ }
7701
+ }
7702
+ });
7703
+ return { registry, tool };
7704
+ }
7705
+ __name(createWorkflowHost, "createWorkflowHost");
7706
+
7066
7707
  // src/memory/store.ts
7067
7708
  import { realpathSync as realpathSync3 } from "node:fs";
7068
- import { join as join9, resolve as resolve7 } from "node:path";
7709
+ import { join as join11, resolve as resolve7 } from "node:path";
7069
7710
 
7070
7711
  // src/memory/io.ts
7071
7712
  import {
@@ -7079,7 +7720,7 @@ import {
7079
7720
  realpathSync as realpathSync2,
7080
7721
  writeSync
7081
7722
  } from "node:fs";
7082
- import { isAbsolute as isAbsolute5, join as join8, relative as relative5, resolve as resolve6, sep as sep4 } from "node:path";
7723
+ import { isAbsolute as isAbsolute5, join as join10, relative as relative5, resolve as resolve6, sep as sep4 } from "node:path";
7083
7724
  var MEMORY_FILE_MAX_BYTES = 1024 * 1024;
7084
7725
  function missing(error) {
7085
7726
  return error.code === "ENOENT";
@@ -7112,7 +7753,7 @@ function resolveMemoryPath(location, createParents = false) {
7112
7753
  for (let i = 0; i < parts.length; i += 1) {
7113
7754
  const part = parts[i];
7114
7755
  if (part === void 0) throw new Error("Memory path has an invalid segment.");
7115
- candidate = join8(candidate, part);
7756
+ candidate = join10(candidate, part);
7116
7757
  const leaf = i === parts.length - 1;
7117
7758
  let stat5;
7118
7759
  try {
@@ -7242,11 +7883,11 @@ function memoryDir(home) {
7242
7883
  }
7243
7884
  __name(memoryDir, "memoryDir");
7244
7885
  function userFilePath(home) {
7245
- return join9(memoryDir(home), "USER.md");
7886
+ return join11(memoryDir(home), "USER.md");
7246
7887
  }
7247
7888
  __name(userFilePath, "userFilePath");
7248
7889
  function memoryFilePath(home) {
7249
- return join9(memoryDir(home), "MEMORY.md");
7890
+ return join11(memoryDir(home), "MEMORY.md");
7250
7891
  }
7251
7892
  __name(memoryFilePath, "memoryFilePath");
7252
7893
  function projectMemoryFilePath(cwd) {
@@ -7257,9 +7898,9 @@ function projectMemoryFilePath(cwd) {
7257
7898
  if (error.code !== "ENOENT") throw error;
7258
7899
  }
7259
7900
  const root = cliProjectRoot(directory);
7260
- const local = join9(directory, ".namzu", "MEMORY.md");
7901
+ const local = join11(directory, ".namzu", "MEMORY.md");
7261
7902
  if (resolveMemoryPath({ path: local, root }) !== null) return local;
7262
- return join9(root, ".namzu", "MEMORY.md");
7903
+ return join11(root, ".namzu", "MEMORY.md");
7263
7904
  }
7264
7905
  __name(projectMemoryFilePath, "projectMemoryFilePath");
7265
7906
  function projectMemoryLocation(cwd) {
@@ -7289,15 +7930,15 @@ function readMemory(home, cwd) {
7289
7930
  }
7290
7931
  }, "read");
7291
7932
  const userRoot = memoryDir(home);
7292
- const user = read(join9(userRoot, "USER.md"), () => ({
7933
+ const user = read(join11(userRoot, "USER.md"), () => ({
7293
7934
  root: userRoot,
7294
- path: join9(userRoot, "USER.md")
7935
+ path: join11(userRoot, "USER.md")
7295
7936
  }));
7296
- const memory = read(join9(userRoot, "MEMORY.md"), () => ({
7937
+ const memory = read(join11(userRoot, "MEMORY.md"), () => ({
7297
7938
  root: userRoot,
7298
- path: join9(userRoot, "MEMORY.md")
7939
+ path: join11(userRoot, "MEMORY.md")
7299
7940
  }));
7300
- const project = cwd && !isUserMemoryFile(join9(resolve7(cwd), ".namzu", "MEMORY.md"), userRoot) ? read(join9(resolve7(cwd), ".namzu", "MEMORY.md"), () => projectLocation(cwd)) : null;
7941
+ const project = cwd && !isUserMemoryFile(join11(resolve7(cwd), ".namzu", "MEMORY.md"), userRoot) ? read(join11(resolve7(cwd), ".namzu", "MEMORY.md"), () => projectLocation(cwd)) : null;
7301
7942
  return { user, memory, project, ...diagnostics.length > 0 ? { diagnostics } : {} };
7302
7943
  }
7303
7944
  __name(readMemory, "readMemory");
@@ -7309,7 +7950,7 @@ function isUserMemoryFile(projectPath, userRoot) {
7309
7950
  return resolve7(path);
7310
7951
  }
7311
7952
  }, "canonical");
7312
- return canonical(projectPath) === canonical(join9(userRoot, "MEMORY.md"));
7953
+ return canonical(projectPath) === canonical(join11(userRoot, "MEMORY.md"));
7313
7954
  }
7314
7955
  __name(isUserMemoryFile, "isUserMemoryFile");
7315
7956
  function capped(text, file) {
@@ -7458,8 +8099,8 @@ __name(renderStoredMemorySection, "renderStoredMemorySection");
7458
8099
 
7459
8100
  // src/memory/typed.ts
7460
8101
  import { createHash as createHash4 } from "node:crypto";
7461
- import { access, readFile as readFile3, rename as rename3, writeFile as writeFile2 } from "node:fs/promises";
7462
- import { join as join10 } from "node:path";
8102
+ import { access, readFile as readFile4, rename as rename3, writeFile as writeFile2 } from "node:fs/promises";
8103
+ import { join as join12 } from "node:path";
7463
8104
  function firstLine2(text, limit) {
7464
8105
  const line = (text.split(/\r?\n/).find((part) => part.trim()) ?? "").replace(/\s+/g, " ").trim();
7465
8106
  if (line.length <= limit) return line;
@@ -7483,7 +8124,7 @@ async function saveTypedNote(store, text, type = "project") {
7483
8124
  saved: false,
7484
8125
  duplicate: true,
7485
8126
  type: record.entry.type ?? type,
7486
- ...record.entry.name ? { name: record.entry.name, path: join10(store.path, `${record.entry.name}.md`) } : {}
8127
+ ...record.entry.name ? { name: record.entry.name, path: join12(store.path, `${record.entry.name}.md`) } : {}
7487
8128
  };
7488
8129
  }
7489
8130
  }
@@ -7498,7 +8139,7 @@ async function saveTypedNote(store, text, type = "project") {
7498
8139
  return {
7499
8140
  saved: true,
7500
8141
  type,
7501
- ...entry.name ? { name: entry.name, path: join10(store.path, `${entry.name}.md`) } : {}
8142
+ ...entry.name ? { name: entry.name, path: join12(store.path, `${entry.name}.md`) } : {}
7502
8143
  };
7503
8144
  }
7504
8145
  __name(saveTypedNote, "saveTypedNote");
@@ -7516,7 +8157,7 @@ __name(composeStoredMemoryPrompt, "composeStoredMemoryPrompt");
7516
8157
  var MARKER = "migration.json";
7517
8158
  async function readMarker(directory) {
7518
8159
  try {
7519
- const parsed = JSON.parse(await readFile3(join10(directory, MARKER), "utf8"));
8160
+ const parsed = JSON.parse(await readFile4(join12(directory, MARKER), "utf8"));
7520
8161
  return parsed !== null && typeof parsed === "object" ? parsed : {};
7521
8162
  } catch (error) {
7522
8163
  if (error.code === "ENOENT") return {};
@@ -7529,7 +8170,7 @@ async function markCuratedFile(directory, path, state) {
7529
8170
  const files = { ...marker.curatedFiles ?? {} };
7530
8171
  files[path] = { ...files[path] ?? {}, ...state };
7531
8172
  await writeFile2(
7532
- join10(directory, MARKER),
8173
+ join12(directory, MARKER),
7533
8174
  `${JSON.stringify({ ...marker, curatedFiles: files }, null, 2)}
7534
8175
  `,
7535
8176
  { mode: 384 }
@@ -7596,7 +8237,7 @@ async function migrateMemoryOnce(options) {
7596
8237
  const skippedRecords = [];
7597
8238
  let importedRecords = 0;
7598
8239
  let notesOffer;
7599
- const indexPath = join10(directory, "index.json");
8240
+ const indexPath = join12(directory, "index.json");
7600
8241
  if (await exists(indexPath)) {
7601
8242
  try {
7602
8243
  const disk = new DiskMemoryStore({ baseDir: directory, directory });
@@ -7619,11 +8260,11 @@ async function migrateMemoryOnce(options) {
7619
8260
  }
7620
8261
  }
7621
8262
  await retire(indexPath);
7622
- const content = join10(directory, "content");
8263
+ const content = join12(directory, "content");
7623
8264
  const retiredContent = await exists(content) ? await retire(content) : content;
7624
8265
  for (const record of refused) {
7625
8266
  skippedRecords.push(
7626
- `"${record.title}" (${record.id}) was not moved: ${record.reason} It is kept in ${join10(retiredContent, `${record.id}.json`)}.`
8267
+ `"${record.title}" (${record.id}) was not moved: ${record.reason} It is kept in ${join12(retiredContent, `${record.id}.json`)}.`
7627
8268
  );
7628
8269
  }
7629
8270
  } catch (error) {
@@ -7985,25 +8626,25 @@ __name(admitToolView, "admitToolView");
7985
8626
  function createCliToolPresenter(registry) {
7986
8627
  const log = cliLogger().child({ [SCOPE_ATTRIBUTE]: "cli/tool-presentation" });
7987
8628
  const presenter = createToolPresenter(registry, log);
7988
- const admit = /* @__PURE__ */ __name((toolName, hook, present) => {
8629
+ const admit = /* @__PURE__ */ __name((toolName2, hook, present) => {
7989
8630
  try {
7990
8631
  const view = admitToolView(present());
7991
8632
  if (view) return view;
7992
8633
  } catch {
7993
8634
  }
7994
8635
  log.warn("Tool presentation was invalid; using a plain view", {
7995
- "namzu.tool.name": toolName,
8636
+ "namzu.tool.name": toolName2,
7996
8637
  "namzu.tool.presenter_hook": hook
7997
8638
  });
7998
8639
  return void 0;
7999
8640
  }, "admit");
8000
8641
  return {
8001
- presentCall: /* @__PURE__ */ __name((toolName, input) => admit(toolName, "presentCall", () => presenter.presentCall(toolName, input)) ?? {
8642
+ presentCall: /* @__PURE__ */ __name((toolName2, input) => admit(toolName2, "presentCall", () => presenter.presentCall(toolName2, input)) ?? {
8002
8643
  kind: "generic",
8003
8644
  // Never stringify unreadable input as a replacement for a broken label.
8004
- label: toolName
8645
+ label: toolName2
8005
8646
  }, "presentCall"),
8006
- presentResult: /* @__PURE__ */ __name((toolName, input, result) => admit(toolName, "presentResult", () => presenter.presentResult(toolName, input, result)) ?? {
8647
+ presentResult: /* @__PURE__ */ __name((toolName2, input, result) => admit(toolName2, "presentResult", () => presenter.presentResult(toolName2, input, result)) ?? {
8007
8648
  kind: "terminal",
8008
8649
  output: (result.success ? result.output : result.error ?? result.output) ?? ""
8009
8650
  }, "presentResult")
@@ -8360,10 +9001,10 @@ function clipRequestContext(prompt, limit, kind) {
8360
9001
  __name(clipRequestContext, "clipRequestContext");
8361
9002
  async function createAgentSession(prefs, detected, options = {}) {
8362
9003
  if (options.palEnvironment) {
8363
- const { createPalAgentSession } = await import("./agent-session-C2HDOXK4.js");
9004
+ const { createPalAgentSession } = await import("./agent-session-DU55LD4P.js");
8364
9005
  return createPalAgentSession(prefs, detected, options);
8365
9006
  }
8366
- const { palAtWorkspace } = await import("./store-2PDDGKYZ.js");
9007
+ const { palAtWorkspace } = await import("./store-7WZWQXKX.js");
8367
9008
  if (palAtWorkspace(options.cwd ?? process.cwd()))
8368
9009
  throw new Error("This Pal requires its owned virtual computer. Open it with namzu pal chat.");
8369
9010
  const fileObservations = /* @__PURE__ */ new Map();
@@ -8843,6 +9484,9 @@ async function createAgentSession(prefs, detected, options = {}) {
8843
9484
  const goalAuthorities = /* @__PURE__ */ new Map();
8844
9485
  const delegatedResumeHandlers = /* @__PURE__ */ new Map();
8845
9486
  const delegatedReviewAllowedCalls = /* @__PURE__ */ new Map();
9487
+ const delegatedWorkflowAuth = /* @__PURE__ */ new Map();
9488
+ let workflowHost;
9489
+ const workflowEndListeners = /* @__PURE__ */ new Set();
8846
9490
  const goalToolNames = new Set(SESSION_GOAL_TOOL_NAMES);
8847
9491
  if (options.sessionGoals) {
8848
9492
  toolsets.push(
@@ -9152,6 +9796,73 @@ async function createAgentSession(prefs, detected, options = {}) {
9152
9796
  new ToolManager({ toolsets: agentToolsets, messages: /* @__PURE__ */ __name(() => [], "messages") }).dispose();
9153
9797
  toolsets.push(...agentToolsets);
9154
9798
  allowedAgentIds = sub.allowedAgentIds;
9799
+ workflowHost = createWorkflowHost({
9800
+ subagents: sub,
9801
+ runsDirectory: /* @__PURE__ */ __name((turnId) => {
9802
+ if (options.ephemeral) return void 0;
9803
+ const owner = delegationScopes.get(turnId) ?? scope;
9804
+ return join13(paths.sessionDir({ sessionId: owner.sessionId }), "runs");
9805
+ }, "runsDirectory"),
9806
+ refusal: /* @__PURE__ */ __name((turnId) => {
9807
+ const auth = delegatedWorkflowAuth.get(turnId);
9808
+ if (!auth) return "This turn cannot start a workflow.";
9809
+ return workflowRefusal({ interactive: auth.interactive, mode: auth.mode() });
9810
+ }, "refusal"),
9811
+ openRunTurn: /* @__PURE__ */ __name((originTurnId, runId) => {
9812
+ const runTurnId = generateTurnId();
9813
+ const origin = delegatedWorkflowAuth.get(originTurnId);
9814
+ const ownerScope = delegationScopes.get(originTurnId) ?? { ...scope };
9815
+ const control = createLiveModeControl({
9816
+ initial: origin?.mode() ?? "prompt",
9817
+ ...origin ? { read: origin.mode } : {},
9818
+ handlerFor: /* @__PURE__ */ __name((mode) => makeResumeHandler(
9819
+ approval,
9820
+ origin?.reviewer?.onPermission,
9821
+ mode,
9822
+ reviewExemptionFor(mode, manager, (input) => sub.launchesReadOnlyAgent(input)),
9823
+ { unattendedSandboxEscape },
9824
+ screenPolicyFor(() => manager)
9825
+ ), "handlerFor")
9826
+ });
9827
+ liveModeControls.add(control);
9828
+ delegationScopes.set(runTurnId, ownerScope);
9829
+ delegationLimits.set(
9830
+ runTurnId,
9831
+ delegationLimits.get(originTurnId) ?? resolveTurnGuards(options.limits, void 0)
9832
+ );
9833
+ delegatedResumeHandlers.set(runTurnId, control.handler);
9834
+ delegatedReviewAllowedCalls.set(runTurnId, control.reviewAllowedCalls);
9835
+ const model2 = delegationModels.get(originTurnId);
9836
+ if (model2) delegationModels.set(runTurnId, model2);
9837
+ void runId;
9838
+ let released;
9839
+ return {
9840
+ turnId: runTurnId,
9841
+ release: /* @__PURE__ */ __name(() => {
9842
+ released ??= (async () => {
9843
+ liveModeControls.delete(control);
9844
+ delegationScopes.delete(runTurnId);
9845
+ delegationLimits.delete(runTurnId);
9846
+ delegatedResumeHandlers.delete(runTurnId);
9847
+ delegatedReviewAllowedCalls.delete(runTurnId);
9848
+ delegationModels.delete(runTurnId);
9849
+ await sub.releaseTurn(runTurnId);
9850
+ })();
9851
+ return released;
9852
+ }, "release")
9853
+ };
9854
+ }, "openRunTurn"),
9855
+ limitsFor: /* @__PURE__ */ __name((turnId) => {
9856
+ const budget = delegationLimits.get(turnId)?.tokenBudget;
9857
+ return {
9858
+ ...budget !== void 0 && budget > 0 ? { tokenBudget: budget } : {},
9859
+ ...options.workflow
9860
+ };
9861
+ }, "limitsFor"),
9862
+ onEnd: /* @__PURE__ */ __name((end) => {
9863
+ for (const listener of [...workflowEndListeners]) listener(end);
9864
+ }, "onEnd")
9865
+ });
9155
9866
  } catch (err) {
9156
9867
  try {
9157
9868
  await subagentRuntime?.close();
@@ -9223,7 +9934,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9223
9934
  if (options.openUrl) toolsets.push(toolset("open-url", [createOpenUrlTool()]));
9224
9935
  const decisionTool = maybeCreateDecisionTool(options.decision, process.env);
9225
9936
  if (decisionTool) toolsets.push(toolset("decide", [decisionTool]));
9226
- const operatorPals = await import("./operator-tools-GI63VOXH.js");
9937
+ const operatorPals = await import("./operator-tools-H4MYC5PE.js");
9227
9938
  toolsets.push(
9228
9939
  readyWhen(
9229
9940
  toolset(
@@ -9356,6 +10067,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9356
10067
  const reasoningLookup = new AbortController();
9357
10068
  const operations = new SessionOperationOwner(async () => {
9358
10069
  reasoningLookup.abort();
10070
+ workflowHost?.registry.close();
9359
10071
  const results = await Promise.allSettled([
9360
10072
  Promise.resolve().then(() => manager.dispose()),
9361
10073
  options.conversationSessions ? releaseConversationEvidence(options.conversationSessions, scope.sessionId) : void 0,
@@ -9828,6 +10540,32 @@ async function createAgentSession(prefs, detected, options = {}) {
9828
10540
  if (job.owner === jobOwner) listener(job);
9829
10541
  }) ?? (() => {
9830
10542
  }), "onJobExit"),
10543
+ ...workflowHost ? {
10544
+ workflows: /* @__PURE__ */ ((host) => ({
10545
+ runs: /* @__PURE__ */ __name(() => host.registry.list(), "runs"),
10546
+ subscribe: /* @__PURE__ */ __name((listener) => host.registry.subscribe(listener), "subscribe"),
10547
+ stop: /* @__PURE__ */ __name((runId) => host.registry.stop(runId), "stop"),
10548
+ skipAgent: /* @__PURE__ */ __name((runId, index) => host.registry.skipAgent(runId, index), "skipAgent"),
10549
+ agentOf: /* @__PURE__ */ __name((viewId) => host.registry.agentOf(viewId), "agentOf"),
10550
+ history: /* @__PURE__ */ __name(async () => {
10551
+ const live = host.registry.list();
10552
+ const known = new Set(live.map((view) => view.runId));
10553
+ const saved = options.ephemeral ? [] : await listWorkflowRuns(
10554
+ join13(paths.sessionDir({ sessionId: scope.sessionId }), "runs")
10555
+ ).catch(() => []);
10556
+ return [
10557
+ ...[...live].sort((a, b) => b.startedAt - a.startedAt),
10558
+ ...saved.filter((view) => !known.has(view.runId))
10559
+ ];
10560
+ }, "history"),
10561
+ onEnd: /* @__PURE__ */ __name((listener) => {
10562
+ workflowEndListeners.add(listener);
10563
+ return () => workflowEndListeners.delete(listener);
10564
+ }, "onEnd"),
10565
+ idle: /* @__PURE__ */ __name((signal) => host.registry.whenIdle(signal), "idle"),
10566
+ reset: /* @__PURE__ */ __name(() => host.registry.reset(), "reset")
10567
+ }))(workflowHost)
10568
+ } : {},
9831
10569
  ...subagentRuntime ? {
9832
10570
  subagents: subagentRuntime.activity,
9833
10571
  onSubagentReport: /* @__PURE__ */ __name((listener) => {
@@ -9836,6 +10574,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9836
10574
  directChildReports.delete(listener);
9837
10575
  };
9838
10576
  }, "onSubagentReport"),
10577
+ stopSubagent: /* @__PURE__ */ __name((viewId) => subagentRuntime?.stopChild(viewId) ?? false, "stopSubagent"),
9839
10578
  messageSubagent: /* @__PURE__ */ __name((viewId, message2, opts) => operations.promise(opts?.signal, async (signal) => {
9840
10579
  const runtime = subagentRuntime;
9841
10580
  if (!runtime) throw new Error("Delegation is unavailable.");
@@ -9976,6 +10715,8 @@ async function createAgentSession(prefs, detected, options = {}) {
9976
10715
  mcpStatus: /* @__PURE__ */ __name(() => mcp.current(), "mcpStatus"),
9977
10716
  ...browserControl ? { browser: browserControl } : {},
9978
10717
  configNotices: [
10718
+ // Git for Windows is missing and the shell tool runs cmd.exe: said once, here.
10719
+ ...sandbox.provider === void 0 && windowsShellNotice() !== void 0 ? [windowsShellNotice()] : [],
9979
10720
  ...capabilityNotice ? [capabilityNotice] : [],
9980
10721
  ...effortNotice ? [effortNotice] : [],
9981
10722
  ...passthroughNotice ? [passthroughNotice] : [],
@@ -10084,6 +10825,11 @@ async function createAgentSession(prefs, detected, options = {}) {
10084
10825
  if (opts?.waitForInbound) delegatedInputWaiters.set(turnId2, opts.waitForInbound);
10085
10826
  delegationScopes.set(turnId2, turnScope);
10086
10827
  delegationLimits.set(turnId2, turnLimits);
10828
+ delegatedWorkflowAuth.set(turnId2, {
10829
+ interactive: opts?.workflowReview?.onPermission !== void 0,
10830
+ mode: /* @__PURE__ */ __name(() => modeControl.current(), "mode"),
10831
+ reviewer: opts?.workflowReview
10832
+ });
10087
10833
  if (capturedAuthority) {
10088
10834
  if (goalAuthorities.has(turnId2)) {
10089
10835
  throw new Error(`Turn ${turnId2} already owns goal-round authority.`);
@@ -10198,6 +10944,19 @@ async function createAgentSession(prefs, detected, options = {}) {
10198
10944
  render: /* @__PURE__ */ __name(() => invocationContext, "render")
10199
10945
  });
10200
10946
  }
10947
+ const workflowOffer = workflowHost !== void 0 && opts?.workflowReview !== void 0 && !residentContext && workflowOffered({
10948
+ hypermode: opts?.hypermode === true,
10949
+ userText: lastUserText(messages)
10950
+ });
10951
+ if (workflowOffer && workflowHost) {
10952
+ runToolsets = [...runToolsets, toolset("workflow", [workflowHost.tool])];
10953
+ if (runManager !== manager) runManager.dispose();
10954
+ runManager = new ToolManager({
10955
+ toolsets: runToolsets,
10956
+ ...screensConfig !== void 0 ? { resultGuardrails: screensConfig } : {},
10957
+ messages: /* @__PURE__ */ __name(() => [], "messages")
10958
+ });
10959
+ }
10201
10960
  const systemPrompt = [
10202
10961
  NAMZU_IDENTITY,
10203
10962
  residentContext ? void 0 : CODING_AGENT_WORKING_DOCTRINE,
@@ -10207,6 +10966,7 @@ async function createAgentSession(prefs, detected, options = {}) {
10207
10966
  // to use a tool it was not sent.
10208
10967
  residentContext || options.withheldTools?.includes(AGENT_LAUNCH_TOOL) ? void 0 : CODING_AGENT_DELEGATION_DOCTRINE,
10209
10968
  !residentContext && opts?.hypermode ? CODING_AGENT_HYPERMODE_DOCTRINE : void 0,
10969
+ workflowOffer ? WORKFLOW_DOCTRINE : void 0,
10210
10970
  residentContext ? void 0 : palPromptBlock(),
10211
10971
  options.conversationSessions ? CONVERSATION_EVIDENCE_GUIDANCE : void 0,
10212
10972
  options.toolLoading === "deferred" ? DEFERRED_TOOL_GUIDANCE : void 0,
@@ -10374,6 +11134,7 @@ async function createAgentSession(prefs, detected, options = {}) {
10374
11134
  delegatedInputWaiters.delete(turnId2);
10375
11135
  delegationScopes.delete(turnId2);
10376
11136
  delegationLimits.delete(turnId2);
11137
+ delegatedWorkflowAuth.delete(turnId2);
10377
11138
  await subagentRuntime?.releaseTurn(turnId2);
10378
11139
  }
10379
11140
  }
@@ -11054,9 +11815,9 @@ function confirmsItself(name, input) {
11054
11815
  }
11055
11816
  __name(confirmsItself, "confirmsItself");
11056
11817
  function declaredReadOnly(manager) {
11057
- return (toolName, input) => {
11818
+ return (toolName2, input) => {
11058
11819
  try {
11059
- return manager.get(toolName)?.isReadOnly?.(input) === true;
11820
+ return manager.get(toolName2)?.isReadOnly?.(input) === true;
11060
11821
  } catch {
11061
11822
  return false;
11062
11823
  }
@@ -11127,6 +11888,10 @@ function toAgentEvent(event, presenter, readsOnly) {
11127
11888
  if (view.kind === "diff") rememberCallDiff(event.toolUseId, view);
11128
11889
  return {
11129
11890
  summary: viewToSummary(view),
11891
+ ...(() => {
11892
+ const command = view.kind === "terminal" ? view.command : view.kind === "generic" && view.facts?.kind === "command" ? view.facts.command : void 0;
11893
+ return command ? { command } : {};
11894
+ })(),
11130
11895
  ...view.kind === "generic" && view.activity ? { activity: view.activity } : {},
11131
11896
  detail: viewToLines(view),
11132
11897
  ...view.kind === "generic" && view.presentation === "activity" ? { standalone: true } : {}
@@ -11195,6 +11960,7 @@ function toAgentEvent(event, presenter, readsOnly) {
11195
11960
  summary: headline ?? summary,
11196
11961
  ...headline ? { headline } : {},
11197
11962
  ...plainFailure ? { plainFailure } : {},
11963
+ ...tidy?.shell ? { shell: tidy.shell } : {},
11198
11964
  ...event.durationMs !== void 0 ? { durationMs: event.durationMs } : {},
11199
11965
  ...view.kind === "generic" && view.visibility === "hidden" ? { hidden: true } : {},
11200
11966
  ...event.isError && view.kind === "generic" && view.outcome === "cancelled" ? { cancelled: true } : {},
@@ -11680,4 +12446,4 @@ export {
11680
12446
  RESULT_SUMMARY_WHOLE_MAX,
11681
12447
  resultSummaryLine
11682
12448
  };
11683
- //# sourceMappingURL=chunk-H7VJHF5S.js.map
12449
+ //# sourceMappingURL=chunk-H6MWKPHM.js.map