very-happy-cli 0.2.166 → 0.2.168

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 (178) hide show
  1. package/dist/{AcpBackend-tRWk7yi7.mjs → AcpBackend-BoLDLYNT.mjs} +3 -3
  2. package/dist/{AcpBackend-20VHOXwb.cjs → AcpBackend-r83MMm-i.cjs} +3 -3
  3. package/dist/{BasePermissionHandler-COKc4pmt.cjs → BasePermissionHandler-CS0eRtT-.cjs} +1 -1
  4. package/dist/{BasePermissionHandler-CDCLIrZJ.mjs → BasePermissionHandler-DTcVlmKi.mjs} +1 -1
  5. package/dist/{BaseReasoningProcessor-BDVKvooR.mjs → BaseReasoningProcessor-BddnNlXQ.mjs} +1 -1
  6. package/dist/{BaseReasoningProcessor-DAGQdkNp.cjs → BaseReasoningProcessor-RJiBhA8h.cjs} +1 -1
  7. package/dist/{agentHome-2IbIjKCa.mjs → agentHome--LRsdUx6.mjs} +4 -4
  8. package/dist/{agentHome-KVWj6nCl.cjs → agentHome-D-e_j9hK.cjs} +4 -4
  9. package/dist/{api-DnNL5fLw.cjs → api-COSJ3Yb7.cjs} +88 -10
  10. package/dist/{api-Cmz3XS4P.mjs → api-hXLwtgMi.mjs} +88 -10
  11. package/dist/{apiMachine-DeoQ8QbZ.cjs → apiMachine-BTCUUGC6.cjs} +50 -15
  12. package/dist/{apiMachine-B6ySCFe0.mjs → apiMachine-BauSXWNd.mjs} +50 -15
  13. package/dist/{attachmentContent-DPWxHgX4.cjs → attachmentContent-BCK0AxDS.cjs} +2 -2
  14. package/dist/{attachmentContent-CTXapi-_.mjs → attachmentContent-CS0B2N0Q.mjs} +2 -2
  15. package/dist/{attachmentLimits-BfgKV5iE.cjs → attachmentLimits-BEYEEBm8.cjs} +13 -1
  16. package/dist/{attachmentLimits-C1PCCM79.mjs → attachmentLimits-CxG3T18E.mjs} +13 -1
  17. package/dist/{auth-pzWIFdOD.mjs → auth-BFeFguVs.mjs} +5 -5
  18. package/dist/{auth-BMaBjRAj.mjs → auth-BUXH1L2k.mjs} +10 -10
  19. package/dist/{auth-D4-eQz85.cjs → auth-CCj5KlYS.cjs} +10 -10
  20. package/dist/{auth-ietHtvwu.cjs → auth-CfB2XcAW.cjs} +5 -5
  21. package/dist/{auto-DL75Dx3I.mjs → auto-D5BYdAoT.mjs} +14 -14
  22. package/dist/{auto-DOWTQDPa.cjs → auto-ZCHKb4jo.cjs} +14 -14
  23. package/dist/{bootstrap-BpXIc2wn.cjs → bootstrap-DSX64t23.cjs} +2 -2
  24. package/dist/{bootstrap-XE8A7Ut2.mjs → bootstrap-DklT121U.mjs} +2 -2
  25. package/dist/{browser-CcG8GLRV.cjs → browser-CeekQeKt.cjs} +1 -1
  26. package/dist/{browser-DDFi1T8C.mjs → browser-DUf1dth8.mjs} +1 -1
  27. package/dist/{claudeLocal-DmM5Oyhv.mjs → claudeLocal-C8pXtb8q.mjs} +5 -5
  28. package/dist/{claudeLocal-DXBXwIOG.cjs → claudeLocal-hH0YYex3.cjs} +5 -5
  29. package/dist/{claudeLocalLauncher-Cs4eUC3P.mjs → claudeLocalLauncher-AtUe2tM-.mjs} +10 -10
  30. package/dist/{claudeLocalLauncher-C41Y6Kp4.cjs → claudeLocalLauncher-B-ta13pT.cjs} +10 -10
  31. package/dist/{claudeSessionFork-BdLnc2Hv.mjs → claudeSessionFork-BQPBKEHk.mjs} +1 -1
  32. package/dist/{claudeSessionFork-Cs0I3eGI.cjs → claudeSessionFork-Cq9FBfjD.cjs} +1 -1
  33. package/dist/{client-CbK33y_s.mjs → client-Bg6-mQKO.mjs} +3 -3
  34. package/dist/{client-GjTnsq6F.mjs → client-Cbl3ejoq.mjs} +2 -2
  35. package/dist/{client-JISJx2f-.cjs → client-DZpkmS5l.cjs} +3 -3
  36. package/dist/{client-DJ0kX_8M.cjs → client-EnFomCjx.cjs} +2 -2
  37. package/dist/codex/happyMcpStdioBridge.cjs +14 -14
  38. package/dist/codex/happyMcpStdioBridge.mjs +14 -14
  39. package/dist/{codexAppServerClient-BTjn2ZCZ.cjs → codexAppServerClient-pllsN90-.cjs} +4 -4
  40. package/dist/{codexAppServerClient-CldXEojt.mjs → codexAppServerClient-sWuwtddZ.mjs} +4 -4
  41. package/dist/{codexCommand-DjMU-Ijf.mjs → codexCommand-DbTkMlW4.mjs} +137 -56
  42. package/dist/{codexCommand-BpD0N1F7.cjs → codexCommand-_jkx59gI.cjs} +137 -56
  43. package/dist/{config-DuLL0Ppe.cjs → config-BuIIZPZK.cjs} +3 -3
  44. package/dist/{config-DjSJKatx.mjs → config-FCOoREKj.mjs} +3 -3
  45. package/dist/{configuration-D2v3puap.mjs → configuration-BZo1JWNV.mjs} +2 -2
  46. package/dist/{configuration-B0cb3xA3.cjs → configuration-DeuGrnej.cjs} +1 -1
  47. package/dist/{connect-CnNNyM9I.mjs → connect-C2yHh85e.mjs} +13 -13
  48. package/dist/{connect-B7JWEzyg.cjs → connect-CjDdF12U.cjs} +13 -13
  49. package/dist/{context-BFUpYT39.cjs → context-BhvZtm3j.cjs} +1 -1
  50. package/dist/{context-DjfqLWzE.mjs → context-DZIIcfld.mjs} +1 -1
  51. package/dist/{controlClient-BMUJfUeF.mjs → controlClient-CXD-Xdny.mjs} +18 -4
  52. package/dist/{controlClient-CmnHGcyl.cjs → controlClient-IDE3se23.cjs} +18 -3
  53. package/dist/{createSessionMetadata-DbfRBhRu.cjs → createSessionMetadata-BCHFLSLk.cjs} +56 -3
  54. package/dist/{createSessionMetadata-DU0bCg2m.mjs → createSessionMetadata-DoLFya-Q.mjs} +57 -5
  55. package/dist/defaultPermissionMode-BtZtLdQz.cjs +197 -0
  56. package/dist/defaultPermissionMode-Dxfv-5Ud.mjs +191 -0
  57. package/dist/{deterministicJson-Dp3TVyap.cjs → deterministicJson-BqQKrUzw.cjs} +8 -8
  58. package/dist/{deterministicJson-D-WPUrZb.mjs → deterministicJson-CF1fJMaM.mjs} +8 -8
  59. package/dist/{doctor-BlXXyQ1L.mjs → doctor-C98yYhYr.mjs} +6 -6
  60. package/dist/{doctor-CkJmdPbi.cjs → doctor-D61ncaeL.cjs} +6 -6
  61. package/dist/{downloadTarget-DjSwMHun.mjs → downloadTarget-CaISZbNy.mjs} +6 -6
  62. package/dist/{downloadTarget-CiQqRIc-.cjs → downloadTarget-Dist9t2e.cjs} +6 -6
  63. package/dist/{ensureDaemonRunning-C_aIOhgG.cjs → ensureDaemonRunning-BB0hnWY_.cjs} +5 -5
  64. package/dist/{ensureDaemonRunning-CAQag1zE.mjs → ensureDaemonRunning-CNiqOarI.mjs} +5 -5
  65. package/dist/{handleResumeCommand-Ci7wacT-.mjs → handleResumeCommand-BzcANj0i.mjs} +5 -5
  66. package/dist/{handleResumeCommand-6KzBGDnl.cjs → handleResumeCommand-CkzW-T_f.cjs} +5 -5
  67. package/dist/{index-DEKIgZUo.cjs → index-BQU1sS9K.cjs} +4 -4
  68. package/dist/{index-DBmNwMX9.cjs → index-BeeWN9Et.cjs} +33 -33
  69. package/dist/{index-WGCT6SSV.mjs → index-CdmIOFwG.mjs} +34 -34
  70. package/dist/{index-HQsigW_J.mjs → index-D2hg_u5i.mjs} +3 -3
  71. package/dist/{index-DQplgo0W.mjs → index-Dgqk3lfG.mjs} +4 -4
  72. package/dist/{index-CaFCAlX8.cjs → index-DipBfs9w.cjs} +3 -3
  73. package/dist/index.cjs +2 -2
  74. package/dist/index.mjs +2 -2
  75. package/dist/{install-oJUvsFu9.mjs → install-CK1FvmYQ.mjs} +3 -3
  76. package/dist/{install-CejEiRGW.cjs → install-VtuffPLu.cjs} +3 -3
  77. package/dist/lib.cjs +11 -11
  78. package/dist/lib.d.cts +61 -0
  79. package/dist/lib.d.mts +61 -0
  80. package/dist/lib.mjs +11 -11
  81. package/dist/{lidState-D8BmnJV1.cjs → lidState-2IT0tas7.cjs} +1 -1
  82. package/dist/{lidState-BfximpjX.mjs → lidState-CJ3XkJRn.mjs} +1 -1
  83. package/dist/{localHappyAgentAuth-d7B6S_o7.cjs → localHappyAgentAuth-CPMh61Su.cjs} +1 -1
  84. package/dist/{localHappyAgentAuth-Ct1aXwqd.mjs → localHappyAgentAuth-DkLbntlf.mjs} +1 -1
  85. package/dist/{logger-BpQcwNnt.mjs → logger-C6zzu57a.mjs} +2 -2
  86. package/dist/{logger-JTcJU-uL.cjs → logger-Ockf1cjN.cjs} +2 -2
  87. package/dist/{machineMetadata-BBg_Njw3.cjs → machineMetadata-CoMYwSlG.cjs} +4 -3
  88. package/dist/{machineMetadata-CBdxABeI.mjs → machineMetadata-DmTGIZAV.mjs} +4 -3
  89. package/dist/{main-B5b1gA3K.mjs → main-B8TX9xPq.mjs} +45 -45
  90. package/dist/{main-C16fOGgn.cjs → main-CThJ9JQb.cjs} +45 -45
  91. package/dist/{manager-BQ4flvQZ.mjs → manager-BEsI4qt3.mjs} +9 -3
  92. package/dist/{manager-Cly8xVIR.cjs → manager-HrEj442o.cjs} +8 -2
  93. package/dist/{mcp-BnNiBBax.cjs → mcp-Dwku1p2I.cjs} +14 -14
  94. package/dist/{mcp-DGNWgVdv.mjs → mcp-Yw93dOiW.mjs} +14 -14
  95. package/dist/mirrorProtocol-CQ5fAUgq.mjs +1247 -0
  96. package/dist/mirrorProtocol-CdPhEBSh.cjs +1270 -0
  97. package/dist/{package-BqwrPxL0.mjs → package-5xAdq5fu.mjs} +7 -7
  98. package/dist/{package-C1XvUQFy.cjs → package-DfoyJe1O.cjs} +7 -7
  99. package/dist/{peerTools-DPvbcs8V.cjs → peerTools-BEnBvEcU.cjs} +4 -4
  100. package/dist/{peerTools-CeCe-3lk.mjs → peerTools-uDR6MG0-.mjs} +4 -4
  101. package/dist/{persistence-2Xp_o6x6.cjs → persistence-B5oT6oQ9.cjs} +147 -25
  102. package/dist/{persistence-B9LmhAE2.mjs → persistence-B6M_W5iC.mjs} +123 -12
  103. package/dist/{piRunnerArgs-DI29dDNo.cjs → piRunnerArgs-MLN46-nK.cjs} +1 -1
  104. package/dist/{piRunnerArgs-7FaTyNOq.mjs → piRunnerArgs-vNIUWHqo.mjs} +1 -1
  105. package/dist/{piRuntime-R8XVChxK.cjs → piRuntime-DkUg8_5q.cjs} +1 -1
  106. package/dist/{piRuntime-0qEK5AqE.mjs → piRuntime-WMuI7f4q.mjs} +1 -1
  107. package/dist/{piTerminal-zcQKc8Sp.mjs → piTerminal-4NBSZVxd.mjs} +16 -16
  108. package/dist/{piTerminal-Ccj0KNPr.cjs → piTerminal-Bskvs69Z.cjs} +16 -16
  109. package/dist/{rateLimitWindows-C2Jk3Ih7.cjs → rateLimitWindows-C2-Ky86q.cjs} +1 -1
  110. package/dist/{rateLimitWindows-Dhfhbtqu.mjs → rateLimitWindows-CJ1xDAxa.mjs} +1 -1
  111. package/dist/{registerCommonHandlers-DdfGsFbM.mjs → registerCommonHandlers-BLHKlk5Z.mjs} +2 -2
  112. package/dist/{registerCommonHandlers-Aha_KfM3.cjs → registerCommonHandlers-COSTo15G.cjs} +2 -2
  113. package/dist/{registerKillSessionHandler-DboQlGcH.mjs → registerKillSessionHandler-BVQfhSgm.mjs} +14 -9
  114. package/dist/{registerKillSessionHandler-CjitOpUA.cjs → registerKillSessionHandler-DDZISNzu.cjs} +14 -9
  115. package/dist/{remoteSessionClient-BwI8rpQw.cjs → remoteSessionClient-B2pOMZRw.cjs} +5 -5
  116. package/dist/{remoteSessionClient-B2DtWuNP.mjs → remoteSessionClient-Dx0M2MXV.mjs} +5 -5
  117. package/dist/{reportProgressTool-B-Rcy0s3.cjs → reportProgressTool-C5vDEv9Y.cjs} +1 -1
  118. package/dist/{reportProgressTool-DnAD8wOa.mjs → reportProgressTool-CcwFr0ek.mjs} +1 -1
  119. package/dist/{run-Bh66Xs40.cjs → run-BKTv1E-D.cjs} +323 -37
  120. package/dist/{run-DPEwJpQR.mjs → run-BZjIDOGM.mjs} +322 -36
  121. package/dist/{runClaude-DLr_nBzw.mjs → runClaude-DFa77Ffl.mjs} +87 -25
  122. package/dist/{runClaude-C-lJdAKD.cjs → runClaude-DUlFZWiK.cjs} +87 -25
  123. package/dist/{runClaudeDeps-vWWLod7J.cjs → runClaudeDeps--TnER0c3.cjs} +100 -31
  124. package/dist/{runClaudeDeps-C7JV7nXG.mjs → runClaudeDeps-BYohagQU.mjs} +105 -36
  125. package/dist/{runGemini-o-CUSayc.cjs → runGemini-BSBejXek.cjs} +32 -32
  126. package/dist/{runGemini-tH6sLw-G.mjs → runGemini-CUiq1Zei.mjs} +32 -32
  127. package/dist/{runOpenClaw-C5DZvVhn.mjs → runOpenClaw-CgwRP4gR.mjs} +16 -16
  128. package/dist/{runOpenClaw-D24f35l0.cjs → runOpenClaw-DQFEi3E1.cjs} +16 -16
  129. package/dist/{sandbox-BaL1aslA.mjs → sandbox-BTwAN7Yi.mjs} +4 -4
  130. package/dist/{sandbox-TJZJ6ngw.cjs → sandbox-DuLRfMY3.cjs} +4 -4
  131. package/dist/selfCheck-DF26lf1b.mjs +84 -0
  132. package/dist/{selfCheck-Dugi0Nk_.cjs → selfCheck-DuOLndWl.cjs} +34 -34
  133. package/dist/{send-DDcJ3ayi.mjs → send-ComZSvT5.mjs} +8 -8
  134. package/dist/{send-CkWOSYmU.cjs → send-Dl4TJ0Ia.cjs} +8 -8
  135. package/dist/{server-7qFQ8J2u.cjs → server-CWmamKcS.cjs} +6 -6
  136. package/dist/{server-CUjRvQSd.mjs → server-CXFSsyZx.mjs} +4 -4
  137. package/dist/{sessionLock-DfhNICyS.cjs → sessionLock-BFD8cFNP.cjs} +12 -3
  138. package/dist/{sessionLock-DqVyHFAQ.mjs → sessionLock-DCKf-gjd.mjs} +12 -4
  139. package/dist/{sessionModeFile-M4OpiyrF.mjs → sessionModeFile-BYxsFSvc.mjs} +1 -1
  140. package/dist/{sessionModeFile-CIznKD7O.cjs → sessionModeFile-i-MVQRcU.cjs} +1 -1
  141. package/dist/{sessionOps-DOyy4gkY.cjs → sessionOps-BAQ_80Rg.cjs} +4 -4
  142. package/dist/{sessionOps-BnaEaOKs.mjs → sessionOps-CBXsQGV5.mjs} +4 -4
  143. package/dist/{sessionScanner-CcuOn9uU.mjs → sessionScanner-CwPBvQK2.mjs} +3 -3
  144. package/dist/{sessionScanner-Cu1yKlj4.cjs → sessionScanner-Dth3iDCi.cjs} +3 -3
  145. package/dist/{sessions-BQgk5Kw8.cjs → sessions-BULd_RQt.cjs} +9 -9
  146. package/dist/{sessions-C9O91rL1.mjs → sessions-DYAqiUS0.mjs} +9 -9
  147. package/dist/{setupOfflineReconnection-Byy8aeKT.mjs → setupOfflineReconnection-Bo9xb30l.mjs} +2 -2
  148. package/dist/{setupOfflineReconnection-DFmQ8s6I.cjs → setupOfflineReconnection-DI8BQf_g.cjs} +2 -2
  149. package/dist/{spawn-EZ2yrtWd.mjs → spawn-DmXpKIOT.mjs} +13 -13
  150. package/dist/{spawn-BS7LPmSm.cjs → spawn-oikb5mUh.cjs} +13 -13
  151. package/dist/{spawnHappyCLI-BAa49m0q.mjs → spawnHappyCLI-BCnZfffk.mjs} +1 -1
  152. package/dist/{spawnHappyCLI-DyaldIe5.cjs → spawnHappyCLI-Cs177BB4.cjs} +1 -1
  153. package/dist/{specialCommands-DouFaJ_0.cjs → specialCommands-CmrwEh71.cjs} +3 -3
  154. package/dist/{specialCommands-CCWtwIGZ.mjs → specialCommands-xD4uOtdG.mjs} +3 -3
  155. package/dist/{startFileWatcher-Dfs4whzr.mjs → startFileWatcher-De7rN8QW.mjs} +1 -1
  156. package/dist/{startFileWatcher-DQbbypJv.cjs → startFileWatcher-S_Af_QPR.cjs} +1 -1
  157. package/dist/{sync-x_lI_3j_.cjs → sync-BS9_zSQ2.cjs} +1 -1
  158. package/dist/{sync-BLpH13Kb.mjs → sync-CHOB3Org.mjs} +1 -1
  159. package/dist/{systemPrompt-4erwILTB.cjs → systemPrompt-D2ICcIsu.cjs} +1 -1
  160. package/dist/{systemPrompt-BanyDihy.mjs → systemPrompt-DNLUUejs.mjs} +1 -1
  161. package/dist/{teams-DzetlGWC.cjs → teams-BUbESH6L.cjs} +6 -6
  162. package/dist/{teams-D6BOT3lR.mjs → teams-By3oBC7r.mjs} +6 -6
  163. package/dist/{time-CfDKj6Bx.mjs → time-CN0jVVir.mjs} +1 -1
  164. package/dist/{time-T0YmeOhS.cjs → time-uSKpEhew.cjs} +1 -1
  165. package/dist/{titleGenerator-CoMxqKfP.cjs → titleGenerator-CLIXjn9b.cjs} +2 -2
  166. package/dist/{titleGenerator-ChImQ4q-.mjs → titleGenerator-CegRJ47n.mjs} +1 -1
  167. package/dist/{todo-CZZebKZg.cjs → todo-Bg1vurv9.cjs} +5 -5
  168. package/dist/{todo-SVtYxGON.mjs → todo-Bl3abqvy.mjs} +5 -5
  169. package/dist/{tools-3X2z3YDe.mjs → tools-BcLUrC57.mjs} +1 -1
  170. package/dist/{tools-IJ0TAcJs.cjs → tools-DuWKlc0k.cjs} +1 -1
  171. package/dist/{uninstall-CypD-kr1.mjs → uninstall-BlpZlM9U.mjs} +3 -3
  172. package/dist/{uninstall-CqqCWj7w.cjs → uninstall-DWnj2XVT.cjs} +3 -3
  173. package/package.json +7 -7
  174. package/dist/defaultPermissionMode-BnxJPVHT.mjs +0 -4
  175. package/dist/defaultPermissionMode-CxmTXUQR.cjs +0 -7
  176. package/dist/mirrorProtocol-BEGk2--0.cjs +0 -266
  177. package/dist/mirrorProtocol-h5WHpdhh.mjs +0 -248
  178. package/dist/selfCheck-DPi4lqme.mjs +0 -84
