@namzu/cli 36.2.0 → 36.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/chunks/{acp-P22WRX3A.js → acp-2DS2IECT.js} +58 -34
  4. package/dist/chunks/acp-2DS2IECT.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-PAGVUATH.js} +22 -22
  8. package/dist/chunks/agent-session-PLIPF3XG.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-MWFKUXP2.js} +3 -3
  11. package/dist/chunks/{browser-JRWZ3PYX.js → browser-FZWYOIIJ.js} +6 -6
  12. package/dist/chunks/{chat-3IJFKDSN.js → chat-W355SFNQ.js} +13 -13
  13. package/dist/chunks/{chunk-S7E42272.js → chunk-2BZOT2CT.js} +2 -2
  14. package/dist/chunks/{chunk-7OEK2NAO.js → chunk-2O7KYX4V.js} +8 -8
  15. package/dist/chunks/{chunk-OS7IVIYH.js → chunk-2TGQ2B53.js} +242 -3
  16. package/dist/chunks/{chunk-OS7IVIYH.js.map → chunk-2TGQ2B53.js.map} +3 -3
  17. package/dist/chunks/{chunk-LIZPXS73.js → chunk-3F5DGROG.js} +2 -2
  18. package/dist/chunks/{chunk-NKEOCU52.js → chunk-3M3PMQ3I.js} +7 -7
  19. package/dist/chunks/{chunk-KNNQHRZ4.js → chunk-46B7KRXY.js} +6 -6
  20. package/dist/chunks/{chunk-PT7TZNBV.js → chunk-52OVP5BG.js} +4 -4
  21. package/dist/chunks/{chunk-X2YRM3UE.js → chunk-56OUKG5W.js} +3 -3
  22. package/dist/chunks/{chunk-53EZXXT4.js → chunk-5H4LJ4AN.js} +27 -9
  23. package/dist/chunks/chunk-5H4LJ4AN.js.map +6 -0
  24. package/dist/chunks/{chunk-HJ42RG5U.js → chunk-5URT3ZM2.js} +4 -4
  25. package/dist/chunks/{chunk-ZZ6Z2DO6.js → chunk-6CGC72OA.js} +10 -10
  26. package/dist/chunks/{chunk-GWOW3U2S.js → chunk-6TDJXZ5W.js} +4 -4
  27. package/dist/chunks/{chunk-7WQV2FSF.js → chunk-AHYHR5DY.js} +3 -3
  28. package/dist/chunks/{chunk-XAKL7C7B.js → chunk-AP5KD43Y.js} +2 -2
  29. package/dist/chunks/{chunk-NRML7BIR.js → chunk-AS7UWXMN.js} +4 -4
  30. package/dist/chunks/{chunk-QQLB573I.js → chunk-BOV53LZO.js} +2 -2
  31. package/dist/chunks/{chunk-GPBUDMUF.js → chunk-BUCICQWG.js} +2 -2
  32. package/dist/chunks/{chunk-5PQVJBIO.js → chunk-CZVHXYGD.js} +6 -3
  33. package/dist/chunks/{chunk-5PQVJBIO.js.map → chunk-CZVHXYGD.js.map} +1 -1
  34. package/dist/chunks/{chunk-CFN7CUD3.js → chunk-DYUOXP5Q.js} +13 -13
  35. package/dist/chunks/{chunk-G5XTLTDR.js → chunk-E7HLYLD7.js} +3 -3
  36. package/dist/chunks/{chunk-ABD2DOO2.js → chunk-EKUJUPFA.js} +4 -4
  37. package/dist/chunks/{chunk-YEFJAE2B.js → chunk-EZ6ZSHYX.js} +27 -26
  38. package/dist/chunks/{chunk-YEFJAE2B.js.map → chunk-EZ6ZSHYX.js.map} +1 -1
  39. package/dist/chunks/{chunk-AABPCENY.js → chunk-F3YQ2CSZ.js} +4 -4
  40. package/dist/chunks/{chunk-2VXA7GZU.js → chunk-FU4GQ7K2.js} +2 -2
  41. package/dist/chunks/{chunk-VHKKPDL2.js → chunk-GQN64E36.js} +3 -3
  42. package/dist/chunks/{chunk-3OZ2OBGU.js → chunk-HKDPP2JF.js} +2 -2
  43. package/dist/chunks/{chunk-YZ675PG4.js → chunk-HSEJGSXE.js} +2 -2
  44. package/dist/chunks/{chunk-ZXWJ6G3J.js → chunk-I6CDUPVR.js} +2 -2
  45. package/dist/chunks/{chunk-27VZRJTG.js → chunk-IQBR45AU.js} +2 -2
  46. package/dist/chunks/{chunk-HIZ7F6BT.js → chunk-JCDTR2ZU.js} +4 -4
  47. package/dist/chunks/{chunk-ZNAH4EGP.js → chunk-KMHLON54.js} +2 -2
  48. package/dist/chunks/{chunk-CXLSM5SH.js → chunk-KOG2WB66.js} +4 -4
  49. package/dist/chunks/{chunk-AGHVC2IJ.js → chunk-LBH5WVXU.js} +2 -2
  50. package/dist/chunks/{chunk-22P25PLK.js → chunk-LYDXPWAZ.js} +22 -4
  51. package/dist/chunks/{chunk-22P25PLK.js.map → chunk-LYDXPWAZ.js.map} +1 -1
  52. package/dist/chunks/{chunk-U5AWHJ7O.js → chunk-MBBFX64S.js} +2 -2
  53. package/dist/chunks/{chunk-PJ3UYK2K.js → chunk-MJO6CH5F.js} +3 -3
  54. package/dist/chunks/{chunk-AVIW5JJF.js → chunk-NATYSTPM.js} +2 -2
  55. package/dist/chunks/{chunk-YLIKDPD6.js → chunk-NBD5MAGK.js} +9 -9
  56. package/dist/chunks/{chunk-43FBWINL.js → chunk-PINPSIJ5.js} +5 -5
  57. package/dist/chunks/{chunk-AL6ESCHD.js → chunk-PLKJKF32.js} +12 -12
  58. package/dist/chunks/chunk-QBAISLAD.js +750 -0
  59. package/dist/chunks/chunk-QBAISLAD.js.map +6 -0
  60. package/dist/chunks/{chunk-KQOIPRZ5.js → chunk-QRT3N2K3.js} +2 -2
  61. package/dist/chunks/{chunk-DYBUCWAB.js → chunk-QXDKRJZ5.js} +3 -3
  62. package/dist/chunks/{chunk-EOO5AKO4.js → chunk-RBX6RVYO.js} +6 -6
  63. package/dist/chunks/{chunk-VSUHR44P.js → chunk-RM6HTBJK.js} +2 -2
  64. package/dist/chunks/{chunk-WW4VKEBD.js → chunk-S6MZK4LD.js} +2 -2
  65. package/dist/chunks/{chunk-H7VJHF5S.js → chunk-SFUUN6B3.js} +957 -262
  66. package/dist/chunks/chunk-SFUUN6B3.js.map +6 -0
  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-IMNF2CDN.js} +10 -10
  88. package/dist/chunks/{eval-GYPUHRIK.js → eval-VHWEJ4GG.js} +2 -2
  89. package/dist/chunks/{exec-AHAC6YBQ.js → exec-2KM6DH56.js} +149 -41
  90. package/dist/chunks/exec-2KM6DH56.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-5C4TCX6J.js} +13 -13
  93. package/dist/chunks/{lifecycle-7LD634AQ.js → lifecycle-IHW4P636.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-F3TFROMK.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-UCYGJN75.js} +11 -11
  102. package/dist/chunks/{providers-YV45XVWS.js → providers-BHF65IUG.js} +6 -6
  103. package/dist/chunks/{resident-OC2D5V5I.js → resident-CNS3XQRU.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-KN5YGOSJ.js} +8 -8
  106. package/dist/chunks/{service-67FZ3N75.js → service-OEOHUGM6.js} +22 -22
  107. package/dist/chunks/session-step-AYHFVVX6.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-JKZOXURU.js} +2535 -1325
  114. package/dist/chunks/tui-JKZOXURU.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 +19 -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 +73 -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 +38 -0
  194. package/dist/tui/workflow-runs.d.ts.map +1 -0
  195. package/package.json +4 -4
  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-PAGVUATH.js.map} +0 -0
  209. /package/dist/chunks/{agent-session-C2HDOXK4.js.map → agent-session-PLIPF3XG.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-MWFKUXP2.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-W355SFNQ.js.map} +0 -0
  214. /package/dist/chunks/{chunk-S7E42272.js.map → chunk-2BZOT2CT.js.map} +0 -0
  215. /package/dist/chunks/{chunk-7OEK2NAO.js.map → chunk-2O7KYX4V.js.map} +0 -0
  216. /package/dist/chunks/{chunk-LIZPXS73.js.map → chunk-3F5DGROG.js.map} +0 -0
  217. /package/dist/chunks/{chunk-NKEOCU52.js.map → chunk-3M3PMQ3I.js.map} +0 -0
  218. /package/dist/chunks/{chunk-KNNQHRZ4.js.map → chunk-46B7KRXY.js.map} +0 -0
  219. /package/dist/chunks/{chunk-PT7TZNBV.js.map → chunk-52OVP5BG.js.map} +0 -0
  220. /package/dist/chunks/{chunk-X2YRM3UE.js.map → chunk-56OUKG5W.js.map} +0 -0
  221. /package/dist/chunks/{chunk-HJ42RG5U.js.map → chunk-5URT3ZM2.js.map} +0 -0
  222. /package/dist/chunks/{chunk-ZZ6Z2DO6.js.map → chunk-6CGC72OA.js.map} +0 -0
  223. /package/dist/chunks/{chunk-GWOW3U2S.js.map → chunk-6TDJXZ5W.js.map} +0 -0
  224. /package/dist/chunks/{chunk-7WQV2FSF.js.map → chunk-AHYHR5DY.js.map} +0 -0
  225. /package/dist/chunks/{chunk-XAKL7C7B.js.map → chunk-AP5KD43Y.js.map} +0 -0
  226. /package/dist/chunks/{chunk-NRML7BIR.js.map → chunk-AS7UWXMN.js.map} +0 -0
  227. /package/dist/chunks/{chunk-QQLB573I.js.map → chunk-BOV53LZO.js.map} +0 -0
  228. /package/dist/chunks/{chunk-GPBUDMUF.js.map → chunk-BUCICQWG.js.map} +0 -0
  229. /package/dist/chunks/{chunk-CFN7CUD3.js.map → chunk-DYUOXP5Q.js.map} +0 -0
  230. /package/dist/chunks/{chunk-G5XTLTDR.js.map → chunk-E7HLYLD7.js.map} +0 -0
  231. /package/dist/chunks/{chunk-ABD2DOO2.js.map → chunk-EKUJUPFA.js.map} +0 -0
  232. /package/dist/chunks/{chunk-AABPCENY.js.map → chunk-F3YQ2CSZ.js.map} +0 -0
  233. /package/dist/chunks/{chunk-2VXA7GZU.js.map → chunk-FU4GQ7K2.js.map} +0 -0
  234. /package/dist/chunks/{chunk-VHKKPDL2.js.map → chunk-GQN64E36.js.map} +0 -0
  235. /package/dist/chunks/{chunk-3OZ2OBGU.js.map → chunk-HKDPP2JF.js.map} +0 -0
  236. /package/dist/chunks/{chunk-YZ675PG4.js.map → chunk-HSEJGSXE.js.map} +0 -0
  237. /package/dist/chunks/{chunk-ZXWJ6G3J.js.map → chunk-I6CDUPVR.js.map} +0 -0
  238. /package/dist/chunks/{chunk-27VZRJTG.js.map → chunk-IQBR45AU.js.map} +0 -0
  239. /package/dist/chunks/{chunk-HIZ7F6BT.js.map → chunk-JCDTR2ZU.js.map} +0 -0
  240. /package/dist/chunks/{chunk-ZNAH4EGP.js.map → chunk-KMHLON54.js.map} +0 -0
  241. /package/dist/chunks/{chunk-CXLSM5SH.js.map → chunk-KOG2WB66.js.map} +0 -0
  242. /package/dist/chunks/{chunk-AGHVC2IJ.js.map → chunk-LBH5WVXU.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-YLIKDPD6.js.map → chunk-NBD5MAGK.js.map} +0 -0
  247. /package/dist/chunks/{chunk-43FBWINL.js.map → chunk-PINPSIJ5.js.map} +0 -0
  248. /package/dist/chunks/{chunk-AL6ESCHD.js.map → chunk-PLKJKF32.js.map} +0 -0
  249. /package/dist/chunks/{chunk-KQOIPRZ5.js.map → chunk-QRT3N2K3.js.map} +0 -0
  250. /package/dist/chunks/{chunk-DYBUCWAB.js.map → chunk-QXDKRJZ5.js.map} +0 -0
  251. /package/dist/chunks/{chunk-EOO5AKO4.js.map → chunk-RBX6RVYO.js.map} +0 -0
  252. /package/dist/chunks/{chunk-VSUHR44P.js.map → chunk-RM6HTBJK.js.map} +0 -0
  253. /package/dist/chunks/{chunk-WW4VKEBD.js.map → chunk-S6MZK4LD.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-IMNF2CDN.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-5C4TCX6J.js.map} +0 -0
  276. /package/dist/chunks/{lifecycle-7LD634AQ.js.map → lifecycle-IHW4P636.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-F3TFROMK.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-UCYGJN75.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-CNS3XQRU.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-KN5YGOSJ.js.map} +0 -0
  289. /package/dist/chunks/{service-67FZ3N75.js.map → service-OEOHUGM6.js.map} +0 -0
  290. /package/dist/chunks/{session-step-YNMU75FQ.js.map → session-step-AYHFVVX6.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,34 @@ import { createRequire as __namzuCreateRequire } from 'node:module';
2
2
  const require = __namzuCreateRequire(import.meta.url);
3
3
  import {
4
4
  openManagedWorktrees
5
- } from "./chunk-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
+ initialRunView,
22
+ launchedText,
17
23
  readStoredTurnGuards,
18
- resolveTurnGuards
19
- } from "./chunk-L6FMG3R6.js";
24
+ reduceRunView,
25
+ resolveTurnGuards,
26
+ viewFromJournal,
27
+ workflowOffered,
28
+ workflowRefusal
29
+ } from "./chunk-QBAISLAD.js";
20
30
  import {
21
31
  openInBrowser
22
- } from "./chunk-XAKL7C7B.js";
32
+ } from "./chunk-AP5KD43Y.js";
23
33
  import {
24
34
  CredentialRefreshRejectedError,
25
35
  CredentialWithdrawnError,
@@ -27,7 +37,7 @@ import {
27
37
  ensureFreshStoredCodexCredential,
28
38
  readSubscriptionCredential,
29
39
  sameOAuthCredential
30
- } from "./chunk-HJ42RG5U.js";
40
+ } from "./chunk-5URT3ZM2.js";
31
41
  import {
32
42
  debugRequested
33
43
  } from "./chunk-GNBMKISG.js";
