very-happy-cli 0.2.189 → 0.2.190

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 (199) hide show
  1. package/dist/{AcpBackend-fj16v_cf.mjs → AcpBackend-Dd1h-Rgt.mjs} +3 -3
  2. package/dist/{AcpBackend-DRPJ2g9G.cjs → AcpBackend-dkRv9QHm.cjs} +3 -3
  3. package/dist/{AcpSessionManager-DM-KKg6v.cjs → AcpSessionManager-AqWAqahm.cjs} +1 -1
  4. package/dist/{AcpSessionManager-BZPmUDL5.mjs → AcpSessionManager-QBZ-CIf7.mjs} +2 -2
  5. package/dist/{BasePermissionHandler-CVtH-snr.mjs → BasePermissionHandler-CLp1ge-4.mjs} +1 -1
  6. package/dist/{BasePermissionHandler-DjM16uJz.cjs → BasePermissionHandler-CpSugp7Z.cjs} +1 -1
  7. package/dist/{acpSessionResume-2BTMsB7_.cjs → acpSessionResume-CZao6QEd.cjs} +1 -1
  8. package/dist/{acpSessionResume-Dxl1LRAT.mjs → acpSessionResume-CcpDuIO5.mjs} +1 -1
  9. package/dist/{agentHome-CHctmMzZ.mjs → agentHome-BJGRA2Kx.mjs} +4 -4
  10. package/dist/{agentHome-W17n1gnH.cjs → agentHome-fIUqT-pn.cjs} +4 -4
  11. package/dist/{api-BDuuyys8.cjs → api-CXL6jp-p.cjs} +18 -9
  12. package/dist/{api-B0yN68XH.mjs → api-Dw8gFsQi.mjs} +19 -10
  13. package/dist/{apiMachine-mc9CsKuS.mjs → apiMachine-BBNEtjf7.mjs} +56 -15
  14. package/dist/{apiMachine-iddD-F19.cjs → apiMachine-C6UqHoPF.cjs} +55 -14
  15. package/dist/{attachmentContent-CcIdMfAx.mjs → attachmentContent-CC4yIrSm.mjs} +2 -2
  16. package/dist/{attachmentContent-Cc5b7TPr.cjs → attachmentContent-NmVfKp-B.cjs} +2 -2
  17. package/dist/{auth-DQKSpaEf.cjs → auth-Bb_SL2os.cjs} +5 -5
  18. package/dist/{auth-DNAgkUkB.mjs → auth-Bh6SUoGi.mjs} +8 -8
  19. package/dist/{auth-CyrVvWHF.mjs → auth-Bj0psrD2.mjs} +5 -5
  20. package/dist/{auth-B7tVmyfX.cjs → auth-DKa4MsAi.cjs} +8 -8
  21. package/dist/{auto-CetlumDo.cjs → auto-C9Qohh0P.cjs} +15 -15
  22. package/dist/{auto-BklCipw1.mjs → auto-DK7pbCnV.mjs} +18 -18
  23. package/dist/{bootstrap-DfXwkUQb.mjs → bootstrap-Ct9Nb4sv.mjs} +2 -2
  24. package/dist/{bootstrap-CDY-Vz8q.cjs → bootstrap-DBJB0y-H.cjs} +2 -2
  25. package/dist/{browser-vb0k1zfI.mjs → browser-BGxDRhHy.mjs} +1 -1
  26. package/dist/{browser-D1yzC0Tu.cjs → browser-CLJWcodR.cjs} +1 -1
  27. package/dist/{claudeLocal-2dJIiTIq.cjs → claudeLocal-B6YDYlnY.cjs} +4 -4
  28. package/dist/{claudeLocal-Bid_rC_v.mjs → claudeLocal-Ux31hZyC.mjs} +5 -5
  29. package/dist/{claudeLocalLauncher-5pzpETxd.mjs → claudeLocalLauncher-D06QijMw.mjs} +10 -10
  30. package/dist/{claudeLocalLauncher-Jm5oQX5Z.cjs → claudeLocalLauncher-DFvmF8rC.cjs} +9 -9
  31. package/dist/{claudeSessionFork-DzecSBO4.mjs → claudeSessionFork-D2GI7P59.mjs} +1 -1
  32. package/dist/{claudeSessionFork-DsbcuDEJ.cjs → claudeSessionFork-DTLZ2rek.cjs} +1 -1
  33. package/dist/{client-D0aYWt53.cjs → client-Bffkrs5p.cjs} +2 -2
  34. package/dist/{client-BNmFaRXZ.cjs → client-CARZ_lNS.cjs} +3 -3
  35. package/dist/{client-DIfxYk7B.cjs → client-CMKGrnmT.cjs} +2 -2
  36. package/dist/{client-B161HwAk.mjs → client-CnGNYidN.mjs} +2 -2
  37. package/dist/{client-C9Ecbtko.mjs → client-CtL0Vtww.mjs} +4 -4
  38. package/dist/{client-CvjjadIE.mjs → client-DZkBUoh9.mjs} +2 -2
  39. package/dist/codex/happyMcpStdioBridge.cjs +15 -15
  40. package/dist/codex/happyMcpStdioBridge.mjs +16 -16
  41. package/dist/{codexAppServerClient-BlVmpjR-.mjs → codexAppServerClient-CLc5nhLT.mjs} +13 -6
  42. package/dist/{codexAppServerClient-CO9f4Jr8.cjs → codexAppServerClient-CpT9F6EM.cjs} +13 -6
  43. package/dist/{codexCommand-BfoRP6E9.cjs → codexCommand-39kH99SJ.cjs} +72 -48
  44. package/dist/{codexCommand-CAMR4g5o.mjs → codexCommand-Dliq3EBv.mjs} +69 -45
  45. package/dist/{codexTermination-IrLZQzKC.cjs → codexTermination-ByW7tRjr.cjs} +1 -1
  46. package/dist/{codexTermination-BvGlN02_.mjs → codexTermination-ORIw0gpU.mjs} +1 -1
  47. package/dist/{codexThreadFork-DNekT4nQ.cjs → codexThreadFork-5kwoKjMu.cjs} +11 -17
  48. package/dist/{codexThreadFork-R76RU5H0.mjs → codexThreadFork-DobPd19R.mjs} +11 -17
  49. package/dist/{config-BGFqQGvh.cjs → config-CeIzCsfj.cjs} +3 -3
  50. package/dist/{config-CtMgGPvf.mjs → config-CxSsGO1Z.mjs} +3 -3
  51. package/dist/{configuration-1FabKklB.mjs → configuration-Dechcvd-.mjs} +1 -1
  52. package/dist/{configuration-C0ctLGW2.cjs → configuration-Dt5lKW3P.cjs} +1 -1
  53. package/dist/{connect-DSw-2f52.cjs → connect-NPDzIVC6.cjs} +12 -12
  54. package/dist/{connect-0lSugpjf.mjs → connect-UwQHvCpR.mjs} +13 -13
  55. package/dist/{context-D-hEk5pC.cjs → context-BdZssgF0.cjs} +1 -1
  56. package/dist/{context-BgxbXWKS.mjs → context-C9JbJoNe.mjs} +1 -1
  57. package/dist/{controlClient-F7hAEEy2.cjs → controlClient-BRk65BRO.cjs} +3 -3
  58. package/dist/{controlClient-DwNnNAUx.mjs → controlClient-D7NGfmtq.mjs} +3 -3
  59. package/dist/{createSessionMetadata-DezS33OM.cjs → createSessionMetadata-B_HZCDj_.cjs} +2 -2
  60. package/dist/{createSessionMetadata-CG6Klinp.mjs → createSessionMetadata-DyhFKAby.mjs} +2 -2
  61. package/dist/defaultPermissionMode-BnxJPVHT.mjs +4 -0
  62. package/dist/defaultPermissionMode-CxmTXUQR.cjs +7 -0
  63. package/dist/{deterministicJson-D0LU_XbO.cjs → deterministicJson-BEygolBQ.cjs} +12 -12
  64. package/dist/{deterministicJson-BMwgK21e.mjs → deterministicJson-DNmMVhFu.mjs} +13 -13
  65. package/dist/{doctor-wVNvRarN.cjs → doctor-B9lW1WlG.cjs} +7 -7
  66. package/dist/{doctor-D16hySse.mjs → doctor-BdBi7TFZ.mjs} +7 -7
  67. package/dist/{downloadTarget-C6tqaXGm.mjs → downloadTarget-CGojGjaN.mjs} +6 -6
  68. package/dist/{downloadTarget-aNcCxVRL.cjs → downloadTarget-DS0zT2AU.cjs} +6 -6
  69. package/dist/{ensureDaemonRunning-DZq8bvsp.mjs → ensureDaemonRunning-BOdbryDM.mjs} +5 -5
  70. package/dist/{ensureDaemonRunning-CIghxgDR.cjs → ensureDaemonRunning-Bibp6vhe.cjs} +5 -5
  71. package/dist/exitAfterFlush-AbKNZM0N.mjs +23 -0
  72. package/dist/exitAfterFlush-DIT_sIxR.cjs +25 -0
  73. package/dist/{handleResumeCommand-BNnD7EuD.mjs → handleResumeCommand-CgLzBYne.mjs} +5 -5
  74. package/dist/{handleResumeCommand-CMUTygsm.cjs → handleResumeCommand-DXOuWr4p.cjs} +5 -5
  75. package/dist/{agentAttachments-Dbw8iMCZ.cjs → heldInput-BOtqFO2r.cjs} +27 -0
  76. package/dist/heldInput-C69lA2dH.mjs +44 -0
  77. package/dist/{index-De02DNu5.cjs → index-Bs5FD8JF.cjs} +4 -4
  78. package/dist/{index-BuiG8hmg.mjs → index-CBHfkQNY.mjs} +133 -54
  79. package/dist/{index-4TpmBb2Q.cjs → index-CwRW11hT.cjs} +3 -3
  80. package/dist/{index-Df0bc_et.mjs → index-DUByZsKe.mjs} +4 -4
  81. package/dist/{index-B81qV_F_.cjs → index-DXSIi6j_.cjs} +4 -4
  82. package/dist/{index-BCQr-5Ei.mjs → index-Db0HIC-k.mjs} +4 -4
  83. package/dist/{index-WKyN-bNy.mjs → index-DmqsRnV7.mjs} +1 -1
  84. package/dist/{index-CnzsOD19.cjs → index-f8oDidjV.cjs} +131 -52
  85. package/dist/{index-CKd20r1W.mjs → index-rNTX33in.mjs} +3 -3
  86. package/dist/index.cjs +2 -2
  87. package/dist/index.mjs +2 -2
  88. package/dist/{install-DNbIEJUk.cjs → install-CXIL_FYx.cjs} +3 -3
  89. package/dist/{install-23ehAdTD.mjs → install-DfPrEWGG.mjs} +3 -3
  90. package/dist/lib.cjs +11 -11
  91. package/dist/lib.d.cts +53 -1
  92. package/dist/lib.d.mts +53 -1
  93. package/dist/lib.mjs +12 -12
  94. package/dist/{lidState-q5Its2Hm.mjs → lidState-D0DF20oG.mjs} +1 -1
  95. package/dist/{lidState-B4dHJCeS.cjs → lidState-q_XFYg33.cjs} +1 -1
  96. package/dist/{localHappyAgentAuth-C_G5u5lY.mjs → localHappyAgentAuth-BBhM4Qk1.mjs} +1 -1
  97. package/dist/{localHappyAgentAuth-CG2nPD_H.cjs → localHappyAgentAuth-CKNW-MXw.cjs} +1 -1
  98. package/dist/{logger-BP1SW7Cs.cjs → logger-BBRTTVsQ.cjs} +2 -2
  99. package/dist/{logger-DOKH3Zbh.mjs → logger-CL7pin9b.mjs} +2 -2
  100. package/dist/{machineMetadata-D-5qeIqd.mjs → machineMetadata-DP06qdBk.mjs} +3 -3
  101. package/dist/{machineMetadata-BKX3ov9g.cjs → machineMetadata-DnFNlrVK.cjs} +3 -3
  102. package/dist/{main-ndpVIaSG.cjs → main-DLOXykOR.cjs} +49 -48
  103. package/dist/{main-DODz8DQE.mjs → main-DO7nRvhf.mjs} +49 -48
  104. package/dist/{mcp-BBwbSODp.mjs → mcp-C-4sPTae.mjs} +15 -15
  105. package/dist/{mcp-Bc4U4exu.cjs → mcp-Du0MgR7e.cjs} +14 -14
  106. package/dist/{mirrorProtocol-CiA3hO2y.cjs → mirrorProtocol-GuWMxLkh.cjs} +2 -2
  107. package/dist/{mirrorProtocol-D2vTWteS.mjs → mirrorProtocol-dkq2ZENA.mjs} +3 -3
  108. package/dist/{package-DTcaIhjW.mjs → package-C6uiXULx.mjs} +7 -7
  109. package/dist/{package-CYDdLA6R.cjs → package-DrY090nZ.cjs} +7 -7
  110. package/dist/{panels-C2xZ8rqU.cjs → panels-4DRBKHZP.cjs} +5 -5
  111. package/dist/{panels-DCaLxlSL.mjs → panels-DXYdJA6n.mjs} +5 -5
  112. package/dist/{peerTools-B4315xjX.cjs → peerTools-5ZM4spcZ.cjs} +5 -5
  113. package/dist/{peerTools-BtrUnSwz.mjs → peerTools-dY1aJez4.mjs} +5 -5
  114. package/dist/{persistence-CrzC7yr_.cjs → persistence-Bl5S3TLB.cjs} +6 -2
  115. package/dist/{persistence-0INrP3aB.mjs → persistence-Dogj7JIp.mjs} +6 -3
  116. package/dist/{piRunnerArgs-BtzW_kfh.cjs → piRunnerArgs-C3jZ1M6b.cjs} +1 -1
  117. package/dist/{piRunnerArgs-DRuxMlX1.mjs → piRunnerArgs-D8nN_Iit.mjs} +1 -1
  118. package/dist/{piRuntime-DEbPE_kW.cjs → piRuntime-Bd9-eq6M.cjs} +1 -1
  119. package/dist/{piRuntime-BMAFpIBV.mjs → piRuntime-BoeMsAXK.mjs} +1 -1
  120. package/dist/{piTerminal-MtxDtBE2.cjs → piTerminal-C3j1ca3x.cjs} +16 -16
  121. package/dist/{piTerminal-DQXV8_we.mjs → piTerminal-GEPkIGD4.mjs} +17 -17
  122. package/dist/{pushNotifications-CalIS9sq.cjs → pushNotifications-CfspRcl-.cjs} +20 -2
  123. package/dist/{pushNotifications-Cq1s8YVK.mjs → pushNotifications-dUceOIni.mjs} +21 -3
  124. package/dist/{query-CE2XDhhw.cjs → query-DjsVgG3E.cjs} +1 -1
  125. package/dist/{query-BYiPBHPC.mjs → query-iYH-tm7L.mjs} +1 -1
  126. package/dist/{rateLimitReporter-BKmoOZQi.cjs → rateLimitReporter-DUu2KydZ.cjs} +3 -3
  127. package/dist/{rateLimitReporter-DR5LXuiQ.mjs → rateLimitReporter-jeVi-fym.mjs} +3 -3
  128. package/dist/{rateLimitWindows-Cs56YJCH.cjs → rateLimitWindows-Bx3ROBP5.cjs} +1 -1
  129. package/dist/{rateLimitWindows-5vIuNjko.mjs → rateLimitWindows-CEn0DXaX.mjs} +1 -1
  130. package/dist/{registerCommonHandlers-DZPozYxc.cjs → registerCommonHandlers-Beun-cQv.cjs} +2 -2
  131. package/dist/{registerCommonHandlers-DWkTysjD.mjs → registerCommonHandlers-DWZ7mfdt.mjs} +2 -2
  132. package/dist/{registerKillSessionHandler-DhCjrs44.cjs → registerKillSessionHandler-CA1FFr_F.cjs} +15 -5
  133. package/dist/{registerKillSessionHandler-CSCTRIbI.mjs → registerKillSessionHandler-CzgklwLG.mjs} +16 -6
  134. package/dist/{remoteSessionClient-Vfj_5g2-.mjs → remoteSessionClient-BiC2KDew.mjs} +5 -5
  135. package/dist/{remoteSessionClient-Dq8XTLQP.cjs → remoteSessionClient-DGFI__5Z.cjs} +5 -5
  136. package/dist/{reportProgressTool-B7zmX7NJ.mjs → reportProgressTool-CgPy6n_7.mjs} +3 -3
  137. package/dist/{reportProgressTool-DznxPKES.cjs → reportProgressTool-CvPGov1F.cjs} +2 -2
  138. package/dist/{run-DSfNcR62.mjs → run-B_gFgJVB.mjs} +392 -42
  139. package/dist/{run-Ca8BiNCp.cjs → run-rPqQwDi_.cjs} +389 -39
  140. package/dist/{runClaude-hoepv-0X.mjs → runClaude-CykqeXK7.mjs} +26 -23
  141. package/dist/{runClaude-ClQQcgoO.cjs → runClaude-DM8gm8iu.cjs} +27 -24
  142. package/dist/{runClaudeDeps-D_v8t2SK.mjs → runClaudeDeps-D2phXGut.mjs} +101 -44
  143. package/dist/{runClaudeDeps-ck5_GYlP.cjs → runClaudeDeps-DGAomimZ.cjs} +94 -37
  144. package/dist/{runGemini-Cj0XsMiM.cjs → runGemini-CXTeSOZp.cjs} +32 -32
  145. package/dist/{runGemini-CTr2-cYG.mjs → runGemini-CtWCVkj5.mjs} +33 -33
  146. package/dist/{runOpenClaw-CdDMntiV.mjs → runOpenClaw-BBdjlViJ.mjs} +18 -18
  147. package/dist/{runOpenClaw-BoN1e3lP.cjs → runOpenClaw-CH_9_RyZ.cjs} +17 -17
  148. package/dist/{sandbox-BY2h19gc.cjs → sandbox-Bb5IMun3.cjs} +4 -4
  149. package/dist/{sandbox-DcaWB-Ou.mjs → sandbox-DGmXZ6Zz.mjs} +4 -4
  150. package/dist/selfCheck-BfK945YQ.mjs +86 -0
  151. package/dist/{selfCheck-DFS_GUaQ.cjs → selfCheck-CccwNTTK.cjs} +37 -37
  152. package/dist/{send-UBTHHNvZ.mjs → send-B6rHg8GT.mjs} +8 -8
  153. package/dist/{send-BMsUYU6g.cjs → send-BpiXPkDo.cjs} +8 -8
  154. package/dist/{server-Dt3mCtfQ.mjs → server-BkdAyHhC.mjs} +4 -4
  155. package/dist/{server-YrHMHNz1.cjs → server-DHUzjApC.cjs} +6 -6
  156. package/dist/{sessionLock-DSqiP2lH.cjs → sessionLock-BFBReiKq.cjs} +134 -3
  157. package/dist/{sessionLock-tEFvFXLD.mjs → sessionLock-Ca_bIo50.mjs} +121 -4
  158. package/dist/{sessionOps-CljctDs5.mjs → sessionOps-CA2kpm66.mjs} +13 -5
  159. package/dist/{sessionOps-BzeOKIEF.cjs → sessionOps-DeWVqpe4.cjs} +13 -4
  160. package/dist/{sessionProvider-ORgzmkXy.cjs → sessionProvider-VFbtUmMR.cjs} +5 -5
  161. package/dist/{sessionProvider-BnUFSJXM.mjs → sessionProvider-g18IiK74.mjs} +5 -5
  162. package/dist/{sessionScanner-Cr6PJ3PT.cjs → sessionScanner-CGzsN8V6.cjs} +3 -3
  163. package/dist/{sessionScanner-DZUlkdF6.mjs → sessionScanner-DDDud5re.mjs} +3 -3
  164. package/dist/{sessions-15cag-su.mjs → sessions-B4d50sCI.mjs} +35 -26
  165. package/dist/{sessions-aIo_HjmY.cjs → sessions-CKJPWFgu.cjs} +36 -25
  166. package/dist/{setupOfflineReconnection-B7I8R2Ex.mjs → setupOfflineReconnection-CyPNgyCe.mjs} +2 -2
  167. package/dist/{setupOfflineReconnection-tV0Q1dgR.cjs → setupOfflineReconnection-DPXRo_zf.cjs} +2 -2
  168. package/dist/{spawn-VG-HjJiR.cjs → spawn-CgSJzzWS.cjs} +13 -13
  169. package/dist/{spawn-ByrQgruJ.mjs → spawn-CrYN_OOT.mjs} +15 -15
  170. package/dist/{spawnAgents-Bh1RPShN.mjs → spawnAgents-DWCDYCQ1.mjs} +1 -1
  171. package/dist/{spawnHappyCLI-CxiR2Qoy.cjs → spawnHappyCLI-CTy3p6V_.cjs} +1 -1
  172. package/dist/{spawnHappyCLI-CEsXwz5V.mjs → spawnHappyCLI-DjbkiSH1.mjs} +1 -1
  173. package/dist/{startFileWatcher-C-XCZ5t2.cjs → startFileWatcher-BQs0cJA-.cjs} +1 -1
  174. package/dist/{startFileWatcher-DkEeeAtL.mjs → startFileWatcher-Dedtu1vq.mjs} +1 -1
  175. package/dist/{defaultPermissionMode-e2bIIJG4.mjs → startupSessionCreate-BKFU4v_h.mjs} +25 -6
  176. package/dist/{defaultPermissionMode-5EvgRq38.cjs → startupSessionCreate-Dxy3X4DG.cjs} +25 -7
  177. package/dist/{streamRelay-CqBynIon.mjs → streamRelay-P9e7Sohm.mjs} +1 -1
  178. package/dist/{sync-CoChLEIg.cjs → sync-DtWB7RzA.cjs} +1 -1
  179. package/dist/{sync-BvDMkKAN.mjs → sync-eZkXnsW_.mjs} +1 -1
  180. package/dist/{systemPrompt-Dy_Rf-0Z.cjs → systemPrompt-2XOpZ1j6.cjs} +1 -1
  181. package/dist/{systemPrompt-CgDaPigN.mjs → systemPrompt-Bn6g6aCH.mjs} +2 -2
  182. package/dist/{teams-DPvfLAk8.cjs → teams-ecFay4Gn.cjs} +6 -6
  183. package/dist/{teams-BC4_e5hR.mjs → teams-nadkqrbW.mjs} +7 -7
  184. package/dist/{template-CEK8MEjo.mjs → template-BiTD-jI9.mjs} +1 -1
  185. package/dist/{time-CUK37wiV.mjs → time-CN3TuSVG.mjs} +1 -1
  186. package/dist/{time-XwEZxKGc.cjs → time-gPD_EmA-.cjs} +1 -1
  187. package/dist/{titleGenerator-DWRVdqMU.mjs → titleGenerator-DgzTQdn2.mjs} +1 -1
  188. package/dist/{titleGenerator-DVX0NZUn.cjs → titleGenerator-lT5ldPuN.cjs} +2 -2
  189. package/dist/{todo-CKGrSrRE.cjs → todo-B1VeMk5A.cjs} +5 -5
  190. package/dist/{todo-BNMGXneA.mjs → todo-BIxd7l2Q.mjs} +6 -6
  191. package/dist/{tools-CjMafO_D.cjs → tools-DvqbLsCF.cjs} +1 -1
  192. package/dist/{tools-CCIEAVbB.mjs → tools-zXJpxiG_.mjs} +1 -1
  193. package/dist/{uninstall-CJvJ7gjr.mjs → uninstall-9htK6mb7.mjs} +3 -3
  194. package/dist/{uninstall-BdFbTXnL.cjs → uninstall-CvIOpwB5.cjs} +3 -3
  195. package/package.json +7 -7
  196. package/dist/agentAttachments-M_B5qEF2.mjs +0 -18
  197. package/dist/selfCheck-BQ_H2Sns.mjs +0 -86
  198. package/dist/startupSessionCreate-CYc8mra-.cjs +0 -26
  199. package/dist/startupSessionCreate-npXe2TdN.mjs +0 -24