@@ -1,25 +1,25 @@
1
1
  'use strict';
2
2
 
3
- var mirrorProtocol = require('./mirrorProtocol-BEGk2--0.cjs');
4
- var piRunnerArgs = require('./piRunnerArgs-DI29dDNo.cjs');
3
+ var mirrorProtocol = require('./mirrorProtocol-CdPhEBSh.cjs');
4
+ var piRunnerArgs = require('./piRunnerArgs-MLN46-nK.cjs');
5
5
  var fs = require('fs/promises');
6
6
  var tmp = require('tmp');
7
7
  var axios = require('axios');
8
- var api = require('./api-DnNL5fLw.cjs');
8
+ var api = require('./api-COSJ3Yb7.cjs');
9
9
  var spawnAgents = require('./spawnAgents-vglexX9N.cjs');
10
- var logger = require('./logger-JTcJU-uL.cjs');
10
+ var logger = require('./logger-Ockf1cjN.cjs');
11
11
  var node_fs = require('node:fs');
12
12
  var path = require('node:path');
13
- var index$2 = require('./index-CaFCAlX8.cjs');
14
- var auth = require('./auth-ietHtvwu.cjs');
15
- var configuration = require('./configuration-B0cb3xA3.cjs');
13
+ var index$2 = require('./index-DipBfs9w.cjs');
14
+ var auth = require('./auth-CfB2XcAW.cjs');
15
+ var configuration = require('./configuration-DeuGrnej.cjs');
16
16
  var child_process = require('child_process');