@@ -35,7 +45,7 @@ import {
35
45
  configuredPassthroughTools,
36
46
  resolveToolResultScreens,
37
47
  unmatchedPassthroughTools
38
- } from "./chunk-U5AWHJ7O.js";
48
+ } from "./chunk-MBBFX64S.js";
39
49
  import {
40
50
  formatSize,
41
51
  homePath,
@@ -63,7 +73,7 @@ import {
63
73
  requiresCredentialForModel,
64
74
  resolveChainCapabilities,
65
75
  unresolvedMembers
66
- } from "./chunk-CFN7CUD3.js";
76
+ } from "./chunk-DYUOXP5Q.js";
67
77
  import {
68
78
  PROVIDER_REGISTRY,
69
79
  missingCredentialMessage,
@@ -71,11 +81,11 @@ import {
71
81
  } from "./chunk-6LLJQ3KY.js";
72
82
  import {
73
83
  cliLogger
74
- } from "./chunk-2VXA7GZU.js";
84
+ } from "./chunk-FU4GQ7K2.js";
75
85
  import {
76
86
  isPermissionMode,
77
87
  permissionModeLabel
78
- } from "./chunk-AGHVC2IJ.js";
88
+ } from "./chunk-LBH5WVXU.js";
79
89
  import {
80
90
  probeCapabilities
81
91
  } from "./chunk-OH6TB27S.js";
