very-happy-cli 0.2.175 → 0.2.177

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 (185) hide show
  1. package/dist/{AcpBackend-Sb6N_HcB.cjs → AcpBackend-B-ny68XM.cjs} +188 -37
  2. package/dist/{AcpBackend-BZrLVcHb.mjs → AcpBackend-B0K0WrtW.mjs} +187 -38
  3. package/dist/{AcpSessionManager-C2MqOirs.cjs → AcpSessionManager-CjdJLofq.cjs} +1 -1
  4. package/dist/{AcpSessionManager-y1Iy1mzc.mjs → AcpSessionManager-DykjzBM4.mjs} +1 -1
  5. package/dist/{BasePermissionHandler-BbLYwd13.cjs → BasePermissionHandler-DR6nxuEn.cjs} +1 -1
  6. package/dist/{BasePermissionHandler-DriZLITp.mjs → BasePermissionHandler-hdY7kTqX.mjs} +1 -1
  7. package/dist/{agentHome-BoYfpemd.cjs → agentHome-BdTXEUPe.cjs} +4 -4
  8. package/dist/{agentHome-BtuRubHG.mjs → agentHome-GRN2VfHv.mjs} +4 -4
  9. package/dist/{api-KZmVqSKO.cjs → api-BWX10o97.cjs} +17 -10
  10. package/dist/{api-D08IEaWa.mjs → api-CKBViqI3.mjs} +18 -11
  11. package/dist/{apiMachine-Dct2GDAq.cjs → apiMachine-BYYFGgFs.cjs} +15 -14
  12. package/dist/{apiMachine-Cx9Zn-78.mjs → apiMachine-DttO4UFj.mjs} +15 -14
  13. package/dist/{attachmentContent-PrNJg8gG.mjs → attachmentContent-cPVF463_.mjs} +2 -2
  14. package/dist/{attachmentContent-4L9dO8E3.cjs → attachmentContent-kJKXpkMX.cjs} +2 -2
  15. package/dist/{attachmentLimits-BLbji11b.mjs → attachmentLimits-Di1Z93lN.mjs} +1 -1
  16. package/dist/{attachmentLimits-D6bT2jU1.cjs → attachmentLimits-DtFqqiwR.cjs} +1 -1
  17. package/dist/{auth-D1qHU-i_.mjs → auth-BmESeKuM.mjs} +5 -5
  18. package/dist/{auth-PY_HGlzz.mjs → auth-CKdXb9zp.mjs} +8 -8
  19. package/dist/{auth-BGmM3Vlm.cjs → auth-CTECt2Oz.cjs} +5 -5
  20. package/dist/{auth-BI0CsMcy.cjs → auth-DNxVmVbn.cjs} +8 -8
  21. package/dist/{auto-COMphIfD.mjs → auto-Ch3203qd.mjs} +17 -16
  22. package/dist/{auto-DM4_FeKb.cjs → auto-D1ypjjfx.cjs} +16 -15
  23. package/dist/{backgroundTaskActivity-8PdPxrvy.mjs → backgroundTaskActivity-BVwJBl02.mjs} +1 -1
  24. package/dist/{bootstrap-DTJ6-vYT.cjs → bootstrap-6OI698q9.cjs} +2 -2
  25. package/dist/{bootstrap-CWjpC5-J.mjs → bootstrap-C0s2bPFQ.mjs} +2 -2
  26. package/dist/{browser-xuW4fiHo.mjs → browser-BlLWZUMx.mjs} +1 -1
  27. package/dist/{browser-DmgVoopB.cjs → browser-DG6Uof5O.cjs} +1 -1
  28. package/dist/{claudeLocal-B0P-wVJJ.mjs → claudeLocal-CcWcKnoo.mjs} +5 -5
  29. package/dist/{claudeLocal-CtZVz3ee.cjs → claudeLocal-CemsIArT.cjs} +5 -5
  30. package/dist/{claudeLocalLauncher-D4vmjI3c.mjs → claudeLocalLauncher-7p6y88nj.mjs} +15 -18
  31. package/dist/{claudeLocalLauncher-Dnv4CH8r.cjs → claudeLocalLauncher-A4VuevIi.cjs} +15 -18
  32. package/dist/{claudeSessionFork-CxjOBoBh.mjs → claudeSessionFork-BtROOjqf.mjs} +1 -1
  33. package/dist/{claudeSessionFork-DQk5-dzR.cjs → claudeSessionFork-CbDfm8Fz.cjs} +1 -1
  34. package/dist/{client-eQjOvC55.mjs → client-BPMWutfs.mjs} +3 -3
  35. package/dist/{client-BhLhjj_x.cjs → client-COmgDDy0.cjs} +2 -2
  36. package/dist/{client-C4ddTzrD.mjs → client-DG5ndWLw.mjs} +2 -2
  37. package/dist/{client-BHZVyQwi.cjs → client-DyvBTYee.cjs} +3 -3
  38. package/dist/codex/happyMcpStdioBridge.cjs +15 -15
  39. package/dist/codex/happyMcpStdioBridge.mjs +16 -16
  40. package/dist/{codexAppServerClient-CppPl_R6.mjs → codexAppServerClient-D-Z8qSfI.mjs} +233 -24
  41. package/dist/{codexAppServerClient-D-9z-lWP.cjs → codexAppServerClient-R24WZZfg.cjs} +233 -24
  42. package/dist/{codexCommand-AgVJYnFU.cjs → codexCommand-6hW19gsq.cjs} +159 -84
  43. package/dist/{codexCommand-BdrBNbZu.mjs → codexCommand-CVTkZJ1o.mjs} +158 -83
  44. package/dist/{BaseReasoningProcessor-_S1PbSvH.cjs → codexTermination-BBU7e92y.cjs} +25 -1
  45. package/dist/{BaseReasoningProcessor-DnykPlPo.mjs → codexTermination-CCIfwzcx.mjs} +25 -2
  46. package/dist/{config-Cr3VUzbE.mjs → config-CvsNChKX.mjs} +3 -3
  47. package/dist/{config-D89sE3wK.cjs → config-DhdrvOLV.cjs} +3 -3
  48. package/dist/{configuration-BNGPXg07.mjs → configuration-D55F0t16.mjs} +1 -1
  49. package/dist/{configuration-UV4EE5ui.cjs → configuration-DZPy0T9Z.cjs} +1 -1
  50. package/dist/{connect-C0iLkCiY.mjs → connect-CwCXMRmD.mjs} +14 -14
  51. package/dist/{connect-B35YXbdZ.cjs → connect-Wz-XZYXW.cjs} +13 -13
  52. package/dist/{context-BmH2BKip.cjs → context-BKbrZ55r.cjs} +1 -1
  53. package/dist/{context-Ptdnlcv6.mjs → context-CCRpVXFo.mjs} +1 -1
  54. package/dist/{controlClient-DqtC0pq1.mjs → controlClient-C4xB5J6O.mjs} +4 -4
  55. package/dist/{controlClient-CtsQMw--.cjs → controlClient-SX8gSza2.cjs} +3 -3
  56. package/dist/{createSessionMetadata-2IuH5nlA.cjs → createSessionMetadata-BCFmYlBo.cjs} +2 -2
  57. package/dist/{createSessionMetadata-CtNMvfth.mjs → createSessionMetadata-Bi-m0Y_O.mjs} +2 -2
  58. package/dist/{defaultPermissionMode-Bn4HcU8S.cjs → defaultPermissionMode-DMBEnXll.cjs} +2 -2
  59. package/dist/{defaultPermissionMode-DYihjV2g.mjs → defaultPermissionMode-wBcbBezm.mjs} +2 -2
  60. package/dist/{deterministicJson-DF4xv6MH.mjs → deterministicJson-BkQETt8_.mjs} +9 -9
  61. package/dist/{deterministicJson-je21npNx.cjs → deterministicJson-ChGfQEF6.cjs} +9 -9
  62. package/dist/{doctor-Ba92L7-b.mjs → doctor-B9c2C9dF.mjs} +8 -8
  63. package/dist/{doctor-BXKcYVGU.cjs → doctor-BsN3JZJn.cjs} +7 -7
  64. package/dist/{downloadTarget-CUJg8iJV.mjs → downloadTarget-ByXzbDK4.mjs} +6 -6
  65. package/dist/{downloadTarget-JC7FZl7W.cjs → downloadTarget-Dj3WoVJa.cjs} +6 -6
  66. package/dist/{ensureDaemonRunning-JPA9tHNE.mjs → ensureDaemonRunning--HYzs5Ce.mjs} +5 -5
  67. package/dist/{ensureDaemonRunning-bIp6-vgi.cjs → ensureDaemonRunning-7Wb8M7Lv.cjs} +5 -5
  68. package/dist/{handleResumeCommand-B6lE5DtU.mjs → handleResumeCommand-DHddBkNJ.mjs} +5 -5
  69. package/dist/{handleResumeCommand-B6b9kIYf.cjs → handleResumeCommand-OmuUGYjQ.cjs} +5 -5
  70. package/dist/{index-B2KL0aPc.cjs → index-BRJzH4sc.cjs} +141 -87
  71. package/dist/{index-CjE4kBKx.mjs → index-BzJNDsJq.mjs} +143 -89
  72. package/dist/{index-B6UGRQ7h.mjs → index-CEjJnq05.mjs} +3 -0
  73. package/dist/{index-CZLwo1FS.mjs → index-CEm0MYiS.mjs} +3 -3
  74. package/dist/{index-B1ABQRrB.cjs → index-CrR4JISa.cjs} +4 -4
  75. package/dist/{index-D759ViMU.cjs → index-D9NoYc5I.cjs} +3 -3
  76. package/dist/{index-D3kI0hDR.cjs → index-DFPT4HOO.cjs} +3 -0
  77. package/dist/{index-boE-d8CM.mjs → index-DMy3OCBe.mjs} +8 -1
  78. package/dist/{index-BZdhwBKa.cjs → index-De8L5lFK.cjs} +8 -0
  79. package/dist/{index-DW1ONaGc.mjs → index-Dhl6_bw7.mjs} +4 -4
  80. package/dist/index.cjs +2 -2
  81. package/dist/index.mjs +2 -2
  82. package/dist/{install-KjIsK_EA.cjs → install-1qn-D9FS.cjs} +3 -3
  83. package/dist/{install-CmojqnLK.mjs → install-BDIUtPXi.mjs} +3 -3
  84. package/dist/lib.cjs +12 -12
  85. package/dist/lib.d.cts +7 -1
  86. package/dist/lib.d.mts +7 -1
  87. package/dist/lib.mjs +13 -13
  88. package/dist/{lidState-CL1NdKfQ.mjs → lidState-BqVsw7H1.mjs} +1 -1
  89. package/dist/{lidState-BmJp2pLt.cjs → lidState-DxbK0qfu.cjs} +1 -1
  90. package/dist/{localHappyAgentAuth-B7f4Ysn0.mjs → localHappyAgentAuth-Ce8kO2yc.mjs} +1 -1
  91. package/dist/{localHappyAgentAuth-9SP7hdiw.cjs → localHappyAgentAuth-D5tANdRD.cjs} +1 -1
  92. package/dist/{logger-D5EzMy30.mjs → logger-13cBr_ew.mjs} +2 -2
  93. package/dist/{logger-C7dRaCkE.cjs → logger-LvwVeATU.cjs} +2 -2
  94. package/dist/{machineMetadata-DYYuK_0c.cjs → machineMetadata-29h7vgf4.cjs} +3 -3
  95. package/dist/{machineMetadata-DqplCWue.mjs → machineMetadata-dMida2qq.mjs} +3 -3
  96. package/dist/{main-kgCQgknK.cjs → main-DpM5jaFH.cjs} +44 -44
  97. package/dist/{main-CnV62agu.mjs → main-x4nAhdH5.mjs} +44 -44
  98. package/dist/{mcp-bDPaj-tM.mjs → mcp-DMiFGYMT.mjs} +15 -15
  99. package/dist/{mcp-BV0vxHtz.cjs → mcp-DQv3caXs.cjs} +14 -14
  100. package/dist/{mirrorProtocol-BSHVZ8Nf.cjs → mirrorProtocol-BfrERW7Z.cjs} +3 -3
  101. package/dist/{mirrorProtocol-ClKhNXYe.mjs → mirrorProtocol-Bz8tEabR.mjs} +3 -3
  102. package/dist/{package-VqWv7EI5.cjs → package-Ch9WGDV_.cjs} +7 -7
  103. package/dist/{package-D0dxZ-W8.mjs → package-CjlsAaRe.mjs} +7 -7
  104. package/dist/{peerTools-B_eiNB3P.mjs → peerTools-CxmrKnfV.mjs} +4 -4
  105. package/dist/{peerTools-BktGmlpd.cjs → peerTools-DtGKWli5.cjs} +4 -4
  106. package/dist/{persistence-CIIhP0Uw.mjs → persistence-C_tYtOqK.mjs} +2 -2
  107. package/dist/{persistence-DweHi8xa.cjs → persistence-DXbKOHxl.cjs} +2 -2
  108. package/dist/{piRunnerArgs-BNzWTNRV.cjs → piRunnerArgs-BVRZe2AR.cjs} +1 -1
  109. package/dist/{piRunnerArgs-cQafsadv.mjs → piRunnerArgs-BpHc-JZl.mjs} +1 -1
  110. package/dist/{piRuntime-VZLSwW-4.cjs → piRuntime-D7eio8Ix.cjs} +1 -1
  111. package/dist/{piRuntime-Bel5lOLb.mjs → piRuntime-DOdGF395.mjs} +1 -1
  112. package/dist/{piTerminal-CS5SDi_H.mjs → piTerminal-dpxz4Q8D.mjs} +17 -17
  113. package/dist/{piTerminal-DkR8sPv-.cjs → piTerminal-y_PRo2NY.cjs} +16 -16
  114. package/dist/processTree-CMHWlVse.cjs +66 -0
  115. package/dist/processTree-CP5IvQ2Z.mjs +61 -0
  116. package/dist/{rateLimitWindows-Bp4T21RI.cjs → rateLimitWindows-DFnMU2Vt.cjs} +1 -1
  117. package/dist/{rateLimitWindows-Bo6XVnie.mjs → rateLimitWindows-DYHDGuzQ.mjs} +1 -1
  118. package/dist/{registerCommonHandlers-B7QZxkCL.cjs → registerCommonHandlers-60VuTkdg.cjs} +2 -2
  119. package/dist/{registerCommonHandlers-CR5jpiSx.mjs → registerCommonHandlers-D8OMpBbQ.mjs} +2 -2
  120. package/dist/{registerKillSessionHandler-DLiu24CQ.mjs → registerKillSessionHandler-Drhf7-Vz.mjs} +6 -6
  121. package/dist/{registerKillSessionHandler-CcX84g-T.cjs → registerKillSessionHandler-pqChBKwO.cjs} +6 -6
  122. package/dist/{remoteSessionClient-CL3akj0K.cjs → remoteSessionClient-B7NvjHD3.cjs} +5 -5
  123. package/dist/{remoteSessionClient-CUjw1COc.mjs → remoteSessionClient-D01Hso2-.mjs} +5 -5
  124. package/dist/{reportProgressTool-BLLwMQrN.mjs → reportProgressTool-B203EZCR.mjs} +2 -2
  125. package/dist/{reportProgressTool-DzMi4mvH.cjs → reportProgressTool-Du_zAK4h.cjs} +2 -2
  126. package/dist/{run-DGokR_6q.mjs → run-DX4Zs3Ug.mjs} +34 -34
  127. package/dist/{run-5pmOElaW.cjs → run-DZ5jU53c.cjs} +34 -34
  128. package/dist/{runClaude-BFlpZQds.mjs → runClaude-CgPHXP0L.mjs} +27 -23
  129. package/dist/{runClaude-EnYNvkV0.cjs → runClaude-ClRhHpwR.cjs} +26 -22
  130. package/dist/{runClaudeDeps-CUDebE9e.cjs → runClaudeDeps-D2v_WDSL.cjs} +387 -89
  131. package/dist/{runClaudeDeps-D1M1dzlZ.mjs → runClaudeDeps-Dz2iydq4.mjs} +393 -95
  132. package/dist/{runGemini-Bu69Zu1u.cjs → runGemini-BtZqGFkp.cjs} +208 -193
  133. package/dist/{runGemini-Bub8T5cM.mjs → runGemini-DBXxpoY8.mjs} +208 -193
  134. package/dist/{runOpenClaw-DVu73F_i.mjs → runOpenClaw-BOHpzCEU.mjs} +19 -19
  135. package/dist/{runOpenClaw-Cob5F3FC.cjs → runOpenClaw-D8q8G57u.cjs} +18 -18
  136. package/dist/{sandbox-9EKOFyQF.mjs → sandbox-C452Vrsc.mjs} +4 -4
  137. package/dist/{sandbox-GDqMagSF.cjs → sandbox-Cu9mMzjx.cjs} +4 -4
  138. package/dist/selfCheck-BAvqBwBR.mjs +84 -0
  139. package/dist/{selfCheck-DiNo34da.cjs → selfCheck-gKa3uVr1.cjs} +35 -35
  140. package/dist/{send-ThC80164.cjs → send-2Vb5eppI.cjs} +8 -8
  141. package/dist/{send-wgtHphq8.mjs → send-B8HARi7x.mjs} +9 -9
  142. package/dist/{server-Bb8v2fOj.mjs → server-BBWCIZyS.mjs} +4 -4
  143. package/dist/{server-bidHnstE.cjs → server-Db9Wuam3.cjs} +6 -6
  144. package/dist/{sessionLock-BWBcBZKh.cjs → sessionLock-6qL_N6Rn.cjs} +3 -3
  145. package/dist/{sessionLock-gb32sVPR.mjs → sessionLock-ZfvFVdUi.mjs} +3 -3
  146. package/dist/{sessionModeFile-C-fr1M1h.mjs → sessionModeFile-CWVq8AT9.mjs} +1 -1
  147. package/dist/{sessionModeFile-DhuTNcJr.cjs → sessionModeFile-CsLtn_PL.cjs} +1 -1
  148. package/dist/{sessionOps-ByZJbkMq.mjs → sessionOps-CdgbEJgf.mjs} +5 -5
  149. package/dist/{sessionOps-9MChM9Op.cjs → sessionOps-Dmt7WUUs.cjs} +4 -4
  150. package/dist/{sessionScanner-CxXPAVyS.mjs → sessionScanner-CNVaSNOn.mjs} +34 -4
  151. package/dist/{sessionScanner-BpegdnXK.cjs → sessionScanner-CQL_WSaC.cjs} +34 -3
  152. package/dist/{sessions-C1X4z_Lm.cjs → sessions-BJblG_Hx.cjs} +9 -9
  153. package/dist/{sessions-l-UgJGjV.mjs → sessions-DTomHfFg.mjs} +10 -10
  154. package/dist/{setupOfflineReconnection-CgtXlV74.mjs → setupOfflineReconnection-C5trsV-j.mjs} +2 -2
  155. package/dist/{setupOfflineReconnection-CS_8Da8R.cjs → setupOfflineReconnection-DVA0VpQL.cjs} +2 -2
  156. package/dist/{spawn-FyoHqYWo.mjs → spawn-CQJFgoOq.mjs} +15 -14
  157. package/dist/{spawn-D2BlNdZu.cjs → spawn-DRyNAqD8.cjs} +14 -13
  158. package/dist/{spawnAgents-BhsbJ253.mjs → spawnAgents-BjtmjBvP.mjs} +1 -1
  159. package/dist/{spawnAgents-CgMKuOhZ.cjs → spawnAgents-CCjJifAW.cjs} +1 -1
  160. package/dist/{spawnHappyCLI-DsC256j_.mjs → spawnHappyCLI-B_0RWxD4.mjs} +1 -1
  161. package/dist/{spawnHappyCLI-DByQcqEN.cjs → spawnHappyCLI-ChniczJ5.cjs} +1 -1
  162. package/dist/{specialCommands-DGUeZqdm.cjs → specialCommands-DbntVs0d.cjs} +3 -3
  163. package/dist/{specialCommands-DUUBqzvd.mjs → specialCommands-DkdFJi4N.mjs} +3 -3
  164. package/dist/{startFileWatcher-BtBaahTn.cjs → startFileWatcher-C292fhra.cjs} +1 -1
  165. package/dist/{startFileWatcher-CaYRObJu.mjs → startFileWatcher-UQyTSRAP.mjs} +1 -1
  166. package/dist/{streamRelay-DqPFsCgx.cjs → streamRelay-Cx01enfe.cjs} +1 -1
  167. package/dist/{streamRelay-C8zI7OnR.mjs → streamRelay-_qCd873P.mjs} +1 -1
  168. package/dist/{sync-D5YqUVjS.mjs → sync-C3p7-KLn.mjs} +1 -1
  169. package/dist/{sync-BK-IBkuB.cjs → sync-C7sxoUYG.cjs} +1 -1
  170. package/dist/{systemPrompt-e-qeag_h.mjs → systemPrompt-CdHOlyVW.mjs} +2 -2
  171. package/dist/{systemPrompt-DaTKLEb-.cjs → systemPrompt-DtibzbRU.cjs} +2 -2
  172. package/dist/{teams-D9xwa_d3.cjs → teams-D7O7TpVU.cjs} +6 -6
  173. package/dist/{teams-ClrppvKu.mjs → teams-ujXr3AFn.mjs} +6 -6
  174. package/dist/{time-0szhiPo4.cjs → time-Dg5tVB8S.cjs} +1 -1
  175. package/dist/{time-CvrpeD3S.mjs → time-yEL6wHUF.mjs} +1 -1
  176. package/dist/{titleGenerator-Dz5P7sE1.cjs → titleGenerator-BMEaDTwU.cjs} +2 -2
  177. package/dist/{titleGenerator-BZ5770wq.mjs → titleGenerator-Dr-BtjzO.mjs} +1 -1
  178. package/dist/{todo-CkmNJQey.cjs → todo-CUcFamGs.cjs} +6 -6
  179. package/dist/{todo-o-miKcN2.mjs → todo-CvJe4M2C.mjs} +6 -6
  180. package/dist/{tools-Cp0qJeBq.mjs → tools-BrM3bZW5.mjs} +1 -1
  181. package/dist/{tools-C77-Ssan.cjs → tools-DDKTB5aQ.cjs} +1 -1
  182. package/dist/{uninstall-DGUPERDX.cjs → uninstall-7oLuhYIu.cjs} +3 -3
  183. package/dist/{uninstall-jNJDCLD_.mjs → uninstall-CEcMMQGz.mjs} +3 -3
  184. package/package.json +7 -7
  185. package/dist/selfCheck-CNo4uzGB.mjs +0 -84