17
- var _package = require('./package-C1XvUQFy.cjs');
18
- var doctor = require('./doctor-CkJmdPbi.cjs');
19
- var spawnHappyCLI = require('./spawnHappyCLI-DyaldIe5.cjs');
20
- var persistence = require('./persistence-2Xp_o6x6.cjs');
21
- var controlClient = require('./controlClient-CmnHGcyl.cjs');
22
- var sessionOps = require('./sessionOps-DOyy4gkY.cjs');
17
+ var _package = require('./package-DfoyJe1O.cjs');
18
+ var doctor = require('./doctor-D61ncaeL.cjs');
19
+ var spawnHappyCLI = require('./spawnHappyCLI-Cs177BB4.cjs');
20
+ var persistence = require('./persistence-B5oT6oQ9.cjs');
21
+ var controlClient = require('./controlClient-IDE3se23.cjs');
22
+ var sessionOps = require('./sessionOps-BAQ_80Rg.cjs');
23
23
  var fastify = require('fastify');
24
24
  var z = require('zod');
25
25
  var fastifyTypeProviderZod = require('fastify-type-provider-zod');
@@ -27,45 +27,45 @@ var authRelay = require('./authRelay-BdYkC1Po.cjs');
27
27
  var node_crypto = require('node:crypto');