@@ -1,25 +1,25 @@
1
- import { i as isClaudeSessionId, g as extractCompleteLines, h as decideBackfill, j as parseTerminalHookPayload, k as decideMirrorBinding, M as MIRROR_BACKFILL_LINES_DEFAULT, m as mirrorLineKey, n as mirrorLocalId, o as initializeOwnedWorktree, e as summarizeSpawnSessionForLog, q as startAgentVersionChecks, W as WORKTREE_CAPABILITY_VERSION, t as currentWorktreeService } from './mirrorProtocol-D2vTWteS.mjs';
1
+ import { i as isClaudeSessionId, g as extractCompleteLines, h as decideBackfill, j as parseTerminalHookPayload, k as decideMirrorBinding, M as MIRROR_BACKFILL_LINES_DEFAULT, m as mirrorLineKey, n as mirrorLocalId, o as initializeOwnedWorktree, e as summarizeSpawnSessionForLog, q as startAgentVersionChecks, W as WORKTREE_CAPABILITY_VERSION, t as currentWorktreeService } from './mirrorProtocol-dkq2ZENA.mjs';
2
2
  import { F as FS_MKDIR_CAPABILITY_VERSION } from './fsMkdir-DumgLTzR.mjs';
3
- import { P as PI_ADAPTER_INSTALL_HINT, s as sanitizeSpawnModel } from './piRunnerArgs-DRuxMlX1.mjs';
3
+ import { P as PI_ADAPTER_INSTALL_HINT, s as sanitizeSpawnModel } from './piRunnerArgs-D8nN_Iit.mjs';
4
4
  import fs from 'fs/promises';