@@ -1,10 +1,11 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
3
3
  import { randomUUID } from 'node:crypto';
4
- import { l as logger } from './logger-D5EzMy30.mjs';
5
- import { d as delay } from './time-CvrpeD3S.mjs';
4
+ import { l as logger } from './logger-13cBr_ew.mjs';
5
+ import { d as delay } from './time-yEL6wHUF.mjs';
6
6
  import { c as contentLogMetadata, e as errorLogMetadata } from './contentLogMetadata-BlWI0egu.mjs';
7
- import { p as packageJson } from './package-D0dxZ-W8.mjs';
7
+ import { r as readableStderrTail, a as appendStderrRing, s as stopProcessGracefully, k as killProcessTree } from './processTree-CP5IvQ2Z.mjs';
8
+ import { p as packageJson } from './package-CjlsAaRe.mjs';
8
9
 
9
10
  function acpImageBlocks(attachments, supportsImages) {
10
11
  return attachments.filter((file) => ["image/jpeg", "image/png", "image/gif", "image/webp"].includes(file.mimeType)).map((file) => {
@@ -13,6 +14,19 @@ function acpImageBlocks(attachments, supportsImages) {
13
14
  });
14
15
  }
15
16
 
17
+ function isAgentExitError(error) {
18
+ return error instanceof Error && error.agentExited === true;
19
+ }
20
+ function agentExitError(agentName, code, signal, tail) {
21
+ const exited = `${agentName} process exited (code=${code ?? "null"}${signal ? `, signal=${signal}` : ""})`;
22
+ return Object.assign(new Error(tail ? `${exited}: ${tail}` : exited), {
23
+ agentExited: true,
24
+ agentExitCode: code,
25
+ agentExitSignal: signal,
26
+ agentStderrTail: tail
27
+ });
28
+ }
29
+
16
30
  const DEFAULT_TIMEOUTS = {
17
31
  /** Default initialization timeout: 60 seconds */
18
32
  init: 6e4,
@@ -185,6 +199,48 @@ function buildAcpPermissionMeta(toolCall) {
185
199
  return meta;
186
200
  }
187
201
 
202
+ const PI_ACP_RETRY = /^Retrying(?: \(attempt \d+\/\d+, waiting \d+s\))?\.\.\.$/;
203
+ const PI_ACP_RETRY_END = "Retry finished, resuming.";
204
+ const PI_ACP_COMPACTION = "Context nearing limit, running automatic compaction...";
205
+ const PI_ACP_COMPACTION_END = "Automatic compaction finished; context was summarized to continue the session.";
206
+ const PI_ACP_UNSUPPORTED = /^Pi (input|editor) UI request is not supported in ACP yet; cancelling it\.$/;
207
+ function notifyMeta(meta) {
208
+ if (!meta || typeof meta !== "object") return null;
209
+ const piAcp = meta.piAcp;
210
+ if (!piAcp || typeof piAcp !== "object") return null;
211
+ const notify = piAcp.notify;
212
+ if (!notify || typeof notify !== "object") return null;
213
+ const level = notify.level;
214
+ return { ...typeof level === "string" ? { level } : {} };
215
+ }
216
+ function classifyPiAcpNotice(text, meta) {
217
+ const notify = notifyMeta(meta);
218
+ if (notify) return { kind: "notify", text: text.trim(), ...notify.level ? { level: notify.level } : {} };
219
+ const trimmed = text.trim();
220
+ if (PI_ACP_RETRY.test(trimmed)) return { kind: "retry", text: trimmed };
221
+ if (trimmed === PI_ACP_RETRY_END) return { kind: "retry-end", text: trimmed };
222
+ if (trimmed === PI_ACP_COMPACTION) return { kind: "compaction", text: trimmed };
223
+ if (trimmed === PI_ACP_COMPACTION_END) return { kind: "compaction-end", text: trimmed };
224
+ if (PI_ACP_UNSUPPORTED.test(trimmed)) return { kind: "unsupported", text: trimmed };
225
+ return null;
226
+ }
227
+ function acpNoticeMessage(agentName, notice) {
228
+ switch (notice.kind) {
229
+ case "retry":
230
+ return `${agentName} is retrying the model request${notice.text.startsWith("Retrying (") ? ` ${notice.text.slice("Retrying ".length).replace(/\.\.\.$/, "")}` : ""}`;
231
+ case "retry-end":
232
+ return `${agentName} retry finished, resuming`;
233
+ case "compaction":
234
+ return `${agentName} is compacting its context (nearing the limit)`;
235
+ case "compaction-end":
236
+ return `${agentName} compacted its context; the session continues on a summary`;
237
+ case "unsupported":
238
+ return `${agentName}: ${notice.text}`;
239
+ case "notify":
240
+ return `${agentName}${notice.level && notice.level !== "info" ? ` ${notice.level}` : ""}: ${notice.text}`;
241
+ }
242
+ }
243
+
188
244
  const DEFAULT_IDLE_TIMEOUT_MS = 500;
189
245
  const DEFAULT_TOOL_CALL_TIMEOUT_MS = 12e4;
190
246
  function parseArgsFromContent(content) {
@@ -238,6 +294,13 @@ function handleAgentMessageChunk(update, ctx) {
238
294
  if (typeof text !== "string") {
239
295
  return { handled: false };
240
296
  }
297
+ if (ctx.transport.agentName === "pi") {
298
+ const notice = classifyPiAcpNotice(text, update._meta);
299
+ if (notice) {
300
+ ctx.emit({ type: "event", name: "notice", payload: notice });
301
+ return { handled: true };
302
+ }
303
+ }
241
304
  const isThinking = /^\*\*[^*]+\*\*\n/.test(text);
242
305
  if (isThinking) {
243
306
  ctx.emit({
@@ -300,25 +363,6 @@ function startToolCall(toolCallId, toolKind, update, ctx, source) {
300
363
  if (isInvestigation) {
301
364
  logger.debug(`[AcpBackend] \u{1F50D} Investigation tool detected - extended timeout (10min) will be used`);
302
365
  }
303
- const timeoutMs = ctx.transport.getToolCallTimeout?.(toolCallId, toolKindStr) ?? DEFAULT_TOOL_CALL_TIMEOUT_MS;
304
- if (!ctx.toolCallTimeouts.has(toolCallId)) {
305
- const timeout = setTimeout(() => {
306
- const duration = formatDuration(ctx.toolCallStartTimes.get(toolCallId));
307
- logger.debug(`[AcpBackend] Tool call TIMEOUT (from ${source}): ${toolCallId} after ${(timeoutMs / 1e3).toFixed(0)}s - Duration: ${duration}, removing from active set`);
308
- ctx.activeToolCalls.delete(toolCallId);
309
- ctx.toolCallStartTimes.delete(toolCallId);
310
- ctx.toolCallTimeouts.delete(toolCallId);
311
- ctx.toolCallOutputs.delete(toolCallId);
312
- if (ctx.activeToolCalls.size === 0) {
313
- logger.debug("[AcpBackend] No more active tool calls after timeout, emitting idle status");
314
- ctx.emitIdleStatus();
315
- }
316
- }, timeoutMs);
317
- ctx.toolCallTimeouts.set(toolCallId, timeout);
318
- logger.debug(`[AcpBackend] \u23F1\uFE0F Set timeout for ${toolCallId}: ${(timeoutMs / 1e3).toFixed(0)}s${isInvestigation ? " (investigation tool)" : ""}`);
319
- } else {
320
- logger.debug(`[AcpBackend] Timeout already set for ${toolCallId}, skipping`);
321
- }
322
366
  ctx.clearIdleTimeout();
323
367
  ctx.emit({ type: "status", status: "running" });
324
368
  const args = parseArgsFromContent(update.content);
@@ -631,6 +675,23 @@ class AcpBackend {
631
675
  toolCallCountSincePrompt = 0;
632
676
  /** Timeout for emitting 'idle' status after last message chunk */
633
677
  idleTimeout = null;
678
+ // B-629 (approach from Orca, src/main/acp/acp-agent-connection.ts): the agent process is
679
+ // part of the turn. Its last stderr lines are kept so its death can be explained, any exit
680
+ // (code or signal) is announced as `stopped`, and a request in flight when it dies rejects
681
+ // at once instead of waiting forever on a stream that will never answer.
682
+ /** Last stderr output of the agent process, bounded. */
683
+ stderrRing = "";
684
+ static STDERR_TAIL_CHARS = 2e3;
685
+ /** Set when the current agent process exited; the backend takes no further prompt. */
686
+ exited = null;
687
+ /** Rejects with the exit error when the current agent process exits (one per spawn). */
688
+ processGone = null;
689
+ /** Fails the request in flight (an oversized frame that was its answer, see MAX_FRAME_CHARS). */
690
+ inflightReject = null;
691
+ /** A single JSON-RPC line longer than this is dropped rather than buffered (Orca: 16 MiB). */
692
+ static MAX_FRAME_CHARS = 16 * 1024 * 1024;
693
+ /** How long the graceful stop gets on dispose before the process tree is killed. */
694
+ static DISPOSE_GRACE_MS = 4e3;
634
695
  /** Transport handler for agent-specific behavior */
635
696
  transport;
636
697
  onMessage(handler) {
@@ -642,6 +703,23 @@ class AcpBackend {
642
703
  this.listeners.splice(index, 1);
643
704
  }
644
705
  }
706
+ /** B-629: the agent's last stderr lines, one line, for a message a person reads. */
707
+ stderrTail() {
708
+ return readableStderrTail(this.stderrRing);
709
+ }
710
+ /** B-629: the agent process exited; this backend cannot take another prompt. */
711
+ get hasExited() {
712
+ return this.exited !== null;
713
+ }
714
+ /** B-629: a frame that cannot be read in full. One that answers a request fails that request. */
715
+ onOversizedFrame(head, chars) {
716
+ const looksLikeResponse = /"id"\s*:\s*\d+/.test(head) && /"(result|error)"\s*:/.test(head);
717
+ logger.debug(`[AcpBackend] Dropped an oversized ${this.transport.agentName} frame (${Math.round(chars / 1024 / 1024)} MiB${looksLikeResponse ? ", a response" : ""})`);
718
+ if (!looksLikeResponse) return;
719
+ const error = new Error(`${this.transport.agentName} sent a ${Math.round(chars / 1024 / 1024)} MiB response frame that cannot be read; the turn was given up`);
720
+ this.inflightReject?.(error);
721
+ this.emit({ type: "status", status: "error", detail: error.message });
722
+ }
645
723
  emit(msg) {
646
724
  if (this.disposed) return;
647
725
  for (const listener of this.listeners) {
@@ -684,6 +762,15 @@ class AcpBackend {
684
762
  if (!this.process.stdin || !this.process.stdout || !this.process.stderr) {
685
763
  throw new Error("Failed to create stdio pipes");
686
764
  }
765
+ const child = this.process;
766
+ let rejectGone;
767
+ const processGone = new Promise((_, reject) => {
768
+ rejectGone = reject;
769
+ });
770
+ processGone.catch(() => void 0);
771
+ this.processGone = processGone;
772
+ this.exited = null;
773
+ this.stderrRing = "";
687
774
  let startupFailure = null;
688
775
  let startupFailureSettled = false;
689
776
  let rejectStartupFailure = null;
@@ -703,6 +790,9 @@ class AcpBackend {
703
790
  this.process.stderr.on("data", (data) => {
704
791
  const text = data.toString();
705
792
  if (!text.trim()) return;
793
+ if (this.process === child) {
794
+ this.stderrRing = appendStderrRing(this.stderrRing, text, AcpBackend.STDERR_TAIL_CHARS);
795
+ }
706
796
  const hasActiveInvestigation = this.transport.isInvestigationTool ? Array.from(this.activeToolCalls).some((id) => this.transport.isInvestigationTool(id)) : false;
707
797
  const context = {
708
798
  activeToolCalls: this.activeToolCalls,
@@ -726,10 +816,14 @@ class AcpBackend {
726
816
  this.emit({ type: "status", status: "error", detail: err.message });
727
817
  });
728
818
  this.process.on("exit", (code, signal) => {
729
- if (!this.disposed && code !== 0 && code !== null) {
730
- signalStartupFailure(new Error(`Exit code: ${code}`));
731
- logger.debug(`[AcpBackend] Process exited with code ${code}, signal ${signal}`);
732
- this.emit({ type: "status", status: "stopped", detail: `Exit code: ${code}` });
819
+ const error = agentExitError(this.transport.agentName, code, signal, this.stderrTail());
820
+ setTimeout(() => rejectGone(error), 50);
821
+ if (this.process !== child) return;
822
+ this.exited = { code, signal, error };
823
+ signalStartupFailure(error);
824
+ logger.debug(`[AcpBackend] Process exited with code ${code}, signal ${signal}`);
825
+ if (!this.disposed) {
826
+ this.emit({ type: "status", status: "stopped", detail: error.message });
733
827
  }
734
828
  });
735
829
  const streams = nodeToWebStreams(
@@ -739,6 +833,7 @@ class AcpBackend {
739
833
  const writable = streams.writable;
740
834
  const readable = streams.readable;
741
835
  const transport = this.transport;
836
+ const backend = this;
742
837
  const filteredReadable = new ReadableStream({
743
838
  async start(controller) {
744
839
  const reader = readable.getReader();
@@ -769,8 +864,18 @@ class AcpBackend {
769
864
  buffer += decoder.decode(value, { stream: true });
770
865
  const lines = buffer.split("\n");
771
866
  buffer = lines.pop() || "";
867
+ if (buffer.length > AcpBackend.MAX_FRAME_CHARS) {
868
+ backend.onOversizedFrame(buffer.slice(0, 200), buffer.length);
869
+ buffer = "";
870
+ filteredCount++;
871
+ }
772
872
  for (const line of lines) {
773
873
  if (!line.trim()) continue;
874
+ if (line.length > AcpBackend.MAX_FRAME_CHARS) {
875
+ backend.onOversizedFrame(line.slice(0, 200), line.length);
876
+ filteredCount++;
877
+ continue;
878
+ }
774
879
  const filtered = transport.filterStdoutLine?.(line);
775
880
  if (filtered === void 0) {
776
881
  controller.enqueue(encoder.encode(line + "\n"));
@@ -1180,6 +1285,11 @@ class AcpBackend {
1180
1285
  get supportsImageAttachments() {
1181
1286
  return this.supportsImagePrompt;
1182
1287
  }
1288
+ /**
1289
+ * B-629: the turn is over when ACP's `prompt` answers (the agent sends every update before
1290
+ * its response on the same ordered stream), never when the text goes quiet — the idle
1291
+ * heuristic below is only a status hint now. Resolves with the agent's `stopReason`.
1292
+ */
1183
1293
  async sendPrompt(sessionId, prompt, attachments = []) {
1184
1294
  const promptHasChangeTitle = this.options.hasChangeTitleInstruction?.(prompt) ?? false;
1185
1295
  this.toolCallCountSincePrompt = 0;
@@ -1190,11 +1300,18 @@ class AcpBackend {
1190
1300
  if (this.disposed) {
1191
1301
  throw new Error("Backend has been disposed");
1192
1302
  }
1303
+ if (this.exited) {
1304
+ throw this.exited.error;
1305
+ }
1193
1306
  if (!this.connection || !this.acpSessionId) {
1194
1307
  throw new Error("Session not started");
1195
1308
  }
1196
1309
  this.emit({ type: "status", status: "running" });
1197
1310
  this.waitingForResponse = true;
1311
+ const inflight = new Promise((_, reject) => {
1312
+ this.inflightReject = reject;
1313
+ });
1314
+ inflight.catch(() => void 0);
1198
1315
  try {
1199
1316
  logger.debug("[AcpBackend] Sending prompt:", {
1200
1317
  sessionId,
@@ -1212,14 +1329,21 @@ class AcpBackend {
1212
1329
  sessionId: this.acpSessionId,
1213
1330
  blockCount: promptRequest.prompt.length
1214
1331
  });
1215
- const response = await this.connection.prompt(promptRequest);
1332
+ const response = await Promise.race([
1333
+ this.connection.prompt(promptRequest),
1334
+ this.processGone ?? new Promise(() => void 0),
1335
+ inflight
1336
+ ]);
1216
1337
  if (response.usage) {
1217
1338
  this.emit({ type: "token-count", ...response.usage });
1218
1339
  }
1219
- logger.debug("[AcpBackend] Prompt request sent to ACP connection");
1340
+ const stopReason = typeof response.stopReason === "string" ? response.stopReason : void 0;
1341
+ logger.debug(`[AcpBackend] Prompt answered (stopReason=${stopReason ?? "none"})`);
1342
+ this.finishTurn();
1343
+ return stopReason ? { stopReason } : {};
1220
1344
  } catch (error) {
1221
1345
  logger.debug("[AcpBackend] Error sending prompt:", errorLogMetadata(error));
1222
- this.waitingForResponse = false;
1346
+ this.finishTurn(false);
1223
1347
  let errorDetail;
1224
1348
  if (error instanceof Error) {
1225
1349
  errorDetail = error.message;
@@ -1242,7 +1366,29 @@ class AcpBackend {
1242
1366
  detail: errorDetail
1243
1367
  });
1244
1368
  throw error;
1369
+ } finally {
1370
+ this.inflightReject = null;
1371
+ }
1372
+ }
1373
+ /**
1374
+ * B-629: the turn's bookkeeping ends with the prompt answer: no response is awaited any
1375
+ * more, the idle timer and per-call timers are dropped, and the calls still marked active
1376
+ * belong to a turn that is over. `idle` is emitted once for status listeners.
1377
+ */
1378
+ finishTurn(announceIdle = true) {
1379
+ this.waitingForResponse = false;
1380
+ if (this.idleTimeout) {
1381
+ clearTimeout(this.idleTimeout);
1382
+ this.idleTimeout = null;
1383
+ }
1384
+ for (const timeout of this.toolCallTimeouts.values()) {
1385
+ clearTimeout(timeout);
1245
1386
  }
1387
+ this.toolCallTimeouts.clear();
1388
+ this.activeToolCalls.clear();
1389
+ this.toolCallStartTimes.clear();
1390
+ this.toolCallOutputs.clear();
1391
+ if (announceIdle) this.emitIdleStatus();
1246
1392
  }
1247
1393
  /**
1248
1394
  * Set a session config option value.
@@ -1387,7 +1533,7 @@ class AcpBackend {
1387
1533
  if (this.disposed) return;
1388
1534
  logger.debug("[AcpBackend] Disposing backend");
1389
1535
  this.disposed = true;
1390
- if (this.connection && this.acpSessionId) {
1536
+ if (this.connection && this.acpSessionId && !this.exited) {
1391
1537
  try {
1392
1538
  await Promise.race([
1393
1539
  this.connection.cancel({ sessionId: this.acpSessionId }),
@@ -1399,16 +1545,19 @@ class AcpBackend {
1399
1545
  }
1400
1546
  }
1401
1547
  if (this.process) {
1402
- this.process.kill("SIGTERM");
1548
+ const proc = this.process;
1549
+ stopProcessGracefully(proc);
1403
1550
  await new Promise((resolve) => {
1551
+ if (proc.exitCode != null || proc.signalCode != null) {
1552
+ resolve();
1553
+ return;
1554
+ }
1404
1555
  const timeout = setTimeout(() => {
1405
- if (this.process) {
1406
- logger.debug("[AcpBackend] Force killing process");
1407
- this.process.kill("SIGKILL");
1408
- }
1556
+ logger.debug("[AcpBackend] Force killing process tree");
1557
+ killProcessTree(proc);
1409
1558
  resolve();
1410
- }, 1e3);
1411
- this.process?.once("exit", () => {
1559
+ }, AcpBackend.DISPOSE_GRACE_MS);
1560
+ proc.once("exit", () => {
1412
1561
  clearTimeout(timeout);
1413
1562
  resolve();
1414
1563
  });
@@ -1433,4 +1582,4 @@ class AcpBackend {
1433
1582
  }
1434
1583
  }
1435
1584
 
1436
- export { AcpBackend as A, DefaultTransport as D, DEFAULT_IDLE_TIMEOUT_MS as a, DEFAULT_TOOL_CALL_TIMEOUT_MS as b, formatDurationMinutes as c, handleAgentThoughtChunk as d, extractErrorDetail as e, formatDuration as f, handleLegacyMessageChunk as g, handleAgentMessageChunk as h, handlePlanUpdate as i, handleThinkingUpdate as j, handleToolCall as k, handleToolCallUpdate as l, parseArgsFromContent as p };
1585
+ export { AcpBackend as A, DefaultTransport as D, acpNoticeMessage as a, DEFAULT_IDLE_TIMEOUT_MS as b, DEFAULT_TOOL_CALL_TIMEOUT_MS as c, formatDurationMinutes as d, extractErrorDetail as e, formatDuration as f, handleAgentThoughtChunk as g, handleAgentMessageChunk as h, isAgentExitError as i, handleLegacyMessageChunk as j, handlePlanUpdate as k, handleThinkingUpdate as l, handleToolCall as m, handleToolCallUpdate as n, parseArgsFromContent as p };
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var cuid2 = require('@paralleldrive/cuid2');
4
- var index = require('./index-BZdhwBKa.cjs');
4
+ var index = require('./index-De8L5lFK.cjs');
5
5
 
6
6
  function turnOptions(turnId, time) {
7
7
  return turnId ? { turn: turnId, time } : { time };
@@ -1,5 +1,5 @@
1
1
  import { createId } from '@paralleldrive/cuid2';
2
- import { s as streamKeyOf, c as createEnvelope } from './index-boE-d8CM.mjs';
2
+ import { s as streamKeyOf, c as createEnvelope } from './index-DMy3OCBe.mjs';
3
3
 
4
4
  function turnOptions(turnId, time) {
5
5
  return turnId ? { turn: turnId, time } : { time };
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var logger = require('./logger-C7dRaCkE.cjs');
3
+ var logger = require('./logger-LvwVeATU.cjs');
4
4
 
5
5
  class BasePermissionHandler {
6
6
  pendingRequests = /* @__PURE__ */ new Map();
@@ -1,4 +1,4 @@
1
- import { l as logger } from './logger-D5EzMy30.mjs';
1
+ import { l as logger } from './logger-13cBr_ew.mjs';
2
2
 
3
3
  class BasePermissionHandler {
4
4
  pendingRequests = /* @__PURE__ */ new Map();
@@ -2,14 +2,14 @@
2
2
 
3
3
  var chalk = require('chalk');
4
4
  var os = require('node:os');
5
- var persistence = require('./persistence-DweHi8xa.cjs');
5
+ var persistence = require('./persistence-DXbKOHxl.cjs');
6
6
  require('node:fs');
7
- require('./logger-C7dRaCkE.cjs');
7
+ require('./logger-LvwVeATU.cjs');
8
8
  var loginShellEnv = require('./loginShellEnv-BkuYtExZ.cjs');
9
9
  require('node:fs/promises');
10
- require('./configuration-UV4EE5ui.cjs');
10
+ require('./configuration-DZPy0T9Z.cjs');
11
11
  require('node:path');
12
- require('./package-VqWv7EI5.cjs');
12
+ require('./package-Ch9WGDV_.cjs');
13
13
  require('zod');
14
14
  require('./authRelay-BdYkC1Po.cjs');
15
15
  require('node:crypto');
@@ -1,13 +1,13 @@
1
1
  import chalk from 'chalk';
2
2
  import { homedir } from 'node:os';
3
- import { r as readSettings, u as updateSettings } from './persistence-CIIhP0Uw.mjs';
3
+ import { r as readSettings, u as updateSettings } from './persistence-C_tYtOqK.mjs';
4
4
  import 'node:fs';
5
- import './logger-D5EzMy30.mjs';
5
+ import './logger-13cBr_ew.mjs';
6
6
  import { d as describeAgentHome, p as probeLoginShellEnv, r as resolveAgentHomes, e as expandHomePath, A as AGENT_HOME_ENV_NAMES } from './loginShellEnv-Dw8M7tkI.mjs';
7
7
  import 'node:fs/promises';
8
- import './configuration-BNGPXg07.mjs';
8
+ import './configuration-D55F0t16.mjs';
9
9
  import 'node:path';
10
- import './package-D0dxZ-W8.mjs';
10
+ import './package-CjlsAaRe.mjs';
11
11
  import 'zod';
12
12
  import './authRelay-DSAvg1uv.mjs';
13
13
  import 'node:crypto';
@@ -1,22 +1,22 @@
1
1
  'use strict';
2
2
 
3
3
  var axios = require('axios');
4
- var logger = require('./logger-C7dRaCkE.cjs');
5
- var lidState = require('./lidState-BmJp2pLt.cjs');
4
+ var logger = require('./logger-LvwVeATU.cjs');
5
+ var lidState = require('./lidState-DxbK0qfu.cjs');
6
6
  var node_events = require('node:events');
7
7
  var socket_ioClient = require('socket.io-client');
8
- var attachmentLimits = require('./attachmentLimits-D6bT2jU1.cjs');
8
+ var attachmentLimits = require('./attachmentLimits-DtFqqiwR.cjs');
9
9
  var authRelay = require('./authRelay-BdYkC1Po.cjs');
10
10
  var limits = require('./limits-C-a7gr04.cjs');
11
- var time = require('./time-0szhiPo4.cjs');
12
- var configuration = require('./configuration-UV4EE5ui.cjs');
11
+ var time = require('./time-Dg5tVB8S.cjs');
12
+ var configuration = require('./configuration-DZPy0T9Z.cjs');
13
13
  var node_crypto = require('node:crypto');
14
- var index = require('./index-BZdhwBKa.cjs');
15
- var registerCommonHandlers = require('./registerCommonHandlers-B7QZxkCL.cjs');
14
+ var index = require('./index-De8L5lFK.cjs');
15
+ var registerCommonHandlers = require('./registerCommonHandlers-60VuTkdg.cjs');
16
16
  var cuid2 = require('@paralleldrive/cuid2');
17
- var sync = require('./sync-BK-IBkuB.cjs');
17
+ var sync = require('./sync-C7sxoUYG.cjs');
18
18
  var backgroundTaskActivity = require('./backgroundTaskActivity-CBvUdj39.cjs');
19
- var controlClient = require('./controlClient-CtsQMw--.cjs');
19
+ var controlClient = require('./controlClient-SX8gSza2.cjs');
20
20
  var contentLogMetadata = require('./contentLogMetadata-ZSFk_NjQ.cjs');
21
21
  var chalk = require('chalk');
22
22
 
@@ -1952,6 +1952,12 @@ class ApiSessionClient extends node_events.EventEmitter {
1952
1952
  }));
1953
1953
  }
1954
1954
  }
1955
+ /**
1956
+ * Returns true when a `turn-end` envelope went out, false when no turn was
1957
+ * open to close (B-631: the web renders a failed turn-end's `error` as its
1958
+ * own line, so a launcher sends the matching session event only when this
1959
+ * says the turn-end did not carry it).
1960
+ */
1955
1961
  closeClaudeSessionTurn(status = "completed", meta) {
1956
1962
  this.emit("turn-ended", status);
1957
1963
  const mapped = closeClaudeTurnWithStatus(this.claudeSessionProtocolState, status, meta);
@@ -1959,6 +1965,7 @@ class ApiSessionClient extends node_events.EventEmitter {
1959
1965
  for (const envelope of mapped.envelopes) {
1960
1966
  this.sendSessionProtocolMessage(envelope);
1961
1967
  }
1968
+ return mapped.envelopes.some((envelope) => envelope.ev.t === "turn-end");
1962
1969
  }
1963
1970
  sendCodexMessage(body) {
1964
1971
  let content = {
@@ -3166,7 +3173,7 @@ class ApiClient {
3166
3173
  return new ApiSessionClient(this.credential.token, session, opts);
3167
3174
  }
3168
3175
  async machineSyncClient(machine) {
3169
- const { ApiMachineClient } = await Promise.resolve().then(function () { return require('./apiMachine-Dct2GDAq.cjs'); });
3176
+ const { ApiMachineClient } = await Promise.resolve().then(function () { return require('./apiMachine-BYYFGgFs.cjs'); });
3170
3177
  return new ApiMachineClient(this.credential.token, machine);
3171
3178
  }
3172
3179
  push() {
@@ -1,20 +1,20 @@
1
1
  import axios from 'axios';
2
- import { l as logger, r as redactLogValue } from './logger-D5EzMy30.mjs';
3
- import { R as RpcHandlerManager, a as answerSocketRequest, c as connectGuarded, s as socketConnectGuard, d as describeSocketAckDrop, b as safeAck, i as isRateQuotaCode, p as pauseForRateQuota, e as shouldReconnect } from './lidState-CL1NdKfQ.mjs';
2
+ import { l as logger, r as redactLogValue } from './logger-13cBr_ew.mjs';
3
+ import { R as RpcHandlerManager, a as answerSocketRequest, c as connectGuarded, s as socketConnectGuard, d as describeSocketAckDrop, b as safeAck, i as isRateQuotaCode, p as pauseForRateQuota, e as shouldReconnect } from './lidState-BqVsw7H1.mjs';
4
4
  import { EventEmitter } from 'node:events';
5
5
  import { io } from 'socket.io-client';
6
- import { A as AsyncLock, a as MAX_CHAT_ATTACHMENT_ENCRYPTED_BYTES, U as UserMessageSchema, F as FileEventMessageSchema } from './attachmentLimits-BLbji11b.mjs';
6
+ import { A as AsyncLock, a as MAX_CHAT_ATTACHMENT_ENCRYPTED_BYTES, U as UserMessageSchema, F as FileEventMessageSchema } from './attachmentLimits-Di1Z93lN.mjs';
7
7
  import { h as decrypt, d as decodeBase64, i as decryptBlob, e as encodeBase64, g as encrypt, l as libsodiumEncryptForPublicKey, j as libsodiumPublicKeyFromSecretKey, k as getRandomBytes } from './authRelay-DSAvg1uv.mjs';
8
8
  import { p as prepareClipboardText, d as prepareClipboardHistoryText } from './limits-DIo7rEBR.mjs';
9
- import { b as backoff, d as delay, e as exponentialBackoffDelay } from './time-CvrpeD3S.mjs';
10
- import { c as configuration } from './configuration-BNGPXg07.mjs';
9
+ import { b as backoff, d as delay, e as exponentialBackoffDelay } from './time-yEL6wHUF.mjs';
10
+ import { c as configuration } from './configuration-D55F0t16.mjs';
11
11
  import { createHmac, randomUUID } from 'node:crypto';
12
- import { c as createEnvelope, s as streamKeyOf, R as ReleaseDrainNoticeSchema, q as RelayAssignmentResponseSchema } from './index-boE-d8CM.mjs';
13
- import { r as registerCommonHandlers } from './registerCommonHandlers-CR5jpiSx.mjs';
12
+ import { c as createEnvelope, s as streamKeyOf, R as ReleaseDrainNoticeSchema, q as RelayAssignmentResponseSchema } from './index-DMy3OCBe.mjs';
13
+ import { r as registerCommonHandlers } from './registerCommonHandlers-D8OMpBbQ.mjs';
14
14
  import { createId } from '@paralleldrive/cuid2';
15
- import { I as InvalidateSync } from './sync-D5YqUVjS.mjs';
16
- import { B as BackgroundTaskReporter } from './backgroundTaskActivity-8PdPxrvy.mjs';
17
- import { k as notifyDaemonTurnEvent, m as notifyDaemonBackgroundTasks } from './controlClient-DqtC0pq1.mjs';
15
+ import { I as InvalidateSync } from './sync-C3p7-KLn.mjs';
16
+ import { B as BackgroundTaskReporter } from './backgroundTaskActivity-BVwJBl02.mjs';
17
+ import { k as notifyDaemonTurnEvent, m as notifyDaemonBackgroundTasks } from './controlClient-C4xB5J6O.mjs';
18
18
  import { c as contentLogMetadata } from './contentLogMetadata-BlWI0egu.mjs';
19
19
  import chalk from 'chalk';
20
20
 
@@ -1950,6 +1950,12 @@ class ApiSessionClient extends EventEmitter {
1950
1950
  }));
1951
1951
  }
1952
1952
  }
1953
+ /**
1954
+ * Returns true when a `turn-end` envelope went out, false when no turn was
1955
+ * open to close (B-631: the web renders a failed turn-end's `error` as its
1956
+ * own line, so a launcher sends the matching session event only when this
1957
+ * says the turn-end did not carry it).
1958
+ */
1953
1959
  closeClaudeSessionTurn(status = "completed", meta) {
1954
1960
  this.emit("turn-ended", status);
1955
1961
  const mapped = closeClaudeTurnWithStatus(this.claudeSessionProtocolState, status, meta);
@@ -1957,6 +1963,7 @@ class ApiSessionClient extends EventEmitter {
1957
1963
  for (const envelope of mapped.envelopes) {
1958
1964
  this.sendSessionProtocolMessage(envelope);
1959
1965
  }
1966
+ return mapped.envelopes.some((envelope) => envelope.ev.t === "turn-end");
1960
1967
  }
1961
1968
  sendCodexMessage(body) {
1962
1969
  let content = {
@@ -3164,7 +3171,7 @@ class ApiClient {
3164
3171
  return new ApiSessionClient(this.credential.token, session, opts);
3165
3172
  }
3166
3173
  async machineSyncClient(machine) {
3167
- const { ApiMachineClient } = await import('./apiMachine-Cx9Zn-78.mjs');
3174
+ const { ApiMachineClient } = await import('./apiMachine-DttO4UFj.mjs');
3168
3175
  return new ApiMachineClient(this.credential.token, machine);
3169
3176
  }
3170
3177
  push() {
@@ -1,43 +1,43 @@
1
1
  'use strict';
2
2
 
3
3
  var socket_ioClient = require('socket.io-client');
4
- var logger = require('./logger-C7dRaCkE.cjs');
5
- var lidState = require('./lidState-BmJp2pLt.cjs');
6
- var mirrorProtocol = require('./mirrorProtocol-BSHVZ8Nf.cjs');
7
- var configuration = require('./configuration-UV4EE5ui.cjs');
4
+ var logger = require('./logger-LvwVeATU.cjs');
5
+ var lidState = require('./lidState-DxbK0qfu.cjs');
6
+ var mirrorProtocol = require('./mirrorProtocol-BfrERW7Z.cjs');
7
+ var configuration = require('./configuration-DZPy0T9Z.cjs');
8
8
  var cliUpdate = require('./cliUpdate-DsKXPFYp.cjs');
9
- var registerCommonHandlers = require('./registerCommonHandlers-B7QZxkCL.cjs');
9
+ var registerCommonHandlers = require('./registerCommonHandlers-60VuTkdg.cjs');
10
10
  var promises = require('node:fs/promises');
11
11
  var path = require('node:path');
12
12
  var os = require('node:os');
13
13
  var node_child_process = require('node:child_process');
14
- var persistence = require('./persistence-DweHi8xa.cjs');
14
+ var persistence = require('./persistence-DXbKOHxl.cjs');
15
15
  var authRelay = require('./authRelay-BdYkC1Po.cjs');
16
16
  var limits = require('./limits-C-a7gr04.cjs');
17
- var time = require('./time-0szhiPo4.cjs');
17
+ var time = require('./time-Dg5tVB8S.cjs');
18
18
  var pty = require('node-pty');
19
19
  var terminals = require('./terminals-B_bfC9c2.cjs');
20
20
  var tmuxSocket = require('./tmuxSocket-D-Xt6Vn-.cjs');
21
- var index = require('./index-B1ABQRrB.cjs');
21
+ var index = require('./index-CrR4JISa.cjs');
22
22
  var node_crypto = require('node:crypto');
23
23
  var node_fs = require('node:fs');
24
24
  var axios = require('axios');
25
25
  var projectPath = require('./projectPath-ChLhdOyt.cjs');
26
26
  var ids = require('./ids-B6ZC0HGt.cjs');
27
27
  var detectCLI = require('./detectCLI-DR9ZaN6B.cjs');
28
- var localHappyAgentAuth = require('./localHappyAgentAuth-9SP7hdiw.cjs');
28
+ var localHappyAgentAuth = require('./localHappyAgentAuth-D5tANdRD.cjs');
29
29
  var path$1 = require('./path-B7zW-WwE.cjs');
30
30
  var oneShotPrompts = require('./oneShotPrompts-CL0dip9C.cjs');
31
- var claudeSessionFork = require('./claudeSessionFork-DQk5-dzR.cjs');
32
- var codexAppServerClient = require('./codexAppServerClient-D-9z-lWP.cjs');
33
- var index$1 = require('./index-BZdhwBKa.cjs');
31
+ var claudeSessionFork = require('./claudeSessionFork-CbDfm8Fz.cjs');
32
+ var codexAppServerClient = require('./codexAppServerClient-R24WZZfg.cjs');
33
+ var index$1 = require('./index-De8L5lFK.cjs');
34
34
  var codexThreadFork = require('./codexThreadFork-DNekT4nQ.cjs');
35
- var rateLimitWindows = require('./rateLimitWindows-Bp4T21RI.cjs');
35
+ var rateLimitWindows = require('./rateLimitWindows-DFnMU2Vt.cjs');
36
36
  require('chalk');
37
37
  require('node:util');
38
38
  require('os');
39
39
  require('child_process');
40
- require('./package-VqWv7EI5.cjs');
40
+ require('./package-Ch9WGDV_.cjs');
41
41
  require('util');
42
42
  require('fs/promises');
43
43
  require('crypto');
@@ -53,6 +53,7 @@ require('node:readline');
53
53
  require('./contentLogMetadata-ZSFk_NjQ.cjs');
54
54
  require('./manager-HrEj442o.cjs');
55
55
  require('@anthropic-ai/sandbox-runtime');
56
+ require('./processTree-CMHWlVse.cjs');
56
57
  require('@paralleldrive/cuid2');
57
58
 
58
59
  function _interopNamespaceDefault(e) {