28
28
  var previewPath = require('./previewPath-B0rBdhy1.cjs');
29
29
  var backgroundTaskActivity = require('./backgroundTaskActivity-CBvUdj39.cjs');
30
- var rateLimitWindows = require('./rateLimitWindows-C2Jk3Ih7.cjs');
31
- var peerTools = require('./peerTools-DPvbcs8V.cjs');
30
+ var rateLimitWindows = require('./rateLimitWindows-C2-Ky86q.cjs');
31
+ var peerTools = require('./peerTools-BEnBvEcU.cjs');
32
32
  var os = require('node:os');
33
- var remoteSessionClient = require('./remoteSessionClient-BwI8rpQw.cjs');
34
- var bootstrap = require('./bootstrap-BpXIc2wn.cjs');
35
- var index$1 = require('./index-DEKIgZUo.cjs');
33
+ var remoteSessionClient = require('./remoteSessionClient-B2pOMZRw.cjs');
34
+ var bootstrap = require('./bootstrap-DSX64t23.cjs');
35
+ var index$1 = require('./index-BQU1sS9K.cjs');
36
36
  var fs$1 = require('fs');
37
37
  var path$2 = require('path');
38
38
  var node_child_process = require('node:child_process');
39
39
  var projectPath = require('./projectPath-ChLhdOyt.cjs');
40
40
  var doctorReadiness = require('./doctorReadiness-BCZGcN0a.cjs');
41
- var machineMetadata = require('./machineMetadata-BBg_Njw3.cjs');
42
- var handleResumeCommand = require('./handleResumeCommand-6KzBGDnl.cjs');
41
+ var machineMetadata = require('./machineMetadata-CoMYwSlG.cjs');
42
+ var handleResumeCommand = require('./handleResumeCommand-CkzW-T_f.cjs');
43
43
  var promises = require('node:fs/promises');
44
44
  var cliUpdate = require('./cliUpdate-DsKXPFYp.cjs');
45
+ var client = require('./client-EnFomCjx.cjs');
45
46
  var module$1 = require('node:module');
46
47
  var path$1 = require('./path-B7zW-WwE.cjs');
47
48
  var editPaths = require('./editPaths-Bqp4OFPw.cjs');
48
- var startFileWatcher = require('./startFileWatcher-DQbbypJv.cjs');
49
- var sync = require('./sync-x_lI_3j_.cjs');
49
+ var startFileWatcher = require('./startFileWatcher-S_Af_QPR.cjs');
50
+ var sync = require('./sync-BS9_zSQ2.cjs');
50
51
  var types = require('./types-CRS-srZK.cjs');
51
52
  var tmuxSocket = require('./tmuxSocket-D-Xt6Vn-.cjs');
52
- var sessionLock = require('./sessionLock-DfhNICyS.cjs');
53
+ var sessionLock = require('./sessionLock-BFD8cFNP.cjs');
53
54
  var doctor$1 = require('./doctor-u46qYYKX.cjs');
54
55
  var resources = require('./resources-JDPugcDq.cjs');
55
56
  var node_util = require('node:util');
56
57
  var index = require('./index-C9hI8a10.cjs');
57
- var client = require('./client-DJ0kX_8M.cjs');
58
58
  var template = require('./template-BaHAmH2K.cjs');
59
59
  var loginShellEnv = require('./loginShellEnv-BkuYtExZ.cjs');
60
- require('./sessionModeFile-CIznKD7O.cjs');
61
- require('./lidState-D8BmnJV1.cjs');
60
+ require('./sessionModeFile-i-MVQRcU.cjs');
61
+ require('./lidState-2IT0tas7.cjs');
62
62
  require('os');
63
63
  require('node:events');
64
64
  require('socket.io-client');
65
- require('./attachmentLimits-BfgKV5iE.cjs');
65
+ require('./attachmentLimits-BEYEEBm8.cjs');
66
66
  require('./limits-C-a7gr04.cjs');