5
5
  import os from 'os';
6
6
  import * as tmp from 'tmp';
7
7
  import axios from 'axios';
8
8
  import { readFileSync, openSync, fsyncSync, closeSync, renameSync, existsSync, readdirSync, statSync, unlinkSync, realpathSync, promises, constants as constants$1, writeFileSync, mkdirSync, accessSync, readSync, rmdirSync } from 'node:fs';
9
9
  import { join, isAbsolute, resolve, dirname, sep, basename, relative } from 'node:path';
10
- import { f as ensurePrivateDirectorySync, w as writePrivateFileSync, c as configuration } from './configuration-1FabKklB.mjs';
11
- import { T as TurnActivityTracker, A as ApiClient } from './api-B0yN68XH.mjs';
12
- import { S as SPAWN_AGENTS, i as isSpawnAgent, s as sanitizeSpawnPermissionMode, r as resolveSpawnPermissionMode, a as resolveFirstMessageMeta, j as joinProject } from './spawnAgents-Bh1RPShN.mjs';
13
- import { l as logger } from './logger-DOKH3Zbh.mjs';
14
- import { p as pruneStaleCompileCaches } from './index-CKd20r1W.mjs';
15
- import { a as authAndSetupMachineIfNeeded } from './auth-CyrVvWHF.mjs';
10
+ import { f as ensurePrivateDirectorySync, w as writePrivateFileSync, c as configuration } from './configuration-Dechcvd-.mjs';
11
+ import { T as TurnActivityTracker, A as ApiClient } from './api-Dw8gFsQi.mjs';
12
+ import { S as SPAWN_AGENTS, i as isSpawnAgent, s as sanitizeSpawnPermissionMode, r as resolveSpawnPermissionMode, a as resolveFirstMessageMeta, j as joinProject } from './spawnAgents-DWCDYCQ1.mjs';
13
+ import { l as logger } from './logger-CL7pin9b.mjs';
14
+ import { p as pruneStaleCompileCaches } from './index-rNTX33in.mjs';
15
+ import { a as authAndSetupMachineIfNeeded } from './auth-Bj0psrD2.mjs';
16
16
  import { spawn, execSync } from 'child_process';