@@ -86,7 +96,7 @@ import {
86
96
  import {
87
97
  conversationLogPath,
88
98
  ensureSessionStarted
89
- } from "./chunk-ABD2DOO2.js";
99
+ } from "./chunk-EKUJUPFA.js";
90
100
  import {
91
101
  INSTRUCTIONS_FILENAME,
92
102
  MAX_CHARS_PER_FILE,
@@ -96,13 +106,13 @@ import {
96
106
  } from "./chunk-H6B6AROX.js";
97
107
  import {
98
108
  ensurePrivateStateDirectory
99
- } from "./chunk-WW4VKEBD.js";
109
+ } from "./chunk-S6MZK4LD.js";
100
110
  import {
101
111
  restrictToOwner
102
- } from "./chunk-QQLB573I.js";
112
+ } from "./chunk-BOV53LZO.js";
103
113
  import {
104
114
  namzuHomePath
105
- } from "./chunk-3OZ2OBGU.js";
115
+ } from "./chunk-HKDPP2JF.js";
106
116
  import {
107
117
  AgentManager,
108
118
  AgentRegistry,
@@ -124,6 +134,7 @@ import {
124
134
  EXPLORE_AGENT_DESCRIPTION,
125
135
  EXPLORE_AGENT_ID,
126
136
  EXPLORE_AGENT_PROMPT,
137
+ FileWorkflowJournal,
127
138
  GitWorktreeDriver,
128
139
  GuardedFetchProvider,
129
140
  InMemorySessionLog,
@@ -156,6 +167,8 @@ import {
156
167
  TopicManager,
157
168
  TurnCancelled,
158
169
  WebFetchTool,
170
+ WorkflowRuntime,
171
+ WorkflowScriptError,
159
172
  WorkspaceBackendRegistry,
160
173
  abandonTurn,
161
174
  asSessionId,
@@ -213,6 +226,7 @@ import {
213
226
  mapTools,
214
227
  mcpJsonSchemaToZod,
215
228
  openSessionTokenBudget,
229
+ parseWorkflowMeta,
216
230
  query,
217
231
  readSessionLog,
218
232
  readyWhen,
@@ -230,9 +244,10 @@ import {
230
244
  toolset,
231
245
  untrustedEnvelopeBody,
232
246
  webGuidanceContribution,
247
+ windowsShellNotice,
233
248
  withProviderFallback,
234
249
  wrapUntrusted
235
- } from "./chunk-ZKTLXAQK.js";
250
+ } from "./chunk-V3ZLK3XQ.js";
236
251
  import {
237
252
  __name
238
253
  } from "./chunk-76FLAFCG.js";
@@ -621,6 +636,7 @@ __name(isAuthoredSentence, "isAuthoredSentence");
621
636
 
622
637
  // src/tui/tidy-tool-output.ts
623
638
  import { stripVTControlCharacters } from "node:util";
639
+ var BACKGROUND_NOTE = "Running in the background (\u2193 to manage)";
624
640
  function looksBinary(text) {
625
641
  if (text.includes("\0")) return true;
626
642
  if (text.length === 0) return false;
@@ -634,7 +650,8 @@ function looksBinary(text) {
634
650
  __name(looksBinary, "looksBinary");
635
651
  function tidyTerminalOutput(raw) {
636
652
  if (looksBinary(raw)) {
637
- return { output: "The command printed binary data, which is not shown." };
653
+ const output2 = "The command printed binary data, which is not shown.";
654
+ return { output: output2, shell: { stdout: [], stderr: [], failed: false, note: output2 } };
638
655
  }
639
656
  let failure;
640
657
  const kept = [];
@@ -648,7 +665,18 @@ function tidyTerminalOutput(raw) {
648
665
  kept.push(line);
649
666
  }
650
667
  while (kept.length > 0 && kept[kept.length - 1]?.trim() === "") kept.pop();
651
- return { output: kept.join("\n"), ...failure ? { failure } : {} };
668
+ const output = kept.join("\n");
669
+ const background = /^Started background job /.test(output);
670
+ const code = failure ? /\d+/.exec(failure)?.[0] : void 0;
671
+ const shell = {
672
+ stdout: background || output.length === 0 ? [] : kept,
673
+ stderr: [],
674
+ failed: failure !== void 0,
675
+ ...background ? { note: BACKGROUND_NOTE } : {},
676
+ ...failure ? { note: code ? `Exit code ${code}` : failure } : {},
677
+ ...failure && output.length > 0 && !background ? { status: code ? `Exit code ${code}` : failure } : {}
678
+ };
679
+ return { output, ...failure ? { failure } : {}, shell };
652
680
  }
653
681
  __name(tidyTerminalOutput, "tidyTerminalOutput");
654
682
  function shortCommand(command) {
@@ -684,21 +712,33 @@ function tidyCommandOutput(facts, raw) {
684
712
  const how = endedHow(facts);
685
713
  const label = shortCommand(facts.command);
686
714
  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");
715
+ const status = !how ? void 0 : facts.timedOut ? "Timed out" : facts.signal ? "Stopped before it finished" : `Exit code ${facts.exitCode}`;
716
+ const cell = /* @__PURE__ */ __name((stdout2, stderr2, note) => ({
717
+ stdout: stdout2,
718
+ stderr: stderr2,
719
+ failed: how !== void 0,
720
+ ...status && (stdout2.length > 0 || stderr2.length > 0) ? { status } : {},
721
+ ...status ? { note: status } : note ? { note } : {}
722
+ }), "cell");
723
+ const withFailure = /* @__PURE__ */ __name((output, shell) => ({
724
+ output,
725
+ ...failure ? { failure } : {},
726
+ shell
727
+ }), "withFailure");
688
728
  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
729
+ const sentence = `The command printed binary data (${formatSize(facts.binary.bytes)}), which is not shown.`;
730
+ return withFailure(sentence, cell([], [], sentence));
731
+ }
732
+ const clean = /* @__PURE__ */ __name((window) => window && window.totalBytes > 0 ? windowLines(window).map((line) => stripVTControlCharacters(line)) : [], "clean");
733
+ const stdout = clean(facts.stdout);
734
+ const stderr = clean(facts.stderr);
735
+ if (stdout.length > 0 || stderr.length > 0) {
736
+ return withFailure([...stdout, ...stderr].join("\n"), cell(stdout, stderr));
737
+ }
738
+ return withFailure(
739
+ tidyTerminalOutput(raw).output,
740
+ cell([], [], facts.background ? BACKGROUND_NOTE : void 0)
695
741
  );
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
742
  }
703
743
  __name(tidyCommandOutput, "tidyCommandOutput");
704
744
  function unknownToolNotice(result) {
@@ -822,14 +862,14 @@ function formatCompactCount(value) {
822
862
  __name(formatCompactCount, "formatCompactCount");
823
863
 
824
864
  // src/tui/web-activity.ts
825
- function webActivityKind(toolName) {
826
- if (toolName === "web_search") return "search";
827
- if (toolName === "web_fetch") return "fetch";
865
+ function webActivityKind(toolName2) {
866
+ if (toolName2 === "web_search") return "search";
867
+ if (toolName2 === "web_fetch") return "fetch";
828
868
  return void 0;
829
869
  }
830
870
  __name(webActivityKind, "webActivityKind");
831
- function webActivityFromInput(toolName, input) {
832
- const kind = webActivityKind(toolName);
871
+ function webActivityFromInput(toolName2, input) {
872
+ const kind = webActivityKind(toolName2);
833
873
  if (!kind) return void 0;
834
874
  const field = kind === "search" ? "query" : "url";
835
875
  const value = input !== null && typeof input === "object" ? input[field] : void 0;
@@ -884,7 +924,7 @@ __name(oneLine, "oneLine");
884
924
  // src/tui/agent.ts
885
925
  import { SubprocessComputerUseHost } from "@namzu/computer-use";
886
926
  import { realpath as realpath4, stat as stat4 } from "node:fs/promises";
887
- import { parse, resolve as resolve8 } from "node:path";
927
+ import { join as join13, parse, resolve as resolve8 } from "node:path";
888
928
 
889
929
  // src/checkpoints/store.ts
890
930
  import { randomUUID as randomUUID2 } from "node:crypto";
@@ -4658,6 +4698,27 @@ var SubagentActivityMonitor = class {
4658
4698
  getNarration() {
4659
4699
  return [...this.narration];
4660
4700
  }
4701
+ /**
4702
+ * The cheap facts a progress line needs about one child, without copying
4703
+ * its transcript: spend, tool executions and the tool it ran last.
4704
+ */
4705
+ progressOf(viewId) {
4706
+ const record = this.records.get(viewId);
4707
+ if (!record) return void 0;
4708
+ let lastTool;
4709
+ for (let index = record.rows.length - 1; index >= 0; index -= 1) {
4710
+ const row = record.rows[index];
4711
+ if (row?.kind === "tool") {
4712
+ lastTool = row.text;
4713
+ break;
4714
+ }
4715
+ }
4716
+ return {
4717
+ ...record.tokens !== void 0 ? { tokens: record.tokens } : {},
4718
+ ...record.toolCalls !== void 0 ? { toolCalls: record.toolCalls } : {},
4719
+ ...lastTool !== void 0 ? { lastTool } : {}
4720
+ };
4721
+ }
4661
4722
  getSnapshot() {
4662
4723
  return [...this.records.values()].sort((left, right) => {
4663
4724
  const live = Number(isTerminal(left.status)) - Number(isTerminal(right.status));
@@ -5745,6 +5806,7 @@ var SUBAGENT_PROMPT = [
5745
5806
  // the parent does not is the same defect in the other direction.
5746
5807
  CODING_AGENT_WORKING_DOCTRINE
5747
5808
  ].join("\n");
5809
+ var WORKFLOW_RUN_GROUP_PREFIX = "wf:";
5748
5810
  var ParentTaskScheduler = class extends LocalTaskScheduler {
5749
5811
  constructor(manager, context, onEvent, validateParent) {
5750
5812
  super(manager, context, onEvent);
@@ -6040,6 +6102,194 @@ async function createSubagentRuntime(opts) {
6040
6102
  }, "completionInboxForTurn");
6041
6103
  const activity = new SubagentActivityMonitor();
6042
6104
  let dynCounter = 0;
6105
+ const launchChild = /* @__PURE__ */ __name(async (input, context, hooks = {}) => {
6106
+ const {
6107
+ description,
6108
+ prompt,
6109
+ subagent_type,
6110
+ role,
6111
+ workflow,
6112
+ phase,
6113
+ phase_order,
6114
+ phase_detail,
6115
+ run_in_background,
6116
+ workspace,
6117
+ model: requestedModel,
6118
+ provider: requestedProvider,
6119
+ effort: requestedEffort
6120
+ } = input;
6121
+ if (!requestedModel && (requestedProvider || requestedEffort))
6122
+ throw new Error("Supply model when selecting a child provider or effort.");
6123
+ const explore = subagent_type === EXPLORE_SUBAGENT;
6124
+ const fileAgent = subagent_type !== void 0 ? fileAgents.get(subagent_type) : void 0;
6125
+ const inherited = opts.resolveTurnModel?.(context.turnId);
6126
+ const parentModel = inherited?.model ?? opts.model;
6127
+ const selects = requestedModel !== void 0 && (requestedModel !== parentModel || requestedProvider !== void 0 || requestedEffort !== void 0 || fileAgent?.model !== void 0 && fileAgent.model !== parentModel);
6128
+ if (selects && !opts.resolveModel)
6129
+ throw new Error("Child model selection is unavailable in this host.");
6130
+ const selection = selects ? await opts.resolveModel?.(
6131
+ {
6132
+ model: requestedModel,
6133
+ provider: requestedProvider,
6134
+ effort: requestedEffort
6135
+ },
6136
+ context.abortSignal
6137
+ ) : (
6138
+ // A file agent that pins its own model keeps it; any other child
6139
+ // of a turn on another model than the session's runs on that one.
6140
+ fileAgent?.model === void 0 ? inherited : void 0
6141
+ );
6142
+ let agentId = fileAgent?.name ?? (explore ? EXPLORE_SUBAGENT : GENERAL_PURPOSE_SUBAGENT);
6143
+ const persona = typeof role === "string" ? role.trim() : "";
6144
+ const dynamic = persona.length > 0 || selection !== void 0;
6145
+ if (dynamic) {
6146
+ agentId = `dyn-${++dynCounter}`;
6147
+ registry.register(
6148
+ buildDefinition(
6149
+ agentId,
6150
+ `Dynamic specialist: ${agentId}`,
6151
+ fileAgent ? `${fileAgent.prompt}
6152
+
6153
+ ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6154
+ opts,
6155
+ fileAgent ? fileAgentTools(fileAgent, opts) : explore ? () => opts.buildTools().map(
6156
+ (ts) => filtered(
6157
+ ts,
6158
+ (tool) => isTrustedReadOnly(tool, void 0, toToolSourceRef(ts.source))
6159
+ )
6160
+ ) : opts.buildTools,
6161
+ selection?.model ?? fileAgent?.model ?? parentModel,
6162
+ selection
6163
+ )
6164
+ );
6165
+ }
6166
+ const seed = {
6167
+ agentId,
6168
+ model: selection?.model ?? fileAgent?.model ?? parentModel,
6169
+ description,
6170
+ prompt,
6171
+ batchId: context.toolBatchId,
6172
+ toolUseId: context.toolUseId,
6173
+ workflowId: hooks.workflowId ?? String(context.turnId),
6174
+ workflow,
6175
+ phase,
6176
+ phaseOrder: phase_order,
6177
+ phaseDetail: phase_detail
6178
+ };
6179
+ const tracker = activity.begin(seed);
6180
+ hooks.onView?.(tracker.viewId);
6181
+ const resumeHandler = opts.resolveResumeHandler?.(context.turnId) ?? refuseUnownedChildReview;
6182
+ const configOverrides = {
6183
+ ...resolveTurnGuards(opts, opts.resolveLimits?.(context.turnId)),
6184
+ ...selection ? { model: selection.model, effort: selection.effort } : {},
6185
+ ...Object.keys(context.env ?? {}).length > 0 ? { env: context.env } : {},
6186
+ // The parent turn's tool-result screens, so a sub-agent judges a
6187
+ // connected answer the way the turn that asked for the work
6188
+ // does. Without it the child's executor installs the shipped
6189
+ // default, and `toolResultScreens: []` — the operator's off
6190
+ // switch — would hold for the parent and not for anything it
6191
+ // delegated to, which is the half an operator does not watch.
6192
+ //
6193
+ // `[]` is carried rather than skipped: empty is a decision, and
6194
+ // a `length` test — which is the shape that gets this wrong,
6195
+ // since `[]` is truthy — would turn it back into absent.
6196
+ ...context.toolResultGuardrails ? { toolResultGuardrails: context.toolResultGuardrails } : {},
6197
+ resumeHandler
6198
+ };
6199
+ let taskOwnsCleanup = false;
6200
+ let retained;
6201
+ const cleanupDefinition = /* @__PURE__ */ __name(() => {
6202
+ if (dynamic && !retained) registry.unregister(agentId);
6203
+ }, "cleanupDefinition");
6204
+ try {
6205
+ const parentKey = sessionKey(await resolveParent(context.turnId));
6206
+ const gateway = await gatewayForTurn(context.turnId);
6207
+ const completionInbox = await completionInboxForTurn(context.turnId);
6208
+ const subdirectory = workspace === "worktree" ? await worktreeDriver.selectedSubdirectory() : void 0;
6209
+ const outcome = await runBlockingAgentTask({
6210
+ gateway: await gatewayForTurn(context.turnId),
6211
+ signal: context.abortSignal,
6212
+ waitForInbound: opts.resolveWaitForInbound?.(context.turnId),
6213
+ background: run_in_background === true,
6214
+ ...hooks.cancelCause ? { cancelCause: hooks.cancelCause } : {},
6215
+ completionInbox,
6216
+ onCreated: /* @__PURE__ */ __name((task) => {
6217
+ taskOwnsCleanup = true;
6218
+ retained = {
6219
+ parentKey,
6220
+ agentId,
6221
+ dynamic,
6222
+ seed,
6223
+ config: {
6224
+ ...selection ? { model: selection.model, effort: selection.effort } : {},
6225
+ ...configOverrides.env ? { env: configOverrides.env } : {},
6226
+ ...configOverrides.toolResultGuardrails ? {
6227
+ toolResultGuardrails: configOverrides.toolResultGuardrails
6228
+ } : {}
6229
+ },
6230
+ workspace: workspace ?? "shared",
6231
+ gateway,
6232
+ task,
6233
+ turnId: context.turnId,
6234
+ busy: false
6235
+ };
6236
+ conversations.set(tracker.viewId, retained);
6237
+ const visible = new Set(activity.getSnapshot().map((value) => value.viewId));
6238
+ for (const [id, previous] of conversations) {
6239
+ if (visible.has(id) || previous.busy || !isTerminalAgentTaskState(previous.task.state))
6240
+ continue;
6241
+ conversations.delete(id);
6242
+ if (previous.dynamic) registry.unregister(previous.agentId);
6243
+ }
6244
+ tracker.settle(task);
6245
+ }, "onCreated"),
6246
+ onSettled: /* @__PURE__ */ __name((completed) => {
6247
+ if (retained) retained.task = completed;
6248
+ tracker.settle(completed);
6249
+ }, "onSettled"),
6250
+ onFailed: /* @__PURE__ */ __name((error) => tracker.fail(error), "onFailed"),
6251
+ onFinished: cleanupDefinition,
6252
+ create: {
6253
+ agentId,
6254
+ prompt,
6255
+ workingDirectory: opts.cwd,
6256
+ workspace: workspace === "worktree" ? {
6257
+ mode: "isolated",
6258
+ backend: "git-worktree",
6259
+ retention: "retain",
6260
+ ...subdirectory ? { subdirectory } : {}
6261
+ } : { mode: "shared" },
6262
+ // The same labels the monitor was seeded with, sent down so the
6263
+ // child's `agent_pending` carries them: a listener or SSE
6264
+ // consumer outside this process then groups the child the way
6265
+ // the operator sees it here, instead of the grouping living
6266
+ // only in the closure above. Display-only on both paths — no
6267
+ // dependency, barrier or serial execution follows from any.
6268
+ ...workflow ? { workflow } : {},
6269
+ ...phase ? { phase } : {},
6270
+ ...phase_detail ? { phaseDetail: phase_detail } : {},
6271
+ ...phase_order !== void 0 ? { phaseOrder: phase_order } : {},
6272
+ // Hang the child session off THIS tool's span, so the delegation
6273
+ // shows up inside the turn that asked for it. Without it a
6274
+ // sub-agent opens its OWN root trace, and the one structure
6275
+ // a delegation trace exists to record — who dispatched whom
6276
+ // — is the thing that goes missing.
6277
+ ...context.parentSpan ? { parentSpan: context.parentSpan } : {},
6278
+ configOverrides,
6279
+ onEvent: hooks.onEvent ? (event) => {
6280
+ tracker.onEvent(event);
6281
+ hooks.onEvent?.(event);
6282
+ } : tracker.onEvent
6283
+ }
6284
+ });
6285
+ return { outcome, agentId };
6286
+ } catch (error) {
6287
+ tracker.fail(error);
6288
+ throw error;
6289
+ } finally {
6290
+ if (!taskOwnsCleanup) cleanupDefinition();
6291
+ }
6292
+ }, "launchChild");
6043
6293
  const agentTool = defineTool({
6044
6294
  name: "Agent",
6045
6295
  description: [
@@ -6053,7 +6303,7 @@ async function createSubagentRuntime(opts) {
6053
6303
  "Omit `role` for the plain sub-agent.",
6054
6304
  "The sub-agent runs in its own context with its own tools and cannot see this conversation \u2014 put everything it needs in `prompt`.",
6055
6305
  "Call this multiple times in one response to run specialists in parallel. Tasks beyond the project's live-agent capacity wait in a queue and start as slots become available. Queued tasks have not started execution; do not relaunch them.",
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.",
6306
+ "When coordinating several specialists, give them the same `workflow` label and an explicit `phase` plus `phase_order` so the operator can follow the work in the agent cockpit. For work with several phases or many agents, use the `workflow` tool instead when it is in your tool list, and keep these labels for a small fan-out.",
6057
6307
  "These fields are display annotations only; they do not create dependencies, barriers, or serial execution.",
6058
6308
  fileAgentSummary.length > 0 ? `Project-defined types: ${fileAgentSummary}.` : ""
6059
6309
  ].filter((part) => part.length > 0).join(" "),
@@ -6137,202 +6387,116 @@ async function createSubagentRuntime(opts) {
6137
6387
  concurrencySafe: true,
6138
6388
  timeoutMs: opts.resolveLimits ? 0 : opts.timeoutMs ?? CLI_INTERACTIVE_TURN_TIMEOUT_MS,
6139
6389
  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?.(
6390
+ const { description, run_in_background } = input;
6391
+ const { outcome, agentId } = await launchChild(input, context);
6392
+ if (outcome.kind === "yielded") {
6393
+ const progress = outcome.handle.state === "pending" ? "queued for an available slot" : "still running";
6394
+ return {
6395
+ success: true,
6396
+ output: `Sub-agent ${agentId} for task ${JSON.stringify(description)} is ${progress} as task ${outcome.handle.taskId}; it has not completed.${workspaceNote(outcome.handle)} ${run_in_background ? "Continue independent work while this task runs in the background." : "Waiting was released because the operator sent a message. Answer their question or status request before making further tool calls; preserve existing work unless they ask to cancel or change it."} Its actual result will arrive as a task notification; do not launch the same work again.`,
6397
+ data: {
6398
+ task_id: outcome.handle.taskId,
6399
+ state: outcome.handle.state,
6400
+ ...workspaceData(outcome.handle),
6401
+ wait_released: run_in_background ? "background" : "operator_input"
6402
+ }
6403
+ };
6404
+ }
6405
+ return completedAgentResult(outcome.handle);
6406
+ }
6407
+ });
6408
+ const launchWorkflowAgent = /* @__PURE__ */ __name(async (launch) => {
6409
+ if (launch.agentType !== void 0 && !agentTypeIds.includes(launch.agentType)) {
6410
+ throw new Error(
6411
+ `Unknown agent type "${launch.agentType}". Available: ${agentTypeIds.join(", ")}.`
6412
+ );
6413
+ }
6414
+ if (launch.effort !== void 0 && launch.model === void 0) {
6415
+ throw new Error("Supply model when selecting an agent effort.");
6416
+ }
6417
+ const prompt = launch.schema === void 0 ? launch.prompt : `${launch.prompt}
6418
+
6419
+ Answer with one JSON value that satisfies this JSON Schema and nothing else:
6420
+ ${JSON.stringify(launch.schema)}`;
6421
+ const label = launch.workflowName === DEFAULT_AGENT_WORKFLOW ? "Workflow" : launch.workflowName;
6422
+ let viewId;
6423
+ let lastReport = 0;
6424
+ const report = /* @__PURE__ */ __name((force) => {
6425
+ if (!viewId || !launch.onProgress) return;
6426
+ const at = Date.now();
6427
+ if (!force && at - lastReport < 250) return;
6428
+ lastReport = at;
6429
+ const progress = activity.progressOf(viewId);
6430
+ if (progress) launch.onProgress(progress);
6431
+ }, "report");
6432
+ try {
6433
+ const { outcome } = await launchChild(
6434
+ {
6435
+ description: launch.label,
6436
+ prompt,
6437
+ run_in_background: false,
6438
+ ...launch.agentType !== void 0 ? { subagent_type: launch.agentType } : {},
6439
+ ...launch.model !== void 0 ? { model: launch.model } : {},
6440
+ ...launch.effort !== void 0 ? { effort: launch.effort } : {},
6441
+ workflow: label,
6442
+ ...launch.phaseTitle !== void 0 ? { phase: launch.phaseTitle } : {},
6443
+ ...launch.phaseIndex !== void 0 ? { phase_order: launch.phaseIndex } : {},
6444
+ ...launch.phaseDetail !== void 0 ? { phase_detail: launch.phaseDetail } : {}
6445
+ },
6165
6446
  {
6166
- model: requestedModel,
6167
- provider: requestedProvider,
6168
- effort: requestedEffort
6447
+ turnId: launch.turnId,
6448
+ abortSignal: launch.signal,
6449
+ toolBatchId: launch.runId,
6450
+ ...launch.inherit?.env ? { env: launch.inherit.env } : {},
6451
+ ...launch.inherit?.toolResultGuardrails ? { toolResultGuardrails: launch.inherit.toolResultGuardrails } : {}
6169
6452
  },
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
6453
+ {
6454
+ workflowId: `${WORKFLOW_RUN_GROUP_PREFIX}${launch.runId}`,
6455
+ cancelCause: "user",
6456
+ onView: /* @__PURE__ */ __name((id) => {
6457
+ viewId = id;
6458
+ launch.onView?.(id);
6459
+ }, "onView"),
6460
+ onEvent: /* @__PURE__ */ __name(() => report(false), "onEvent")
6461
+ }
6175
6462
  );
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
- );
6463
+ report(true);
6464
+ const stats = viewId ? activity.progressOf(viewId) : void 0;
6465
+ const tokens = stats?.tokens ?? 0;
6466
+ const toolCalls = stats?.toolCalls ?? 0;
6467
+ if (outcome.kind !== "completed") {
6468
+ return {
6469
+ state: "error",
6470
+ tokens,
6471
+ toolCalls,
6472
+ error: "The agent did not finish."
6473
+ };
6199
6474
  }
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();
6475
+ const handle = outcome.handle;
6476
+ const status = agentTaskOutcome(handle);
6477
+ const turn = handle.result;
6478
+ const value = turn?.structuredOutput ?? turn?.result;
6479
+ const text = typeof value === "string" ? value : value === void 0 ? "" : JSON.stringify(value);
6480
+ if (status !== "completed") {
6481
+ return {
6482
+ state: "error",
6483
+ tokens,
6484
+ toolCalls,
6485
+ error: `The agent ended as ${status}${turn?.lastError ? `: ${turn.lastError}` : "."}`
6486
+ };
6333
6487
  }
6488
+ return { state: "done", text, tokens, toolCalls };
6489
+ } catch (error) {
6490
+ if (launch.signal.aborted) throw error;
6491
+ const stats = viewId ? activity.progressOf(viewId) : void 0;
6492
+ return {
6493
+ state: "error",
6494
+ tokens: stats?.tokens ?? 0,
6495
+ toolCalls: stats?.toolCalls ?? 0,
6496
+ error: error instanceof Error ? error.message : String(error)
6497
+ };
6334
6498
  }
6335
- });
6499
+ }, "launchWorkflowAgent");
6336
6500
  const agentTaskListTool = defineTool({
6337
6501
  name: "agent_task_list",
6338
6502
  description: "List the agent invocations launched by this turn and their current status, without waiting or starting work. Use this for agent progress questions. task_list contains planning items, not agent invocations. Use wait_for_task with a live ID for its result. Set history: true to inspect agents saved from earlier turns of this conversation, optionally session_id for one saved result; saved agents are not live.",
@@ -6819,10 +6983,21 @@ ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6819
6983
  };
6820
6984
  }
6821
6985
  }) : void 0;
6986
+ const stopChild = /* @__PURE__ */ __name((viewId) => {
6987
+ if (closed) return false;
6988
+ const owned = conversations.get(viewId);
6989
+ const shown = activity.getSnapshot().find((value) => value.viewId === viewId);
6990
+ if (!owned || !shown || shown.replayed) return false;
6991
+ const current = owned.gateway.getTask(owned.task.taskId) ?? owned.task;
6992
+ if (isTerminalAgentTaskState(current.state)) return false;
6993
+ owned.gateway.cancelTask(owned.task.taskId, "user");
6994
+ return true;
6995
+ }, "stopChild");
6822
6996
  return {
6823
6997
  cancelAgentTool,
6824
6998
  modelCatalogueTool,
6825
6999
  messageChild,
7000
+ stopChild,
6826
7001
  gatewayForTurn,
6827
7002
  completionInboxForTurn,
6828
7003
  releaseTurn,
@@ -6846,6 +7021,7 @@ ${persona}` : persona || (explore ? EXPLORE_PROMPT : SUBAGENT_PROMPT),
6846
7021
  return type === EXPLORE_SUBAGENT;
6847
7022
  },
6848
7023
  activity,
7024
+ launchWorkflowAgent,
6849
7025
  close
6850
7026
  };
6851
7027
  }
@@ -6866,7 +7042,7 @@ async function runBlockingAgentTask(input) {
6866
7042
  if (taskCancellationAttempted) return;
6867
7043
  taskCancellationAttempted = true;
6868
7044
  try {
6869
- gateway.cancelTask(task.taskId, "parent");
7045
+ gateway.cancelTask(task.taskId, input.cancelCause ?? "parent");
6870
7046
  } catch {
6871
7047
  }
6872
7048
  }, "cancel");
@@ -7063,9 +7239,403 @@ ${SUBAGENT_PROMPT}`;
7063
7239
  }
7064
7240
  __name(buildDefinition, "buildDefinition");
7065
7241
 
7242
+ // src/integrations/workflows/doctrine.ts
7243
+ var WORKFLOW_DOCTRINE = [
7244
+ "The `workflow` tool is available this turn because the operator asked for orchestration.",
7245
+ "Use it for work with several phases or many agents: write the script once, call `workflow`, and the runtime schedules the agents and groups them by phase. Keep `Agent` calls (with a `workflow` label and a `phase`) for a small fan-out of a few agents, and for a single subagent.",
7246
+ "A workflow runs in the background and the operator approves the script before it starts. After you start one, tell the operator in one sentence that it is running; its result reaches you in a single message when it ends, and you then report the outcome."
7247
+ ].join("\n");
7248
+
7249
+ // src/integrations/workflows/history.ts
7250
+ import { readFile as readFile3, readdir as readdir2 } from "node:fs/promises";
7251
+ import { join as join8 } from "node:path";
7252
+ var RUN_ID = /^w[0-9a-z]{8}$/;
7253
+ async function readWorkflowJournal(file) {
7254
+ let text;
7255
+ try {
7256
+ text = await readFile3(file, "utf8");
7257
+ } catch (error) {
7258
+ if (error.code === "ENOENT") return [];
7259
+ throw error;
7260
+ }
7261
+ const records = [];
7262
+ for (const line of text.split("\n")) {
7263
+ if (line.trim().length === 0) continue;
7264
+ try {
7265
+ const parsed = JSON.parse(line);
7266
+ if (typeof parsed === "object" && parsed !== null && "type" in parsed) {
7267
+ records.push(parsed);
7268
+ }
7269
+ } catch {
7270
+ }
7271
+ }
7272
+ return records;
7273
+ }
7274
+ __name(readWorkflowJournal, "readWorkflowJournal");
7275
+ async function readWorkflowRun(runsDirectory, runId) {
7276
+ if (!RUN_ID.test(runId)) return void 0;
7277
+ const records = await readWorkflowJournal(join8(runsDirectory, runId, "workflow", "journal.jsonl"));
7278
+ return viewFromJournal(records);
7279
+ }
7280
+ __name(readWorkflowRun, "readWorkflowRun");
7281
+ async function listWorkflowRuns(runsDirectory) {
7282
+ let entries;
7283
+ try {
7284
+ entries = await readdir2(runsDirectory);
7285
+ } catch (error) {
7286
+ if (error.code === "ENOENT") return [];
7287
+ throw error;
7288
+ }
7289
+ const views = await Promise.all(
7290
+ entries.filter((name) => RUN_ID.test(name)).map((name) => readWorkflowRun(runsDirectory, name))
7291
+ );
7292
+ return views.filter((view) => view !== void 0).sort((a, b) => b.startedAt - a.startedAt);
7293
+ }
7294
+ __name(listWorkflowRuns, "listWorkflowRuns");
7295
+
7296
+ // src/integrations/workflows/host.ts
7297
+ import { randomBytes as randomBytes3 } from "node:crypto";
7298
+ import { join as join9 } from "node:path";
7299
+
7300
+ // src/integrations/workflows/registry.ts
7301
+ var WorkflowRunRegistry = class {
7302
+ static {
7303
+ __name(this, "WorkflowRunRegistry");
7304
+ }
7305
+ runs = /* @__PURE__ */ new Map();
7306
+ listeners = /* @__PURE__ */ new Set();
7307
+ runtime;
7308
+ now;
7309
+ notifyTimer;
7310
+ closed = false;
7311
+ constructor(options = {}) {
7312
+ this.now = options.now ?? Date.now;
7313
+ this.runtime = options.runtime ?? new WorkflowRuntime();
7314
+ }
7315
+ list() {
7316
+ return [...this.runs.values()].map((run2) => run2.view);
7317
+ }
7318
+ get(runId) {
7319
+ return this.runs.get(runId)?.view;
7320
+ }
7321
+ subscribe(listener) {
7322
+ this.listeners.add(listener);
7323
+ return () => this.listeners.delete(listener);
7324
+ }
7325
+ /** Runs that have not ended. */
7326
+ running() {
7327
+ return this.list().filter((view) => view.status === "running");
7328
+ }
7329
+ /** Begin a run. Returns at once; the run goes on in the background. */
7330
+ start(input) {
7331
+ if (this.closed) throw new Error("Workflows are closed for this session.");
7332
+ const run2 = {
7333
+ view: initialRunView({
7334
+ runId: input.runId,
7335
+ name: input.meta.name,
7336
+ description: input.meta.description,
7337
+ phases: input.meta.phases,
7338
+ at: this.now()
7339
+ }),
7340
+ abort: new AbortController(),
7341
+ finalized: false
7342
+ };
7343
+ this.runs.set(input.runId, run2);
7344
+ this.notifySoon(true);
7345
+ const settle = /* @__PURE__ */ __name(async (result, error) => {
7346
+ const at = this.now();
7347
+ if (run2.view.status === "running") {
7348
+ run2.view = {
7349
+ ...run2.view,
7350
+ status: run2.abort.signal.aborted ? "stopped" : "failed",
7351
+ endedAt: at,
7352
+ ...error !== void 0 ? { error } : {}
7353
+ };
7354
+ }
7355
+ run2.view = closeOpenAgents(run2.view, at);
7356
+ try {
7357
+ await input.onEnd?.({ view: run2.view, ...result ? { result } : {} });
7358
+ } catch {
7359
+ }
7360
+ run2.finalized = true;
7361
+ this.notifySoon(true);
7362
+ }, "settle");
7363
+ void this.runtime.run({
7364
+ script: input.script,
7365
+ ...input.args !== void 0 ? { args: input.args } : {},
7366
+ ...input.limits ? { limits: input.limits } : {},
7367
+ ...input.journal ? { journal: input.journal } : {},
7368
+ runId: input.runId,
7369
+ signal: run2.abort.signal,
7370
+ onControl: /* @__PURE__ */ __name((control) => {
7371
+ run2.control = control;
7372
+ }, "onControl"),
7373
+ onEvent: /* @__PURE__ */ __name((event) => {
7374
+ run2.view = reduceRunView(run2.view, event);
7375
+ this.notifySoon(event.type !== "workflow_agent" || event.state !== "progress");
7376
+ }, "onEvent"),
7377
+ spawnAgent: /* @__PURE__ */ __name((request, signal) => input.spawn(request, signal, (viewId) => {
7378
+ run2.view = attachAgentView(run2.view, request.index, viewId);
7379
+ this.notifySoon(false);
7380
+ }), "spawnAgent")
7381
+ }).then(
7382
+ (result) => settle(result),
7383
+ (error) => settle(void 0, error instanceof Error ? error.message : String(error))
7384
+ );
7385
+ return run2.view;
7386
+ }
7387
+ /**
7388
+ * Resolves once no run is going, or when `signal` aborts (whichever is first).
7389
+ * A run's own limits bound the wait: the runtime stops one at its duration cap.
7390
+ */
7391
+ whenIdle(signal) {
7392
+ const going = /* @__PURE__ */ __name(() => [...this.runs.values()].some((run2) => !run2.finalized), "going");
7393
+ if (!going() || signal?.aborted) return Promise.resolve();
7394
+ return new Promise((resolve9) => {
7395
+ const done = /* @__PURE__ */ __name(() => {
7396
+ off();
7397
+ signal?.removeEventListener("abort", done);
7398
+ resolve9();
7399
+ }, "done");
7400
+ const off = this.subscribe(() => {
7401
+ if (!going()) done();
7402
+ });
7403
+ signal?.addEventListener("abort", done, { once: true });
7404
+ });
7405
+ }
7406
+ /** Stop a run: queued agents never start, running ones are aborted. False when it is not running. */
7407
+ stop(runId) {
7408
+ const run2 = this.runs.get(runId);
7409
+ if (!run2 || run2.view.status !== "running") return false;
7410
+ run2.abort.abort(new Error("The operator stopped this workflow."));
7411
+ return true;
7412
+ }
7413
+ /** Skip one agent of a run. False when it is not running or already settled. */
7414
+ skipAgent(runId, index) {
7415
+ const run2 = this.runs.get(runId);
7416
+ if (!run2 || run2.view.status !== "running") return false;
7417
+ return run2.control?.skipAgent(index) ?? false;
7418
+ }
7419
+ /** Which run and agent a monitor row stands for, if any. */
7420
+ agentOf(viewId) {
7421
+ for (const run2 of this.runs.values()) {
7422
+ const agent = run2.view.agents.find((item) => item.viewId === viewId);
7423
+ if (agent) return { runId: run2.view.runId, index: agent.index };
7424
+ }
7425
+ return void 0;
7426
+ }
7427
+ /** Forget runs that have ended (a new conversation). Running ones are stopped first. */
7428
+ reset() {
7429
+ for (const run2 of this.runs.values()) run2.abort.abort(new Error("The conversation changed."));
7430
+ this.runs.clear();
7431
+ this.notifySoon(true);
7432
+ }
7433
+ close() {
7434
+ this.closed = true;
7435
+ for (const run2 of this.runs.values()) run2.abort.abort(new Error("The session ended."));
7436
+ if (this.notifyTimer) clearTimeout(this.notifyTimer);
7437
+ this.notifyTimer = void 0;
7438
+ this.listeners.clear();
7439
+ }
7440
+ notifySoon(now) {
7441
+ if (this.closed) return;
7442
+ if (now) {
7443
+ if (this.notifyTimer) clearTimeout(this.notifyTimer);
7444
+ this.notifyTimer = void 0;
7445
+ for (const listener of [...this.listeners]) listener();
7446
+ return;
7447
+ }
7448
+ if (this.notifyTimer) return;
7449
+ this.notifyTimer = setTimeout(() => {
7450
+ this.notifyTimer = void 0;
7451
+ for (const listener of [...this.listeners]) listener();
7452
+ }, 100);
7453
+ this.notifyTimer.unref?.();
7454
+ }
7455
+ };
7456
+
7457
+ // src/integrations/workflows/host.ts
7458
+ var MAX_WORKFLOW_SCRIPT_CHARS = 262144;
7459
+ var MAX_WORKFLOW_ARGS_CHARS = 65536;
7460
+ var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
7461
+ function createWorkflowRunId(isTaken = () => false) {
7462
+ for (; ; ) {
7463
+ let body = "";
7464
+ while (body.length < 8) {
7465
+ for (const byte of randomBytes3(16)) {
7466
+ if (byte >= 252) continue;
7467
+ body += ALPHABET[byte % 36];
7468
+ if (body.length === 8) break;
7469
+ }
7470
+ }
7471
+ const id = `w${body}`;
7472
+ if (!isTaken(id)) return id;
7473
+ }
7474
+ }
7475
+ __name(createWorkflowRunId, "createWorkflowRunId");
7476
+ function toolName(label) {
7477
+ if (!label) return { name: "tool" };
7478
+ const open3 = label.indexOf("(");
7479
+ return open3 > 0 ? { name: label.slice(0, open3), summary: label } : { name: label, summary: label };
7480
+ }
7481
+ __name(toolName, "toolName");
7482
+ function describeWorkflowCall(input) {
7483
+ if (typeof input.description === "string" && input.description.trim().length > 0) {
7484
+ return input.description.trim().replace(/\s+/g, " ");
7485
+ }
7486
+ if (typeof input.script === "string") {
7487
+ try {
7488
+ return parseWorkflowMeta(input.script).description.replace(/\s+/g, " ");
7489
+ } catch {
7490
+ const first = input.script.split("\n").find((line) => line.trim().length > 0);
7491
+ if (first) return first.trim().slice(0, 80);
7492
+ }
7493
+ }
7494
+ return "workflow";
7495
+ }
7496
+ __name(describeWorkflowCall, "describeWorkflowCall");
7497
+ function createWorkflowHost(options) {
7498
+ const registry = options.registry ?? new WorkflowRunRegistry();
7499
+ const tool = defineTool({
7500
+ name: WORKFLOW_TOOL_NAME,
7501
+ description: WORKFLOW_TOOL_DESCRIPTION,
7502
+ inputSchema: mcpJsonSchemaToZod({
7503
+ type: "object",
7504
+ properties: {
7505
+ script: {
7506
+ type: "string",
7507
+ maxLength: MAX_WORKFLOW_SCRIPT_CHARS,
7508
+ description: "The workflow script: `export const meta = {...}` first, then the code. Plain JavaScript, not wrapped in a function or a code fence."
7509
+ },
7510
+ args: {
7511
+ description: "JSON the script reads as `args`. Keep it small; the operator reads it before the run starts."
7512
+ },
7513
+ description: {
7514
+ type: "string",
7515
+ maxLength: 200,
7516
+ description: "Optional one-line summary shown to the operator instead of meta.description."
7517
+ }
7518
+ },
7519
+ required: ["script"],
7520
+ additionalProperties: false
7521
+ }),
7522
+ largeStringArguments: { script: 2e4 },
7523
+ truncatedInputHint: "Write a shorter script: shared helpers, loops instead of repeated lines, and prompts built from args.",
7524
+ malformedInputHint: 'Every character of "script" goes inside a JSON string: write a newline as \\n, a tab as \\t, a double quote as \\" and a backslash as \\\\.',
7525
+ // The person reads `Workflow(<what it is for>)`, never the script.
7526
+ presentCall: /* @__PURE__ */ __name((input) => ({
7527
+ kind: "generic",
7528
+ label: `Workflow(${describeWorkflowCall(input)})`,
7529
+ presentation: "activity"
7530
+ }), "presentCall"),
7531
+ category: "custom",
7532
+ permissions: [],
7533
+ readOnly: false,
7534
+ destructive: false,
7535
+ concurrencySafe: false,
7536
+ async execute(input, context) {
7537
+ const { script, args } = input;
7538
+ const refused = options.refusal(context.turnId);
7539
+ if (refused !== void 0) return { success: false, output: "", error: refused };
7540
+ if (args !== void 0 && JSON.stringify(args).length > MAX_WORKFLOW_ARGS_CHARS) {
7541
+ return {
7542
+ success: false,
7543
+ output: "",
7544
+ error: `args is larger than ${MAX_WORKFLOW_ARGS_CHARS} characters. Pass less, or have the agents read a file.`
7545
+ };
7546
+ }
7547
+ let meta;
7548
+ try {
7549
+ meta = parseWorkflowMeta(script);
7550
+ } catch (error) {
7551
+ if (error instanceof WorkflowScriptError) {
7552
+ return { success: false, output: "", error: error.message };
7553
+ }
7554
+ throw error;
7555
+ }
7556
+ const runId = createWorkflowRunId((id) => registry.get(id) !== void 0);
7557
+ const turn = options.openRunTurn(context.turnId, runId);
7558
+ const runs = options.runsDirectory(context.turnId);
7559
+ const limits = options.limitsFor?.(context.turnId);
7560
+ const journal = runs === void 0 ? void 0 : new FileWorkflowJournal(join9(runs, runId, "workflow"));
7561
+ const phaseDetail = /* @__PURE__ */ __name((title) => title === void 0 ? void 0 : meta.phases.find((phase) => phase.title.trim() === title.trim())?.detail, "phaseDetail");
7562
+ try {
7563
+ const view = registry.start({
7564
+ runId,
7565
+ meta,
7566
+ script,
7567
+ ...args !== void 0 ? { args } : {},
7568
+ ...limits ? { limits } : {},
7569
+ ...journal ? { journal } : {},
7570
+ spawn: /* @__PURE__ */ __name(async (request, signal, viewed) => {
7571
+ const detail = phaseDetail(request.phaseTitle);
7572
+ const outcome = await options.subagents.launchWorkflowAgent({
7573
+ turnId: turn.turnId,
7574
+ runId,
7575
+ workflowName: meta.name,
7576
+ label: request.label,
7577
+ prompt: request.prompt,
7578
+ ...request.phaseTitle !== void 0 ? { phaseTitle: request.phaseTitle } : {},
7579
+ ...request.phaseIndex !== void 0 ? { phaseIndex: request.phaseIndex } : {},
7580
+ ...detail !== void 0 ? { phaseDetail: detail } : {},
7581
+ ...request.agentType !== void 0 ? { agentType: request.agentType } : {},
7582
+ ...request.model !== void 0 ? { model: request.model } : {},
7583
+ ...request.effort !== void 0 ? { effort: request.effort } : {},
7584
+ ...request.schema !== void 0 ? { schema: request.schema } : {},
7585
+ signal,
7586
+ inherit: {
7587
+ ...context.env ? { env: context.env } : {},
7588
+ ...context.toolResultGuardrails ? { toolResultGuardrails: context.toolResultGuardrails } : {}
7589
+ },
7590
+ onView: viewed,
7591
+ onProgress: /* @__PURE__ */ __name((progress) => {
7592
+ const last = toolName(progress.lastTool);
7593
+ request.onProgress({
7594
+ ...progress.tokens !== void 0 ? { tokens: progress.tokens } : {},
7595
+ ...progress.toolCalls !== void 0 ? { toolCalls: progress.toolCalls } : {},
7596
+ ...progress.lastTool !== void 0 ? {
7597
+ lastToolName: last.name,
7598
+ lastToolSummary: last.summary ?? last.name
7599
+ } : {}
7600
+ });
7601
+ }, "onProgress")
7602
+ });
7603
+ return {
7604
+ state: outcome.state,
7605
+ ...outcome.text !== void 0 ? { text: outcome.text } : {},
7606
+ tokens: outcome.tokens,
7607
+ toolCalls: outcome.toolCalls,
7608
+ ...outcome.error !== void 0 ? { error: outcome.error } : {}
7609
+ };
7610
+ }, "spawn"),
7611
+ onEnd: /* @__PURE__ */ __name(async (end) => {
7612
+ await turn.release().catch(() => void 0);
7613
+ options.onEnd?.(end);
7614
+ }, "onEnd")
7615
+ });
7616
+ return {
7617
+ success: true,
7618
+ output: launchedText(view),
7619
+ data: {
7620
+ run_id: runId,
7621
+ name: meta.name,
7622
+ description: input && typeof input.description === "string" ? input.description : meta.description,
7623
+ phases: meta.phases.map((phase) => phase.title)
7624
+ }
7625
+ };
7626
+ } catch (error) {
7627
+ await turn.release();
7628
+ throw error;
7629
+ }
7630
+ }
7631
+ });
7632
+ return { registry, tool };
7633
+ }
7634
+ __name(createWorkflowHost, "createWorkflowHost");
7635
+
7066
7636
  // src/memory/store.ts
7067
7637
  import { realpathSync as realpathSync3 } from "node:fs";
7068
- import { join as join9, resolve as resolve7 } from "node:path";
7638
+ import { join as join11, resolve as resolve7 } from "node:path";
7069
7639
 
7070
7640
  // src/memory/io.ts
7071
7641
  import {
@@ -7079,7 +7649,7 @@ import {
7079
7649
  realpathSync as realpathSync2,
7080
7650
  writeSync
7081
7651
  } from "node:fs";
7082
- import { isAbsolute as isAbsolute5, join as join8, relative as relative5, resolve as resolve6, sep as sep4 } from "node:path";
7652
+ import { isAbsolute as isAbsolute5, join as join10, relative as relative5, resolve as resolve6, sep as sep4 } from "node:path";
7083
7653
  var MEMORY_FILE_MAX_BYTES = 1024 * 1024;
7084
7654
  function missing(error) {
7085
7655
  return error.code === "ENOENT";
@@ -7112,7 +7682,7 @@ function resolveMemoryPath(location, createParents = false) {
7112
7682
  for (let i = 0; i < parts.length; i += 1) {
7113
7683
  const part = parts[i];
7114
7684
  if (part === void 0) throw new Error("Memory path has an invalid segment.");
7115
- candidate = join8(candidate, part);
7685
+ candidate = join10(candidate, part);
7116
7686
  const leaf = i === parts.length - 1;
7117
7687
  let stat5;
7118
7688
  try {
@@ -7242,11 +7812,11 @@ function memoryDir(home) {
7242
7812
  }
7243
7813
  __name(memoryDir, "memoryDir");
7244
7814
  function userFilePath(home) {
7245
- return join9(memoryDir(home), "USER.md");
7815
+ return join11(memoryDir(home), "USER.md");
7246
7816
  }
7247
7817
  __name(userFilePath, "userFilePath");
7248
7818
  function memoryFilePath(home) {
7249
- return join9(memoryDir(home), "MEMORY.md");
7819
+ return join11(memoryDir(home), "MEMORY.md");
7250
7820
  }
7251
7821
  __name(memoryFilePath, "memoryFilePath");
7252
7822
  function projectMemoryFilePath(cwd) {
@@ -7257,9 +7827,9 @@ function projectMemoryFilePath(cwd) {
7257
7827
  if (error.code !== "ENOENT") throw error;
7258
7828
  }
7259
7829
  const root = cliProjectRoot(directory);
7260
- const local = join9(directory, ".namzu", "MEMORY.md");
7830
+ const local = join11(directory, ".namzu", "MEMORY.md");
7261
7831
  if (resolveMemoryPath({ path: local, root }) !== null) return local;
7262
- return join9(root, ".namzu", "MEMORY.md");
7832
+ return join11(root, ".namzu", "MEMORY.md");
7263
7833
  }
7264
7834
  __name(projectMemoryFilePath, "projectMemoryFilePath");
7265
7835
  function projectMemoryLocation(cwd) {
@@ -7289,15 +7859,15 @@ function readMemory(home, cwd) {
7289
7859
  }
7290
7860
  }, "read");
7291
7861
  const userRoot = memoryDir(home);
7292
- const user = read(join9(userRoot, "USER.md"), () => ({
7862
+ const user = read(join11(userRoot, "USER.md"), () => ({
7293
7863
  root: userRoot,
7294
- path: join9(userRoot, "USER.md")
7864
+ path: join11(userRoot, "USER.md")
7295
7865
  }));
7296
- const memory = read(join9(userRoot, "MEMORY.md"), () => ({
7866
+ const memory = read(join11(userRoot, "MEMORY.md"), () => ({
7297
7867
  root: userRoot,
7298
- path: join9(userRoot, "MEMORY.md")
7868
+ path: join11(userRoot, "MEMORY.md")
7299
7869
  }));
7300
- const project = cwd && !isUserMemoryFile(join9(resolve7(cwd), ".namzu", "MEMORY.md"), userRoot) ? read(join9(resolve7(cwd), ".namzu", "MEMORY.md"), () => projectLocation(cwd)) : null;
7870
+ const project = cwd && !isUserMemoryFile(join11(resolve7(cwd), ".namzu", "MEMORY.md"), userRoot) ? read(join11(resolve7(cwd), ".namzu", "MEMORY.md"), () => projectLocation(cwd)) : null;
7301
7871
  return { user, memory, project, ...diagnostics.length > 0 ? { diagnostics } : {} };
7302
7872
  }
7303
7873
  __name(readMemory, "readMemory");
@@ -7309,7 +7879,7 @@ function isUserMemoryFile(projectPath, userRoot) {
7309
7879
  return resolve7(path);
7310
7880
  }
7311
7881
  }, "canonical");
7312
- return canonical(projectPath) === canonical(join9(userRoot, "MEMORY.md"));
7882
+ return canonical(projectPath) === canonical(join11(userRoot, "MEMORY.md"));
7313
7883
  }
7314
7884
  __name(isUserMemoryFile, "isUserMemoryFile");
7315
7885
  function capped(text, file) {
@@ -7458,8 +8028,8 @@ __name(renderStoredMemorySection, "renderStoredMemorySection");
7458
8028
 
7459
8029
  // src/memory/typed.ts
7460
8030
  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";
8031
+ import { access, readFile as readFile4, rename as rename3, writeFile as writeFile2 } from "node:fs/promises";
8032
+ import { join as join12 } from "node:path";
7463
8033
  function firstLine2(text, limit) {
7464
8034
  const line = (text.split(/\r?\n/).find((part) => part.trim()) ?? "").replace(/\s+/g, " ").trim();
7465
8035
  if (line.length <= limit) return line;
@@ -7483,7 +8053,7 @@ async function saveTypedNote(store, text, type = "project") {
7483
8053
  saved: false,
7484
8054
  duplicate: true,
7485
8055
  type: record.entry.type ?? type,
7486
- ...record.entry.name ? { name: record.entry.name, path: join10(store.path, `${record.entry.name}.md`) } : {}
8056
+ ...record.entry.name ? { name: record.entry.name, path: join12(store.path, `${record.entry.name}.md`) } : {}
7487
8057
  };
7488
8058
  }
7489
8059
  }
@@ -7498,7 +8068,7 @@ async function saveTypedNote(store, text, type = "project") {
7498
8068
  return {
7499
8069
  saved: true,
7500
8070
  type,
7501
- ...entry.name ? { name: entry.name, path: join10(store.path, `${entry.name}.md`) } : {}
8071
+ ...entry.name ? { name: entry.name, path: join12(store.path, `${entry.name}.md`) } : {}
7502
8072
  };
7503
8073
  }
7504
8074
  __name(saveTypedNote, "saveTypedNote");
@@ -7516,7 +8086,7 @@ __name(composeStoredMemoryPrompt, "composeStoredMemoryPrompt");
7516
8086
  var MARKER = "migration.json";
7517
8087
  async function readMarker(directory) {
7518
8088
  try {
7519
- const parsed = JSON.parse(await readFile3(join10(directory, MARKER), "utf8"));
8089
+ const parsed = JSON.parse(await readFile4(join12(directory, MARKER), "utf8"));
7520
8090
  return parsed !== null && typeof parsed === "object" ? parsed : {};
7521
8091
  } catch (error) {
7522
8092
  if (error.code === "ENOENT") return {};
@@ -7529,7 +8099,7 @@ async function markCuratedFile(directory, path, state) {
7529
8099
  const files = { ...marker.curatedFiles ?? {} };
7530
8100
  files[path] = { ...files[path] ?? {}, ...state };
7531
8101
  await writeFile2(
7532
- join10(directory, MARKER),
8102
+ join12(directory, MARKER),
7533
8103
  `${JSON.stringify({ ...marker, curatedFiles: files }, null, 2)}
7534
8104
  `,
7535
8105
  { mode: 384 }
@@ -7596,7 +8166,7 @@ async function migrateMemoryOnce(options) {
7596
8166
  const skippedRecords = [];
7597
8167
  let importedRecords = 0;
7598
8168
  let notesOffer;
7599
- const indexPath = join10(directory, "index.json");
8169
+ const indexPath = join12(directory, "index.json");
7600
8170
  if (await exists(indexPath)) {
7601
8171
  try {
7602
8172
  const disk = new DiskMemoryStore({ baseDir: directory, directory });
@@ -7619,11 +8189,11 @@ async function migrateMemoryOnce(options) {
7619
8189
  }
7620
8190
  }
7621
8191
  await retire(indexPath);
7622
- const content = join10(directory, "content");
8192
+ const content = join12(directory, "content");
7623
8193
  const retiredContent = await exists(content) ? await retire(content) : content;
7624
8194
  for (const record of refused) {
7625
8195
  skippedRecords.push(
7626
- `"${record.title}" (${record.id}) was not moved: ${record.reason} It is kept in ${join10(retiredContent, `${record.id}.json`)}.`
8196
+ `"${record.title}" (${record.id}) was not moved: ${record.reason} It is kept in ${join12(retiredContent, `${record.id}.json`)}.`
7627
8197
  );
7628
8198
  }
7629
8199
  } catch (error) {
@@ -7985,25 +8555,25 @@ __name(admitToolView, "admitToolView");
7985
8555
  function createCliToolPresenter(registry) {
7986
8556
  const log = cliLogger().child({ [SCOPE_ATTRIBUTE]: "cli/tool-presentation" });
7987
8557
  const presenter = createToolPresenter(registry, log);
7988
- const admit = /* @__PURE__ */ __name((toolName, hook, present) => {
8558
+ const admit = /* @__PURE__ */ __name((toolName2, hook, present) => {
7989
8559
  try {
7990
8560
  const view = admitToolView(present());
7991
8561
  if (view) return view;
7992
8562
  } catch {
7993
8563
  }
7994
8564
  log.warn("Tool presentation was invalid; using a plain view", {
7995
- "namzu.tool.name": toolName,
8565
+ "namzu.tool.name": toolName2,
7996
8566
  "namzu.tool.presenter_hook": hook
7997
8567
  });
7998
8568
  return void 0;
7999
8569
  }, "admit");
8000
8570
  return {
8001
- presentCall: /* @__PURE__ */ __name((toolName, input) => admit(toolName, "presentCall", () => presenter.presentCall(toolName, input)) ?? {
8571
+ presentCall: /* @__PURE__ */ __name((toolName2, input) => admit(toolName2, "presentCall", () => presenter.presentCall(toolName2, input)) ?? {
8002
8572
  kind: "generic",
8003
8573
  // Never stringify unreadable input as a replacement for a broken label.
8004
- label: toolName
8574
+ label: toolName2
8005
8575
  }, "presentCall"),
8006
- presentResult: /* @__PURE__ */ __name((toolName, input, result) => admit(toolName, "presentResult", () => presenter.presentResult(toolName, input, result)) ?? {
8576
+ presentResult: /* @__PURE__ */ __name((toolName2, input, result) => admit(toolName2, "presentResult", () => presenter.presentResult(toolName2, input, result)) ?? {
8007
8577
  kind: "terminal",
8008
8578
  output: (result.success ? result.output : result.error ?? result.output) ?? ""
8009
8579
  }, "presentResult")
@@ -8360,10 +8930,10 @@ function clipRequestContext(prompt, limit, kind) {
8360
8930
  __name(clipRequestContext, "clipRequestContext");
8361
8931
  async function createAgentSession(prefs, detected, options = {}) {
8362
8932
  if (options.palEnvironment) {
8363
- const { createPalAgentSession } = await import("./agent-session-C2HDOXK4.js");
8933
+ const { createPalAgentSession } = await import("./agent-session-PLIPF3XG.js");
8364
8934
  return createPalAgentSession(prefs, detected, options);
8365
8935
  }
8366
- const { palAtWorkspace } = await import("./store-2PDDGKYZ.js");
8936
+ const { palAtWorkspace } = await import("./store-7WZWQXKX.js");
8367
8937
  if (palAtWorkspace(options.cwd ?? process.cwd()))
8368
8938
  throw new Error("This Pal requires its owned virtual computer. Open it with namzu pal chat.");
8369
8939
  const fileObservations = /* @__PURE__ */ new Map();
@@ -8843,6 +9413,9 @@ async function createAgentSession(prefs, detected, options = {}) {
8843
9413
  const goalAuthorities = /* @__PURE__ */ new Map();
8844
9414
  const delegatedResumeHandlers = /* @__PURE__ */ new Map();
8845
9415
  const delegatedReviewAllowedCalls = /* @__PURE__ */ new Map();
9416
+ const delegatedWorkflowAuth = /* @__PURE__ */ new Map();
9417
+ let workflowHost;
9418
+ const workflowEndListeners = /* @__PURE__ */ new Set();
8846
9419
  const goalToolNames = new Set(SESSION_GOAL_TOOL_NAMES);
8847
9420
  if (options.sessionGoals) {
8848
9421
  toolsets.push(
@@ -9152,6 +9725,73 @@ async function createAgentSession(prefs, detected, options = {}) {
9152
9725
  new ToolManager({ toolsets: agentToolsets, messages: /* @__PURE__ */ __name(() => [], "messages") }).dispose();
9153
9726
  toolsets.push(...agentToolsets);
9154
9727
  allowedAgentIds = sub.allowedAgentIds;
9728
+ workflowHost = createWorkflowHost({
9729
+ subagents: sub,
9730
+ runsDirectory: /* @__PURE__ */ __name((turnId) => {
9731
+ if (options.ephemeral) return void 0;
9732
+ const owner = delegationScopes.get(turnId) ?? scope;
9733
+ return join13(paths.sessionDir({ sessionId: owner.sessionId }), "runs");
9734
+ }, "runsDirectory"),
9735
+ refusal: /* @__PURE__ */ __name((turnId) => {
9736
+ const auth = delegatedWorkflowAuth.get(turnId);
9737
+ if (!auth) return "This turn cannot start a workflow.";
9738
+ return workflowRefusal({ interactive: auth.interactive, mode: auth.mode() });
9739
+ }, "refusal"),
9740
+ openRunTurn: /* @__PURE__ */ __name((originTurnId, runId) => {
9741
+ const runTurnId = generateTurnId();
9742
+ const origin = delegatedWorkflowAuth.get(originTurnId);
9743
+ const ownerScope = delegationScopes.get(originTurnId) ?? { ...scope };
9744
+ const control = createLiveModeControl({
9745
+ initial: origin?.mode() ?? "prompt",
9746
+ ...origin ? { read: origin.mode } : {},
9747
+ handlerFor: /* @__PURE__ */ __name((mode) => makeResumeHandler(
9748
+ approval,
9749
+ origin?.reviewer?.onPermission,
9750
+ mode,
9751
+ reviewExemptionFor(mode, manager, (input) => sub.launchesReadOnlyAgent(input)),
9752
+ { unattendedSandboxEscape },
9753
+ screenPolicyFor(() => manager)
9754
+ ), "handlerFor")
9755
+ });
9756
+ liveModeControls.add(control);
9757
+ delegationScopes.set(runTurnId, ownerScope);
9758
+ delegationLimits.set(
9759
+ runTurnId,
9760
+ delegationLimits.get(originTurnId) ?? resolveTurnGuards(options.limits, void 0)
9761
+ );
9762
+ delegatedResumeHandlers.set(runTurnId, control.handler);
9763
+ delegatedReviewAllowedCalls.set(runTurnId, control.reviewAllowedCalls);
9764
+ const model2 = delegationModels.get(originTurnId);
9765
+ if (model2) delegationModels.set(runTurnId, model2);
9766
+ void runId;
9767
+ let released;
9768
+ return {
9769
+ turnId: runTurnId,
9770
+ release: /* @__PURE__ */ __name(() => {
9771
+ released ??= (async () => {
9772
+ liveModeControls.delete(control);
9773
+ delegationScopes.delete(runTurnId);
9774
+ delegationLimits.delete(runTurnId);
9775
+ delegatedResumeHandlers.delete(runTurnId);
9776
+ delegatedReviewAllowedCalls.delete(runTurnId);
9777
+ delegationModels.delete(runTurnId);
9778
+ await sub.releaseTurn(runTurnId);
9779
+ })();
9780
+ return released;
9781
+ }, "release")
9782
+ };
9783
+ }, "openRunTurn"),
9784
+ limitsFor: /* @__PURE__ */ __name((turnId) => {
9785
+ const budget = delegationLimits.get(turnId)?.tokenBudget;
9786
+ return {
9787
+ ...budget !== void 0 && budget > 0 ? { tokenBudget: budget } : {},
9788
+ ...options.workflow
9789
+ };
9790
+ }, "limitsFor"),
9791
+ onEnd: /* @__PURE__ */ __name((end) => {
9792
+ for (const listener of [...workflowEndListeners]) listener(end);
9793
+ }, "onEnd")
9794
+ });
9155
9795
  } catch (err) {
9156
9796
  try {
9157
9797
  await subagentRuntime?.close();
@@ -9223,7 +9863,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9223
9863
  if (options.openUrl) toolsets.push(toolset("open-url", [createOpenUrlTool()]));
9224
9864
  const decisionTool = maybeCreateDecisionTool(options.decision, process.env);
9225
9865
  if (decisionTool) toolsets.push(toolset("decide", [decisionTool]));
9226
- const operatorPals = await import("./operator-tools-GI63VOXH.js");
9866
+ const operatorPals = await import("./operator-tools-H4MYC5PE.js");
9227
9867
  toolsets.push(
9228
9868
  readyWhen(
9229
9869
  toolset(
@@ -9356,6 +9996,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9356
9996
  const reasoningLookup = new AbortController();
9357
9997
  const operations = new SessionOperationOwner(async () => {
9358
9998
  reasoningLookup.abort();
9999
+ workflowHost?.registry.close();
9359
10000
  const results = await Promise.allSettled([
9360
10001
  Promise.resolve().then(() => manager.dispose()),
9361
10002
  options.conversationSessions ? releaseConversationEvidence(options.conversationSessions, scope.sessionId) : void 0,
@@ -9828,6 +10469,32 @@ async function createAgentSession(prefs, detected, options = {}) {
9828
10469
  if (job.owner === jobOwner) listener(job);
9829
10470
  }) ?? (() => {
9830
10471
  }), "onJobExit"),
10472
+ ...workflowHost ? {
10473
+ workflows: /* @__PURE__ */ ((host) => ({
10474
+ runs: /* @__PURE__ */ __name(() => host.registry.list(), "runs"),
10475
+ subscribe: /* @__PURE__ */ __name((listener) => host.registry.subscribe(listener), "subscribe"),
10476
+ stop: /* @__PURE__ */ __name((runId) => host.registry.stop(runId), "stop"),
10477
+ skipAgent: /* @__PURE__ */ __name((runId, index) => host.registry.skipAgent(runId, index), "skipAgent"),
10478
+ agentOf: /* @__PURE__ */ __name((viewId) => host.registry.agentOf(viewId), "agentOf"),
10479
+ history: /* @__PURE__ */ __name(async () => {
10480
+ const live = host.registry.list();
10481
+ const known = new Set(live.map((view) => view.runId));
10482
+ const saved = options.ephemeral ? [] : await listWorkflowRuns(
10483
+ join13(paths.sessionDir({ sessionId: scope.sessionId }), "runs")
10484
+ ).catch(() => []);
10485
+ return [
10486
+ ...[...live].sort((a, b) => b.startedAt - a.startedAt),
10487
+ ...saved.filter((view) => !known.has(view.runId))
10488
+ ];
10489
+ }, "history"),
10490
+ onEnd: /* @__PURE__ */ __name((listener) => {
10491
+ workflowEndListeners.add(listener);
10492
+ return () => workflowEndListeners.delete(listener);
10493
+ }, "onEnd"),
10494
+ idle: /* @__PURE__ */ __name((signal) => host.registry.whenIdle(signal), "idle"),
10495
+ reset: /* @__PURE__ */ __name(() => host.registry.reset(), "reset")
10496
+ }))(workflowHost)
10497
+ } : {},
9831
10498
  ...subagentRuntime ? {
9832
10499
  subagents: subagentRuntime.activity,
9833
10500
  onSubagentReport: /* @__PURE__ */ __name((listener) => {
@@ -9836,6 +10503,7 @@ async function createAgentSession(prefs, detected, options = {}) {
9836
10503
  directChildReports.delete(listener);
9837
10504
  };
9838
10505
  }, "onSubagentReport"),
10506
+ stopSubagent: /* @__PURE__ */ __name((viewId) => subagentRuntime?.stopChild(viewId) ?? false, "stopSubagent"),
9839
10507
  messageSubagent: /* @__PURE__ */ __name((viewId, message2, opts) => operations.promise(opts?.signal, async (signal) => {
9840
10508
  const runtime = subagentRuntime;
9841
10509
  if (!runtime) throw new Error("Delegation is unavailable.");
@@ -9976,6 +10644,8 @@ async function createAgentSession(prefs, detected, options = {}) {
9976
10644
  mcpStatus: /* @__PURE__ */ __name(() => mcp.current(), "mcpStatus"),
9977
10645
  ...browserControl ? { browser: browserControl } : {},
9978
10646
  configNotices: [
10647
+ // Git for Windows is missing and the shell tool runs cmd.exe: said once, here.
10648
+ ...sandbox.provider === void 0 && windowsShellNotice() !== void 0 ? [windowsShellNotice()] : [],
9979
10649
  ...capabilityNotice ? [capabilityNotice] : [],
9980
10650
  ...effortNotice ? [effortNotice] : [],
9981
10651
  ...passthroughNotice ? [passthroughNotice] : [],
@@ -10084,6 +10754,11 @@ async function createAgentSession(prefs, detected, options = {}) {
10084
10754
  if (opts?.waitForInbound) delegatedInputWaiters.set(turnId2, opts.waitForInbound);
10085
10755
  delegationScopes.set(turnId2, turnScope);
10086
10756
  delegationLimits.set(turnId2, turnLimits);
10757
+ delegatedWorkflowAuth.set(turnId2, {
10758
+ interactive: opts?.workflowReview?.onPermission !== void 0,
10759
+ mode: /* @__PURE__ */ __name(() => modeControl.current(), "mode"),
10760
+ reviewer: opts?.workflowReview
10761
+ });
10087
10762
  if (capturedAuthority) {
10088
10763
  if (goalAuthorities.has(turnId2)) {
10089
10764
  throw new Error(`Turn ${turnId2} already owns goal-round authority.`);
@@ -10198,6 +10873,19 @@ async function createAgentSession(prefs, detected, options = {}) {
10198
10873
  render: /* @__PURE__ */ __name(() => invocationContext, "render")
10199
10874
  });
10200
10875
  }
10876
+ const workflowOffer = workflowHost !== void 0 && opts?.workflowReview !== void 0 && !residentContext && workflowOffered({
10877
+ hypermode: opts?.hypermode === true,
10878
+ userText: lastUserText(messages)
10879
+ });
10880
+ if (workflowOffer && workflowHost) {
10881
+ runToolsets = [...runToolsets, toolset("workflow", [workflowHost.tool])];
10882
+ if (runManager !== manager) runManager.dispose();
10883
+ runManager = new ToolManager({
10884
+ toolsets: runToolsets,
10885
+ ...screensConfig !== void 0 ? { resultGuardrails: screensConfig } : {},
10886
+ messages: /* @__PURE__ */ __name(() => [], "messages")
10887
+ });
10888
+ }
10201
10889
  const systemPrompt = [
10202
10890
  NAMZU_IDENTITY,
10203
10891
  residentContext ? void 0 : CODING_AGENT_WORKING_DOCTRINE,
@@ -10207,6 +10895,7 @@ async function createAgentSession(prefs, detected, options = {}) {
10207
10895
  // to use a tool it was not sent.
10208
10896
  residentContext || options.withheldTools?.includes(AGENT_LAUNCH_TOOL) ? void 0 : CODING_AGENT_DELEGATION_DOCTRINE,
10209
10897
  !residentContext && opts?.hypermode ? CODING_AGENT_HYPERMODE_DOCTRINE : void 0,
10898
+ workflowOffer ? WORKFLOW_DOCTRINE : void 0,
10210
10899
  residentContext ? void 0 : palPromptBlock(),
10211
10900
  options.conversationSessions ? CONVERSATION_EVIDENCE_GUIDANCE : void 0,
10212
10901
  options.toolLoading === "deferred" ? DEFERRED_TOOL_GUIDANCE : void 0,
@@ -10374,6 +11063,7 @@ async function createAgentSession(prefs, detected, options = {}) {
10374
11063
  delegatedInputWaiters.delete(turnId2);
10375
11064
  delegationScopes.delete(turnId2);
10376
11065
  delegationLimits.delete(turnId2);
11066
+ delegatedWorkflowAuth.delete(turnId2);
10377
11067
  await subagentRuntime?.releaseTurn(turnId2);
10378
11068
  }
10379
11069
  }
@@ -11054,9 +11744,9 @@ function confirmsItself(name, input) {
11054
11744
  }
11055
11745
  __name(confirmsItself, "confirmsItself");
11056
11746
  function declaredReadOnly(manager) {
11057
- return (toolName, input) => {
11747
+ return (toolName2, input) => {
11058
11748
  try {
11059
- return manager.get(toolName)?.isReadOnly?.(input) === true;
11749
+ return manager.get(toolName2)?.isReadOnly?.(input) === true;
11060
11750
  } catch {
11061
11751
  return false;
11062
11752
  }
@@ -11127,6 +11817,10 @@ function toAgentEvent(event, presenter, readsOnly) {
11127
11817
  if (view.kind === "diff") rememberCallDiff(event.toolUseId, view);
11128
11818
  return {
11129
11819
  summary: viewToSummary(view),
11820
+ ...(() => {
11821
+ const command = view.kind === "terminal" ? view.command : view.kind === "generic" && view.facts?.kind === "command" ? view.facts.command : void 0;
11822
+ return command ? { command } : {};
11823
+ })(),
11130
11824
  ...view.kind === "generic" && view.activity ? { activity: view.activity } : {},
11131
11825
  detail: viewToLines(view),
11132
11826
  ...view.kind === "generic" && view.presentation === "activity" ? { standalone: true } : {}
@@ -11195,6 +11889,7 @@ function toAgentEvent(event, presenter, readsOnly) {
11195
11889
  summary: headline ?? summary,
11196
11890
  ...headline ? { headline } : {},
11197
11891
  ...plainFailure ? { plainFailure } : {},
11892
+ ...tidy?.shell ? { shell: tidy.shell } : {},
11198
11893
  ...event.durationMs !== void 0 ? { durationMs: event.durationMs } : {},
11199
11894
  ...view.kind === "generic" && view.visibility === "hidden" ? { hidden: true } : {},
11200
11895
  ...event.isError && view.kind === "generic" && view.outcome === "cancelled" ? { cancelled: true } : {},
@@ -11680,4 +12375,4 @@ export {
11680
12375
  RESULT_SUMMARY_WHOLE_MAX,
11681
12376
  resultSummaryLine
11682
12377
  };
11683
- //# sourceMappingURL=chunk-H7VJHF5S.js.map
12378
+ //# sourceMappingURL=chunk-SFUUN6B3.js.map