67
- require('./time-T0YmeOhS.cjs');
68
- require('./registerCommonHandlers-Aha_KfM3.cjs');
67
+ require('./time-uSKpEhew.cjs');
68
+ require('./registerCommonHandlers-COSTo15G.cjs');
69
69
  require('util');
70
70
  require('crypto');
71
71
  require('cross-spawn');
@@ -73,12 +73,12 @@ require('@paralleldrive/cuid2');
73
73
  require('./contentLogMetadata-ZSFk_NjQ.cjs');
74
74
  require('chalk');
75
75
  require('tweetnacl');
76
- require('./browser-CcG8GLRV.cjs');
76
+ require('./browser-CeekQeKt.cjs');
77
77
  require('open');
78
78
  require('./ids-B6ZC0HGt.cjs');
79
79
  require('url');
80
80
  require('./detectCLI-DR9ZaN6B.cjs');
81
- require('./localHappyAgentAuth-d7B6S_o7.cjs');
81
+ require('./localHappyAgentAuth-CPMh61Su.cjs');
82
82
  require('ps-list');
83
83
 
84
84
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
@@ -418,6 +418,29 @@ function isAuthorizedDaemonControlRequest(authorization, controlToken) {
418
418
  return configuredTokenIsUsable && node_crypto.timingSafeEqual(expectedDigest, candidateDigest);
419
419
  }
420
420
 