17
- import { p as packageJson } from './package-DTcaIhjW.mjs';
18
- import { a as globalPrefixForPackage, N as NPM_SAFE_ARG, g as getEnvironmentInfo } from './doctor-D16hySse.mjs';
19
- import { s as spawnHappyCLI } from './spawnHappyCLI-CEsXwz5V.mjs';
20
- import { c as readPersistedSessions, r as readSettings, l as latchKeepAwake, q as reportSignature, s as decideDaemonHibernation, t as nextCheckDelay, v as persistSession, d as readDaemonState, x as acquireDaemonLock, a as resolveCheckMs, y as resolveIdleMs, z as deletePersistedSessions, A as writeDaemonState, B as writeSettings, C as settingIdleMs, u as updateSettings, D as rewriteCredentialsForRelay, g as readCredentials, E as releaseDaemonLock } from './persistence-0INrP3aB.mjs';
21
- import { i as isDaemonRunningCurrentlyInstalledHappyVersion, s as stopDaemon, u as cleanupDaemonState } from './controlClient-DwNnNAUx.mjs';
22
- import { e as sendUserMessage, f as readSessionMetadata, r as readSessionTranscript, l as listAccountSessions, a as listSessions, M as MAX_READ_LIMIT, s as sessionWebUrl, g as waitForSessionKey, d as archiveSession, j as analyzeLatestTurn, k as readSessionLog, m as TURN_WINDOW, n as userPromptText } from './sessionOps-CljctDs5.mjs';
17
+ import { p as packageJson } from './package-C6uiXULx.mjs';
18
+ import { a as globalPrefixForPackage, N as NPM_SAFE_ARG, g as getEnvironmentInfo } from './doctor-BdBi7TFZ.mjs';
19
+ import { s as spawnHappyCLI } from './spawnHappyCLI-DjbkiSH1.mjs';
20
+ import { c as readPersistedSessions, r as readSettings, l as latchKeepAwake, s as reportSignature, t as decideDaemonHibernation, v as nextCheckDelay, x as persistSession, d as readDaemonState, y as acquireDaemonLock, a as resolveCheckMs, z as resolveIdleMs, A as deletePersistedSessions, B as writeDaemonState, C as writeSettings, D as settingIdleMs, u as updateSettings, E as rewriteCredentialsForRelay, g as readCredentials, F as releaseDaemonLock } from './persistence-Dogj7JIp.mjs';
21
+ import { i as isDaemonRunningCurrentlyInstalledHappyVersion, s as stopDaemon, u as cleanupDaemonState } from './controlClient-D7NGfmtq.mjs';
22
+ import { e as sendUserMessage, f as readSessionMetadata, r as readSessionTranscript, l as listAccountSessions, a as listSessions, M as MAX_READ_LIMIT, s as sessionWebUrl, j as lineageOf, g as waitForSessionKey, d as archiveSession, k as analyzeLatestTurn, m as readSessionLog, n as TURN_WINDOW, p as userPromptText } from './sessionOps-CA2kpm66.mjs';
23
23
  import fastify from 'fastify';
24
24
  import { z } from 'zod';
25
25
  import { validatorCompiler, serializerCompiler } from 'fastify-type-provider-zod';
@@ -27,63 +27,63 @@ import { d as decodeBase64, s as sameRelay, e as encodeBase64, h as decrypt } fr
27
27
  import { randomBytes, createHash, timingSafeEqual, randomUUID } from 'node:crypto';
28
28
  import { c as checkPreviewPath } from './previewPath-CXN4Vag0.mjs';
29
29
  import { a as BACKGROUND_TASKS_MAX, d as BACKGROUND_TASK_DESCRIPTION_MAX, e as BackgroundTaskTracker } from './backgroundTaskActivity-8PdPxrvy.mjs';
30
- import { b as sanitizeRateLimitReport } from './rateLimitWindows-5vIuNjko.mjs';
31
- import { f as formatEditConflictNotice, b as SESSION_PEER_SENT_FROM, s as sendPeerMessage, l as listPeerSessions, C as CLI_PEER_SENDER_ID } from './peerTools-BtrUnSwz.mjs';
30
+ import { b as sanitizeRateLimitReport } from './rateLimitWindows-CEn0DXaX.mjs';
31
+ import { f as formatEditConflictNotice, b as SESSION_PEER_SENT_FROM, s as sendPeerMessage, l as listPeerSessions, C as CLI_PEER_SENDER_ID } from './peerTools-dY1aJez4.mjs';
32
32
  import os$1, { hostname, homedir, tmpdir } from 'node:os';
33
- import { c as RemoteCallBudget, e as REMOTE_WRITE_CALLS_PER_MINUTE, d as deliverToSession, g as guardRemoteSessionOpsRequest, h as remoteError, i as REMOTE_OP_DEADLINE_MS, j as formatRemoteAuditLine, k as REMOTE_SEND_COMMIT_DEADLINE_MS, m as REMOTE_RESUME_WAIT_MS, n as capRemoteTranscript, o as capRemoteText, p as REMOTE_ANSWER_MAX_BYTES, q as REMOTE_TITLE_MAX_BYTES } from './remoteSessionClient-Vfj_5g2-.mjs';
34
- import { assistantHome, bootstrapAssistantHome } from './bootstrap-DfXwkUQb.mjs';
35
- import { refreshAgentHomes, locateClaudeConversation, agentHomeSpawnEnv } from './index-Df0bc_et.mjs';
33
+ import { c as RemoteCallBudget, e as REMOTE_WRITE_CALLS_PER_MINUTE, d as deliverToSession, g as guardRemoteSessionOpsRequest, h as remoteError, i as REMOTE_OP_DEADLINE_MS, j as formatRemoteAuditLine, k as REMOTE_SEND_COMMIT_DEADLINE_MS, m as REMOTE_RESUME_WAIT_MS, n as capRemoteTranscript, o as capRemoteText, p as REMOTE_ANSWER_MAX_BYTES, q as REMOTE_TITLE_MAX_BYTES } from './remoteSessionClient-BiC2KDew.mjs';
34
+ import { assistantHome, bootstrapAssistantHome } from './bootstrap-Ct9Nb4sv.mjs';
35
+ import { refreshAgentHomes, locateClaudeConversation, agentHomeSpawnEnv } from './index-DUByZsKe.mjs';
36
36
  import require$$0, { existsSync as existsSync$1, statSync as statSync$1, mkdtempSync, rmSync } from 'fs';
37
37
  import require$$1, { join as join$1 } from 'path';
38
38
  import { spawn as spawn$1, execFile, spawnSync } from 'node:child_process';
39
39
  import { p as projectPath } from './projectPath-BTBIMB57.mjs';
40
40
  import { d as daemonEndpointsMatch, r as resolveClaudeCredentialReadiness } from './doctorReadiness-C208SMN9.mjs';
41
- import { o as ownerRetryPending, c as consumeOwnerRetry, s as spawnGate, a as afterStartupFailure, b as startupFailureMessage, T as TEAM_SPAWN_MAX_ATTEMPTS, d as TEAM_CLEANUP_RETRY_MS, g as getInitialMachineMetadata, e as getStartupCliAvailability, f as TEAM_RETRY_CAPABILITY_VERSION, w as withRunningCliFacts } from './machineMetadata-D-5qeIqd.mjs';
41
+ import { o as ownerRetryPending, c as consumeOwnerRetry, s as spawnGate, a as afterStartupFailure, b as startupFailureMessage, T as TEAM_SPAWN_MAX_ATTEMPTS, d as TEAM_CLEANUP_RETRY_MS, g as getInitialMachineMetadata, e as getStartupCliAvailability, f as TEAM_RETRY_CAPABILITY_VERSION, w as withRunningCliFacts } from './machineMetadata-DP06qdBk.mjs';
42
42
  import { M as ModelConfigError, B as BackupStore, r as readConfigFile, s as sha256, a as atomicWriteFile } from './fileStore-5qpetZS0.mjs';