421
+ const WrapperIdleSnapshotSchema = z.z.object({
422
+ flavor: z.z.string().max(64),
423
+ resumable: z.z.boolean(),
424
+ uiSession: z.z.boolean(),
425
+ variant: z.z.string().max(64).optional(),
426
+ spawnedBy: z.z.string().max(64).optional(),
427
+ tags: z.z.array(z.z.string().max(128)).max(64).optional(),
428
+ keepAwake: z.z.boolean(),
429
+ keepAwakeSetting: z.z.boolean().optional(),
430
+ thinking: z.z.boolean(),
431
+ queuedInputs: z.z.number().int().nonnegative(),
432
+ waitingForInput: z.z.boolean(),
433
+ pendingRequests: z.z.number().int().nonnegative(),
434
+ backgroundTasks: z.z.number().int().nonnegative(),
435
+ scheduledWakeups: z.z.number().int().nonnegative().optional(),
436
+ lastActivityAt: z.z.number(),
437
+ exiting: z.z.boolean().optional()
438
+ }).passthrough();
439
+ const HibernateCheckBodySchema = z.z.object({
440
+ sessionId: z.z.string().min(1).max(200),
441
+ pid: z.z.number().int().positive(),
442
+ report: WrapperIdleSnapshotSchema
443
+ });
421
444
  const BackgroundTaskInfoSchema = z.z.object({
422
445
  id: z.z.string().min(1).max(200),
423
446
  type: z.z.string().max(64),
@@ -451,7 +474,8 @@ function startDaemonControlServer({
451
474
  onSessionEdit,
452
475
  listPeers,
453
476
  isTurnActive,
454
- onRateLimits
477
+ onRateLimits,
478
+ onHibernateCheck
455
479
  }) {
456
480
  return new Promise((resolve) => {
457
481
  const app = fastify({
@@ -534,6 +558,29 @@ function startDaemonControlServer({
534
558
  onSessionStateEvent?.(sessionId, event, spawnedBy);
535
559
  return { status: "ok" };
536
560
  });
561
+ if (onHibernateCheck) {
562
+ typed.post("/session-hibernate-check", {
563
+ schema: {
564
+ body: HibernateCheckBodySchema,
565
+ response: {
566
+ 200: z.z.object({
567
+ hibernate: z.z.boolean(),
568
+ reason: z.z.string().optional(),
569
+ idleMs: z.z.number().optional(),
570
+ nextCheckMs: z.z.number().optional(),
571
+ keepAwake: z.z.boolean().optional()
572
+ })
573
+ }
574
+ }
575
+ }, async (request) => {
576
+ try {
577
+ return await onHibernateCheck(request.body);
578
+ } catch (error) {
579
+ logger.logger.debug("[CONTROL SERVER] hibernate check failed:", error);
580
+ return { hibernate: false, reason: "error" };
581
+ }
582
+ });
583
+ }
537
584
  typed.post("/list", {
538
585
  schema: {
539
586
  response: {
@@ -2413,6 +2460,133 @@ function createUpdateController(deps) {
2413
2460
  return { refresh, retry, request, tick, withHandover, holdHandover, isRunning: () => running };
2414
2461
  }
2415
2462
 
2463
+ const AUTOMATION_BINDINGS_TTL_MS = 10 * 60 * 1e3;
2464
+ const HIBERNATION_IN_FLIGHT_MS = 6e4;
2465
+ const HIBERNATION_EXIT_WAIT_MS = 15e3;
2466
+ async function waitForPidsToExit(pids, isAlive, timeoutMs = HIBERNATION_EXIT_WAIT_MS, sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)), now = Date.now) {
2467
+ const deadline = now() + timeoutMs;
2468
+ while (pids.some(isAlive)) {
2469
+ if (now() >= deadline) return false;
2470
+ await sleep(100);
2471
+ }
2472
+ return true;
2473
+ }
2474
+ function createDaemonHibernation(deps) {
2475
+ const now = () => (deps.now ?? Date.now)();
2476
+ const signatures = /* @__PURE__ */ new Map();
2477
+ const approved = /* @__PURE__ */ new Map();
2478
+ let bindings = null;
2479
+ let bindingsInFlight = null;
2480
+ async function automationBound(fresh = false) {
2481
+ if (!fresh && bindings && now() - bindings.at < AUTOMATION_BINDINGS_TTL_MS) return bindings.ids;
2482
+ if (fresh && bindingsInFlight) await bindingsInFlight;
2483
+ if (!bindingsInFlight) {
2484
+ bindingsInFlight = deps.loadAutomationBindings().then((ids) => {
2485
+ bindings = { at: now(), ids: new Set(ids) };
2486
+ return bindings.ids;
2487
+ }).catch((error) => {
2488
+ deps.log?.(`[hibernate] automation bindings unknown: ${error instanceof Error ? error.message : String(error)}`);
2489
+ return null;
2490
+ }).finally(() => {
2491
+ bindingsInFlight = null;
2492
+ });
2493
+ }
2494
+ return bindingsInFlight;
2495
+ }
2496
+ function inFlight(except) {
2497
+ const t = now();
2498
+ for (const [id, at] of approved) {
2499
+ if (t - at > HIBERNATION_IN_FLIGHT_MS) approved.delete(id);
2500
+ else if (id !== except) return true;
2501
+ }
2502
+ return false;
2503
+ }
2504
+ async function check(request) {
2505
+ const idleMs = deps.idleMs();
2506
+ const t = now();
2507
+ const tracked = deps.tracked(request.sessionId, request.pid);
2508
+ const latchedBefore = deps.readKeepAwake?.(request.sessionId) ?? false;
2509
+ const latched = persistence.latchKeepAwake(request.report.keepAwakeSetting, latchedBefore || request.report.keepAwake);
2510
+ if (latched !== latchedBefore) deps.writeKeepAwake?.(request.sessionId, latched);
2511
+ if (latched && !request.report.keepAwake) request = { ...request, report: { ...request.report, keepAwake: true } };
2512
+ const signature = persistence.reportSignature(request.report);
2513
+ const previousSignature = signatures.get(request.sessionId);
2514
+ signatures.set(request.sessionId, signature);
2515
+ const base = {
2516
+ idleMs,
2517
+ now: t,
2518
+ sessionId: request.sessionId,
2519
+ pid: request.pid,
2520
+ report: request.report,
2521
+ trackedLive: !!tracked?.live,
2522
+ trackedSpawnedBy: tracked?.spawnedBy,
2523
+ teamsMember: deps.teamsMember(request.sessionId),
2524
+ turnActive: deps.turnActive(request.sessionId),
2525
+ backgroundTasks: deps.backgroundTasks(request.sessionId),
2526
+ previousSignature,
2527
+ hibernationInFlight: inFlight(request.sessionId)
2528
+ };
2529
+ let verdict = persistence.decideDaemonHibernation({ ...base, automationBound: /* @__PURE__ */ new Set() });
2530
+ if (verdict.ok || verdict.reason === "unconfirmed" || verdict.reason === "busy") {
2531
+ verdict = persistence.decideDaemonHibernation({ ...base, automationBound: await automationBound() });
2532
+ }
2533
+ if (verdict.ok) {
2534
+ verdict = persistence.decideDaemonHibernation({ ...base, automationBound: await automationBound(true) });
2535
+ }
2536
+ if (verdict.ok) {
2537
+ approved.set(request.sessionId, t);
2538
+ signatures.delete(request.sessionId);
2539
+ deps.log?.(`[hibernate] approved ${request.sessionId} (pid ${request.pid}, idle ${Math.round((t - request.report.lastActivityAt) / 1e3)}s)`);
2540
+ return { hibernate: true, idleMs, ...latched ? { keepAwake: true } : {} };
2541
+ }
2542
+ const next = verdict.reason === "unconfirmed" ? deps.checkMs : persistence.nextCheckDelay(verdict, request.report, idleMs, deps.checkMs, t);
2543
+ return { hibernate: false, reason: verdict.reason, idleMs, nextCheckMs: next, ...latched ? { keepAwake: true } : {} };
2544
+ }
2545
+ return {
2546
+ check,
2547
+ /** Called when the wrapper exits: true when this exit is the hibernation we approved. */
2548
+ consumeExit(sessionId) {
2549
+ const at = approved.get(sessionId);
2550
+ approved.delete(sessionId);
2551
+ signatures.delete(sessionId);
2552
+ return at !== void 0 && now() - at <= HIBERNATION_IN_FLIGHT_MS * 5;
2553
+ },
2554
+ /** Review P1-2: an approved hibernation whose wrapper has not exited yet. */
2555
+ pendingExit(sessionId) {
2556
+ const at = approved.get(sessionId);
2557
+ return at !== void 0 && now() - at <= HIBERNATION_IN_FLIGHT_MS * 5;
2558
+ },
2559
+ forget(sessionId) {
2560
+ signatures.delete(sessionId);
2561
+ },
2562
+ /** Drop the cached Automations bindings (e.g. after the setting changed). */
2563
+ invalidateBindings() {
2564
+ bindings = null;
2565
+ }
2566
+ };
2567
+ }
2568
+ async function collectAutomationBindings(client, machineId) {
2569
+ const ids = /* @__PURE__ */ new Set();
2570
+ const automations = await client.list(machineId);
2571
+ for (const automation of automations) {
2572
+ const action = automation.action;
2573
+ if (action?.kind === "send" && typeof action.sessionId === "string") ids.add(action.sessionId);
2574
+ if (action?.kind === "spawn" && action.sticky) {
2575
+ for (const sticky of await client.stickies(automation.id)) ids.add(sticky.sessionId);
2576
+ }
2577
+ }
2578
+ return [...ids];
2579
+ }
2580
+ const AUTOMATION_WAKE_TIMEOUT_MS = 6e4;
2581
+ async function waitForSessionLive(sessionId, live, timeoutMs = AUTOMATION_WAKE_TIMEOUT_MS, sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)), now = Date.now) {
2582
+ const deadline = now() + timeoutMs;
2583
+ while (!live(sessionId)) {
2584
+ if (now() >= deadline) return false;
2585
+ await sleep(250);
2586
+ }
2587
+ return true;
2588
+ }
2589
+
2416
2590
  const CLAUDE_KEYCHAIN_SERVICE_PREFIX = "Claude Code";
2417
2591
  function keychainIdentity(env = process.env, deps = {}) {
2418
2592
  const home = deps.home ?? os.homedir();
@@ -2476,7 +2650,7 @@ function parseJsonObject(text) {
2476
2650
  return null;
2477
2651
  }
2478
2652
  }
2479
- function resolveSdkClaudeBinary(platform = process.platform, arch = process.arch, resolver = (s) => module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('run-Bh66Xs40.cjs', document.baseURI).href))).resolve(s)) {
2653
+ function resolveSdkClaudeBinary(platform = process.platform, arch = process.arch, resolver = (s) => module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('run-BKTv1E-D.cjs', document.baseURI).href))).resolve(s)) {
2480
2654
  const platformArch = `${platform}-${arch}`;
2481
2655
  const candidates = [
2482
2656
  `@anthropic-ai/claude-agent-sdk-${platformArch}/claude`,
@@ -3558,7 +3732,7 @@ function writeReceipt$1(home, receipt) {
3558
3732
 
3559
3733
  const exec = node_util.promisify(node_child_process.execFile);
3560
3734
  const git = async (directory, args) => (await exec("git", ["-C", directory, ...args], { timeout: 3e4, maxBuffer: 2 * 1024 * 1024 })).stdout.trim();
3561
- async function prepareTeamWorktree(home, repository, id) {
3735
+ async function prepareTeamWorktree(home, repository, id, origin = "teams") {
3562
3736
  if (repository === "~") repository = os.homedir();
3563
3737
  else if (repository.startsWith("~/") || process.platform === "win32" && repository.startsWith("~\\")) repository = path.join(os.homedir(), repository.slice(2));
3564
3738
  if (!path.isAbsolute(repository) || !/^[a-zA-Z0-9_-]{1,128}$/.test(id)) throw new Error("A team task requires an absolute repository path and valid operation id");
@@ -3575,6 +3749,7 @@ async function prepareTeamWorktree(home, repository, id) {
3575
3749
  if (path.resolve(common) !== path.resolve(expected)) throw new Error("Team worktree belongs to another repository");
3576
3750
  } else {
3577
3751
  await git(repository, ["worktree", "add", "-b", branch, directory, "HEAD"]);
3752
+ await mirrorProtocol.initializeOwnedWorktree({ source: repository, worktree: directory, branch, origin });
3578
3753
  }
3579
3754
  return { directory, repository, branch };
3580
3755
  }
@@ -4222,6 +4397,35 @@ function createAutomationRunner(deps) {
4222
4397
  }
4223
4398
  })();
4224
4399
  }
4400
+ function wakeThenSend(claimed, sessionId, text, stickyKey) {
4401
+ const { run, automation } = claimed;
4402
+ const item = track(claimed, "send", sessionId);
4403
+ item.waking = true;
4404
+ gating++;
4405
+ void (async () => {
4406
+ try {
4407
+ const woke = await deps.wakeHibernated(sessionId).catch(() => false);
4408
+ if (!tracked.has(run.id) || closed) return;
4409
+ item.waking = false;
4410
+ if (!woke || !deps.live(sessionId)) {
4411
+ await finish(item, { claimId: run.claimId, status: "failed", sessionId, error: `Session ${sessionId} was hibernated and could not be woken in time`, needsAttention: true, attentionReason: "session_wake_failed" });
4412
+ return;
4413
+ }
4414
+ persist({ runId: run.id, automationId: automation.id, kind: "send", phase: "running", claimId: run.claimId, sessionId, ...stickyKey ? { stickyKey } : {} });
4415
+ try {
4416
+ await send(sessionId, text, { localId: `automation-${run.id}` });
4417
+ } catch (error) {
4418
+ await finish(item, { claimId: run.claimId, status: "failed", sessionId, error: template.clipText(`Message delivery failed: ${error instanceof Error ? error.message : String(error)}`, index.AUTOMATION_SUMMARY_MAX_CHARS), needsAttention: true, attentionReason: "send_failed" });
4419
+ return;
4420
+ }
4421
+ await reportRunning(item, sessionId, stickyKey);
4422
+ } finally {
4423
+ item.waking = false;
4424
+ gating--;
4425
+ }
4426
+ })();
4427
+ }
4428
+ const wakeable = (sessionId) => !deps.live(sessionId) && !!deps.wakeHibernated && deps.isHibernated?.(sessionId) === true;
4225
4429
  async function perform(claimed, action, context, env) {
4226
4430
  const { run, automation } = claimed;
4227
4431
  const header = automationPromptHeader(automation.name, run.id);
@@ -4249,6 +4453,11 @@ function createAutomationRunner(deps) {
4249
4453
  return;
4250
4454
  }
4251
4455
  if (action.kind === "send") {
4456
+ if (wakeable(action.sessionId)) {
4457
+ wakeThenSend(claimed, action.sessionId, `${header}
4458
+ ${action.prompt}`);
4459
+ return;
4460
+ }
4252
4461
  if (!deps.live(action.sessionId)) {
4253
4462
  await failNow(claimed, "send", `Session ${action.sessionId} is not running on this machine`, "session_not_live", action.sessionId);
4254
4463
  return;
@@ -4277,6 +4486,11 @@ ${action.prompt}`, { localId: `automation-${run.id}` });
4277
4486
  const stickyKey = action.sticky ? template.renderTemplate(action.sticky.key, context) : void 0;
4278
4487
  if (stickyKey) {
4279
4488
  const bound = claimed.stickies.find((sticky) => sticky.key === stickyKey);
4489
+ if (bound && wakeable(bound.sessionId)) {
4490
+ wakeThenSend(claimed, bound.sessionId, `${header}
4491
+ ${action.prompt}`, stickyKey);
4492
+ return;
4493
+ }
4280
4494
  if (bound && deps.live(bound.sessionId)) {
4281
4495
  persist({ runId: run.id, automationId: automation.id, kind: "send", phase: "running", claimId: run.claimId, sessionId: bound.sessionId, stickyKey });
4282
4496
  try {
@@ -4298,7 +4512,7 @@ ${action.prompt}`, { localId: `automation-${run.id}` });
4298
4512
  }
4299
4513
  if (action.worktree) {
4300
4514
  try {
4301
- directory = (await prepareWorktree(home, directory, `auto-${run.id}`)).directory;
4515
+ directory = (await prepareWorktree(home, directory, `auto-${run.id}`, "automation")).directory;
4302
4516
  } catch (error) {
4303
4517
  await failNow(claimed, "spawn", `Worktree preparation failed: ${error instanceof Error ? error.message : String(error)}`, "worktree_failed");
4304
4518
  return;
@@ -4330,7 +4544,7 @@ ${action.prompt}`, { localId: `automation-${run.id}`, ...meta });
4330
4544
  await finish(item, item.pendingFinal);
4331
4545
  continue;
4332
4546
  }
4333
- if (item.kind === "script") continue;
4547
+ if (item.kind === "script" || item.waking) continue;
4334
4548
  const sessionId = item.sessionId;
4335
4549
  const active = deps.turnActive(sessionId);
4336
4550
  if (active) item.sawTurn = true;
@@ -4548,6 +4762,7 @@ async function startDaemon() {
4548
4762
  let cliUpdateStateRef = null;
4549
4763
  let lastHandoverHold = null;
4550
4764
  let claudeCredentialStoreSetting = (await persistence.readSettings()).claudeCredentialStore === "file" ? "file" : "auto";
4765
+ let agentHibernationSetting = (await persistence.readSettings()).agentHibernationIdleMs;
4551
4766
  try {
4552
4767
  const homes = await index$1.refreshAgentHomes();
4553
4768
  logger.logger.debug(`[DAEMON RUN] Claude config dir: ${loginShellEnv.describeAgentHome(homes.claudeConfigDir)}; Codex home: ${loginShellEnv.describeAgentHome(homes.codexHome)}`);
@@ -4634,6 +4849,40 @@ async function startDaemon() {
4634
4849
  const turnActivity = new api.TurnActivityTracker();
4635
4850
  const backgroundTasks = new backgroundTaskActivity.BackgroundTaskTracker();
4636
4851
  const peerCoordinator = createPeerCoordinator({ getChildren: () => Array.from(pidToTrackedSession.values()) });
4852
+ const hibernationAutomations = client.createAutomationsClient({ serverUrl: configuration.configuration.serverUrl, token: credentials.token, client: "daemon-hibernate" });
4853
+ const daemonHibernation = createDaemonHibernation({
4854
+ idleMs: () => persistence.resolveIdleMs(agentHibernationSetting),
4855
+ checkMs: persistence.resolveCheckMs(),
4856
+ tracked: (sessionId, pid) => {
4857
+ const tracked = pidToTrackedSession.get(pid);
4858
+ if (!tracked || tracked.happySessionId !== sessionId) return null;
4859
+ let live = false;
4860
+ try {
4861
+ process.kill(pid, 0);
4862
+ live = true;
4863
+ } catch {
4864
+ live = false;
4865
+ }
4866
+ return { live, ...tracked.spawnedBy ? { spawnedBy: tracked.spawnedBy } : {} };
4867
+ },
4868
+ teamsMember: (sessionId) => teamWorker?.hasSession(sessionId) === true,
4869
+ turnActive: (sessionId) => turnActivity.activeSessions().includes(sessionId),
4870
+ backgroundTasks: (sessionId) => backgroundTasks.count(sessionId),
4871
+ loadAutomationBindings: async () => {
4872
+ try {
4873
+ return await collectAutomationBindings(hibernationAutomations, machineId);
4874
+ } catch (error) {
4875
+ if (client.isAutomationsUnavailable(error)) return [];
4876
+ throw error;
4877
+ }
4878
+ },
4879
+ log: (message) => logger.logger.debug(`[DAEMON RUN] ${message}`),
4880
+ readKeepAwake: (sessionId) => persistence.readPersistedSessions()[sessionId]?.keepAwake === true,
4881
+ writeKeepAwake: (sessionId, value) => {
4882
+ const record = persistence.readPersistedSessions()[sessionId];
4883
+ if (record) persistence.persistSession(sessionId, { ...record, keepAwake: value || void 0 });
4884
+ }
4885
+ });
4637
4886
  const sessionIdToFinishedSession = /* @__PURE__ */ new Map();
4638
4887
  let teamWorker;
4639
4888
  let automationRunner;
@@ -5247,6 +5496,13 @@ async function startDaemon() {
5247
5496
  };
5248
5497
  const resumeSessionImpl = async (happySessionId, options) => {
5249
5498
  try {
5499
+ if (daemonHibernation.pendingExit(happySessionId)) {
5500
+ const dying = [...pidToTrackedSession.entries()].filter(([, s]) => s.happySessionId === happySessionId).map(([pid]) => pid);
5501
+ const exited = await waitForPidsToExit(dying, isPidAlive);
5502
+ logger.logger.debug(`[DAEMON RUN] resume ${happySessionId}: waited for hibernating wrapper(s) ${dying.join(", ")} \u2192 ${exited ? "exited" : "still alive after timeout"}`);
5503
+ if (!exited) return { type: "error", errorMessage: `Session ${happySessionId} is still going to sleep; try again in a few seconds.` };
5504
+ for (const pid of dying) if (pidToTrackedSession.has(pid)) onChildExited(pid);
5505
+ }
5250
5506
  for (const [pid, live] of pidToTrackedSession.entries()) {
5251
5507
  if (live.happySessionId !== happySessionId) continue;
5252
5508
  if (isPidAlive(pid)) {
@@ -5507,6 +5763,14 @@ async function startDaemon() {
5507
5763
  if (session?.happySessionId) turnActivity.forget(session.happySessionId);
5508
5764
  if (session?.happySessionId) backgroundTasks.forget(session.happySessionId);
5509
5765
  if (session?.happySessionId) peerCoordinator.forget(session.happySessionId);
5766
+ if (session?.happySessionId && daemonHibernation.consumeExit(session.happySessionId)) {
5767
+ const persisted2 = persistence.readPersistedSessions()[session.happySessionId];
5768
+ if (persisted2) {
5769
+ const at = Date.now();
5770
+ persistence.persistSession(session.happySessionId, { ...persisted2, savedAt: at, hibernatedAt: at });
5771
+ }
5772
+ logger.logger.debug(`[DAEMON RUN] Session ${session.happySessionId} hibernated (PID ${pid} exited)`);
5773
+ }
5510
5774
  if (session?.happySessionId && session.encryption) {
5511
5775
  sessionIdToFinishedSession.set(session.happySessionId, session);
5512
5776
  logger.logger.debug(`[DAEMON RUN] Process PID ${pid} exited, preserved session ${session.happySessionId} for resume`);
@@ -5602,6 +5866,7 @@ async function startDaemon() {
5602
5866
  onRateLimits: (report) => {
5603
5867
  apiMachineRef?.reportRateLimits(report);
5604
5868
  },
5869
+ onHibernateCheck: (body) => daemonHibernation.check(body),
5605
5870
  listPeers: () => peerCoordinator.list(),
5606
5871
  // B-505: `daemon list` shows which sessions have a turn in flight, so an
5607
5872
  // operator can check the WHOLE machine before a supervised restart.
@@ -5723,6 +5988,13 @@ async function startDaemon() {
5723
5988
  setStore: (store) => claudeAuthService.setStore(store)
5724
5989
  });
5725
5990
  claudeAuthService.start();
5991
+ apiMachine.setAgentHibernationHandlers(persistence.resolveIdleMs(agentHibernationSetting), async (requested) => {
5992
+ const value = requested <= 0 ? 0 : persistence.settingIdleMs(requested);
5993
+ await persistence.updateSettings((current) => ({ ...current, agentHibernationIdleMs: value }));
5994
+ agentHibernationSetting = value;
5995
+ daemonHibernation.invalidateBindings();
5996
+ return persistence.resolveIdleMs(agentHibernationSetting);
5997
+ });
5726
5998
  apiMachine.connect();
5727
5999
  if (identityConflict?.confidence === "weak") {
5728
6000
  void apiMachine.updateMachineMetadata((current) => ({
@@ -5870,18 +6142,32 @@ async function startDaemon() {
5870
6142
  live: (id) => [...pidToTrackedSession.values()].some((s) => s.happySessionId === id && isPidAlive(s.pid)),
5871
6143
  turnActive: (id) => turnActivity.activeSessions().includes(id),
5872
6144
  backgroundTasks: (id) => backgroundTasks.count(id),
6145
+ // B-587 review P2-5: a hibernated target is woken (resume) and the send
6146
+ // waits until its wrapper is back; anything else stays session_not_live.
6147
+ isHibernated: (id) => {
6148
+ const record = persistence.readPersistedSessions()[id];
6149
+ return !!record && typeof record.hibernatedAt === "number" && record.hibernatedAt >= record.savedAt;
6150
+ },
6151
+ wakeHibernated: async (id) => {
6152
+ const result = await resumeSession(id);
6153
+ if (result.type !== "success") return false;
6154
+ return waitForSessionLive(id, (sid) => [...pidToTrackedSession.values()].some((s) => s.happySessionId === sid && isPidAlive(s.pid)));
6155
+ },
5873
6156
  log: (message) => logger.logger.debug(`[DAEMON RUN] ${message}`)
5874
6157
  });
5875
6158
  void apiMachine.updateMachineMetadata((current) => ({
5876
6159
  ...current ?? initialMachineMetadata,
5877
6160
  teamsVersion: 1,
5878
- teamLaunchVersion: 1
6161
+ teamLaunchVersion: 1,
6162
+ // B-586: this daemon serves the worktree-* RPCs (web gates 「在新 worktree 中」 on it).
6163
+ worktreeVersion: mirrorProtocol.WORKTREE_CAPABILITY_VERSION
5879
6164
  })).catch(() => logger.logger.debug("[DAEMON RUN] Teams capability publication will retry on reconnect"));
5880
6165
  const cleanupAndShutdown = async (source, errorMessage) => {
5881
6166
  logger.logger.debug(`[DAEMON RUN] Starting proper cleanup (source: ${source}, errorMessage: ${errorMessage})...`);
5882
6167
  const scrollbackFlush = apiMachine.flushTerminalScrollback();
5883
6168
  teamWorker?.stop();
5884
6169
  automationRunner?.stop({ killScripts: true });
6170
+ mirrorProtocol.currentWorktreeService()?.stopAll();
5885
6171
  if (restartOnStaleVersionAndHeartbeat) {
5886
6172
  clearInterval(restartOnStaleVersionAndHeartbeat);
5887
6173
  logger.logger.debug("[DAEMON RUN] Health check interval cleared");