43
43
  import { c as collectSecretValues, a as parseJsonObject, b as childObject, s as setOrDelete, d as changedPaths, e as stringifyLike, f as fail, n as normalizeModelList, g as normalizeModelId, h as normalizeSecret, i as normalizeBaseUrl, u as uniq, j as baseUrlWarnings, m as maskSecret, k as getPath$1, l as normalizeProviderId, o as piAdapter, r as redactText } from './pi-CqyoZMjI.mjs';
44
44
  import require$$3 from 'crypto';
45
45
  import { c as commandOnPath } from './detectCLI-CSGMlV51.mjs';
46
- import { buildResumeLaunch } from './handleResumeCommand-BNnD7EuD.mjs';
46
+ import { buildResumeLaunch } from './handleResumeCommand-CgLzBYne.mjs';
47
47
  import { n as normalizeWebPanels } from './webPanels-B2_C2-3g.mjs';
48
- import { M as ServerMigrateNoticeSchema, N as isHarnessInstallId, e as AUTOMATION_SUMMARY_MAX_CHARS, Q as AUTOMATION_PRECHECK_OUTPUT_MAX_CHARS, T as AUTOMATION_PRECHECK_DEFAULT_TIMEOUT_MS, b as AUTOMATION_PRECHECK_MAX_TIMEOUT_MS, U as AUTOMATION_CLAIM_MAX_RUNS, V as AUTOMATION_DAEMON_CAPABILITY_PRECHECK, W as AUTOMATION_DEFAULT_LEASE_MS, i as isAutomationRunTerminal, X as HARNESS_INSTALL_CAPABILITY_VERSION } from './index-WKyN-bNy.mjs';
48
+ import { M as ServerMigrateNoticeSchema, N as isHarnessInstallId, e as AUTOMATION_SUMMARY_MAX_CHARS, Q as AUTOMATION_PRECHECK_OUTPUT_MAX_CHARS, T as AUTOMATION_PRECHECK_DEFAULT_TIMEOUT_MS, b as AUTOMATION_PRECHECK_MAX_TIMEOUT_MS, U as AUTOMATION_CLAIM_MAX_RUNS, V as AUTOMATION_DAEMON_CAPABILITY_PRECHECK, W as AUTOMATION_DEFAULT_LEASE_MS, i as isAutomationRunTerminal, X as HARNESS_INSTALL_CAPABILITY_VERSION } from './index-DmqsRnV7.mjs';
49
49
  import { access, symlink, readFile, rm, unlink, readlink, lstat, constants, rename, mkdir, copyFile, readdir, stat, open } from 'node:fs/promises';
50
50
  import { p as parseExactVersion, c as compareExactVersions, f as fetchCliUpdateState, r as resolveCliUpdateCheckInterval, D as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS } from './cliUpdate-Y34VGe9Y.mjs';
51
- import { P as ProjectsUnsupportedError, c as createProjectsClient } from './client-B161HwAk.mjs';
52
- import { c as createAutomationsClient, i as isAutomationsUnavailable, d as AutomationsRequestError } from './client-CvjjadIE.mjs';
51
+ import { P as ProjectsUnsupportedError, c as createProjectsClient } from './client-CnGNYidN.mjs';
52
+ import { d as wrapperReportsIdle, f as decideAutoRestart, s as statusFromVerdict, g as autoRestartNextCheck, h as wrapperStaleness, r as recordAttempt, i as AUTO_RESTART_MAX_ATTEMPTS, j as AUTO_RESTART_MIN_GAP_MS, p as processIdentityFields, k as readSessionLock, l as terminateProcess, n as terminateProcessTree, o as AUTO_RESTARTED_ENV, q as encodeAutoRestarted, u as resolveQuietMs, v as AUTO_RESTART_RECHECK_CAP_MS } from './sessionLock-Ca_bIo50.mjs';
53
+ import { c as createAutomationsClient, i as isAutomationsUnavailable, d as AutomationsRequestError } from './client-DZkBUoh9.mjs';
53
54
  import { w as withKeychainOffPath, a as keychainIdentityFor, i as interpretSecurityRead, s as securityReadArgs, b as securityDeleteArgs, c as keychainOffShimDir, d as interpretCredentialsFile, C as CREDENTIALS_REJECTED_DETAIL, e as buildClaudeAuthState, f as claudeAuthStateChanged, r as resolveSdkClaudeBinary, g as classifyAuthStatus, h as diagnoseStores, p as parseLaunchctlPid, H as HAPPY_DAEMON_LAUNCHD_LABEL, j as classifyLineage, l as probeLaunchdJob, m as detectDaemonSupervisor, n as daemonLineage, o as probeSystemdKillMode, q as wrappersSurviveHandover, t as handoverWaitsForSessions } from './daemonSupervisor-BxohggqN.mjs';
54
55
  import { g as getProjectPath } from './path-D2wdaNSk.mjs';
55
56
  import { b as extractClaudeEditPaths } from './editPaths-BVfS_FFL.mjs';
56
- import { s as startFileWatcher } from './startFileWatcher-DkEeeAtL.mjs';
57
- import { I as InvalidateSync } from './sync-BvDMkKAN.mjs';
57
+ import { s as startFileWatcher } from './startFileWatcher-Dedtu1vq.mjs';
58
+ import { I as InvalidateSync } from './sync-eZkXnsW_.mjs';
58
59
  import { R as RawJSONLinesSchema } from './types-CkqAACXx.mjs';
59
60
  import { t as tmuxArgs, a as scrubTmuxClientEnv, s as shellescape } from './tmuxSocket-B8Yx20sT.mjs';
60
- import { p as processIdentityFields, r as readSessionLock, t as terminateProcess, d as terminateProcessTree } from './sessionLock-tEFvFXLD.mjs';
61
61
  import { findAllHappyProcesses } from './doctor-BPkYWSuq.mjs';
62
62
  import { T as TEAM_SKILL, a as TEAM_LEAD_PLAYBOOK, b as TEAM_MEMBER_RULES } from './resources-CLP_MpK4.mjs';
63
63
  import { promisify } from 'node:util';
64
- import { b as clipText, r as renderAction, c as clipAutomationReport, e as renderTemplate } from './template-CEK8MEjo.mjs';
64
+ import { b as clipText, r as renderAction, c as clipAutomationReport, e as renderTemplate } from './template-BiTD-jI9.mjs';
65
65
  import { d as describeAgentHome } from './loginShellEnv-Dw8M7tkI.mjs';
66
- import './acpSessionResume-Dxl1LRAT.mjs';
67
- import './lidState-q5Its2Hm.mjs';
66
+ import './acpSessionResume-CcpDuIO5.mjs';
67
+ import './lidState-D0DF20oG.mjs';
68
68
  import 'node:events';
69
69
  import 'socket.io-client';
70
- import './pushNotifications-Cq1s8YVK.mjs';
70
+ import './pushNotifications-dUceOIni.mjs';
71
71
  import './contentLogMetadata-BlWI0egu.mjs';
72
72
  import './limits-DIo7rEBR.mjs';
73
- import './time-CUK37wiV.mjs';
74
- import './registerCommonHandlers-DWkTysjD.mjs';
73
+ import './time-CN3TuSVG.mjs';
74
+ import './registerCommonHandlers-DWZ7mfdt.mjs';
75
75
  import 'util';
76
76
  import 'cross-spawn';
77
77
  import '@paralleldrive/cuid2';
78
78
  import 'chalk';
79
79
  import 'node:module';
80
80
  import 'tweetnacl';
81
- import './browser-vb0k1zfI.mjs';
81
+ import './browser-BGxDRhHy.mjs';
82
82
  import 'open';
83
83
  import './specialCommands-MXUN0wfI.mjs';
84
84
  import './ids-DU6sLx4C.mjs';
85
85
  import 'url';
86
- import './localHappyAgentAuth-C_G5u5lY.mjs';
86
+ import './localHappyAgentAuth-BBhM4Qk1.mjs';
87
87
  import './processTreeSnapshot-CuLJDNC-.mjs';
88
88
  import 'ps-list';
89
89
 
@@ -548,7 +548,8 @@ const WrapperIdleSnapshotSchema = z.object({
548
548
  backgroundTasks: z.number().int().nonnegative(),
549
549
  scheduledWakeups: z.number().int().nonnegative().optional(),
550
550
  lastActivityAt: z.number(),
551
- exiting: z.boolean().optional()
551
+ exiting: z.boolean().optional(),
552
+ agentVersion: z.string().max(64).optional()
552
553
  }).passthrough();
553
554
  const HibernateCheckBodySchema = z.object({
554
555
  sessionId: z.string().min(1).max(200),
@@ -1516,6 +1517,7 @@ function summaryFromPersisted(id, persisted) {
1516
1517
  ...meta?.flavor ? { flavor: meta.flavor } : {},
1517
1518
  ...meta?.tags?.length ? { tags: [...meta.tags] } : {},
1518
1519
  ...meta?.variant ? { variant: meta.variant } : {},
1520
+ ...lineageOf(meta),
1519
1521
  ...persisted?.savedAt !== void 0 ? { savedAt: persisted.savedAt } : {},
1520
1522
  url: sessionWebUrl(id)
1521
1523
  };
@@ -5274,6 +5276,253 @@ async function waitForSessionLive(sessionId, live, timeoutMs = AUTOMATION_WAKE_T
5274
5276
  return true;
5275
5277
  }
5276
5278
 
5279
+ function createAutoRestart(deps) {
5280
+ const now = () => (deps.now ?? Date.now)();
5281
+ const random = deps.random ?? Math.random;
5282
+ const statuses = /* @__PURE__ */ new Map();
5283
+ const attempts = /* @__PURE__ */ new Map();
5284
+ const agentVersions = /* @__PURE__ */ new Map();
5285
+ const behindSince = /* @__PURE__ */ new Map();
5286
+ const offline = /* @__PURE__ */ new Map();
5287
+ const schedule = deps.schedule ?? ((fn, ms) => {
5288
+ setTimeout(fn, ms).unref?.();
5289
+ });
5290
+ let inFlight = 0;
5291
+ let lastStartedAt = null;
5292
+ let publishedSignature = "";
5293
+ function publish() {
5294
+ const snapshot = Object.fromEntries([...statuses.entries()].sort(([a], [b]) => a.localeCompare(b)));
5295
+ const signature = JSON.stringify(snapshot);
5296
+ if (signature === publishedSignature) return;
5297
+ publishedSignature = signature;
5298
+ deps.publish(snapshot);
5299
+ }
5300
+ function setStatus(sessionId, status) {
5301
+ if (!status) {
5302
+ statuses.delete(sessionId);
5303
+ return;
5304
+ }
5305
+ const clock = behindSince.get(sessionId);
5306
+ const since = clock && clock.target === status.target ? clock.since : status.since;
5307
+ behindSince.set(sessionId, { target: status.target, since });
5308
+ statuses.set(sessionId, { ...status, since });
5309
+ }
5310
+ function clearSession(sessionId) {
5311
+ statuses.delete(sessionId);
5312
+ behindSince.delete(sessionId);
5313
+ offline.delete(sessionId);
5314
+ }
5315
+ function isLive(sessionId) {
5316
+ return deps.liveSessions().some((session) => session.sessionId === sessionId);
5317
+ }
5318
+ function stalenessFor(tracked, agentVersion) {
5319
+ return wrapperStaleness({
5320
+ wrapperVersion: tracked.wrapperVersion,
5321
+ daemonVersion: deps.daemonVersion,
5322
+ agentVersion,
5323
+ installedAgentVersion: tracked.flavor ? deps.installedAgentVersion(tracked.flavor) : null
5324
+ });
5325
+ }
5326
+ async function run(sessionId, staleness) {
5327
+ const since = statuses.get(sessionId)?.since ?? now();
5328
+ setStatus(sessionId, { state: "restarting", since, target: staleness.target });
5329
+ publish();
5330
+ deps.log?.(`[auto-restart] restarting ${sessionId}: ${staleness.kind} ${staleness.from} \u2192 ${staleness.target}`);
5331
+ try {
5332
+ if (deps.turnActive(sessionId) || deps.backgroundTasks(sessionId) > 0 || deps.automationRunning(sessionId)) {
5333
+ deps.log?.(`[auto-restart] ${sessionId} became busy before the stop; waiting`);
5334
+ setStatus(sessionId, { state: "waiting", reason: "turn-active", since, target: staleness.target });
5335
+ return;
5336
+ }
5337
+ let result;
5338
+ try {
5339
+ result = await deps.restart(sessionId, staleness);
5340
+ } catch (error) {
5341
+ result = { ok: false, error: error instanceof Error ? error.message : String(error) };
5342
+ }
5343
+ const record = recordAttempt(attempts.get(sessionId) ?? null, staleness.target, result.ok, now(), result.ok ? void 0 : result.error);
5344
+ if (record) attempts.set(sessionId, record);
5345
+ else attempts.delete(sessionId);
5346
+ if (result.ok) {
5347
+ deps.log?.(`[auto-restart] ${sessionId} restarted on ${staleness.target}`);
5348
+ clearSession(sessionId);
5349
+ agentVersions.delete(sessionId);
5350
+ } else {
5351
+ deps.log?.(`[auto-restart] ${sessionId} restart failed (attempt ${record?.attempts}): ${result.error}`);
5352
+ const gaveUp = (record?.attempts ?? 0) >= AUTO_RESTART_MAX_ATTEMPTS;
5353
+ if (!isLive(sessionId)) {
5354
+ offline.set(sessionId, staleness);
5355
+ const retryAt = gaveUp || !record ? void 0 : record.notBefore;
5356
+ setStatus(sessionId, { state: "failed", reason: result.error, since, target: staleness.target, offline: true, ...retryAt ? { retryAt } : {} });
5357
+ if (retryAt) schedule(() => {
5358
+ void retryOffline(sessionId);
5359
+ }, Math.max(0, retryAt - now()));
5360
+ } else {
5361
+ setStatus(sessionId, gaveUp ? { state: "failed", reason: result.error, since, target: staleness.target } : { state: "waiting", reason: "backoff", since, target: staleness.target });
5362
+ }
5363
+ }
5364
+ } finally {
5365
+ inFlight -= 1;
5366
+ publish();
5367
+ }
5368
+ }
5369
+ async function retryOffline(sessionId) {
5370
+ const staleness = offline.get(sessionId);
5371
+ if (!staleness || statuses.get(sessionId)?.state !== "failed" || statuses.get(sessionId)?.retryAt === void 0) return;
5372
+ const status = statuses.get(sessionId);
5373
+ const handOver = (why) => {
5374
+ deps.log?.(`[auto-restart] ${sessionId} offline retry skipped: ${why}`);
5375
+ setStatus(sessionId, { state: "failed", reason: status.reason, since: status.since, target: status.target, offline: true });
5376
+ publish();
5377
+ };
5378
+ if (!deps.enabled()) return handOver("switch off");
5379
+ if (isLive(sessionId)) {
5380
+ offline.delete(sessionId);
5381
+ return;
5382
+ }
5383
+ const server = deps.serverSession ? await deps.serverSession(sessionId).catch(() => null) : null;
5384
+ if (!server) return handOver("server state unknown");
5385
+ if (server.archived || server.active) return handOver(server.archived ? "archived" : "active elsewhere");
5386
+ if (isLive(sessionId) || offline.get(sessionId) !== staleness) return;
5387
+ const t = now();
5388
+ if (inFlight > 0 || lastStartedAt !== null && t - lastStartedAt < AUTO_RESTART_MIN_GAP_MS) {
5389
+ schedule(() => {
5390
+ void retryOffline(sessionId);
5391
+ }, AUTO_RESTART_MIN_GAP_MS + Math.round(random() * AUTO_RESTART_MIN_GAP_MS));
5392
+ return;
5393
+ }
5394
+ inFlight += 1;
5395
+ lastStartedAt = t;
5396
+ setStatus(sessionId, { state: "restarting", since: status.since, target: staleness.target });
5397
+ await run(sessionId, staleness);
5398
+ }
5399
+ async function onCheckIn(request) {
5400
+ let t = now();
5401
+ const tracked = deps.tracked(request.sessionId, request.pid);
5402
+ if (request.report.agentVersion) agentVersions.set(request.sessionId, request.report.agentVersion);
5403
+ const staleness = tracked ? stalenessFor(tracked, request.report.agentVersion) : null;
5404
+ if (!staleness) {
5405
+ const had = statuses.has(request.sessionId);
5406
+ clearSession(request.sessionId);
5407
+ if (had) publish();
5408
+ return { nextCheckMs: null, restarting: false };
5409
+ }
5410
+ offline.delete(request.sessionId);
5411
+ const previous = statuses.get(request.sessionId);
5412
+ if (previous?.state === "restarting") return { nextCheckMs: null, restarting: false };
5413
+ const attempt = attempts.get(request.sessionId) ?? null;
5414
+ let input = {
5415
+ enabled: deps.enabled(),
5416
+ now: t,
5417
+ ...deps.quietMs !== void 0 ? { quietMs: deps.quietMs } : {},
5418
+ staleness,
5419
+ trackedLive: !!tracked?.live,
5420
+ report: request.report,
5421
+ turnActive: deps.turnActive(request.sessionId),
5422
+ backgroundTasks: deps.backgroundTasks(request.sessionId),
5423
+ automationRunning: deps.automationRunning(request.sessionId),
5424
+ resumable: false,
5425
+ attempt,
5426
+ inFlight,
5427
+ lastStartedAt
5428
+ };
5429
+ let verdict = decideAutoRestart({ ...input, resumable: true });
5430
+ if (verdict.ok) {
5431
+ const resumable = await deps.resumable(request.sessionId).catch(() => false);
5432
+ t = now();
5433
+ input = {
5434
+ ...input,
5435
+ now: t,
5436
+ trackedLive: !!deps.tracked(request.sessionId, request.pid)?.live,
5437
+ turnActive: deps.turnActive(request.sessionId),
5438
+ backgroundTasks: deps.backgroundTasks(request.sessionId),
5439
+ automationRunning: deps.automationRunning(request.sessionId),
5440
+ resumable,
5441
+ attempt: attempts.get(request.sessionId) ?? null,
5442
+ inFlight,
5443
+ lastStartedAt
5444
+ };
5445
+ verdict = statuses.get(request.sessionId)?.state === "restarting" ? { ok: false, reason: "machine-busy" } : decideAutoRestart(input);
5446
+ }
5447
+ if (verdict.ok) {
5448
+ inFlight += 1;
5449
+ lastStartedAt = t;
5450
+ setStatus(request.sessionId, { state: "restarting", since: previous?.since ?? t, target: staleness.target });
5451
+ setImmediate(() => {
5452
+ void run(request.sessionId, staleness);
5453
+ });
5454
+ return { nextCheckMs: null, restarting: true };
5455
+ }
5456
+ if (input.enabled) setStatus(request.sessionId, statusFromVerdict(verdict, previous, staleness, t, attempt));
5457
+ else {
5458
+ statuses.delete(request.sessionId);
5459
+ if (behindSince.get(request.sessionId)?.target !== staleness.target) behindSince.set(request.sessionId, { target: staleness.target, since: t });
5460
+ }
5461
+ publish();
5462
+ return { nextCheckMs: autoRestartNextCheck(verdict, input, random()), restarting: false };
5463
+ }
5464
+ function sweep() {
5465
+ const t = now();
5466
+ const enabled = deps.enabled();
5467
+ const seen = /* @__PURE__ */ new Set();
5468
+ for (const session of deps.liveSessions()) {
5469
+ seen.add(session.sessionId);
5470
+ const staleness = stalenessFor(session, agentVersions.get(session.sessionId));
5471
+ if (!staleness) {
5472
+ clearSession(session.sessionId);
5473
+ continue;
5474
+ }
5475
+ if (statuses.get(session.sessionId)?.state === "restarting") continue;
5476
+ if (offline.delete(session.sessionId)) statuses.delete(session.sessionId);
5477
+ if (!enabled) {
5478
+ statuses.delete(session.sessionId);
5479
+ if (behindSince.get(session.sessionId)?.target !== staleness.target) behindSince.set(session.sessionId, { target: staleness.target, since: t });
5480
+ continue;
5481
+ }
5482
+ const previous = statuses.get(session.sessionId);
5483
+ if (session.startedBy === "terminal") {
5484
+ if (previous?.state !== "manual" || previous.reason !== "local-terminal" || previous.target !== staleness.target) {
5485
+ setStatus(session.sessionId, { state: "manual", reason: "local-terminal", since: t, target: staleness.target });
5486
+ }
5487
+ continue;
5488
+ }
5489
+ if (previous && previous.target === staleness.target) continue;
5490
+ const reports = wrapperReportsIdle({
5491
+ flavor: session.flavor,
5492
+ capabilities: session.capabilities,
5493
+ spawnedBy: session.spawnedBy,
5494
+ tags: session.tags,
5495
+ variant: session.variant
5496
+ });
5497
+ setStatus(session.sessionId, reports ? { state: "waiting", reason: "awaiting-check-in", since: t, target: staleness.target } : { state: "manual", reason: "no-report", since: t, target: staleness.target });
5498
+ }
5499
+ for (const id of /* @__PURE__ */ new Set([...statuses.keys(), ...behindSince.keys()])) {
5500
+ if (seen.has(id) || statuses.get(id)?.state === "restarting") continue;
5501
+ if (offline.has(id)) continue;
5502
+ clearSession(id);
5503
+ }
5504
+ publish();
5505
+ }
5506
+ return {
5507
+ onCheckIn,
5508
+ sweep,
5509
+ forget(sessionId) {
5510
+ agentVersions.delete(sessionId);
5511
+ const state = statuses.get(sessionId)?.state;
5512
+ if (state === "restarting" || offline.has(sessionId)) return;
5513
+ behindSince.delete(sessionId);
5514
+ if (statuses.delete(sessionId)) publish();
5515
+ },
5516
+ statuses() {
5517
+ return Object.fromEntries(statuses);
5518
+ },
5519
+ /** For tests / diagnostics. */
5520
+ inFlight() {
5521
+ return inFlight;
5522
+ }
5523
+ };
5524
+ }
5525
+
5277
5526
  const CLAUDE_AUTH_PROBE_INTERVAL_MS = 10 * 60 * 1e3;
5278
5527
  const CLAUDE_AUTH_REFRESH_INTERVAL_MS = 30 * 60 * 1e3;
5279
5528
  const PROBE_TIMEOUT_MS = 8e3;
@@ -7408,6 +7657,7 @@ async function startDaemon() {
7408
7657
  let lastHandoverHold = null;
7409
7658
  let claudeCredentialStoreSetting = (await readSettings()).claudeCredentialStore === "file" ? "file" : "auto";
7410
7659
  let agentHibernationSetting = (await readSettings()).agentHibernationIdleMs;
7660
+ let autoRestartSetting = (await readSettings()).autoRestartSessions !== false;
7411
7661
  try {
7412
7662
  const homes = await refreshAgentHomes();
7413
7663
  logger.debug(`[DAEMON RUN] Claude config dir: ${describeAgentHome(homes.claudeConfigDir)}; Codex home: ${describeAgentHome(homes.codexHome)}`);
@@ -7530,6 +7780,7 @@ async function startDaemon() {
7530
7780
  });
7531
7781
  const sessionIdToFinishedSession = /* @__PURE__ */ new Map();
7532
7782
  let teamWorker;
7783
+ let autoRestart;
7533
7784
  let automationRunner;
7534
7785
  let projectPresence;
7535
7786
  const persisted = readPersistedSessions();
@@ -8270,6 +8521,7 @@ async function startDaemon() {
8270
8521
  }
8271
8522
  };
8272
8523
  const restartCounts = /* @__PURE__ */ new Map();
8524
+ const autoRestartExits = /* @__PURE__ */ new Set();
8273
8525
  const stopSessionAndWait = async (happySessionId, timeoutMs = 8e3) => {
8274
8526
  const targets = /* @__PURE__ */ new Set();
8275
8527
  for (const [pid, s] of pidToTrackedSession.entries()) {
@@ -8319,7 +8571,7 @@ async function startDaemon() {
8319
8571
  const restartSessionImpl = async (happySessionId, options) => {
8320
8572
  try {
8321
8573
  const prior = restartCounts.get(happySessionId) ?? 0;
8322
- const decision = decideRestart(prior, DEFAULT_MAX_RESTARTS);
8574
+ const decision = options?.auto ? { allowed: true } : decideRestart(prior, DEFAULT_MAX_RESTARTS);
8323
8575
  if (!decision.allowed) {
8324
8576
  return { type: "error", errorMessage: `restart:${decision.reason}` };
8325
8577
  }
@@ -8370,7 +8622,7 @@ async function startDaemon() {
8370
8622
  if (model) args.push("--model", model);
8371
8623
  const permissionMode = sanitizeSpawnPermissionMode(options?.permissionMode ?? (options?.keepPublishedPermissionMode ? publishedRelaunchPermissionMode(metadata) : void 0));
8372
8624
  if (permissionMode) args.push("--permission-mode", permissionMode);
8373
- restartCounts.set(happySessionId, recordRestartAttempt(prior));
8625
+ if (!options?.auto) restartCounts.set(happySessionId, recordRestartAttempt(prior));
8374
8626
  const teamEnv = await teamRelaunchEnvFor(happySessionId, metadata);
8375
8627
  const result = await spawnTrackedHappyProcess({
8376
8628
  args,
@@ -8391,7 +8643,8 @@ async function startDaemon() {
8391
8643
  HAPPY_RECONNECT_SEQ: String(tracked.encryption.seq),
8392
8644
  HAPPY_RECONNECT_METADATA_VERSION: String(tracked.encryption.metadataVersion),
8393
8645
  HAPPY_RECONNECT_AGENT_STATE_VERSION: String(tracked.encryption.agentStateVersion),
8394
- ...teamEnv
8646
+ ...teamEnv,
8647
+ ...options?.auto ? { [AUTO_RESTARTED_ENV]: encodeAutoRestarted(options.auto.kind, options.auto.target) } : {}
8395
8648
  }
8396
8649
  });
8397
8650
  if (result.type === "success") {
@@ -8434,10 +8687,11 @@ async function startDaemon() {
8434
8687
  };
8435
8688
  const onChildExited = (pid) => {
8436
8689
  const session = pidToTrackedSession.get(pid);
8437
- if (session?.happySessionId && (session.spawnedBy === "teams" || teamWorker?.hasSession(session.happySessionId))) teamWorker?.report(session.happySessionId, "exited");
8690
+ if (session?.happySessionId && !autoRestartExits.has(session.happySessionId) && (session.spawnedBy === "teams" || teamWorker?.hasSession(session.happySessionId))) teamWorker?.report(session.happySessionId, "exited");
8438
8691
  if (session?.happySessionId && automationRunner?.hasSession(session.happySessionId)) automationRunner.report(session.happySessionId, "exited");
8439
8692
  if (session?.happySessionId) turnActivity.forget(session.happySessionId);
8440
8693
  if (session?.happySessionId) backgroundTasks.forget(session.happySessionId);
8694
+ if (session?.happySessionId) autoRestart?.forget(session.happySessionId);
8441
8695
  if (session?.happySessionId) peerCoordinator.forget(session.happySessionId);
8442
8696
  if (session?.happySessionId && daemonHibernation.consumeExit(session.happySessionId)) {
8443
8697
  const persisted2 = readPersistedSessions()[session.happySessionId];
@@ -8518,6 +8772,84 @@ async function startDaemon() {
8518
8772
  })();
8519
8773
  };
8520
8774
  let apiMachineRef = null;
8775
+ let latestAgentVersions = null;
8776
+ const trackedFacts = (tracked) => {
8777
+ const metadata = tracked.happySessionMetadataFromLocalWebhook;
8778
+ return {
8779
+ live: isPidAlive(tracked.pid),
8780
+ wrapperVersion: metadata?.version ?? null,
8781
+ flavor: metadata?.flavor ?? "claude",
8782
+ capabilities: metadata?.capabilities ?? null,
8783
+ spawnedBy: tracked.spawnedBy ?? null,
8784
+ tags: metadata?.tags ?? null,
8785
+ variant: tracked.variant ?? metadata?.variant ?? null,
8786
+ // The wrapper's own word: tracked.startedBy turns into "persisted" /
8787
+ // "recovered" across the very daemon restart an upgrade does.
8788
+ startedBy: metadata?.startedBy ?? null
8789
+ };
8790
+ };
8791
+ const autoRestartScheduler = createAutoRestart({
8792
+ enabled: () => autoRestartSetting,
8793
+ quietMs: resolveQuietMs(),
8794
+ daemonVersion: packageJson.version,
8795
+ installedAgentVersion: (flavor) => flavor === "codex" ? latestAgentVersions?.agents.find((agent) => agent.id === "codex")?.installed ?? null : null,
8796
+ tracked: (sessionId, pid) => {
8797
+ const tracked = pidToTrackedSession.get(pid);
8798
+ if (!tracked || tracked.happySessionId !== sessionId) return null;
8799
+ return trackedFacts(tracked);
8800
+ },
8801
+ liveSessions: () => [...pidToTrackedSession.values()].filter((tracked) => tracked.happySessionId && tracked.happySessionMetadataFromLocalWebhook && isPidAlive(tracked.pid)).map((tracked) => ({ sessionId: tracked.happySessionId, ...trackedFacts(tracked) })),
8802
+ turnActive: (sessionId) => turnActivity.activeSessions().includes(sessionId),
8803
+ backgroundTasks: (sessionId) => backgroundTasks.count(sessionId),
8804
+ automationRunning: (sessionId) => automationRunner?.hasSession(sessionId) === true,
8805
+ // The local copy may predate the agent's conversation id (it is the spawn
8806
+ // webhook's); judge the server copy, exactly as restartSessionImpl will.
8807
+ resumable: async (sessionId) => {
8808
+ const tracked = findTrackedSessionById(sessionId);
8809
+ const local = tracked?.happySessionMetadataFromLocalWebhook;
8810
+ const encryption = tracked?.encryption;
8811
+ if (!local || !encryption) return false;
8812
+ const { metadata } = await resolveRelaunchMetadata(
8813
+ local,
8814
+ () => fetchServerSessionMetadata(sessionId, encryption.encryptionKey, encryption.encryptionVariant)
8815
+ );
8816
+ return resumePrecheck(metadata, {
8817
+ cwdExists: (p) => existsSync$1(p),
8818
+ conversationExists: (cwd, claudeSessionId) => locateClaudeConversation(cwd, claudeSessionId) !== null
8819
+ }).ok;
8820
+ },
8821
+ restart: async (sessionId, staleness) => {
8822
+ autoRestartExits.add(sessionId);
8823
+ try {
8824
+ const result = await restartSession(sessionId, { keepPublishedPermissionMode: true, auto: { kind: staleness.kind, target: staleness.target } });
8825
+ if (result.type !== "success") return { ok: false, error: result.type === "error" ? result.errorMessage : result.type };
8826
+ const after = findTrackedSessionById(sessionId)?.happySessionMetadataFromLocalWebhook?.version;
8827
+ if (staleness.kind === "cli" && after && (compareExactVersions(after, staleness.target) ?? 0) < 0) {
8828
+ return { ok: false, error: `still-behind: ${after}` };
8829
+ }
8830
+ return { ok: true };
8831
+ } finally {
8832
+ autoRestartExits.delete(sessionId);
8833
+ }
8834
+ },
8835
+ // Offline-failure retry guard: nobody restored, archived or resumed it meanwhile.
8836
+ serverSession: async (sessionId) => {
8837
+ const response = await axios.get(`${configuration.serverUrl}/v1/sessions/${encodeURIComponent(sessionId)}`, {
8838
+ headers: { Authorization: `Bearer ${credentials.token}` },
8839
+ timeout: 1e4
8840
+ });
8841
+ const row = response.data.session;
8842
+ if (!row || typeof row.active !== "boolean") return null;
8843
+ return { active: row.active, archived: row.archivedAt != null };
8844
+ },
8845
+ publish: (sessions) => {
8846
+ void apiMachineRef?.setAutoRestartSessions(sessions);
8847
+ },
8848
+ log: (message) => logger.debug(`[DAEMON RUN] ${message}`)
8849
+ });
8850
+ autoRestart = autoRestartScheduler;
8851
+ const autoRestartSweep = setInterval(() => autoRestartScheduler.sweep(), 6e4);
8852
+ autoRestartSweep.unref?.();
8521
8853
  let mirrorManagerRef = null;
8522
8854
  const controlToken = createDaemonControlToken();
8523
8855
  const { port: controlPort, stop: stopControlServer } = await startDaemonControlServer({
@@ -8544,7 +8876,14 @@ async function startDaemon() {
8544
8876
  onRateLimits: (report) => {
8545
8877
  apiMachineRef?.reportRateLimits(report);
8546
8878
  },
8547
- onHibernateCheck: (body) => daemonHibernation.check(body),
8879
+ // B-852: the same idle check-in also decides an automatic restart of a
8880
+ // stale wrapper; hibernation (exit) wins when both say yes.
8881
+ onHibernateCheck: async (body) => {
8882
+ const reply = await daemonHibernation.check(body);
8883
+ if (reply.hibernate) return reply;
8884
+ const auto = await autoRestartScheduler.onCheckIn(body);
8885
+ return { ...reply, nextCheckMs: Math.min(reply.nextCheckMs ?? AUTO_RESTART_RECHECK_CAP_MS, AUTO_RESTART_RECHECK_CAP_MS, auto.nextCheckMs ?? Infinity) };
8886
+ },
8548
8887
  listPeers: () => peerCoordinator.list(),
8549
8888
  // B-505: `daemon list` shows which sessions have a turn in flight, so an
8550
8889
  // operator can check the WHOLE machine before a supervised restart.
@@ -8696,6 +9035,13 @@ async function startDaemon() {
8696
9035
  daemonHibernation.invalidateBindings();
8697
9036
  return resolveIdleMs(agentHibernationSetting);
8698
9037
  });
9038
+ apiMachine.setAutoRestartHandlers(autoRestartSetting, async (enabled) => {
9039
+ await updateSettings((current) => ({ ...current, autoRestartSessions: enabled }));
9040
+ autoRestartSetting = enabled;
9041
+ autoRestartScheduler.sweep();
9042
+ return autoRestartSetting;
9043
+ });
9044
+ setTimeout(() => autoRestartScheduler.sweep(), 5e3).unref?.();
8699
9045
  const webPanelsSync = startWebPanelsSync({
8700
9046
  statMtime: async () => (await fs.stat(configuration.settingsFile).catch(() => null))?.mtimeMs ?? null,
8701
9047
  readRaw: async () => (await readSettings()).webPanels,
@@ -8786,7 +9132,10 @@ async function startDaemon() {
8786
9132
  if (delay !== null) logger.warn(`[DAEMON RUN] CLI update policy announced; re-checking in ${Math.round(delay / 1e3)}s`);
8787
9133
  });
8788
9134
  const stopAgentVersionChecks = startAgentVersionChecks(
8789
- (snapshot) => apiMachine.updateDaemonState((state) => ({ ...state, status: state?.status ?? "running", agentVersions: snapshot })),
9135
+ (snapshot) => {
9136
+ latestAgentVersions = snapshot;
9137
+ return apiMachine.updateDaemonState((state) => ({ ...state, status: state?.status ?? "running", agentVersions: snapshot }));
9138
+ },
8790
9139
  (error) => logger.debug("[DAEMON RUN] Agent version check failed", error)
8791
9140
  );
8792
9141
  harnessInstaller = createHarnessInstaller({
@@ -8968,6 +9317,7 @@ async function startDaemon() {
8968
9317
  logger.debug("[DAEMON RUN] Health check interval cleared");
8969
9318
  }
8970
9319
  clearInterval(cliUpdateInterval);
9320
+ clearInterval(autoRestartSweep);
8971
9321
  policyAnnouncements.stop();
8972
9322
  stopAgentVersionChecks();
8973
9323
  await apiMachine.updateDaemonState((state) => ({