@code-yeongyu/senpi 2026.10.18-1 → 2026.10.19

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 (154) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/bundle/chunks/{anthropic-messages-3CFTFCKV.js → anthropic-messages-EMTBHJMM.js} +2 -2
  3. package/dist/bundle/chunks/{args-SJWMIH2H.js → args-LWR7VFKS.js} +1 -1
  4. package/dist/bundle/chunks/{chunk-IRKZ6FVC.js → chunk-35M5MVUZ.js} +149 -145
  5. package/dist/bundle/chunks/chunk-3DNYAO3P.js +2 -0
  6. package/dist/bundle/chunks/{chunk-T2BEB5SO.js → chunk-7QPFFAJT.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-4RUVN7K3.js → chunk-BOCN744P.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-DDHBG2HU.js → chunk-FM7NDZR5.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-OMY4EC25.js → chunk-FSENE7JK.js} +2 -2
  10. package/dist/bundle/chunks/{chunk-Z2LCTXS2.js → chunk-G7LLAQXI.js} +3 -3
  11. package/dist/bundle/chunks/{chunk-NRHOGI4Z.js → chunk-IM6ZWYTW.js} +2 -2
  12. package/dist/bundle/chunks/{chunk-MLKYJIUK.js → chunk-KM4FMQII.js} +1 -1
  13. package/dist/bundle/chunks/{chunk-OOWML2KE.js → chunk-PMGEQYEP.js} +2 -2
  14. package/dist/bundle/chunks/chunk-QGJLZ6BI.js +2 -0
  15. package/dist/bundle/chunks/{chunk-6EXDMO4S.js → chunk-QJ6MUFXY.js} +1 -1
  16. package/dist/bundle/chunks/{chunk-FZTO2ICI.js → chunk-QRGAMVEE.js} +1 -1
  17. package/dist/bundle/chunks/{chunk-3QVP3ZVI.js → chunk-QXEWAKXA.js} +1 -1
  18. package/dist/bundle/chunks/{chunk-UUMKAA7S.js → chunk-RL5QMGQD.js} +9 -9
  19. package/dist/bundle/chunks/chunk-T36LJ6MW.js +3 -0
  20. package/dist/bundle/chunks/{chunk-GAHIHXVE.js → chunk-VEKNDMUA.js} +1 -1
  21. package/dist/bundle/chunks/{chunk-TFXUF2IL.js → chunk-VPV7ADF3.js} +1 -1
  22. package/dist/bundle/chunks/{chunk-RELAITQ7.js → chunk-X6TWPBI6.js} +1 -1
  23. package/dist/bundle/chunks/{chunk-PKDWFVE4.js → chunk-YUMRZIKJ.js} +6 -6
  24. package/dist/bundle/chunks/chunk-ZPSJQHDK.js +395 -0
  25. package/dist/bundle/chunks/{cli-main-JCSB54VT.js → cli-main-EABMHWFV.js} +1 -1
  26. package/dist/bundle/chunks/{help-fast-path-FVPGRSYA.js → help-fast-path-BYWJN6YX.js} +1 -1
  27. package/dist/bundle/chunks/{host-command-X2ZZFTME.js → host-command-5T34JLBP.js} +1 -1
  28. package/dist/bundle/chunks/{host-lifecycle-OKWTQFUJ.js → host-lifecycle-GSRIQP6Z.js} +1 -1
  29. package/dist/bundle/chunks/host-lifecycle.js +1 -1
  30. package/dist/bundle/chunks/{host-session-command-HKJKOAVS.js → host-session-command-LF6JODPX.js} +1 -1
  31. package/dist/bundle/chunks/{interactive-mode-GJERAFGV.js → interactive-mode-GMWHBIUC.js} +1 -1
  32. package/dist/bundle/chunks/{list-tips-AWDAUHF2.js → list-tips-VSWED3PT.js} +1 -1
  33. package/dist/bundle/chunks/{multi-session-host-JWMGLKAG.js → multi-session-host-3J7STKGD.js} +4 -4
  34. package/dist/bundle/chunks/{openai-codex-responses-RLYFSLK6.js → openai-codex-responses-7YOBPZ2N.js} +1 -1
  35. package/dist/bundle/chunks/{openai-completions-OWNSXMTD.js → openai-completions-HSZPYXEA.js} +1 -1
  36. package/dist/bundle/chunks/{package-manager-cli-FSVS2ND2.js → package-manager-cli-LWQZSWKL.js} +1 -1
  37. package/dist/bundle/chunks/{rotation-stream-M6QV2MMB.js → rotation-stream-QRRWL73X.js} +1 -1
  38. package/dist/bundle/chunks/{rpc-mode-TPG3J3ZJ.js → rpc-mode-6LSWRKXR.js} +1 -1
  39. package/dist/bundle/chunks/{schedule-command-PAVLVMWL.js → schedule-command-7CXMW4WK.js} +1 -1
  40. package/dist/bundle/chunks/{session-control-endpoint-NSMRMKKK.js → session-control-endpoint-E265WAIQ.js} +1 -1
  41. package/dist/bundle/chunks/{session-picker-UV6IVWJY.js → session-picker-XRB3LP5W.js} +1 -1
  42. package/dist/bundle/chunks/session-worker.js +298 -293
  43. package/dist/bundle/cli.js +2 -2
  44. package/dist/bundle/index.js +1 -1
  45. package/dist/bundle/rpc-entry.js +1 -1
  46. package/dist/bundle/runtime-manifest.json +1 -1
  47. package/dist/core/agent-run-continuation.d.ts +24 -0
  48. package/dist/core/agent-run-continuation.js +57 -0
  49. package/dist/core/agent-session.d.ts +38 -1
  50. package/dist/core/agent-session.js +122 -13
  51. package/dist/core/extension-handler-stall-report.d.ts +11 -0
  52. package/dist/core/extension-handler-stall-report.js +26 -0
  53. package/dist/core/extensions/builtin/anthropic-subscription/account-command.js +1 -0
  54. package/dist/core/extensions/builtin/anthropic-subscription/affinity.d.ts +13 -1
  55. package/dist/core/extensions/builtin/anthropic-subscription/affinity.js +15 -4
  56. package/dist/core/extensions/builtin/anthropic-subscription/auth-lane.js +2 -0
  57. package/dist/core/extensions/builtin/anthropic-subscription/failover.d.ts +2 -0
  58. package/dist/core/extensions/builtin/anthropic-subscription/failover.js +3 -2
  59. package/dist/core/extensions/builtin/anthropic-subscription/guidance.d.ts +8 -0
  60. package/dist/core/extensions/builtin/anthropic-subscription/guidance.js +29 -0
  61. package/dist/core/extensions/builtin/anthropic-subscription/settings.d.ts +2 -0
  62. package/dist/core/extensions/builtin/anthropic-subscription/settings.js +4 -0
  63. package/dist/core/extensions/builtin/anthropic-subscription/stream-guidance.js +4 -2
  64. package/dist/core/extensions/handler-budget.d.ts +84 -0
  65. package/dist/core/extensions/handler-budget.js +136 -0
  66. package/dist/core/extensions/runner.d.ts +23 -0
  67. package/dist/core/extensions/runner.js +184 -99
  68. package/dist/core/footer-data-provider.js +2 -1
  69. package/dist/core/keybindings.d.ts +1 -1
  70. package/dist/core/keybindings.js +3 -2
  71. package/dist/core/pending-input-journal.d.ts +6 -1
  72. package/dist/core/pending-input-journal.js +90 -34
  73. package/dist/core/pending-input-public.d.ts +11 -0
  74. package/dist/core/pending-input-public.js +10 -0
  75. package/dist/core/pending-input-session-port.d.ts +15 -0
  76. package/dist/core/pending-input-session-port.js +93 -0
  77. package/dist/core/pending-input-session.d.ts +108 -0
  78. package/dist/core/pending-input-session.js +220 -0
  79. package/dist/core/pending-input-store.d.ts +32 -1
  80. package/dist/core/pending-input-store.js +74 -26
  81. package/dist/core/pending-input-types.d.ts +25 -4
  82. package/dist/core/pending-input.js +36 -18
  83. package/dist/core/session-entry-file.js +1 -0
  84. package/dist/core/session-log.js +1 -1
  85. package/dist/core/session-manager.d.ts +1 -0
  86. package/dist/core/session-manager.js +5 -1
  87. package/dist/core/session-move/bundle.d.ts +39 -0
  88. package/dist/core/session-move/bundle.js +108 -0
  89. package/dist/core/session-move/export.d.ts +18 -0
  90. package/dist/core/session-move/export.js +83 -0
  91. package/dist/core/session-move/finish.d.ts +24 -0
  92. package/dist/core/session-move/finish.js +81 -0
  93. package/dist/core/session-move/import.d.ts +32 -0
  94. package/dist/core/session-move/import.js +124 -0
  95. package/dist/core/session-move/move-ledger.d.ts +47 -0
  96. package/dist/core/session-move/move-ledger.js +151 -0
  97. package/dist/core/session-move/ownership.d.ts +61 -0
  98. package/dist/core/session-move/ownership.js +89 -0
  99. package/dist/core/session-move/requeue.d.ts +8 -0
  100. package/dist/core/session-move/requeue.js +18 -0
  101. package/dist/core/session-move/write-guard.d.ts +22 -0
  102. package/dist/core/session-move/write-guard.js +44 -0
  103. package/dist/core/settings-manager.d.ts +13 -0
  104. package/dist/core/settings-manager.js +17 -0
  105. package/dist/core/turn-deadline.d.ts +2 -0
  106. package/dist/core/turn-deadline.js +10 -3
  107. package/dist/modes/interactive/components/ask-user-async-widget.d.ts +7 -0
  108. package/dist/modes/interactive/components/ask-user-async-widget.js +20 -6
  109. package/dist/modes/rpc/connection-handler.js +3 -0
  110. package/dist/modes/rpc/effect-commands.js +3 -4
  111. package/dist/modes/rpc/host-observe-request.js +1 -0
  112. package/dist/modes/rpc/rpc-client.d.ts +10 -0
  113. package/dist/modes/rpc/rpc-client.js +11 -0
  114. package/dist/modes/rpc/rpc-input-validation.js +8 -0
  115. package/dist/modes/rpc/rpc-types.d.ts +25 -1
  116. package/dist/modes/rpc/session-command-activity.js +1 -0
  117. package/dist/modes/rpc/session-control-actions-data.js +17 -8
  118. package/dist/modes/rpc/session-held.js +1 -0
  119. package/dist/modes/rpc/session-release.js +16 -1
  120. package/dist/modes/rpc/tool-child/admission.d.ts +42 -0
  121. package/dist/modes/rpc/tool-child/admission.js +81 -0
  122. package/dist/modes/rpc/tool-child/admission.test.d.ts +2 -0
  123. package/dist/modes/rpc/tool-child/admission.test.js +166 -0
  124. package/dist/modes/rpc/tool-child/codec.d.ts +21 -0
  125. package/dist/modes/rpc/tool-child/codec.js +137 -0
  126. package/dist/modes/rpc/tool-child/codec.test.d.ts +2 -0
  127. package/dist/modes/rpc/tool-child/codec.test.js +234 -0
  128. package/dist/modes/rpc/tool-child/context.d.ts +42 -0
  129. package/dist/modes/rpc/tool-child/context.js +23 -0
  130. package/dist/modes/rpc/tool-child/flow-control.d.ts +24 -0
  131. package/dist/modes/rpc/tool-child/flow-control.js +80 -0
  132. package/dist/modes/rpc/tool-child/payload-ref-paths.d.ts +9 -0
  133. package/dist/modes/rpc/tool-child/payload-ref-paths.js +45 -0
  134. package/dist/modes/rpc/tool-child/payload-ref.d.ts +58 -0
  135. package/dist/modes/rpc/tool-child/payload-ref.js +166 -0
  136. package/dist/modes/rpc/tool-child/payload-ref.test.d.ts +2 -0
  137. package/dist/modes/rpc/tool-child/payload-ref.test.js +254 -0
  138. package/dist/modes/rpc/tool-child/payload-wire.d.ts +13 -0
  139. package/dist/modes/rpc/tool-child/payload-wire.js +22 -0
  140. package/dist/modes/rpc/tool-child/protocol-guard.d.ts +9 -0
  141. package/dist/modes/rpc/tool-child/protocol-guard.js +128 -0
  142. package/dist/modes/rpc/tool-child/protocol.d.ts +192 -0
  143. package/dist/modes/rpc/tool-child/protocol.js +54 -0
  144. package/dist/utils/wsl.d.ts +2 -2
  145. package/dist/utils/wsl.js +4 -4
  146. package/docs/providers.md +2 -0
  147. package/docs/rpc.md +16 -2
  148. package/docs/settings.md +1 -0
  149. package/docs/terminal-setup.md +2 -0
  150. package/package.json +10 -6
  151. package/dist/bundle/chunks/chunk-COJK5FDH.js +0 -2
  152. package/dist/bundle/chunks/chunk-IDXW4FAO.js +0 -2
  153. package/dist/bundle/chunks/chunk-PFNBY43W.js +0 -2
  154. package/dist/bundle/chunks/chunk-QBD4LY7D.js +0 -395
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
3
- import{enableStartupCompileCache}from"./chunk-MLKYJIUK.js";import{installStaleExtensionContainment,main}from"./chunk-IRKZ6FVC.js";import"./chunk-NRHOGI4Z.js";import"./chunk-5EPXJZ26.js";import"./chunk-SHKXJWK3.js";import{configureHttpDispatcher}from"./chunk-Z2LCTXS2.js";import"./chunk-KI2EEM4R.js";import"./chunk-IDXW4FAO.js";import"./chunk-QBD4LY7D.js";import"./chunk-MF57DS3V.js";import"./chunk-FZTO2ICI.js";import"./chunk-PKDWFVE4.js";import"./chunk-4RSWXPUB.js";import"./chunk-OJPUDLM2.js";import"./chunk-UUMKAA7S.js";import"./chunk-MX6VSFEY.js";import"./chunk-WIAXG52U.js";import"./chunk-QN2BHP3M.js";import"./chunk-AMKQSLWE.js";import"./chunk-RELAITQ7.js";import"./chunk-GAHIHXVE.js";import"./chunk-QMRJYMNH.js";import"./chunk-36GE6JDV.js";import"./chunk-VAUNLGQR.js";import"./chunk-H4QOEVS5.js";import"./chunk-HB35RBP4.js";import"./chunk-3QVP3ZVI.js";import"./chunk-OMY4EC25.js";import"./chunk-SMIIHUSE.js";import"./chunk-YU4AYH4C.js";import"./chunk-DDHBG2HU.js";import"./chunk-BIIMVCMO.js";import"./chunk-7X72IACK.js";import"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-OOWML2KE.js";import"./chunk-T2BEB5SO.js";import"./chunk-TFXUF2IL.js";import"./chunk-XC2CNM26.js";import"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-BMX2U22F.js";import"./chunk-YU2P3CAR.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import{installEarlyInspectorVmImportRecovery}from"./chunk-4RUVN7K3.js";import"./chunk-ZOFZRJSL.js";import"./chunk-2SOVDETB.js";import{APP_NAME,scrubBrandFromEnvironment}from"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-QXREUA5F.js";import"./chunk-WASCMT6Y.js";import"./chunk-COJK5FDH.js";import"./chunk-WHPDEDCC.js";import"./chunk-RUGYFYH7.js";import"./chunk-PFNBY43W.js";import"./chunk-OEFCY46F.js";import"./chunk-KRNXUTZJ.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-TAV6QZFM.js";import"./chunk-PELNNWGO.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";await enableStartupCompileCache();installEarlyInspectorVmImportRecovery();installStaleExtensionContainment();process.title=APP_NAME;scrubBrandFromEnvironment();process.env.PI_CODING_AGENT="true";process.emitWarning=(()=>{});configureHttpDispatcher();await main(process.argv.slice(2));
3
+ import{enableStartupCompileCache}from"./chunk-KM4FMQII.js";import{installStaleExtensionContainment,main}from"./chunk-35M5MVUZ.js";import"./chunk-IM6ZWYTW.js";import"./chunk-5EPXJZ26.js";import"./chunk-SHKXJWK3.js";import{configureHttpDispatcher}from"./chunk-G7LLAQXI.js";import"./chunk-KI2EEM4R.js";import"./chunk-3DNYAO3P.js";import"./chunk-ZPSJQHDK.js";import"./chunk-MF57DS3V.js";import"./chunk-QRGAMVEE.js";import"./chunk-YUMRZIKJ.js";import"./chunk-4RSWXPUB.js";import"./chunk-OJPUDLM2.js";import"./chunk-RL5QMGQD.js";import"./chunk-MX6VSFEY.js";import"./chunk-WIAXG52U.js";import"./chunk-QN2BHP3M.js";import"./chunk-AMKQSLWE.js";import"./chunk-X6TWPBI6.js";import"./chunk-VEKNDMUA.js";import"./chunk-QMRJYMNH.js";import"./chunk-36GE6JDV.js";import"./chunk-VAUNLGQR.js";import"./chunk-H4QOEVS5.js";import"./chunk-HB35RBP4.js";import"./chunk-QXEWAKXA.js";import"./chunk-FSENE7JK.js";import"./chunk-SMIIHUSE.js";import"./chunk-YU4AYH4C.js";import"./chunk-FM7NDZR5.js";import"./chunk-BIIMVCMO.js";import"./chunk-7X72IACK.js";import"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-PMGEQYEP.js";import"./chunk-7QPFFAJT.js";import"./chunk-VPV7ADF3.js";import"./chunk-XC2CNM26.js";import"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-BMX2U22F.js";import"./chunk-YU2P3CAR.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import{installEarlyInspectorVmImportRecovery}from"./chunk-BOCN744P.js";import"./chunk-ZOFZRJSL.js";import"./chunk-2SOVDETB.js";import{APP_NAME,scrubBrandFromEnvironment}from"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-QXREUA5F.js";import"./chunk-WASCMT6Y.js";import"./chunk-T36LJ6MW.js";import"./chunk-WHPDEDCC.js";import"./chunk-RUGYFYH7.js";import"./chunk-QGJLZ6BI.js";import"./chunk-OEFCY46F.js";import"./chunk-KRNXUTZJ.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-TAV6QZFM.js";import"./chunk-PELNNWGO.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";await enableStartupCompileCache();installEarlyInspectorVmImportRecovery();installStaleExtensionContainment();process.title=APP_NAME;scrubBrandFromEnvironment();process.env.PI_CODING_AGENT="true";process.emitWarning=(()=>{});configureHttpDispatcher();await main(process.argv.slice(2));
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{helpFlagsScope,isPlainHelpRequest,resolveHelpProjectTrust,tryPrintHelpWithoutEngine}from"./chunk-SHKXJWK3.js";import"./chunk-OJPUDLM2.js";import"./chunk-GZVCRV7I.js";import"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-OOWML2KE.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-COJK5FDH.js";import"./chunk-WHPDEDCC.js";import"./chunk-PFNBY43W.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";export{helpFlagsScope,isPlainHelpRequest,resolveHelpProjectTrust,tryPrintHelpWithoutEngine};
2
+ import{helpFlagsScope,isPlainHelpRequest,resolveHelpProjectTrust,tryPrintHelpWithoutEngine}from"./chunk-SHKXJWK3.js";import"./chunk-OJPUDLM2.js";import"./chunk-GZVCRV7I.js";import"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-PMGEQYEP.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-T36LJ6MW.js";import"./chunk-WHPDEDCC.js";import"./chunk-QGJLZ6BI.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";export{helpFlagsScope,isPlainHelpRequest,resolveHelpProjectTrust,tryPrintHelpWithoutEngine};
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{parseHostArgs,resolveHostSocket,runHostCommand}from"./chunk-RELAITQ7.js";import"./chunk-GAHIHXVE.js";import"./chunk-QMRJYMNH.js";import"./chunk-36GE6JDV.js";import"./chunk-DDHBG2HU.js";import"./chunk-KUPQO7MC.js";import"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-OOWML2KE.js";import"./chunk-T2BEB5SO.js";import"./chunk-TFXUF2IL.js";import"./chunk-XC2CNM26.js";import"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-COJK5FDH.js";import"./chunk-WHPDEDCC.js";import"./chunk-PFNBY43W.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";export{parseHostArgs,resolveHostSocket,runHostCommand};
2
+ import{parseHostArgs,resolveHostSocket,runHostCommand}from"./chunk-X6TWPBI6.js";import"./chunk-VEKNDMUA.js";import"./chunk-QMRJYMNH.js";import"./chunk-36GE6JDV.js";import"./chunk-FM7NDZR5.js";import"./chunk-KUPQO7MC.js";import"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-PMGEQYEP.js";import"./chunk-7QPFFAJT.js";import"./chunk-VPV7ADF3.js";import"./chunk-XC2CNM26.js";import"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-T36LJ6MW.js";import"./chunk-WHPDEDCC.js";import"./chunk-QGJLZ6BI.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";export{parseHostArgs,resolveHostSocket,runHostCommand};
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
3
- import{INTERNAL_SUPERVISOR_FLAG,classifyChildExit,createInternalSocketPath,findInternalSupervisorArgs,parseSupervisorArgs,resolveCliMainPath,resolveHostChildLaunch,runHostSupervisor,spawnableChildLaunch}from"./chunk-T2BEB5SO.js";import{DEFAULT_HANDOFF_GRACE_MS,DEFAULT_HOST_IDLE_EXIT_MS,HANDOFF_GRACE_MS_ENV,HOST_COLD_START_ENV,HOST_IDLE_EXIT_MS_ENV,IdleExitDecider,parseColdStart,parseIdleExitMs,resolveHostPolicy}from"./chunk-TFXUF2IL.js";import"./chunk-XC2CNM26.js";import"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-IKOFCODM.js";export{DEFAULT_HANDOFF_GRACE_MS,DEFAULT_HOST_IDLE_EXIT_MS,HANDOFF_GRACE_MS_ENV,HOST_COLD_START_ENV,HOST_IDLE_EXIT_MS_ENV,INTERNAL_SUPERVISOR_FLAG,IdleExitDecider,classifyChildExit,createInternalSocketPath,findInternalSupervisorArgs,parseColdStart,parseIdleExitMs,parseSupervisorArgs,resolveCliMainPath,resolveHostChildLaunch,resolveHostPolicy,runHostSupervisor,spawnableChildLaunch};
3
+ import{INTERNAL_SUPERVISOR_FLAG,classifyChildExit,createInternalSocketPath,findInternalSupervisorArgs,parseSupervisorArgs,resolveCliMainPath,resolveHostChildLaunch,runHostSupervisor,spawnableChildLaunch}from"./chunk-7QPFFAJT.js";import{DEFAULT_HANDOFF_GRACE_MS,DEFAULT_HOST_IDLE_EXIT_MS,HANDOFF_GRACE_MS_ENV,HOST_COLD_START_ENV,HOST_IDLE_EXIT_MS_ENV,IdleExitDecider,parseColdStart,parseIdleExitMs,resolveHostPolicy}from"./chunk-VPV7ADF3.js";import"./chunk-XC2CNM26.js";import"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-IKOFCODM.js";export{DEFAULT_HANDOFF_GRACE_MS,DEFAULT_HOST_IDLE_EXIT_MS,HANDOFF_GRACE_MS_ENV,HOST_COLD_START_ENV,HOST_IDLE_EXIT_MS_ENV,INTERNAL_SUPERVISOR_FLAG,IdleExitDecider,classifyChildExit,createInternalSocketPath,findInternalSupervisorArgs,parseColdStart,parseIdleExitMs,parseSupervisorArgs,resolveCliMainPath,resolveHostChildLaunch,resolveHostPolicy,runHostSupervisor,spawnableChildLaunch};
@@ -19,7 +19,7 @@ renameSync(temporary, launcher);
19
19
  `,{mode:CRASH_RECORD_FILE_MODE})}import{rm as rm2}from"node:fs/promises";import{execFile}from"node:child_process";var WINDOWS_FILETIME_EPOCH=116444736000000000n,PROCESS_START_TOLERANCE_MS=3e3;function processStartTimeMs(identity){if(/^\d+$/.test(identity)){let parsed2=Number((BigInt(identity)-WINDOWS_FILETIME_EPOCH)/10000n);return Number.isFinite(parsed2)?parsed2:void 0}let localIdentity=identity.trim(),korean=/^(\d{4})\uB144\s+(\d{1,2})\uC6D4\s+(\d{1,2})\uC77C\s+[\uC6D4\uD654\uC218\uBAA9\uAE08\uD1A0\uC77C]\uC694\uC77C\s+(\d{1,2})\uC2DC\s+(\d{1,2})\uBD84\s+(\d{1,2})\uCD08$/.exec(localIdentity),japanese=/^[\u65E5\u6708\u706B\u6C34\u6728\u91D1\u571F](?:\u66DC\u65E5)?\s+(\d{1,2})\/\s*(\d{1,2})\s+(\d{2}):(\d{2}):(\d{2})\s+(\d{4})$/.exec(localIdentity),parts=korean?korean.slice(1):japanese?[japanese[6],japanese[1],japanese[2],japanese[3],japanese[4],japanese[5]]:void 0;if(parts===void 0){let parsed2=Date.parse(identity);return Number.isFinite(parsed2)?parsed2:void 0}let[year=NaN,month=NaN,day=NaN,hour=NaN,minute=NaN,second=NaN]=parts.map(Number),parsed=new Date(year,month-1,day,hour,minute,second,0);return parsed.getFullYear()===year&&parsed.getMonth()===month-1&&parsed.getDate()===day&&parsed.getHours()===hour&&parsed.getMinutes()===minute&&parsed.getSeconds()===second?parsed.getTime():void 0}function sameProcessStartMs(recorded,observed){return recorded!==void 0&&observed!==void 0&&Number.isFinite(recorded)&&Number.isFinite(observed)&&Math.abs(recorded-observed)<=PROCESS_START_TOLERANCE_MS}function parseDaemonPidFile(text){let parsed;try{parsed=JSON.parse(text)}catch(error){if(error instanceof SyntaxError)return;throw error}let unguarded=parsed!==null&&isRecord(parsed)&&parsed.processStartTime===null;if(!(!isRecord(parsed)||typeof parsed.pid!="number"||!unguarded&&typeof parsed.processStartTime!="string")&&!(!Number.isInteger(parsed.pid)||parsed.pid<=0)){if(unguarded)return{pid:parsed.pid,processStartTime:null};if(!(typeof parsed.processStartTime!="string"||parsed.processStartTime.trim()===""))return{pid:parsed.pid,processStartTime:parsed.processStartTime}}}async function readProcessIdentity(pid,platform=process.platform,timeoutMs,isLive=processIsLive,timeZone){let command=platform==="win32"?{executable:"powershell.exe",args:["-NoProfile","-NonInteractive","-Command",`$process = Get-CimInstance Win32_Process -Filter "ProcessId=${String(pid)}" -ErrorAction Stop; if ($null -eq $process) { Write-Output '__SENPI_ABSENT__'; exit 0 }; $process.CreationDate.ToFileTimeUtc().ToString("D", [Globalization.CultureInfo]::InvariantCulture)`]}:{executable:"ps",args:["-o","lstart=","-p",String(pid)]};return new Promise(resolve4=>{let effectiveTimeoutMs=timeoutMs??(platform==="win32"?1e3:void 0);execFile(command.executable,command.args,{windowsHide:!0,...effectiveTimeoutMs===void 0?{}:{timeout:effectiveTimeoutMs},...platform==="win32"&&timeZone===void 0?{}:{env:{...process.env,LC_ALL:"C",LANG:"C",...timeZone?{TZ:timeZone}:{}}}},(error,stdout)=>{if(error){let code="code"in error?error.code:void 0;if(platform!=="win32"&&code===1||!isLive(pid)){resolve4({kind:"absent"});return}resolve4({kind:"error",error});return}let output=stdout.trim();if(output==="__SENPI_ABSENT__")return resolve4({kind:"absent"});if(!output||platform==="win32"&&!/^\d+$/.test(output))return resolve4({kind:"error",error:new Error("invalid process identity output")});resolve4({kind:"present",identity:timeZone&&platform!=="win32"?`${output} UTC`:output})}).once("error",error=>resolve4({kind:"error",error}))})}async function readProcessStartTime(pid,platform=process.platform,timeoutMs){return readProcessIdentity(pid,platform,timeoutMs).then(result=>{if(result.kind==="error")throw result.error;return result.kind==="present"?result.identity:void 0})}function processIsLive(pid){try{return process.kill(pid,0),!0}catch(error){if(isNodeErrorCode(error,"ESRCH"))return!1;if(isNodeErrorCode(error,"EPERM"))return!0;throw error}}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isNodeErrorCode(error,code){return error instanceof Error&&"code"in error&&error.code===code}import{basename as basename4,join as join8}from"node:path";import{createHash}from"node:crypto";import{basename as basename3,dirname as dirname4,join as join6,win32 as win322}from"node:path";import{existsSync as existsSync2,realpathSync as realpathSync2}from"node:fs";import{basename as basename2,dirname as dirname3,join as join5,resolve as resolve2}from"node:path";function canonicalSessionPath(path){let absolutePath=resolve2(path),missing=[],existing=absolutePath;for(;!existsSync2(existing);){let parent=dirname3(existing);if(parent===existing)return absolutePath;missing.unshift(basename2(existing)),existing=parent}try{return join5(realpathSync2(existing),...missing)}catch{return absolutePath}}function canonicalEndpointPath(socket,platform=process.platform){return platform==="win32"?win322.normalize(socket).toLowerCase():socket.startsWith("\0")?socket:join6(canonicalSessionPath(dirname4(socket)),basename3(socket))}function daemonDirectoryName(socket,platform=process.platform){return directoryNameOf(canonicalEndpointPath(socket,platform))}function directoryNameOf(endpoint){return createHash("sha256").update(endpoint,"utf8").digest("hex").slice(0,16)}import{join as join7}from"node:path";function generationPaths(paths,instanceId){let dir=join7(paths.generationsDir,instanceId);return{dir,relativeDir:`generations/${instanceId}`,pidFile:join7(dir,"host.pid"),settingsFile:join7(dir,"settings.json"),scratchDir:join7(dir,"scratch"),childPidFile:join7(dir,"host-child.pid"),stopIntentFile:join7(dir,"stop-intent.json"),stalledFile:join7(dir,"host-stalled.json"),aliveFile:join7(dir,"host-alive.json"),stopProgressFile:join7(dir,"stop-progress.json")}}var HOST_DAEMON_DIR_ENV="SENPI_RPC_HOST_DAEMON_DIR";function createHostDaemonPaths(target){let flatDir=join8(target.agentDir??getAgentDir(),"rpc-host-daemon");return{socket:target.socket,flatDir,layoutMarker:join8(flatDir,"layout.json"),legacyPidFile:join8(flatDir,"host.pid"),...hostDaemonDirectoryPaths(join8(flatDir,daemonDirectoryName(target.socket)))}}function hostDaemonDirectoryPaths(dir){return{dir,endpointFile:join8(dir,"endpoint.json"),pointerFile:join8(dir,"host.pid"),lockFile:join8(dir,"daemon.lock"),settingsFile:join8(dir,"settings.json"),stderrLog:join8(dir,"stderr.log"),generationsDir:join8(dir,"generations"),reservationsDir:join8(dir,"reservations")}}var HOST_INSTANCE_ID_ENV="SENPI_RPC_HOST_INSTANCE_ID";var HOST_COLD_START_ENV="SENPI_RPC_HOST_COLD_START",HOST_IDLE_EXIT_MS_ENV="SENPI_RPC_HOST_IDLE_EXIT_MS",DEFAULT_HOST_IDLE_EXIT_MS=9e5,HANDOFF_GRACE_MS_ENV="SENPI_RPC_HANDOFF_GRACE_MS",DEFAULT_HANDOFF_GRACE_MS=6e5;function parseColdStart(value){return value==="transient"||value==="persistent"?value:void 0}function parseIdleExitMs(value){if(value===void 0||!/^\d+$/.test(value.trim()))return;let parsed=Number(value.trim());return Number.isFinite(parsed)&&parsed>0?parsed:void 0}function resolveHostPolicy(settings,env){let record2=isRecord2(settings)?settings:{},coldStart=parseColdStart(env[HOST_COLD_START_ENV])??parseColdStart(asOptionalString(record2.coldStart))??"transient",idleExitMs=parseIdleExitMs(env[HOST_IDLE_EXIT_MS_ENV])??parseIdleExitMs(asOptionalString(record2.idleExitMs))??9e5;return{coldStart,idleExitMs}}var IdleExitDecider=class{constructor(idleExitMs,now=Date.now){this.idleExitMs=idleExitMs,this.now=now}update(activity){return activity.connections>0||activity.activeTurns>0?(this.idleSince=void 0,"active"):this.idleExitMs===Number.POSITIVE_INFINITY?"idle":this.idleSince===void 0?(this.idleSince=this.now(),"idle"):this.now()-this.idleSince>=this.idleExitMs?"exit":"idle"}};function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function asOptionalString(value){return typeof value=="string"?value:typeof value=="number"?String(value):void 0}import{randomUUID}from"node:crypto";import{readFile,rename,rm,writeFile}from"node:fs/promises";async function writeJsonAtomic(path,content){let temporary=`${path}.${process.pid}.${randomUUID().slice(0,8)}.tmp`;try{await writeFile(temporary,`${JSON.stringify(content)}
20
20
  `,{mode:384}),await rename(temporary,path)}catch(cause){throw await rm(temporary,{force:!0}).catch(()=>{}),cause}}async function readJsonObject(path){try{let value=JSON.parse(await readFile(path,"utf8"));return typeof value=="object"&&value!==null&&!Array.isArray(value)?{...value}:void 0}catch{return}}function ageOf(at,now){if(typeof at!="string")return;let parsed=Date.parse(at);return Number.isNaN(parsed)?void 0:now-parsed}import{writeSync}from"node:fs";function writeStderrLine(text){try{writeSync(2,`${text}
21
21
  `)}catch{}}function supervisorLog(message){writeStderrLine(`senpi rpc host supervisor: ${message}`)}function errorMessage(cause){return cause instanceof Error?cause.message:String(cause)}var STOP_STALL_EVIDENCE_MAX_AGE_MS=6e4,CHILD_STALLED_STOP_MAX_MS_ENV="SENPI_RPC_CHILD_STALLED_STOP_MAX_MS",DEFAULT_CHILD_STALLED_STOP_MAX_MS=6e4;function childStalledStopMaxMs(env=process.env){return parseIdleExitMs(env[CHILD_STALLED_STOP_MAX_MS_ENV])??DEFAULT_CHILD_STALLED_STOP_MAX_MS}async function readStallEvidence(generation){let raw=await readJsonObject(generation.stalledFile);if(!(raw===void 0||typeof raw.at!="string"||typeof raw.driftMs!="number"))return{at:raw.at,driftMs:raw.driftMs,processCpuMs:typeof raw.processCpuMs=="number"?raw.processCpuMs:0,heapDeltaMb:typeof raw.heapDeltaMb=="number"?raw.heapDeltaMb:0,...typeof raw.sessionId=="string"?{sessionId:raw.sessionId}:{},...typeof raw.tool=="string"?{tool:raw.tool}:{}}}async function recentStall(generation,now,maxAgeMs){let evidence=await readStallEvidence(generation),age=ageOf(evidence?.at,now);return evidence!==void 0&&age!==void 0&&age<=maxAgeMs?evidence:void 0}async function hostLoopStalled(generation,options){if(await recentStall(generation,options.now,options.windowMs)!==void 0)return!0;let heartbeatAge=ageOf((await readJsonObject(generation.aliveFile))?.at,options.now);return heartbeatAge!==void 0&&heartbeatAge>options.errorMs&&heartbeatAge<options.windowMs}async function hostChildAlive(generation){let record2=await readJsonObject(generation.childPidFile),pid=record2?.pid;if(typeof pid!="number"||!Number.isInteger(pid)||pid<=0)return;if(!processIsLive(pid))return!1;let observed=await readProcessIdentity(pid,process.platform,1e3,processIsLive,"UTC");if(!processIsLive(pid))return!1;let recordedMs=typeof record2?.processStartTime=="string"?processStartTimeMs(record2.processStartTime):void 0,observedMs=observed.kind==="present"?processStartTimeMs(observed.identity):void 0;return recordedMs!==void 0&&observedMs!==void 0?sameProcessStartMs(recordedMs,observedMs):(supervisorLog(`host child pid ${pid} start time unreadable; preserving generation`),!0)}function writeStopProgress(generation,progress){return writeJsonAtomic(generation.stopProgressFile,progress)}async function clearStopProgress(generation){await rm2(generation.stopProgressFile,{force:!0}).catch(()=>{})}import{rm as rm3}from"node:fs/promises";var STOP_INTENT_MAX_AGE_MS=12e4,CHILD_STOP_TIMEOUT_MS=5e3,CHILD_KILL_EXIT_TIMEOUT_MS=3e4,SENDER_KINDS=new Set(["ensure","supervisor","stop","successor","handoff"]);async function writeStopIntent(generation,intent,log=message=>{process.stderr.write(`${message}
22
- `)}){try{await writeJsonAtomic(generation.stopIntentFile,intent)}catch(cause){log(`could not record the stop intent for ${generation.dir}: ${cause instanceof Error?cause.message:cause}`)}}async function readStopIntent(generation,options={}){let raw=await readJsonObject(generation.stopIntentFile);if(raw===void 0)return;let intent=parseStopIntent(raw),age=ageOf(raw.at,options.now??Date.now());if(intent!==void 0&&age!==void 0&&age<=(options.maxAgeMs??STOP_INTENT_MAX_AGE_MS))return intent;await clearStopIntent(generation)}async function consumeStopIntent(generation,now=Date.now()){let intent=await readStopIntent(generation,{now});return intent!==void 0&&await clearStopIntent(generation),intent}async function clearStopIntent(generation){await rm3(generation.stopIntentFile,{force:!0}).catch(()=>{})}function layeredSupervisorIntent(outer,supervisor,stop){return outer===void 0?{sender:supervisor,signal:"SIGTERM",...stop}:{sender:outer.sender,chain:[...outer.chain??[outer.sender],supervisor],targetPid:stop.targetPid,reason:`${outer.reason} -> ${stop.reason}`,signal:"SIGTERM",at:stop.at}}function parseStopIntent(raw){let sender=parseSender(raw.sender),chain=Array.isArray(raw.chain)?raw.chain.map(parseSender):void 0;if(!(sender===void 0||chain?.some(entry=>entry===void 0))&&!(typeof raw.reason!="string"||typeof raw.at!="string"))return{sender,...chain?{chain:chain.filter(entry=>entry!==void 0)}:{},targetPid:typeof raw.targetPid=="number"?raw.targetPid:0,reason:raw.reason,signal:typeof raw.signal=="string"?raw.signal:"SIGTERM",at:raw.at}}function parseSender(value){if(typeof value!="object"||value===null)return;let pid=Reflect.get(value,"pid"),kind=Reflect.get(value,"kind"),generation=Reflect.get(value,"generation");if(!(typeof pid!="number"||typeof kind!="string"||!isSenderKind(kind)))return{pid,kind,...typeof generation=="string"?{generation}:{}}}function isSenderKind(kind){return SENDER_KINDS.has(kind)}function classifyChildExit(code,signal){return code===0&&signal===null?{reason:"rpc host exited on its own idle policy",exitCode:0}:{reason:`rpc host process exited unexpectedly (${code??signal})`,exitCode:1}}async function noteChildExit(context){let now=context.now??Date.now(),intent=await consumeStopIntent(context.generation,now).catch(()=>{}),outcome=describeExit(context,intent);if(outcome===void 0)return;let stall=await recentStall(context.generation,now,STOP_STALL_EVIDENCE_MAX_AGE_MS).catch(()=>{});await recordTerminalHostRecord(context.daemonDir,{at:new Date(now).toISOString(),...context.signal===null?{code:context.code??void 0}:{signal:context.signal},uptimeMs:Math.max(0,now-context.childStartedAt),kind:"rpc-host",generation:context.instanceId,...outcome,...stall?{stall:{driftMs:stall.driftMs,at:stall.at,attributedSessionId:stall.sessionId}}:{},...crashingRuntimeVersions()}).catch(()=>{})}function describeExit(context,intent){return intent!==void 0?{detection:"engine_stop",sender:intent.sender,...intent.chain?{chain:intent.chain}:{},reason:intent.reason,stopIntent:!0}:context.shutdown!==void 0?{detection:"engine_stop",sender:context.shutdown.supervisor,reason:context.shutdown.reason,stopIntent:!1}:classifyChildExit(context.code,context.signal).exitCode===0?void 0:{detection:context.signal===null||SELF_INFLICTED_SIGNALS.has(context.signal)?"supervisor":"external",stopIntent:!1}}var SELF_INFLICTED_SIGNALS=new Set(["SIGSEGV","SIGBUS","SIGABRT","SIGILL","SIGFPE","SIGTRAP","SIGSYS"]);function hostCrashCleanupPaths(targets){let publicEntry=targets.platform==="win32"?[targets.publicSocket]:[];return targets.successor?publicEntry:[targets.generationPidFile,targets.settingsFile,...publicEntry,targets.pointerFile]}import{watch}from"node:fs";import{createConnection,Socket}from"node:net";var OBSERVE_REQUEST_FIELD="observe",ORIGIN_HOST_INSTANCE_FIELD="origin_host_instance",OBSERVING_COMMANDS=new Set(["get_protocol_info","list_sessions","subscribe_sessions","unsubscribe_sessions","get_effect_status","get_subscription_limits"]);function isObservingRequest(line){let request;try{request=JSON.parse(line)}catch{return!1}if(typeof request!="object"||request===null||Array.isArray(request))return!1;let record2=request;return record2.type==="warm"?!0:record2[OBSERVE_REQUEST_FIELD]===!0&&OBSERVING_COMMANDS.has(record2.type)}function requestOriginHostInstance(line){let request;try{request=JSON.parse(line)}catch{return}if(typeof request!="object"||request===null||Array.isArray(request))return;let origin=Reflect.get(request,ORIGIN_HOST_INSTANCE_FIELD);return typeof origin=="string"&&origin.length>0?origin:void 0}var MAX_CLASSIFIED_LINE_BYTES=64*1024,NEWLINE=10,ClientOccupancy=class{constructor(onAttach,ownInstance){this.clients=new Set,this.observers=new Set,this.attached=new Set,this.dependents=new Set,this.closed=!1,this.onAttach=onAttach,this.ownInstance=ownInstance}get attachedCount(){return this.attached.size}get unclassifiedCount(){return this.clients.size-this.observers.size-this.attached.size-this.dependents.size}admit(client){if(this.closed)return client.destroy(),!1;this.clients.add(client);let pending=Buffer.alloc(0),attach=()=>{client.off("data",classify),pending=Buffer.alloc(0),this.observers.delete(client),this.attached.add(client),this.onAttach()},depend=()=>{client.off("data",classify),pending=Buffer.alloc(0),this.observers.delete(client),this.dependents.add(client)},classify=chunk=>{pending=Buffer.concat([pending,chunk]);for(let newline=pending.indexOf(NEWLINE);newline!==-1;newline=pending.indexOf(NEWLINE)){let line=pending.subarray(0,newline).toString("utf8");if(pending=pending.subarray(newline+1),!isObservingRequest(line)){this.ownInstance!==void 0&&requestOriginHostInstance(line)===this.ownInstance?depend():attach();return}this.observers.add(client)}pending.length>MAX_CLASSIFIED_LINE_BYTES&&attach()};return client.on("data",classify),!0}release(client){let unclassified=this.clients.has(client)&&!this.observers.has(client)&&!this.attached.has(client)&&!this.dependents.has(client);return this.clients.delete(client),this.observers.delete(client),this.attached.delete(client),this.dependents.delete(client),unclassified}destroyAll(){this.closed=!0;for(let client of this.clients)client.destroy()}};import{readFile as readFile2,writeFile as writeFile2}from"node:fs/promises";import{join as join9}from"node:path";async function readHostOwner(generationDir){let record2=await readJsonObject(join9(generationDir,"owner.json"));if(record2?.owner===null)return null;if(!isRecord3(record2?.owner))return;let{pid,startTime}=record2.owner;return typeof pid=="number"&&Number.isSafeInteger(pid)&&pid>0&&typeof startTime=="string"&&startTime.length>0?{pid,startTime}:void 0}function sameHostOwner(a,b){if(a==null||b==null||a.pid!==b.pid)return!1;let started=processStartTimeMs(a.startTime);return started!==void 0&&started===processStartTimeMs(b.startTime)}async function hostOwnerGone(owner){let observed=await readProcessIdentity(owner.pid,process.platform,1e3,void 0,"UTC");return observed.kind==="absent"||observed.kind==="present"&&processStartTimeMs(observed.identity)!==void 0&&processStartTimeMs(owner.startTime)!==void 0&&!sameProcessStartMs(processStartTimeMs(observed.identity),processStartTimeMs(owner.startTime))}async function readFileOrUndefined(path){try{return await readFile2(path,"utf8")}catch(error){if(isNodeErrorCode2(error,"ENOENT")||isNodeErrorCode2(error,"ENOTDIR"))return;throw error}}function parseJson(text){if(text!==void 0)try{let parsed=JSON.parse(text);return isRecord3(parsed)?parsed:void 0}catch{return}}function isRecord3(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isNodeErrorCode2(error,code){return error instanceof Error&&"code"in error&&error.code===code}var SessionRunActivity=class{#running=new Set;observe(line){let event=parseHostEvent(line);if(event===void 0)return!1;if(event.type==="agent_start")this.#running.add(event.sessionId);else if(event.type==="agent_settled"||event.type==="session_closed")this.#running.delete(event.sessionId);else return!1;return!0}get busySessions(){return this.#running.size}};function parseHostEvent(line){let event;try{event=JSON.parse(line)}catch{return}if(typeof event!="object"||event===null)return;let{type,sessionId}=event;return typeof sessionId=="string"?{type,sessionId}:void 0}import{StringDecoder}from"node:string_decoder";function serializeJsonLine(value){return`${JSON.stringify(value)}
22
+ `)}){try{await writeJsonAtomic(generation.stopIntentFile,intent)}catch(cause){log(`could not record the stop intent for ${generation.dir}: ${cause instanceof Error?cause.message:cause}`)}}async function readStopIntent(generation,options={}){let raw=await readJsonObject(generation.stopIntentFile);if(raw===void 0)return;let intent=parseStopIntent(raw),age=ageOf(raw.at,options.now??Date.now());if(intent!==void 0&&age!==void 0&&age<=(options.maxAgeMs??STOP_INTENT_MAX_AGE_MS))return intent;await clearStopIntent(generation)}async function consumeStopIntent(generation,now=Date.now()){let intent=await readStopIntent(generation,{now});return intent!==void 0&&await clearStopIntent(generation),intent}async function clearStopIntent(generation){await rm3(generation.stopIntentFile,{force:!0}).catch(()=>{})}function layeredSupervisorIntent(outer,supervisor,stop){return outer===void 0?{sender:supervisor,signal:"SIGTERM",...stop}:{sender:outer.sender,chain:[...outer.chain??[outer.sender],supervisor],targetPid:stop.targetPid,reason:`${outer.reason} -> ${stop.reason}`,signal:"SIGTERM",at:stop.at}}function parseStopIntent(raw){let sender=parseSender(raw.sender),chain=Array.isArray(raw.chain)?raw.chain.map(parseSender):void 0;if(!(sender===void 0||chain?.some(entry=>entry===void 0))&&!(typeof raw.reason!="string"||typeof raw.at!="string"))return{sender,...chain?{chain:chain.filter(entry=>entry!==void 0)}:{},targetPid:typeof raw.targetPid=="number"?raw.targetPid:0,reason:raw.reason,signal:typeof raw.signal=="string"?raw.signal:"SIGTERM",at:raw.at}}function parseSender(value){if(typeof value!="object"||value===null)return;let pid=Reflect.get(value,"pid"),kind=Reflect.get(value,"kind"),generation=Reflect.get(value,"generation");if(!(typeof pid!="number"||typeof kind!="string"||!isSenderKind(kind)))return{pid,kind,...typeof generation=="string"?{generation}:{}}}function isSenderKind(kind){return SENDER_KINDS.has(kind)}function classifyChildExit(code,signal){return code===0&&signal===null?{reason:"rpc host exited on its own idle policy",exitCode:0}:{reason:`rpc host process exited unexpectedly (${code??signal})`,exitCode:1}}async function noteChildExit(context){let now=context.now??Date.now(),intent=await consumeStopIntent(context.generation,now).catch(()=>{}),outcome=describeExit(context,intent);if(outcome===void 0)return;let stall=await recentStall(context.generation,now,STOP_STALL_EVIDENCE_MAX_AGE_MS).catch(()=>{});await recordTerminalHostRecord(context.daemonDir,{at:new Date(now).toISOString(),...context.signal===null?{code:context.code??void 0}:{signal:context.signal},uptimeMs:Math.max(0,now-context.childStartedAt),kind:"rpc-host",generation:context.instanceId,...outcome,...stall?{stall:{driftMs:stall.driftMs,at:stall.at,attributedSessionId:stall.sessionId}}:{},...crashingRuntimeVersions()}).catch(()=>{})}function describeExit(context,intent){return intent!==void 0?{detection:"engine_stop",sender:intent.sender,...intent.chain?{chain:intent.chain}:{},reason:intent.reason,stopIntent:!0}:context.shutdown!==void 0?{detection:"engine_stop",sender:context.shutdown.supervisor,reason:context.shutdown.reason,stopIntent:!1}:classifyChildExit(context.code,context.signal).exitCode===0?void 0:{detection:context.signal===null||SELF_INFLICTED_SIGNALS.has(context.signal)?"supervisor":"external",stopIntent:!1}}var SELF_INFLICTED_SIGNALS=new Set(["SIGSEGV","SIGBUS","SIGABRT","SIGILL","SIGFPE","SIGTRAP","SIGSYS"]);function hostCrashCleanupPaths(targets){let publicEntry=targets.platform==="win32"?[targets.publicSocket]:[];return targets.successor?publicEntry:[targets.generationPidFile,targets.settingsFile,...publicEntry,targets.pointerFile]}import{watch}from"node:fs";import{createConnection,Socket}from"node:net";var OBSERVE_REQUEST_FIELD="observe",ORIGIN_HOST_INSTANCE_FIELD="origin_host_instance",OBSERVING_COMMANDS=new Set(["get_protocol_info","list_sessions","subscribe_sessions","unsubscribe_sessions","get_effect_status","get_pending_inputs","get_subscription_limits"]);function isObservingRequest(line){let request;try{request=JSON.parse(line)}catch{return!1}if(typeof request!="object"||request===null||Array.isArray(request))return!1;let record2=request;return record2.type==="warm"?!0:record2[OBSERVE_REQUEST_FIELD]===!0&&OBSERVING_COMMANDS.has(record2.type)}function requestOriginHostInstance(line){let request;try{request=JSON.parse(line)}catch{return}if(typeof request!="object"||request===null||Array.isArray(request))return;let origin=Reflect.get(request,ORIGIN_HOST_INSTANCE_FIELD);return typeof origin=="string"&&origin.length>0?origin:void 0}var MAX_CLASSIFIED_LINE_BYTES=64*1024,NEWLINE=10,ClientOccupancy=class{constructor(onAttach,ownInstance){this.clients=new Set,this.observers=new Set,this.attached=new Set,this.dependents=new Set,this.closed=!1,this.onAttach=onAttach,this.ownInstance=ownInstance}get attachedCount(){return this.attached.size}get unclassifiedCount(){return this.clients.size-this.observers.size-this.attached.size-this.dependents.size}admit(client){if(this.closed)return client.destroy(),!1;this.clients.add(client);let pending=Buffer.alloc(0),attach=()=>{client.off("data",classify),pending=Buffer.alloc(0),this.observers.delete(client),this.attached.add(client),this.onAttach()},depend=()=>{client.off("data",classify),pending=Buffer.alloc(0),this.observers.delete(client),this.dependents.add(client)},classify=chunk=>{pending=Buffer.concat([pending,chunk]);for(let newline=pending.indexOf(NEWLINE);newline!==-1;newline=pending.indexOf(NEWLINE)){let line=pending.subarray(0,newline).toString("utf8");if(pending=pending.subarray(newline+1),!isObservingRequest(line)){this.ownInstance!==void 0&&requestOriginHostInstance(line)===this.ownInstance?depend():attach();return}this.observers.add(client)}pending.length>MAX_CLASSIFIED_LINE_BYTES&&attach()};return client.on("data",classify),!0}release(client){let unclassified=this.clients.has(client)&&!this.observers.has(client)&&!this.attached.has(client)&&!this.dependents.has(client);return this.clients.delete(client),this.observers.delete(client),this.attached.delete(client),this.dependents.delete(client),unclassified}destroyAll(){this.closed=!0;for(let client of this.clients)client.destroy()}};import{readFile as readFile2,writeFile as writeFile2}from"node:fs/promises";import{join as join9}from"node:path";async function readHostOwner(generationDir){let record2=await readJsonObject(join9(generationDir,"owner.json"));if(record2?.owner===null)return null;if(!isRecord3(record2?.owner))return;let{pid,startTime}=record2.owner;return typeof pid=="number"&&Number.isSafeInteger(pid)&&pid>0&&typeof startTime=="string"&&startTime.length>0?{pid,startTime}:void 0}function sameHostOwner(a,b){if(a==null||b==null||a.pid!==b.pid)return!1;let started=processStartTimeMs(a.startTime);return started!==void 0&&started===processStartTimeMs(b.startTime)}async function hostOwnerGone(owner){let observed=await readProcessIdentity(owner.pid,process.platform,1e3,void 0,"UTC");return observed.kind==="absent"||observed.kind==="present"&&processStartTimeMs(observed.identity)!==void 0&&processStartTimeMs(owner.startTime)!==void 0&&!sameProcessStartMs(processStartTimeMs(observed.identity),processStartTimeMs(owner.startTime))}async function readFileOrUndefined(path){try{return await readFile2(path,"utf8")}catch(error){if(isNodeErrorCode2(error,"ENOENT")||isNodeErrorCode2(error,"ENOTDIR"))return;throw error}}function parseJson(text){if(text!==void 0)try{let parsed=JSON.parse(text);return isRecord3(parsed)?parsed:void 0}catch{return}}function isRecord3(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isNodeErrorCode2(error,code){return error instanceof Error&&"code"in error&&error.code===code}var SessionRunActivity=class{#running=new Set;observe(line){let event=parseHostEvent(line);if(event===void 0)return!1;if(event.type==="agent_start")this.#running.add(event.sessionId);else if(event.type==="agent_settled"||event.type==="session_closed")this.#running.delete(event.sessionId);else return!1;return!0}get busySessions(){return this.#running.size}};function parseHostEvent(line){let event;try{event=JSON.parse(line)}catch{return}if(typeof event!="object"||event===null)return;let{type,sessionId}=event;return typeof sessionId=="string"?{type,sessionId}:void 0}import{StringDecoder}from"node:string_decoder";function serializeJsonLine(value){return`${JSON.stringify(value)}
23
23
  `}var MAX_RPC_LINE_CHARACTERS=16*1024*1024;function attachJsonlLineReader(stream,onLine,options={}){let decoder=new StringDecoder("utf8"),maxLineLength=options.maxLineLength??Number.POSITIVE_INFINITY;if(!(maxLineLength>0))throw new Error("maxLineLength must be greater than zero.");let buffer="",discardingOversizedLine=!1,consume=text=>{let offset=0;for(;offset<text.length;){if(discardingOversizedLine){let newlineIndex2=text.indexOf(`
24
24
  `,offset);if(newlineIndex2===-1)return;discardingOversizedLine=!1,offset=newlineIndex2+1;continue}let newlineIndex=text.indexOf(`
25
25
  `,offset);if(newlineIndex===-1){let remainder=text.slice(offset);buffer.length+remainder.length>maxLineLength?(buffer="",discardingOversizedLine=!0,options.onOversizedLine?.()):buffer+=remainder;return}let segment=text.slice(offset,newlineIndex);if(buffer.length+segment.length>maxLineLength)options.onOversizedLine?.();else{let line=buffer+segment;onLine(line.endsWith("\r")?line.slice(0,-1):line)}buffer="",offset=newlineIndex+1}},onData=chunk=>{consume(typeof chunk=="string"?chunk:decoder.write(chunk))},onEnd=()=>{consume(decoder.end()),!discardingOversizedLine&&buffer.length>0&&onLine(buffer.endsWith("\r")?buffer.slice(0,-1):buffer),buffer="",discardingOversizedLine=!1};return stream.on("data",onData),stream.on("end",onEnd),()=>{stream.off("data",onData),stream.off("end",onEnd)}}function activeTurnsForIdleDecision(input){return input.healthy?input.observedBusy:input.unhealthySince===void 0||input.now-input.unhealthySince<input.unknownGraceMs?1:0}function createObserverLink(options){let current,healthy=!1,unhealthySince,retry,armRetry=()=>{retry!==void 0||options.settled()||(retry=options.setTimer(()=>{retry=void 0,open().catch(armRetry)},options.retryDelayMs))};async function open(){let socket=await options.open();current=socket,healthy=!0,unhealthySince=void 0,socket.onLost(()=>{current!==socket||options.settled()||(healthy=!1,unhealthySince??=options.now(),current=void 0,armRetry())})}return{open,healthy:()=>healthy,unhealthySince:()=>unhealthySince,stop:()=>{retry?.cancel(),retry=void 0,current=void 0}}}import{createHash as createHash2,randomBytes,timingSafeEqual}from"node:crypto";import{chmod,mkdir,readFile as readFile3,writeFile as writeFile3}from"node:fs/promises";import{dirname as dirname5,win32 as win323}from"node:path";var WINDOWS_PIPE_PREFIX="\\\\.\\pipe\\senpi-rpc-",SOCKET_SECRET_BYTES=32,SOCKET_SECRET_SUFFIX=".secret",SOCKET_SECRET_FILE_ENV="SENPI_RPC_SOCKET_SECRET_FILE",SOCKET_HANDSHAKE_TIMEOUT_MS=2e3;function socketSecretPath(logicalPath){if(logicalPath.toLowerCase().startsWith("\\\\.\\pipe\\"))throw new Error(`Windows RPC named-pipe addresses need a logical filesystem path for their secret: ${logicalPath}`);return`${logicalPath}${SOCKET_SECRET_SUFFIX}`}async function ensureSocketSecret(path){try{let existing=await readFile3(path);if(existing.length===SOCKET_SECRET_BYTES)return existing}catch(error){if(!isNodeErrorCode3(error,"ENOENT"))throw error}return createSocketSecret(path)}async function createSocketSecret(path){await mkdir(dirname5(path),{recursive:!0});let secret=randomBytes(SOCKET_SECRET_BYTES);return await writeFile3(path,secret,{mode:384}),await chmod(path,384),secret}function resolveSocketTransportAddress(socketPath,platform,secret){if(platform!=="win32"||socketPath.toLowerCase().startsWith("\\\\.\\pipe\\"))return socketPath;if(!/^[a-zA-Z]:[\\/]/.test(socketPath)&&!/^\\\\[^/]/.test(socketPath))throw new Error(`Windows RPC socket path must be drive-qualified or UNC: ${socketPath}`);let canonical=win323.normalize(socketPath).toLowerCase(),identity=Buffer.concat([Buffer.from(canonical,"utf8"),Buffer.from(secret??[])]),name=createHash2("sha256").update(identity).digest("hex").slice(0,32);return`${WINDOWS_PIPE_PREFIX}${name}`}function authenticateSocket(socket,secret,onAuthenticated){let received=Buffer.alloc(0),finish=()=>{clearTimeout(timer),socket.off("data",onData),socket.off("error",onError)},onError=()=>{finish(),socket.destroy()},timer=setTimeout(()=>{finish(),socket.destroy()},SOCKET_HANDSHAKE_TIMEOUT_MS),onData=chunk=>{if(received=Buffer.concat([received,chunk]),received.length<secret.length)return;if(finish(),!timingSafeEqual(received.subarray(0,secret.length),Buffer.from(secret))){socket.destroy();return}let remainder=received.subarray(secret.length);remainder.length>0&&socket.unshift(remainder),onAuthenticated()};socket.on("data",onData),socket.once("error",onError),socket.once("close",finish)}function sendSocketHandshake(socket,secret){socket.write(Buffer.from(secret))}function isNodeErrorCode3(error,code){return error instanceof Error&&"code"in error&&error.code===code}var SupervisorActivity=class{constructor(options){this.runs=new SessionRunActivity,this.options=options,this.decider=new IdleExitDecider(options.idleExitMs),this.clients=new ClientOccupancy(()=>this.refresh(),options.instanceId),this.observerLink=createObserverLink({open:()=>this.connectObserver(),settled:options.settled,retryDelayMs:250,now:Date.now,setTimer:(run,ms)=>{let timer=setTimeout(run,ms);return timer.unref?.(),{cancel:()=>clearTimeout(timer)}}})}current(){return{connections:this.clients.attachedCount,activeTurns:activeTurnsForIdleDecision({healthy:this.observerLink.healthy(),unhealthySince:this.observerLink.unhealthySince(),now:Date.now(),unknownGraceMs:this.decider.idleExitMs,observedBusy:this.runs.busySessions})}}refresh(){let current=this.current();return(current.connections>0||current.activeTurns>0||this.clients.unclassifiedCount>0)&&this.options.onActivity?.(),this.decider.update(current)}quiescent(){return this.observerLink.healthy()&&this.runs.busySessions===0&&this.clients.attachedCount===0&&this.clients.unclassifiedCount===0}openObserver(){return this.observerLink.open()}stopObserver(){this.observerLink.stop(),this.observerSocket?.destroy()}async connectObserver(){let secret=this.options.internalSecret,next=createConnection(resolveSocketTransportAddress(this.options.internalSocket,process.platform,secret));return secret&&sendSocketHandshake(next,secret),await waitForConnect(next,5e3),this.observerSocket=next,attachJsonlLineReader(next,line=>this.observeHostEvent(line),{maxLineLength:MAX_RPC_LINE_CHARACTERS}),{onLost:handler=>{let lost=()=>{handler(),this.options.onActivity?.()};next.once("close",lost),next.once("error",lost)}}}observeHostEvent(line){this.runs.observe(line)&&this.refresh()}},OWNER_EXIT_GRACE_MS=2e3,OWNER_PROBE_MAX_INTERVAL_MS=5e3,SupervisorOwner=class{constructor(generationDir){this.watchFailed=!1,this.nextProbeAt=0,this.probeIntervalMs=1e3,this.gone=!1,this.revision=0,this.stopped=!1,this.idle=new IdleExitDecider(OWNER_EXIT_GRACE_MS,()=>performance.now()),this.generationDir=generationDir}async start(fd){if(await this.reload(),!(fd===void 0||this.owner==null))try{let pipe=new Socket({fd,readable:!0,writable:!1});this.pipe=pipe;let bound=this.owner,failed=!1,eof=()=>{!failed&&!this.stopped&&sameHostOwner(this.owner,bound)&&(this.gone=!0)};pipe.once("end",eof),process.platform==="win32"&&pipe.once("close",eof),pipe.once("error",()=>{failed=!0,this.pipe===pipe&&(this.pipe=void 0),pipe.destroy()}),pipe.resume()}catch{this.pipe=void 0}}async reload(){let revision=++this.revision,next=await readHostOwner(this.generationDir);if(!(this.stopped||revision!==this.revision)){if(sameHostOwner(this.owner,next)||(this.pipe?.destroy(),this.pipe=void 0,this.gone=!1,this.nextProbeAt=0,this.probeIntervalMs=1e3,this.activity()),this.owner=next,next==null)this.watcher?.close(),this.watcher=void 0;else if(!this.watcher&&!this.watchFailed)try{this.watcher=watch(this.generationDir,(_event,filename)=>{filename?.toString()==="owner.json"&&this.reload()}),this.watcher.once("error",()=>{this.watchFailed=!0,this.watcher?.close(),this.watcher=void 0})}catch{this.watchFailed=!0}}}activity(){this.idle.update({connections:1,activeTurns:0})}async shouldExit(activity){this.watcher||await this.reload();let owner=this.owner,revision=this.revision;if(owner!=null&&!this.pipe&&!this.gone&&performance.now()>=this.nextProbeAt){let gone=await hostOwnerGone(owner);if(this.stopped||revision!==this.revision)return!1;this.gone=gone,this.nextProbeAt=performance.now()+this.probeIntervalMs,this.probeIntervalMs=Math.min(OWNER_PROBE_MAX_INTERVAL_MS,this.probeIntervalMs*2)}let quiet=this.gone&&owner!=null&&activity.quiescent();if(this.idle.update({connections:quiet?0:1,activeTurns:0})!=="exit")return!1;let current=await readHostOwner(this.generationDir);return!this.stopped&&revision===this.revision&&sameHostOwner(owner,current)&&activity.quiescent()}stop(){this.stopped=!0,this.watcher?.close(),this.pipe?.destroy()}};function waitForConnect(socket,timeoutMs){return new Promise((resolve4,reject)=>{let timer=setTimeout(()=>{cleanup(),reject(new Error(`observer connection to internal host timed out after ${timeoutMs}ms`))},timeoutMs),onConnect=()=>{cleanup(),resolve4()},onError=cause=>{cleanup(),reject(cause)},cleanup=()=>{clearTimeout(timer),socket.off("connect",onConnect),socket.off("error",onError)};socket.once("connect",onConnect),socket.once("error",onError)})}import{execFile as execFile2}from"node:child_process";import{mkdir as mkdir2,readFile as readFile4,rename as rename2,stat as stat2,unlink,writeFile as writeFile4}from"node:fs/promises";import{createConnection as createConnection2}from"node:net";import{dirname as dirname6}from"node:path";var PUBLIC_SOCKET_IDENTITY_FILE="public-socket.owner";var MAX_SOCKET_PATH_BYTES=103;function sameSocketIdentity(a,b){return a.dev===b.dev&&a.ino===b.ino}function classifyConnectError(code,platform){return code==="ENOENT"?"gone":code==="ECONNREFUSED"?platform==="linux"?"dead":"confirm-holder":"live"}var HOLDER_PROBE_TIMEOUT_MS=5e3,lsofSocketHolders=socketPath=>new Promise(resolve4=>{execFile2("lsof",["-t","--",socketPath],{timeout:HOLDER_PROBE_TIMEOUT_MS},(error,stdout)=>{let pids=String(stdout).split(/\s+/).filter(part=>/^\d+$/.test(part)).map(Number);if(pids.length>0)return resolve4(pids);let exitCode=error===null?void 0:Reflect.get(error,"code");resolve4(error===null||exitCode===1?[]:void 0)})}),CONNECT_PROBE_TIMEOUT_MS=2e3;function connectOnce(socketPath){return new Promise(resolve4=>{let socket=createConnection2(resolveSocketTransportAddress(socketPath,process.platform)),settle=value=>{socket.destroy(),resolve4(value)};socket.setTimeout(CONNECT_PROBE_TIMEOUT_MS,()=>settle({code:"timeout"})),socket.once("connect",()=>settle({connected:!0})),socket.once("error",cause=>settle({code:cause.code}))})}async function socketEntryListenerState(socketPath,platform=process.platform,holders=lsofSocketHolders){let attempt=await connectOnce(socketPath);if("connected"in attempt)return{verdict:"live",evidence:"accepting connections"};let verdict=classifyConnectError(attempt.code,platform);if(verdict!=="confirm-holder")return{verdict,evidence:`connect ${attempt.code??"failed"}`};let pids=await holders(socketPath);return pids===void 0?{verdict:"live",evidence:"connect ECONNREFUSED, holders unknown"}:pids.length>0?{verdict:"live",evidence:`connect ECONNREFUSED, held open by pid ${pids.join(",")}`}:{verdict:"dead",evidence:"connect ECONNREFUSED, held by nobody"}}async function statSocketIdentity(socketPath){try{let{dev,ino}=await stat2(socketPath);return{dev,ino}}catch(cause){if(isNodeErrorCode4(cause,"ENOENT"))return;throw cause}}async function classifyEndpointOwnership(socketPath,identity){if(identity===void 0||process.platform==="win32"||socketPath.startsWith("\0"))return"unknown";let current;try{current=await statSocketIdentity(socketPath)}catch{return"unknown"}return current===void 0?"absent":sameSocketIdentity(current,identity)?"held":"replaced"}async function writeSocketIdentityFile(path,identity){await mkdir2(dirname6(path),{recursive:!0,mode:448});let tmpPath=`${path}.${process.pid}.tmp`;await writeFile4(tmpPath,`${JSON.stringify(identity)}
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{RpcClient,RpcCommandError,RpcRequestTimeoutError,RpcTransportGoneError,isTransportGoneError}from"./chunk-NRHOGI4Z.js";import"./chunk-MF57DS3V.js";import{SessionManager,assertValidSessionId}from"./chunk-PKDWFVE4.js";import"./chunk-4RSWXPUB.js";import"./chunk-UUMKAA7S.js";import{DEFAULT_HOST_LAUNCH_SPEC,HOST_EXIT_ERROR,HOST_EXIT_OK,HOST_EXIT_REFUSED,HOST_EXIT_USAGE,HostLaunchSpecError,STOP_WAIT_BUDGET_MS,daemonEnvKeys,daemonEnvOverrides,emit,ensureHost,loadHostLaunchSpec,refusal,resolveHostSocket,writeDaemonEnvKeys}from"./chunk-RELAITQ7.js";import{HostEnsureRefusedError}from"./chunk-GAHIHXVE.js";import"./chunk-QMRJYMNH.js";import{endpointKindOfSocket}from"./chunk-36GE6JDV.js";import"./chunk-DDHBG2HU.js";import"./chunk-KUPQO7MC.js";import"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-OOWML2KE.js";import"./chunk-T2BEB5SO.js";import"./chunk-TFXUF2IL.js";import{canonicalSessionPath,createHostDaemonPaths}from"./chunk-XC2CNM26.js";import"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import{APP_NAME,getAgentDir}from"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-COJK5FDH.js";import"./chunk-WHPDEDCC.js";import"./chunk-PFNBY43W.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";import{readFileSync}from"node:fs";import{resolve}from"node:path";var DETACH_ACK_TIMEOUT_MS=5e3;async function detachBeforeClose(client,report,timeoutMs=DETACH_ACK_TIMEOUT_MS){let timer,late=new Promise(resolve2=>{timer=setTimeout(()=>resolve2("late"),timeoutMs)});try{await Promise.race([client.detachConnection(),late])==="late"&&report(`the host did not confirm the detach within ${timeoutMs} ms; closing the connection anyway`)}catch(error){if(error instanceof RpcTransportGoneError)return;report(`the host refused the detach (${error instanceof Error?error.message:String(error)}); closing the connection anyway`)}finally{clearTimeout(timer)}}var USAGE_CODES=new Set(["missing_session_id","invalid_path","invalid_session_context","invalid_session_kind","invalid_launch_profile","invalid_session_id","invalid_release_reason","empty","unknown_command"]),FAILURE_CODES=new Set(["open_failed","warm_failed","release_failed"]),REASON_FOR_CODE={streaming:"busy",not_found:"unknown_cursor"},BARE_CODE=/^[a-z][a-z0-9_]*$/;function mapError(error,socket){let detail=error instanceof Error?error.message:String(error);if(error instanceof RpcCommandError){let code=error.errorCode??(BARE_CODE.test(detail)?detail:void 0);if(code===void 0)return hostError(detail,socket);let exitCode=USAGE_CODES.has(code)?HOST_EXIT_USAGE:FAILURE_CODES.has(code)?HOST_EXIT_ERROR:HOST_EXIT_REFUSED;return{exitCode,payload:{action:exitCode===HOST_EXIT_REFUSED?"refuse":"error",reason:REASON_FOR_CODE[code]??code,detail,socket,...error.errorData!==void 0&&{data:error.errorData}}}}return isTransportGoneError(error)?{exitCode:HOST_EXIT_ERROR,payload:{action:"error",reason:"transport_gone",detail,socket}}:hostError(detail,socket)}function hostError(detail,socket){return{exitCode:HOST_EXIT_ERROR,payload:{action:"error",reason:"host_error",detail,socket}}}async function openHostSession(client,request,socket,ensured){let opened=await client.openSession({cwd:request.cwd,retain_on_disconnect:!0,...request.model&&{provider:request.model.provider,modelId:request.model.id}});ensured?.release();let{state}=opened,identity={sessionId:opened.sessionId,sessionPath:state.sessionFile,durableSessionId:state.sessionId};try{request.name!==void 0&&await client.setSessionName(request.name);let disposition=request.prompt===void 0?void 0:await client.prompt(request.prompt);return{exitCode:HOST_EXIT_OK,payload:{action:"open",socket,pid:ensured?.pid,reused:ensured?.reused,...identity,cwd:state.cwd,model:state.model?{provider:state.model.provider,id:state.model.id}:null,attached:opened.attached??!1,...disposition!==void 0&&{prompt:{disposition}}}}}catch(error){let outcome=mapError(error,socket),closed=await closeOpened(client,opened.sessionId);return{...outcome,payload:{...outcome.payload,...identity,closed}}}}async function closeOpened(client,sessionId){try{return await client.closeSession(sessionId),!(await client.listSessions()).some(row=>row.sessionId===sessionId)}catch{return!1}}import{existsSync}from"node:fs";import{readdir}from"node:fs/promises";import{dirname,join}from"node:path";async function resolveSessionRef(client,ref,agentDir){let rows=await client.listSessions(),handle=rows.find(row=>row.sessionId===ref);if(handle)return{kind:"live",row:handle};if(isSessionId(ref)){let byId=await resolveDurableId(ref,rows,agentDir);if(byId)return byId}let named=rows.filter(row=>row.name===ref);if(named.length>1)return{kind:"ambiguous",candidates:named.map(row=>row.sessionId)};let live=named[0]??rows.find(row=>row.sessionPath!==void 0&&samePath(row.sessionPath,ref));return live?{kind:"live",row:live}:looksLikePath(ref)?parkedByPath(ref):{kind:"unknown"}}async function resolveDurableId(id,rows,agentDir){let liveRows=rows.filter(row=>row.durableSessionId===id),transcripts=(await transcriptsUnder(agentDir)).filter(session=>session.id===id),files=new Set([...liveRows.map(row=>row.sessionPath===void 0?row.sessionId:canonicalSessionPath(row.sessionPath)),...transcripts.map(session=>canonicalSessionPath(session.path))]);return files.size>1?{kind:"ambiguous",candidates:[...files]}:liveRows[0]?{kind:"live",row:liveRows[0]}:transcripts[0]?parked(transcripts[0]):void 0}function isSessionId(ref){try{return assertValidSessionId(ref),!0}catch{return!1}}function looksLikePath(ref){return ref.includes("/")||ref.includes("\\")||ref.endsWith(".jsonl")}async function parkedByPath(ref){let path=canonicalSessionPath(ref);if(!existsSync(path))return{kind:"unknown"};let info=(await SessionManager.listAll(dirname(path))).find(session=>samePath(session.path,path));return info?parked(info):{kind:"unknown"}}async function transcriptsUnder(agentDir){let root=join(agentDir,"sessions");if(!existsSync(root))return[];let dirs=(await readdir(root,{withFileTypes:!0})).filter(entry=>entry.isDirectory());return(await Promise.all(dirs.map(entry=>SessionManager.listAll(join(root,entry.name))))).flat()}function parked(info){return{kind:"parked",sessionPath:info.path,cwd:info.cwd,durableSessionId:info.id}}function samePath(left,right){return canonicalSessionPath(left)===canonicalSessionPath(right)}function waitForHostSession(client,sessionId,request,onTransportLoss){let started=Date.now();return new Promise((resolveWait,reject)=>{let finished=!1,observed=!1,state,timer,cleanup=()=>{finished=!0,clearTimeout(timer),unsubscribe(),onTransportLoss(void 0)},fail=error=>{finished||(cleanup(),reject(error))},finish=outcome=>{finished||(cleanup(),resolveWait({exitCode:HOST_EXIT_OK,payload:{action:"wait",sessionId,until:request.until,outcome,waited_ms:Date.now()-started,state:{isStreaming:state?.isStreaming??!1,pendingMessageCount:state?.pendingMessageCount??0,lastAbortSource:state?.lastAbortSource??null}}}))},unsubscribe=client.onEvent(record=>{let event=record;if(event.type==="session_closed"||event.type==="session_parked"){finish(event.type);return}if(event.type==="agent_settled"&&"reason"in event&&event.reason==="session_closed"){finish("session_closed");return}event.type!=="agent_idle"&&!(request.until==="done"&&event.type==="agent_settled")||(observed=!0,client.getState().then(snapshot=>{state=snapshot,request.until==="done"?finish("done"):isDrained(snapshot)&&finish("idle")},fail))});onTransportLoss(fail),timer=setTimeout(()=>{finished||(cleanup(),resolveWait({exitCode:HOST_EXIT_ERROR,payload:{action:"error",reason:"wait_timeout",sessionId,until:request.until,timeoutMs:request.timeoutMs}}))},request.timeoutMs),client.getState().then(snapshot=>{state=snapshot,!observed&&(request.until==="done"?!snapshot.isStreaming:isDrained(snapshot))&&finish("already_idle")},fail)})}function isDrained(state){return!state.isStreaming&&state.steering.length===0&&state.followUp.length===0&&state.ordered.length===0&&state.pendingMessageCount===0}async function runHostSessionRequest(request){let deadline=Date.now()+STOP_WAIT_BUDGET_MS;for(;;)try{return await runHostSessionRequestOnce(request,Math.max(0,deadline-Date.now()))}catch(error){if(request.action==="open"&&error instanceof RpcCommandError&&error.errorCode==="host_stopping"&&Date.now()<deadline)continue;return mapError(error,request.target.socket)}}async function runHostSessionRequestOnce(request,stoppingTimeoutMs){let{socket,agentDir}=request.target,client,ensured,disconnected,connectionUnusable=!1;try{if(await endpointKindOfSocket(socket,agentDir)==="tui")return refusal("refuse",void 0,{reason:"unsupported_endpoint_kind",socket,endpoint_kind:"tui"});request.action==="open"&&(ensured=await ensureHost({socket,agentDir,hostArgs:request.spec.hostArgs,env:daemonEnvOverrides(process.env,request.spec.env),policy:request.spec.policy,upgrade:"never",stoppingTimeoutMs}),ensured.reused||await writeDaemonEnvKeys(createHostDaemonPaths({socket,agentDir}),daemonEnvKeys(process.env,request.spec.env))),client=new RpcClient({socketPath:socket,onDisconnect:error=>{connectionUnusable=!0,disconnected?.(error)}});try{await client.start()}catch(error){if(error instanceof Error&&"code"in error&&(error.code==="ENOENT"||error.code==="ECONNREFUSED"))return refusal("refuse",void 0,{reason:"host_unavailable",socket,detail:error.message});throw error}let sessionId,durableSessionId;if("ref"in request){let found=await resolveSessionRef(client,request.ref,agentDir);if(found.kind==="unknown")return refusal("refuse",void 0,{reason:"unknown_session",ref:request.ref,socket});if(found.kind==="ambiguous"){let detail={reason:"ambiguous_session",ref:request.ref,candidates:found.candidates,socket};return refusal("refuse",void 0,detail)}let reopen=found.kind==="parked"?{sessionPath:found.sessionPath,cwd:found.cwd,retain_on_disconnect:!0}:{sessionPath:found.row.sessionPath,cwd:found.row.cwd};durableSessionId=found.kind==="parked"?found.durableSessionId:found.row.durableSessionId,sessionId=(await client.openSession(reopen)).sessionId}switch(request.action){case"open":return await openHostSession(client,request,socket,ensured);case"prompt":return{exitCode:HOST_EXIT_OK,payload:{action:"prompt",sessionId,disposition:await client.prompt(request.text)}};case"steer":{let streaming=(await client.getState()).isStreaming,disposition=await client.steer(request.text);return{exitCode:HOST_EXIT_OK,payload:{action:"steer",sessionId,disposition,streaming}}}case"abort":{let aborted=(await client.getState()).isStreaming;return await client.abortStrict(),{exitCode:HOST_EXIT_OK,payload:{action:"abort",sessionId,acknowledged:!0,aborted}}}case"model":{await client.setModel(request.model.provider,request.model.id);let state=await client.getState();return{exitCode:HOST_EXIT_OK,payload:{action:"model",sessionId,requested:request.model,model:state.model?{provider:state.model.provider,id:state.model.id}:null,pendingModelSwitch:state.pendingModelSwitch??null}}}case"list":return{exitCode:HOST_EXIT_OK,payload:{action:"list",socket,sessions:await client.listSessions({observe:!0})}};case"state":return{exitCode:HOST_EXIT_OK,payload:{action:"state",sessionId,durableSessionId,state:await client.getState()}};case"read":{if(request.messages){let all=await client.getMessages(),messages=request.tail===void 0?all:all.slice(-request.tail);return{exitCode:HOST_EXIT_OK,payload:{action:"read",sessionId,messages,count:messages.length}}}let{entries,leafId}=await client.getEntries(request.since),slice=request.tail===void 0?entries:entries.slice(-request.tail);return{exitCode:HOST_EXIT_OK,payload:{action:"read",sessionId,entries:slice,count:slice.length,total:entries.length,leafId,nextSince:slice.at(-1)?.id??request.since??null,...request.since!==void 0&&{since:request.since}}}}case"wait":return await waitForHostSession(client,sessionId,request,handler=>{disconnected=handler});case"unload":{let answer=await client.unloadSession({sessionId,interrupt:request.interrupt,force:request.force,clearQueue:request.clearQueue,children:request.children});return{exitCode:answer.outcome==="unloaded"?HOST_EXIT_OK:HOST_EXIT_REFUSED,payload:{action:"unload",sessionId,...answer}}}case"close":{let reason,unsubscribe=client.onEvent(record=>{let event=record;event.type==="session_closed"&&(reason=event.reason)});try{await client.closeSession(sessionId);let remaining=(await client.listSessions()).find(row=>row.sessionId===sessionId);return{exitCode:HOST_EXIT_OK,payload:remaining?{action:"close",sessionId,closed:!1,attachments:remaining.attachments}:{action:"close",sessionId,closed:!0,reason:reason??"client_close"}}}finally{unsubscribe()}}default:return assertNever(request)}}catch(error){if((error instanceof RpcRequestTimeoutError||isTransportGoneError(error))&&(connectionUnusable=!0),request.action==="open"&&error instanceof RpcCommandError&&error.errorCode==="host_stopping")throw error;return error instanceof HostEnsureRefusedError?refusal("refuse",void 0,{reason:error.reason,socket,detail:error.detail}):mapError(error,socket)}finally{ensured?.release(),client&&!connectionUnusable&&await detachBeforeClose(client,line=>process.stderr.write(`senpi host session: ${line}
2
+ import{RpcClient,RpcCommandError,RpcRequestTimeoutError,RpcTransportGoneError,isTransportGoneError}from"./chunk-IM6ZWYTW.js";import"./chunk-MF57DS3V.js";import{SessionManager,assertValidSessionId}from"./chunk-YUMRZIKJ.js";import"./chunk-4RSWXPUB.js";import"./chunk-RL5QMGQD.js";import{DEFAULT_HOST_LAUNCH_SPEC,HOST_EXIT_ERROR,HOST_EXIT_OK,HOST_EXIT_REFUSED,HOST_EXIT_USAGE,HostLaunchSpecError,STOP_WAIT_BUDGET_MS,daemonEnvKeys,daemonEnvOverrides,emit,ensureHost,loadHostLaunchSpec,refusal,resolveHostSocket,writeDaemonEnvKeys}from"./chunk-X6TWPBI6.js";import{HostEnsureRefusedError}from"./chunk-VEKNDMUA.js";import"./chunk-QMRJYMNH.js";import{endpointKindOfSocket}from"./chunk-36GE6JDV.js";import"./chunk-FM7NDZR5.js";import"./chunk-KUPQO7MC.js";import"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-PMGEQYEP.js";import"./chunk-7QPFFAJT.js";import"./chunk-VPV7ADF3.js";import{canonicalSessionPath,createHostDaemonPaths}from"./chunk-XC2CNM26.js";import"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import{APP_NAME,getAgentDir}from"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-T36LJ6MW.js";import"./chunk-WHPDEDCC.js";import"./chunk-QGJLZ6BI.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";import{readFileSync}from"node:fs";import{resolve}from"node:path";var DETACH_ACK_TIMEOUT_MS=5e3;async function detachBeforeClose(client,report,timeoutMs=DETACH_ACK_TIMEOUT_MS){let timer,late=new Promise(resolve2=>{timer=setTimeout(()=>resolve2("late"),timeoutMs)});try{await Promise.race([client.detachConnection(),late])==="late"&&report(`the host did not confirm the detach within ${timeoutMs} ms; closing the connection anyway`)}catch(error){if(error instanceof RpcTransportGoneError)return;report(`the host refused the detach (${error instanceof Error?error.message:String(error)}); closing the connection anyway`)}finally{clearTimeout(timer)}}var USAGE_CODES=new Set(["missing_session_id","invalid_path","invalid_session_context","invalid_session_kind","invalid_launch_profile","invalid_session_id","invalid_release_reason","empty","unknown_command"]),FAILURE_CODES=new Set(["open_failed","warm_failed","release_failed"]),REASON_FOR_CODE={streaming:"busy",not_found:"unknown_cursor"},BARE_CODE=/^[a-z][a-z0-9_]*$/;function mapError(error,socket){let detail=error instanceof Error?error.message:String(error);if(error instanceof RpcCommandError){let code=error.errorCode??(BARE_CODE.test(detail)?detail:void 0);if(code===void 0)return hostError(detail,socket);let exitCode=USAGE_CODES.has(code)?HOST_EXIT_USAGE:FAILURE_CODES.has(code)?HOST_EXIT_ERROR:HOST_EXIT_REFUSED;return{exitCode,payload:{action:exitCode===HOST_EXIT_REFUSED?"refuse":"error",reason:REASON_FOR_CODE[code]??code,detail,socket,...error.errorData!==void 0&&{data:error.errorData}}}}return isTransportGoneError(error)?{exitCode:HOST_EXIT_ERROR,payload:{action:"error",reason:"transport_gone",detail,socket}}:hostError(detail,socket)}function hostError(detail,socket){return{exitCode:HOST_EXIT_ERROR,payload:{action:"error",reason:"host_error",detail,socket}}}async function openHostSession(client,request,socket,ensured){let opened=await client.openSession({cwd:request.cwd,retain_on_disconnect:!0,...request.model&&{provider:request.model.provider,modelId:request.model.id}});ensured?.release();let{state}=opened,identity={sessionId:opened.sessionId,sessionPath:state.sessionFile,durableSessionId:state.sessionId};try{request.name!==void 0&&await client.setSessionName(request.name);let disposition=request.prompt===void 0?void 0:await client.prompt(request.prompt);return{exitCode:HOST_EXIT_OK,payload:{action:"open",socket,pid:ensured?.pid,reused:ensured?.reused,...identity,cwd:state.cwd,model:state.model?{provider:state.model.provider,id:state.model.id}:null,attached:opened.attached??!1,...disposition!==void 0&&{prompt:{disposition}}}}}catch(error){let outcome=mapError(error,socket),closed=await closeOpened(client,opened.sessionId);return{...outcome,payload:{...outcome.payload,...identity,closed}}}}async function closeOpened(client,sessionId){try{return await client.closeSession(sessionId),!(await client.listSessions()).some(row=>row.sessionId===sessionId)}catch{return!1}}import{existsSync}from"node:fs";import{readdir}from"node:fs/promises";import{dirname,join}from"node:path";async function resolveSessionRef(client,ref,agentDir){let rows=await client.listSessions(),handle=rows.find(row=>row.sessionId===ref);if(handle)return{kind:"live",row:handle};if(isSessionId(ref)){let byId=await resolveDurableId(ref,rows,agentDir);if(byId)return byId}let named=rows.filter(row=>row.name===ref);if(named.length>1)return{kind:"ambiguous",candidates:named.map(row=>row.sessionId)};let live=named[0]??rows.find(row=>row.sessionPath!==void 0&&samePath(row.sessionPath,ref));return live?{kind:"live",row:live}:looksLikePath(ref)?parkedByPath(ref):{kind:"unknown"}}async function resolveDurableId(id,rows,agentDir){let liveRows=rows.filter(row=>row.durableSessionId===id),transcripts=(await transcriptsUnder(agentDir)).filter(session=>session.id===id),files=new Set([...liveRows.map(row=>row.sessionPath===void 0?row.sessionId:canonicalSessionPath(row.sessionPath)),...transcripts.map(session=>canonicalSessionPath(session.path))]);return files.size>1?{kind:"ambiguous",candidates:[...files]}:liveRows[0]?{kind:"live",row:liveRows[0]}:transcripts[0]?parked(transcripts[0]):void 0}function isSessionId(ref){try{return assertValidSessionId(ref),!0}catch{return!1}}function looksLikePath(ref){return ref.includes("/")||ref.includes("\\")||ref.endsWith(".jsonl")}async function parkedByPath(ref){let path=canonicalSessionPath(ref);if(!existsSync(path))return{kind:"unknown"};let info=(await SessionManager.listAll(dirname(path))).find(session=>samePath(session.path,path));return info?parked(info):{kind:"unknown"}}async function transcriptsUnder(agentDir){let root=join(agentDir,"sessions");if(!existsSync(root))return[];let dirs=(await readdir(root,{withFileTypes:!0})).filter(entry=>entry.isDirectory());return(await Promise.all(dirs.map(entry=>SessionManager.listAll(join(root,entry.name))))).flat()}function parked(info){return{kind:"parked",sessionPath:info.path,cwd:info.cwd,durableSessionId:info.id}}function samePath(left,right){return canonicalSessionPath(left)===canonicalSessionPath(right)}function waitForHostSession(client,sessionId,request,onTransportLoss){let started=Date.now();return new Promise((resolveWait,reject)=>{let finished=!1,observed=!1,state,timer,cleanup=()=>{finished=!0,clearTimeout(timer),unsubscribe(),onTransportLoss(void 0)},fail=error=>{finished||(cleanup(),reject(error))},finish=outcome=>{finished||(cleanup(),resolveWait({exitCode:HOST_EXIT_OK,payload:{action:"wait",sessionId,until:request.until,outcome,waited_ms:Date.now()-started,state:{isStreaming:state?.isStreaming??!1,pendingMessageCount:state?.pendingMessageCount??0,lastAbortSource:state?.lastAbortSource??null}}}))},unsubscribe=client.onEvent(record=>{let event=record;if(event.type==="session_closed"||event.type==="session_parked"){finish(event.type);return}if(event.type==="agent_settled"&&"reason"in event&&event.reason==="session_closed"){finish("session_closed");return}event.type!=="agent_idle"&&!(request.until==="done"&&event.type==="agent_settled")||(observed=!0,client.getState().then(snapshot=>{state=snapshot,request.until==="done"?finish("done"):isDrained(snapshot)&&finish("idle")},fail))});onTransportLoss(fail),timer=setTimeout(()=>{finished||(cleanup(),resolveWait({exitCode:HOST_EXIT_ERROR,payload:{action:"error",reason:"wait_timeout",sessionId,until:request.until,timeoutMs:request.timeoutMs}}))},request.timeoutMs),client.getState().then(snapshot=>{state=snapshot,!observed&&(request.until==="done"?!snapshot.isStreaming:isDrained(snapshot))&&finish("already_idle")},fail)})}function isDrained(state){return!state.isStreaming&&state.steering.length===0&&state.followUp.length===0&&state.ordered.length===0&&state.pendingMessageCount===0}async function runHostSessionRequest(request){let deadline=Date.now()+STOP_WAIT_BUDGET_MS;for(;;)try{return await runHostSessionRequestOnce(request,Math.max(0,deadline-Date.now()))}catch(error){if(request.action==="open"&&error instanceof RpcCommandError&&error.errorCode==="host_stopping"&&Date.now()<deadline)continue;return mapError(error,request.target.socket)}}async function runHostSessionRequestOnce(request,stoppingTimeoutMs){let{socket,agentDir}=request.target,client,ensured,disconnected,connectionUnusable=!1;try{if(await endpointKindOfSocket(socket,agentDir)==="tui")return refusal("refuse",void 0,{reason:"unsupported_endpoint_kind",socket,endpoint_kind:"tui"});request.action==="open"&&(ensured=await ensureHost({socket,agentDir,hostArgs:request.spec.hostArgs,env:daemonEnvOverrides(process.env,request.spec.env),policy:request.spec.policy,upgrade:"never",stoppingTimeoutMs}),ensured.reused||await writeDaemonEnvKeys(createHostDaemonPaths({socket,agentDir}),daemonEnvKeys(process.env,request.spec.env))),client=new RpcClient({socketPath:socket,onDisconnect:error=>{connectionUnusable=!0,disconnected?.(error)}});try{await client.start()}catch(error){if(error instanceof Error&&"code"in error&&(error.code==="ENOENT"||error.code==="ECONNREFUSED"))return refusal("refuse",void 0,{reason:"host_unavailable",socket,detail:error.message});throw error}let sessionId,durableSessionId;if("ref"in request){let found=await resolveSessionRef(client,request.ref,agentDir);if(found.kind==="unknown")return refusal("refuse",void 0,{reason:"unknown_session",ref:request.ref,socket});if(found.kind==="ambiguous"){let detail={reason:"ambiguous_session",ref:request.ref,candidates:found.candidates,socket};return refusal("refuse",void 0,detail)}let reopen=found.kind==="parked"?{sessionPath:found.sessionPath,cwd:found.cwd,retain_on_disconnect:!0}:{sessionPath:found.row.sessionPath,cwd:found.row.cwd};durableSessionId=found.kind==="parked"?found.durableSessionId:found.row.durableSessionId,sessionId=(await client.openSession(reopen)).sessionId}switch(request.action){case"open":return await openHostSession(client,request,socket,ensured);case"prompt":return{exitCode:HOST_EXIT_OK,payload:{action:"prompt",sessionId,disposition:await client.prompt(request.text)}};case"steer":{let streaming=(await client.getState()).isStreaming,disposition=await client.steer(request.text);return{exitCode:HOST_EXIT_OK,payload:{action:"steer",sessionId,disposition,streaming}}}case"abort":{let aborted=(await client.getState()).isStreaming;return await client.abortStrict(),{exitCode:HOST_EXIT_OK,payload:{action:"abort",sessionId,acknowledged:!0,aborted}}}case"model":{await client.setModel(request.model.provider,request.model.id);let state=await client.getState();return{exitCode:HOST_EXIT_OK,payload:{action:"model",sessionId,requested:request.model,model:state.model?{provider:state.model.provider,id:state.model.id}:null,pendingModelSwitch:state.pendingModelSwitch??null}}}case"list":return{exitCode:HOST_EXIT_OK,payload:{action:"list",socket,sessions:await client.listSessions({observe:!0})}};case"state":return{exitCode:HOST_EXIT_OK,payload:{action:"state",sessionId,durableSessionId,state:await client.getState()}};case"read":{if(request.messages){let all=await client.getMessages(),messages=request.tail===void 0?all:all.slice(-request.tail);return{exitCode:HOST_EXIT_OK,payload:{action:"read",sessionId,messages,count:messages.length}}}let{entries,leafId}=await client.getEntries(request.since),slice=request.tail===void 0?entries:entries.slice(-request.tail);return{exitCode:HOST_EXIT_OK,payload:{action:"read",sessionId,entries:slice,count:slice.length,total:entries.length,leafId,nextSince:slice.at(-1)?.id??request.since??null,...request.since!==void 0&&{since:request.since}}}}case"wait":return await waitForHostSession(client,sessionId,request,handler=>{disconnected=handler});case"unload":{let answer=await client.unloadSession({sessionId,interrupt:request.interrupt,force:request.force,clearQueue:request.clearQueue,children:request.children});return{exitCode:answer.outcome==="unloaded"?HOST_EXIT_OK:HOST_EXIT_REFUSED,payload:{action:"unload",sessionId,...answer}}}case"close":{let reason,unsubscribe=client.onEvent(record=>{let event=record;event.type==="session_closed"&&(reason=event.reason)});try{await client.closeSession(sessionId);let remaining=(await client.listSessions()).find(row=>row.sessionId===sessionId);return{exitCode:HOST_EXIT_OK,payload:remaining?{action:"close",sessionId,closed:!1,attachments:remaining.attachments}:{action:"close",sessionId,closed:!0,reason:reason??"client_close"}}}finally{unsubscribe()}}default:return assertNever(request)}}catch(error){if((error instanceof RpcRequestTimeoutError||isTransportGoneError(error))&&(connectionUnusable=!0),request.action==="open"&&error instanceof RpcCommandError&&error.errorCode==="host_stopping")throw error;return error instanceof HostEnsureRefusedError?refusal("refuse",void 0,{reason:error.reason,socket,detail:error.detail}):mapError(error,socket)}finally{ensured?.release(),client&&!connectionUnusable&&await detachBeforeClose(client,line=>process.stderr.write(`senpi host session: ${line}
3
3
  `)),await client?.stop()}}function assertNever(value){throw new Error(`unreachable host session request: ${JSON.stringify(value)}`)}var USAGE=`usage: ${APP_NAME} host session <command> [--socket <path>] [--json]
4
4
 
5
5
  open --cwd <dir> [--model <provider/id>] [--name <text>] [--prompt <text|@file>] [--launch-spec <file>]
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{InteractiveMode,OptimisticUserEchoController,createInteractiveTui,createInteractiveTuiReference,formatCrashExtensionHint,formatResumeCommand,isApiKeyLoginProvider,shouldShowRetryIndicator,showsStartupDetails,showsStartupHeader}from"./chunk-IRKZ6FVC.js";import"./chunk-NRHOGI4Z.js";import"./chunk-5EPXJZ26.js";import"./chunk-SHKXJWK3.js";import"./chunk-Z2LCTXS2.js";import"./chunk-KI2EEM4R.js";import"./chunk-IDXW4FAO.js";import"./chunk-QBD4LY7D.js";import"./chunk-MF57DS3V.js";import"./chunk-FZTO2ICI.js";import"./chunk-PKDWFVE4.js";import"./chunk-4RSWXPUB.js";import"./chunk-OJPUDLM2.js";import"./chunk-UUMKAA7S.js";import"./chunk-MX6VSFEY.js";import"./chunk-WIAXG52U.js";import"./chunk-QN2BHP3M.js";import"./chunk-AMKQSLWE.js";import"./chunk-RELAITQ7.js";import"./chunk-GAHIHXVE.js";import"./chunk-QMRJYMNH.js";import"./chunk-36GE6JDV.js";import"./chunk-VAUNLGQR.js";import"./chunk-H4QOEVS5.js";import"./chunk-HB35RBP4.js";import"./chunk-3QVP3ZVI.js";import"./chunk-OMY4EC25.js";import"./chunk-SMIIHUSE.js";import"./chunk-YU4AYH4C.js";import"./chunk-DDHBG2HU.js";import"./chunk-BIIMVCMO.js";import"./chunk-7X72IACK.js";import"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-OOWML2KE.js";import"./chunk-T2BEB5SO.js";import"./chunk-TFXUF2IL.js";import"./chunk-XC2CNM26.js";import"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-BMX2U22F.js";import"./chunk-YU2P3CAR.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import"./chunk-4RUVN7K3.js";import"./chunk-ZOFZRJSL.js";import"./chunk-2SOVDETB.js";import"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-QXREUA5F.js";import"./chunk-WASCMT6Y.js";import"./chunk-COJK5FDH.js";import"./chunk-WHPDEDCC.js";import"./chunk-RUGYFYH7.js";import"./chunk-PFNBY43W.js";import"./chunk-OEFCY46F.js";import"./chunk-KRNXUTZJ.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-TAV6QZFM.js";import"./chunk-PELNNWGO.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";export{InteractiveMode,OptimisticUserEchoController,createInteractiveTui,createInteractiveTuiReference,formatCrashExtensionHint,formatResumeCommand,isApiKeyLoginProvider,shouldShowRetryIndicator,showsStartupDetails,showsStartupHeader};
2
+ import{InteractiveMode,OptimisticUserEchoController,createInteractiveTui,createInteractiveTuiReference,formatCrashExtensionHint,formatResumeCommand,isApiKeyLoginProvider,shouldShowRetryIndicator,showsStartupDetails,showsStartupHeader}from"./chunk-35M5MVUZ.js";import"./chunk-IM6ZWYTW.js";import"./chunk-5EPXJZ26.js";import"./chunk-SHKXJWK3.js";import"./chunk-G7LLAQXI.js";import"./chunk-KI2EEM4R.js";import"./chunk-3DNYAO3P.js";import"./chunk-ZPSJQHDK.js";import"./chunk-MF57DS3V.js";import"./chunk-QRGAMVEE.js";import"./chunk-YUMRZIKJ.js";import"./chunk-4RSWXPUB.js";import"./chunk-OJPUDLM2.js";import"./chunk-RL5QMGQD.js";import"./chunk-MX6VSFEY.js";import"./chunk-WIAXG52U.js";import"./chunk-QN2BHP3M.js";import"./chunk-AMKQSLWE.js";import"./chunk-X6TWPBI6.js";import"./chunk-VEKNDMUA.js";import"./chunk-QMRJYMNH.js";import"./chunk-36GE6JDV.js";import"./chunk-VAUNLGQR.js";import"./chunk-H4QOEVS5.js";import"./chunk-HB35RBP4.js";import"./chunk-QXEWAKXA.js";import"./chunk-FSENE7JK.js";import"./chunk-SMIIHUSE.js";import"./chunk-YU4AYH4C.js";import"./chunk-FM7NDZR5.js";import"./chunk-BIIMVCMO.js";import"./chunk-7X72IACK.js";import"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-PMGEQYEP.js";import"./chunk-7QPFFAJT.js";import"./chunk-VPV7ADF3.js";import"./chunk-XC2CNM26.js";import"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-BMX2U22F.js";import"./chunk-YU2P3CAR.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import"./chunk-BOCN744P.js";import"./chunk-ZOFZRJSL.js";import"./chunk-2SOVDETB.js";import"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-QXREUA5F.js";import"./chunk-WASCMT6Y.js";import"./chunk-T36LJ6MW.js";import"./chunk-WHPDEDCC.js";import"./chunk-RUGYFYH7.js";import"./chunk-QGJLZ6BI.js";import"./chunk-OEFCY46F.js";import"./chunk-KRNXUTZJ.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-TAV6QZFM.js";import"./chunk-PELNNWGO.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";export{InteractiveMode,OptimisticUserEchoController,createInteractiveTui,createInteractiveTuiReference,formatCrashExtensionHint,formatResumeCommand,isApiKeyLoginProvider,shouldShowRetryIndicator,showsStartupDetails,showsStartupHeader};
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{TIP_DEFINITIONS}from"./chunk-KI2EEM4R.js";import{KeybindingsManager}from"./chunk-IDXW4FAO.js";import"./chunk-UUMKAA7S.js";import"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-IKOFCODM.js";function collectTips(){let keybindings=new KeybindingsManager,keys=binding=>keybindings.getKeys(binding).join("/");return TIP_DEFINITIONS.map(tip=>{let text=tip.render(keys);return tip.requiresCommand!==void 0?{id:tip.id,text,requiresCommand:tip.requiresCommand}:{id:tip.id,text}})}function listTips(){console.log(JSON.stringify(collectTips(),null,2))}export{collectTips,listTips};
2
+ import{TIP_DEFINITIONS}from"./chunk-KI2EEM4R.js";import{KeybindingsManager}from"./chunk-3DNYAO3P.js";import"./chunk-RL5QMGQD.js";import"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-IKOFCODM.js";function collectTips(){let keybindings=new KeybindingsManager,keys=binding=>keybindings.getKeys(binding).join("/");return TIP_DEFINITIONS.map(tip=>{let text=tip.render(keys);return tip.requiresCommand!==void 0?{id:tip.id,text,requiresCommand:tip.requiresCommand}:{id:tip.id,text}})}function listTips(){console.log(JSON.stringify(collectTips(),null,2))}export{collectTips,listTips};
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{SessionEventWriter,answerSetSessionContext,answerSubscribeSessions,answerUnsubscribeSessions,notAttachedRefusal,publishedSessionContext,recordLoopBlockedMs,registryStatusSource,socketSink}from"./chunk-6EXDMO4S.js";import{ACCEPT_EDITS_PERMISSION_PRESET_CAPABILITY,AUTO_PERMISSION_PRESET_CAPABILITY,AgentSessionRuntime,HostMcpRegistry,ProviderScope,bindToProviderScope,createAgentSessionRuntime,createRpcConnectionHandler,createWebViewBroker,foreignSessionHolders,parsePermissionPresetName,readCodemodeKernelRows,readMainThreadHeapBytes,readOwnFootprint,runWithProviderScope,startHostChildReaper,subscriptionLimits}from"./chunk-IRKZ6FVC.js";import"./chunk-NRHOGI4Z.js";import{readProcessStartMs}from"./chunk-5EPXJZ26.js";import"./chunk-SHKXJWK3.js";import{flushRawStdout,liveToolMediaScope,takeOverStdout,toolMediaPersister,waitForRawStdoutBackpressure,writeRawStdout}from"./chunk-Z2LCTXS2.js";import"./chunk-KI2EEM4R.js";import"./chunk-IDXW4FAO.js";import{ClientAdmissions,DURABLE_CLIENT_MESSAGE_ID_CAPABILITY,EFFECT_LEDGER_CAPABILITY,EMPTY_SESSION_CONTEXT,EffectLedger,answerEffectFromTranscript,beginEffect,buildRpcSessionState,drainSessionEffects,effectAnswer,installSessionEffectSink,isEffectBegin,latestSessionEffect,rpcCommandShapeError,sessionAutoTitleError,sessionBrowserEngineError,sessionContextError,sessionKindError,sessionPromptSurfaceError,sessionRetryFallbackError}from"./chunk-QBD4LY7D.js";import{RPC_ERROR_ATTACHED,RPC_ERROR_HOST_DRAINING,RPC_ERROR_INVALID_LAUNCH_PROFILE,RPC_ERROR_INVALID_PATH,RPC_ERROR_INVALID_RELEASE_REASON,RPC_ERROR_INVALID_SESSION_CONTEXT,RPC_ERROR_INVALID_SESSION_KIND,RPC_ERROR_MISSING_SESSION_ID,RPC_ERROR_OPEN_FAILED,RPC_ERROR_OWNER_CHANGED,RPC_ERROR_RELEASE_FAILED,RPC_ERROR_RELEASE_UNSUPPORTED,RPC_ERROR_SESSION_BUSY,RPC_ERROR_SESSION_CLOSING,RPC_ERROR_SESSION_HELD,RPC_ERROR_TURN_ACTIVE,RPC_ERROR_UNKNOWN_SESSION,RPC_ERROR_WARM_FAILED,STEER_WHEN_IDLE_CAPABILITY}from"./chunk-MF57DS3V.js";import"./chunk-FZTO2ICI.js";import{SessionManager,assertValidSessionId}from"./chunk-PKDWFVE4.js";import{resolveMovedPath}from"./chunk-4RSWXPUB.js";import"./chunk-OJPUDLM2.js";import"./chunk-UUMKAA7S.js";import"./chunk-MX6VSFEY.js";import"./chunk-WIAXG52U.js";import{ownProcessStartedAtMs}from"./chunk-QN2BHP3M.js";import"./chunk-AMKQSLWE.js";import{BEGIN_HANDOVER_COMMAND,EXPECTED_RUNTIME_BUILD_ID_ENV,HostIdleHandover,beginHandoverResponse,handoverRefusal,isHandoffBusy,isHostIdle,parseBeginHandover,performIdleHandover,readDrainVerdicts,runAsHostGenerationProcess,withHostIdentity}from"./chunk-RELAITQ7.js";import{AUTH_KEY_VERIFY_CAPABILITY,AUTO_TITLE_PER_SESSION_CAPABILITY,AUTO_TITLE_SESSIONS_CAPABILITY,BROWSER_ENGINE_CAPABILITY,CONTINUE_FROM_LEAF_CAPABILITY,DETACH_CONNECTION_CAPABILITY,DURABLE_SESSION_ID_CAPABILITY,EVAL_CELLS_CAPABILITY,GENERATION_HANDOFF_CAPABILITY,MEDIA_PLACEHOLDERS_CAPABILITY,MOVED_PATH_GUARD_CAPABILITY,PROMPT_SURFACE_CAPABILITY,PROMPT_SURFACE_CHAT_CAPABILITY,QUEUED_MESSAGE_REVISION_CAPABILITY,RETAIN_ON_DISCONNECT_CAPABILITY,RETRY_FALLBACK_PROFILE_CAPABILITY,RUNTIME_IDENTITY_HANDOVER_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_HELD_CAPABILITY,SESSION_KIND_CAPABILITY,SESSION_STATUS_CAPABILITY,WARM_CAPABILITY,computeRuntimeBuildId,hostGeneration,hostInstanceId,parseClientCapabilities,protocolIdentity}from"./chunk-GAHIHXVE.js";import"./chunk-QMRJYMNH.js";import"./chunk-36GE6JDV.js";import"./chunk-VAUNLGQR.js";import"./chunk-H4QOEVS5.js";import"./chunk-HB35RBP4.js";import"./chunk-3QVP3ZVI.js";import{killTrackedDetachedChildren}from"./chunk-OMY4EC25.js";import"./chunk-SMIIHUSE.js";import"./chunk-YU4AYH4C.js";import"./chunk-DDHBG2HU.js";import"./chunk-BIIMVCMO.js";import"./chunk-7X72IACK.js";import"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import{toolRuntimeCapability}from"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-OOWML2KE.js";import{ClientOccupancy,armHostWatchdog,loopLagErrorMs,prepareSocketPath,readHostWatchdogConfigFromBrandEnv}from"./chunk-T2BEB5SO.js";import{PUBLIC_SOCKET_IDENTITY_FILE,SESSION_PATH_RETRY_AFTER_MS,createEndpointReservations,ownGenerationDir,parseIdleExitMs,readSocketIdentityFile,shieldSocketDuringClose,socketEntryReplaced,statSocketIdentity,unlinkOwnedSocket,waitForSocketIdentityFile,writeHeartbeat,writeStallEvidence}from"./chunk-TFXUF2IL.js";import{MAX_RPC_LINE_CHARACTERS,SOCKET_SECRET_FILE_ENV,attachJsonlLineReader,authenticateSocket,canonicalSessionPath,createHostDaemonPaths,ensureSocketSecret,resolveSocketTransportAddress,sessionDirectoryRemoved,socketSecretPath}from"./chunk-XC2CNM26.js";import{processStartTimeMs}from"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-BMX2U22F.js";import"./chunk-YU2P3CAR.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import"./chunk-4RUVN7K3.js";import"./chunk-ZOFZRJSL.js";import"./chunk-2SOVDETB.js";import{VERSION,envValue,isBunBinary}from"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-QXREUA5F.js";import"./chunk-WASCMT6Y.js";import"./chunk-COJK5FDH.js";import"./chunk-WHPDEDCC.js";import"./chunk-RUGYFYH7.js";import"./chunk-PFNBY43W.js";import"./chunk-OEFCY46F.js";import"./chunk-KRNXUTZJ.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-TAV6QZFM.js";import"./chunk-PELNNWGO.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";import{chmod}from"node:fs/promises";import{createServer}from"node:net";import{basename,dirname,join as join2}from"node:path";var HostCoreGate=class{constructor(registry,route,hooks){this.inFlight=new Map,this.answering=new Set,this.route=route,this.runtimeBuildId=hooks.runtimeBuildId,this.handover=hooks.handover===void 0?void 0:new HostIdleHandover({...hooks.handover,isIdle:()=>isHostIdle(registry,this.inFlight)})}async intercept(parsed,deliver){if(!isRecord(parsed)||parsed.type!==BEGIN_HANDOVER_COMMAND)return!1;let answering=this.answerBegin(parsed).then(deliver);this.answering.add(answering);try{await answering}finally{this.answering.delete(answering)}return!0}async answerBegin(parsed){if(this.handover===void 0)return beginHandoverResponse(parsed.id,{kind:"refused",reason:"handover_unsupported"});let request=parseBeginHandover(parsed);return beginHandoverResponse(parsed.id,typeof request=="string"?request:await this.handover.begin(request))}async answered(){for(;this.answering.size>0;)await Promise.allSettled([...this.answering])}async dispatch(command){let pending=this.handover?.view();if(pending!==void 0&&this.handover?.admits(command.type)===!1)return handoverRefusal(command,pending);let key="sessionId"in command?command.sessionId:void 0;this.inFlight.set(key,(this.inFlight.get(key)??0)+1);let response;try{response=await this.route(command)}finally{let remaining=(this.inFlight.get(key)??1)-1;remaining>0?this.inFlight.set(key,remaining):this.inFlight.delete(key),this.handover?.observe()}return response===void 0?void 0:withHostIdentity(response,this.runtimeBuildId,this.handover?.view())}};function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}import{existsSync as existsSync4}from"node:fs";import{createHash}from"node:crypto";import{existsSync,renameSync}from"node:fs";import{mkdir,readdir,readFile,rm,writeFile}from"node:fs/promises";import{join}from"node:path";var recordDir=daemonDir=>join(daemonDir,"handover-parked"),entryFile=(daemonDir,sessionPath)=>join(recordDir(daemonDir),`${createHash("sha256").update(sessionPath,"utf8").digest("hex").slice(0,16)}.json`),mutationChain=Promise.resolve();function enqueueMutation(mutation){let next=mutationChain.then(mutation,mutation);return mutationChain=next.catch(()=>{}),next}function isEntry(value){if(typeof value!="object"||value===null||Array.isArray(value))return!1;let record=value;return typeof record.sessionPath=="string"&&typeof record.retainOnDisconnect=="boolean"&&(record.durableSessionId===void 0||typeof record.durableSessionId=="string")&&(record.cwd===void 0||typeof record.cwd=="string")&&(record.parkedBy===void 0||typeof record.parkedBy=="string")&&(record.thinkingLevel===void 0||typeof record.thinkingLevel=="string")&&(record.permissionPreset===void 0||typeof record.permissionPreset=="string"&&parsePermissionPresetName(record.permissionPreset)!==void 0)&&sessionPromptSurfaceError(record.promptSurface)===void 0&&sessionBrowserEngineError(record.browserEngine)===void 0&&sessionKindError(record.sessionKind)===void 0&&sessionContextError(record.sessionContext)===void 0&&sessionAutoTitleError(record.autoTitle)===void 0&&sessionRetryFallbackError(record.retryFallback)===void 0&&(record.model===void 0||typeof record.model=="object"&&record.model!==null&&typeof record.model.provider=="string"&&typeof record.model.modelId=="string")}async function writeEntryFile(daemonDir,entry){await mkdir(recordDir(daemonDir),{recursive:!0,mode:448});let file=entryFile(daemonDir,entry.sessionPath),tmp=`${file}.${process.pid}.${Math.random().toString(16).slice(2,10)}.tmp`;await writeFile(tmp,`${JSON.stringify(entry,null,2)}
2
+ import{SessionEventWriter,answerSetSessionContext,answerSubscribeSessions,answerUnsubscribeSessions,notAttachedRefusal,publishedSessionContext,recordLoopBlockedMs,registryStatusSource,socketSink}from"./chunk-QJ6MUFXY.js";import{ACCEPT_EDITS_PERMISSION_PRESET_CAPABILITY,AUTO_PERMISSION_PRESET_CAPABILITY,AgentSessionRuntime,HostMcpRegistry,ProviderScope,bindToProviderScope,createAgentSessionRuntime,createRpcConnectionHandler,createWebViewBroker,foreignSessionHolders,parsePermissionPresetName,readCodemodeKernelRows,readMainThreadHeapBytes,readOwnFootprint,runWithProviderScope,startHostChildReaper,subscriptionLimits}from"./chunk-35M5MVUZ.js";import"./chunk-IM6ZWYTW.js";import{readProcessStartMs}from"./chunk-5EPXJZ26.js";import"./chunk-SHKXJWK3.js";import{flushRawStdout,liveToolMediaScope,takeOverStdout,toolMediaPersister,waitForRawStdoutBackpressure,writeRawStdout}from"./chunk-G7LLAQXI.js";import"./chunk-KI2EEM4R.js";import"./chunk-3DNYAO3P.js";import{ClientAdmissions,DURABLE_CLIENT_MESSAGE_ID_CAPABILITY,EFFECT_LEDGER_CAPABILITY,EMPTY_SESSION_CONTEXT,EffectLedger,answerEffectFromTranscript,beginEffect,buildRpcSessionState,drainSessionEffects,effectAnswer,installSessionEffectSink,isEffectBegin,latestSessionEffect,rpcCommandShapeError,sessionAutoTitleError,sessionBrowserEngineError,sessionContextError,sessionKindError,sessionPromptSurfaceError,sessionRetryFallbackError}from"./chunk-ZPSJQHDK.js";import{RPC_ERROR_ATTACHED,RPC_ERROR_HOST_DRAINING,RPC_ERROR_INVALID_LAUNCH_PROFILE,RPC_ERROR_INVALID_PATH,RPC_ERROR_INVALID_RELEASE_REASON,RPC_ERROR_INVALID_SESSION_CONTEXT,RPC_ERROR_INVALID_SESSION_KIND,RPC_ERROR_MISSING_SESSION_ID,RPC_ERROR_OPEN_FAILED,RPC_ERROR_OWNER_CHANGED,RPC_ERROR_RELEASE_FAILED,RPC_ERROR_RELEASE_UNSUPPORTED,RPC_ERROR_SESSION_BUSY,RPC_ERROR_SESSION_CLOSING,RPC_ERROR_SESSION_HELD,RPC_ERROR_TURN_ACTIVE,RPC_ERROR_UNKNOWN_SESSION,RPC_ERROR_WARM_FAILED,STEER_WHEN_IDLE_CAPABILITY}from"./chunk-MF57DS3V.js";import"./chunk-QRGAMVEE.js";import{SessionManager,SessionMovedAwayError,assertValidSessionId}from"./chunk-YUMRZIKJ.js";import{resolveMovedPath}from"./chunk-4RSWXPUB.js";import"./chunk-OJPUDLM2.js";import"./chunk-RL5QMGQD.js";import"./chunk-MX6VSFEY.js";import"./chunk-WIAXG52U.js";import{ownProcessStartedAtMs}from"./chunk-QN2BHP3M.js";import"./chunk-AMKQSLWE.js";import{BEGIN_HANDOVER_COMMAND,EXPECTED_RUNTIME_BUILD_ID_ENV,HostIdleHandover,beginHandoverResponse,handoverRefusal,isHandoffBusy,isHostIdle,parseBeginHandover,performIdleHandover,readDrainVerdicts,runAsHostGenerationProcess,withHostIdentity}from"./chunk-X6TWPBI6.js";import{AUTH_KEY_VERIFY_CAPABILITY,AUTO_TITLE_PER_SESSION_CAPABILITY,AUTO_TITLE_SESSIONS_CAPABILITY,BROWSER_ENGINE_CAPABILITY,CONTINUE_FROM_LEAF_CAPABILITY,DETACH_CONNECTION_CAPABILITY,DURABLE_SESSION_ID_CAPABILITY,EVAL_CELLS_CAPABILITY,GENERATION_HANDOFF_CAPABILITY,MEDIA_PLACEHOLDERS_CAPABILITY,MOVED_PATH_GUARD_CAPABILITY,PROMPT_SURFACE_CAPABILITY,PROMPT_SURFACE_CHAT_CAPABILITY,QUEUED_MESSAGE_REVISION_CAPABILITY,RETAIN_ON_DISCONNECT_CAPABILITY,RETRY_FALLBACK_PROFILE_CAPABILITY,RUNTIME_IDENTITY_HANDOVER_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_HELD_CAPABILITY,SESSION_KIND_CAPABILITY,SESSION_STATUS_CAPABILITY,WARM_CAPABILITY,computeRuntimeBuildId,hostGeneration,hostInstanceId,parseClientCapabilities,protocolIdentity}from"./chunk-VEKNDMUA.js";import"./chunk-QMRJYMNH.js";import"./chunk-36GE6JDV.js";import"./chunk-VAUNLGQR.js";import"./chunk-H4QOEVS5.js";import"./chunk-HB35RBP4.js";import"./chunk-QXEWAKXA.js";import{killTrackedDetachedChildren}from"./chunk-FSENE7JK.js";import"./chunk-SMIIHUSE.js";import"./chunk-YU4AYH4C.js";import"./chunk-FM7NDZR5.js";import"./chunk-BIIMVCMO.js";import"./chunk-7X72IACK.js";import"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import{toolRuntimeCapability}from"./chunk-GOKAWZUO.js";import"./chunk-26UBFF6N.js";import"./chunk-PMGEQYEP.js";import{ClientOccupancy,armHostWatchdog,loopLagErrorMs,prepareSocketPath,readHostWatchdogConfigFromBrandEnv}from"./chunk-7QPFFAJT.js";import{PUBLIC_SOCKET_IDENTITY_FILE,SESSION_PATH_RETRY_AFTER_MS,createEndpointReservations,ownGenerationDir,parseIdleExitMs,readSocketIdentityFile,shieldSocketDuringClose,socketEntryReplaced,statSocketIdentity,unlinkOwnedSocket,waitForSocketIdentityFile,writeHeartbeat,writeStallEvidence}from"./chunk-VPV7ADF3.js";import{MAX_RPC_LINE_CHARACTERS,SOCKET_SECRET_FILE_ENV,attachJsonlLineReader,authenticateSocket,canonicalSessionPath,createHostDaemonPaths,ensureSocketSecret,resolveSocketTransportAddress,sessionDirectoryRemoved,socketSecretPath}from"./chunk-XC2CNM26.js";import{processStartTimeMs}from"./chunk-7ASLQ243.js";import"./chunk-U3VOXCGP.js";import"./chunk-2VZJTDUX.js";import"./chunk-BMX2U22F.js";import"./chunk-YU2P3CAR.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-AUZXSLZN.js";import"./chunk-BOCN744P.js";import"./chunk-ZOFZRJSL.js";import"./chunk-2SOVDETB.js";import{VERSION,envValue,isBunBinary}from"./chunk-G3ZEPNGM.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-QXREUA5F.js";import"./chunk-WASCMT6Y.js";import"./chunk-T36LJ6MW.js";import"./chunk-WHPDEDCC.js";import"./chunk-RUGYFYH7.js";import"./chunk-QGJLZ6BI.js";import"./chunk-OEFCY46F.js";import"./chunk-KRNXUTZJ.js";import"./chunk-UAQW2T7G.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-45SZOLCU.js";import"./chunk-TAV6QZFM.js";import"./chunk-PELNNWGO.js";import"./chunk-3W47LTXQ.js";import"./chunk-WQLMQGOW.js";import"./chunk-WDTJ6JKE.js";import"./chunk-LAWS3FYQ.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";import{chmod}from"node:fs/promises";import{createServer}from"node:net";import{basename,dirname,join as join2}from"node:path";var HostCoreGate=class{constructor(registry,route,hooks){this.inFlight=new Map,this.answering=new Set,this.route=route,this.runtimeBuildId=hooks.runtimeBuildId,this.handover=hooks.handover===void 0?void 0:new HostIdleHandover({...hooks.handover,isIdle:()=>isHostIdle(registry,this.inFlight)})}async intercept(parsed,deliver){if(!isRecord(parsed)||parsed.type!==BEGIN_HANDOVER_COMMAND)return!1;let answering=this.answerBegin(parsed).then(deliver);this.answering.add(answering);try{await answering}finally{this.answering.delete(answering)}return!0}async answerBegin(parsed){if(this.handover===void 0)return beginHandoverResponse(parsed.id,{kind:"refused",reason:"handover_unsupported"});let request=parseBeginHandover(parsed);return beginHandoverResponse(parsed.id,typeof request=="string"?request:await this.handover.begin(request))}async answered(){for(;this.answering.size>0;)await Promise.allSettled([...this.answering])}async dispatch(command){let pending=this.handover?.view();if(pending!==void 0&&this.handover?.admits(command.type)===!1)return handoverRefusal(command,pending);let key="sessionId"in command?command.sessionId:void 0;this.inFlight.set(key,(this.inFlight.get(key)??0)+1);let response;try{response=await this.route(command)}finally{let remaining=(this.inFlight.get(key)??1)-1;remaining>0?this.inFlight.set(key,remaining):this.inFlight.delete(key),this.handover?.observe()}return response===void 0?void 0:withHostIdentity(response,this.runtimeBuildId,this.handover?.view())}};function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}import{existsSync as existsSync4}from"node:fs";import{createHash}from"node:crypto";import{existsSync,renameSync}from"node:fs";import{mkdir,readdir,readFile,rm,writeFile}from"node:fs/promises";import{join}from"node:path";var recordDir=daemonDir=>join(daemonDir,"handover-parked"),entryFile=(daemonDir,sessionPath)=>join(recordDir(daemonDir),`${createHash("sha256").update(sessionPath,"utf8").digest("hex").slice(0,16)}.json`),mutationChain=Promise.resolve();function enqueueMutation(mutation){let next=mutationChain.then(mutation,mutation);return mutationChain=next.catch(()=>{}),next}function isEntry(value){if(typeof value!="object"||value===null||Array.isArray(value))return!1;let record=value;return typeof record.sessionPath=="string"&&typeof record.retainOnDisconnect=="boolean"&&(record.durableSessionId===void 0||typeof record.durableSessionId=="string")&&(record.cwd===void 0||typeof record.cwd=="string")&&(record.parkedBy===void 0||typeof record.parkedBy=="string")&&(record.thinkingLevel===void 0||typeof record.thinkingLevel=="string")&&(record.permissionPreset===void 0||typeof record.permissionPreset=="string"&&parsePermissionPresetName(record.permissionPreset)!==void 0)&&sessionPromptSurfaceError(record.promptSurface)===void 0&&sessionBrowserEngineError(record.browserEngine)===void 0&&sessionKindError(record.sessionKind)===void 0&&sessionContextError(record.sessionContext)===void 0&&sessionAutoTitleError(record.autoTitle)===void 0&&sessionRetryFallbackError(record.retryFallback)===void 0&&(record.model===void 0||typeof record.model=="object"&&record.model!==null&&typeof record.model.provider=="string"&&typeof record.model.modelId=="string")}async function writeEntryFile(daemonDir,entry){await mkdir(recordDir(daemonDir),{recursive:!0,mode:448});let file=entryFile(daemonDir,entry.sessionPath),tmp=`${file}.${process.pid}.${Math.random().toString(16).slice(2,10)}.tmp`;await writeFile(tmp,`${JSON.stringify(entry,null,2)}
3
3
  `,{mode:384}),renameSync(tmp,file)}function recordHandoverParkedSession(daemonDir,entry){return enqueueMutation(()=>writeEntryFile(daemonDir,entry))}async function readHandoverParkedSessions(daemonDir){let names;try{names=(await readdir(recordDir(daemonDir))).filter(name=>name.endsWith(".json"))}catch{return[]}let entries=[];for(let name of names){let file=join(recordDir(daemonDir),name);try{let parsed=JSON.parse(await readFile(file,"utf8"));isEntry(parsed)&&entries.push(parsed)}catch(cause){cause instanceof SyntaxError&&(process.stderr.write(`senpi rpc handover-parked entry ${name} is corrupt; dropping it
4
- `),await rm(file,{force:!0}))}}return entries}function clearHandoverParkedSession(daemonDir,sessionPath){return enqueueMutation(()=>rm(entryFile(daemonDir,sessionPath),{force:!0}))}function dropHandoverParkedSessionIfFileGone(daemonDir,sessionPath){return existsSync(sessionPath)?Promise.resolve():clearHandoverParkedSession(daemonDir,sessionPath)}import{isAbsolute as isAbsolute2}from"node:path";import{access}from"node:fs/promises";import{isAbsolute}from"node:path";var MAX_WARM_PROFILES=64;function profileKey(profile){let context=Object.entries(profile.sessionContext??{}).sort(([a],[b])=>a<b?-1:a>b?1:0);return JSON.stringify([profile.cwd,profile.sessionKind??"interactive",context])}var HostWarmer=class{constructor(load){this.warm=new Set,this.loading=new Map,this.load=load}async run(profile){let key=profileKey(profile);if(this.warm.has(key))return"already_warm";let pending=this.loading.get(key);return pending===void 0&&(pending=this.loadOnce(key,profile),this.loading.set(key,pending)),await pending,"warmed"}async loadOnce(key,profile){try{if(await this.load(profile),this.warm.add(key),this.warm.size>MAX_WARM_PROFILES){let oldest=this.warm.values().next().value;oldest!==void 0&&this.warm.delete(oldest)}}finally{this.loading.delete(key)}}};function createRegistryWarm(prepare,host){let warmer=new HostWarmer(async profile=>{await access(profile.cwd);let launchProfile={cwd:profile.cwd,...profile.sessionKind!==void 0?{sessionKind:profile.sessionKind}:{},...profile.sessionContext!==void 0?{sessionContext:Object.freeze({...profile.sessionContext})}:{}},scope=new ProviderScope;try{await runWithProviderScope(scope,()=>prepare({cwd:profile.cwd,agentDir:host.agentDir,launchProfile:Object.freeze(launchProfile),...host.mcpRegistry!==void 0?{mcpRegistry:host.mcpRegistry}:{}}))}finally{scope.close()}});return profile=>warmer.run(profile)}function refusal(command,code){return{id:command.id,type:"response",command:"warm",success:!1,error:code}}async function answerWarm(command,host){if(host.draining)return refusal(command,"host_draining");let kindError=sessionKindError(command.kind);if(kindError)return refusal(command,`${RPC_ERROR_INVALID_SESSION_KIND}: ${kindError}`);let contextError=sessionContextError(command.context);if(contextError)return refusal(command,`${RPC_ERROR_INVALID_SESSION_CONTEXT}: ${contextError}`);if(host.warm===void 0)return{id:command.id,type:"response",command:"warm",success:!0,data:{state:"unsupported"}};let sessionContext=host.hostContext?{...command.context,...host.hostContext}:command.context,cwd=command.cwd??host.cwd;if(!isAbsolute(cwd))return refusal(command,RPC_ERROR_INVALID_PATH);try{let state=await host.warm({cwd,...command.kind!==void 0?{sessionKind:command.kind}:{},...sessionContext!==void 0?{sessionContext}:{}});return{id:command.id,type:"response",command:"warm",success:!0,data:{state}}}catch(cause){return refusal(command,`${RPC_ERROR_WARM_FAILED}: ${cause instanceof Error?cause.message:String(cause)}`)}}var RpcSessionRegistryError=class extends Error{constructor(code,reason,detail){super(code==="open_failed"&&reason?`${code}: ${reason}`:code),this.code=code,this.name="RpcSessionRegistryError",detail&&(this.detail=detail)}};function frozenProfile(profile){return Object.freeze({...profile,...profile.holderEndpoint?{holderEndpoint:Object.freeze({...profile.holderEndpoint})}:{},...profile.creationModel?{creationModel:Object.freeze({...profile.creationModel})}:{},...profile.sessionContext?{sessionContext:Object.freeze({...profile.sessionContext})}:{},...profile.retryFallback?{retryFallback:Object.freeze({modelFallback:profile.retryFallback.modelFallback,fallbackChains:Object.freeze(Object.fromEntries(Object.entries(profile.retryFallback.fallbackChains).map(([key,entries])=>[key,Object.freeze([...entries])])))})}:{}})}function sessionIdentity(profile){return{kind:profile.sessionKind??"interactive",context:profile.sessionContext??EMPTY_SESSION_CONTEXT}}function assertRequestedModelResolved(profile,diagnostics){let requested=profile.creationModel;if(requested===void 0)return;let unresolved=diagnostics.find(diagnostic=>diagnostic.code==="model_unresolved");if(unresolved!==void 0)throw new RpcSessionRegistryError("open_failed",`model_unavailable: ${unresolved.message}`,{reason:"model_unavailable",requestedModel:`${requested.provider}/${requested.modelId}`})}var observations=new Set(["get_state","get_effect_status","get_messages","get_entries","get_tree","get_fork_messages","get_last_assistant_text","get_session_stats","resolve_path","get_steering_messages","get_follow_up_messages","get_available_models","get_available_thinking_levels","get_fast_mode","get_commands","get_loaded_surfaces","get_media","get_auth_providers","get_provider_accounts","memory_report","eval_cells.list","eval_cells.peek"]);function refreshesSessionActivity(command){return!observations.has(command)}var DEFAULT_OPEN_IN_PROGRESS_WAIT_MS=45e3,OPEN_IN_PROGRESS_WAIT_RETRY_MS=2e3;function openInProgressWaitMs(){let override=Number(process.env.SENPI_OPEN_IN_PROGRESS_WAIT_MS);return Number.isFinite(override)&&override>0?override:DEFAULT_OPEN_IN_PROGRESS_WAIT_MS}var OpenInProgressWaitError=class extends Error{};function openingOwner(sessionPath){return{instanceId:hostInstanceId(),pid:process.pid,processStartTime:null,sessionPath,attached:!0,current:!0}}function waitWithDeadline(openCompletion,waitMs){let timer;return Promise.race([openCompletion,new Promise((_resolve,reject)=>{timer=setTimeout(()=>reject(new OpenInProgressWaitError),waitMs)})]).finally(()=>{timer!==void 0&&clearTimeout(timer)})}async function attachToOpenSession(entries,sessionPath,profile,options,pathReservations,now){let existing=[...entries].find(([,entry2])=>entry2.reservationKey===sessionPath&&entry2.state==="open");if(!existing){let inFlight=[...entries].find(([,entry2])=>entry2.reservationKey===sessionPath&&entry2.state==="opening");if(inFlight?.[1].openCompletion!==void 0){try{await waitWithDeadline(inFlight[1].openCompletion,openInProgressWaitMs())}catch(cause){throw cause instanceof OpenInProgressWaitError?new RpcSessionRegistryError("session_path_in_use","the session is still opening",{reason:"open_in_progress",retry_after_ms:OPEN_IN_PROGRESS_WAIT_RETRY_MS,owner:openingOwner(sessionPath)}):new RpcSessionRegistryError("session_path_in_use","the in-flight open failed",{reason:"open_failed",retry_after_ms:OPEN_IN_PROGRESS_WAIT_RETRY_MS})}return attachToOpenSession(entries,sessionPath,profile,options,pathReservations,now)}throw new RpcSessionRegistryError("session_path_in_use","the session is still being released",{reason:"path_still_held",retry_after_ms:OPEN_IN_PROGRESS_WAIT_RETRY_MS})}let[handle,entry]=existing,wasParked=entry.retainOnDisconnect===!0&&entry.attachments===0;if(entry.attachments+=1,entry.detachedAt=void 0,pathReservations?.setAttached(sessionPath,!0),options?.retainOnDisconnect&&(entry.retainOnDisconnect=!0),!entry.durableSessionId)throw new RpcSessionRegistryError("session_path_in_use");return profile.promptSurface!==void 0&&profile.promptSurface!==entry.profile.promptSurface&&(entry.profile=frozenProfile({...entry.profile,promptSurface:profile.promptSurface}),entry.runtime?.setPromptSurface(profile.promptSurface)),profile.browserEngine!==void 0&&profile.browserEngine!==entry.profile.browserEngine&&(entry.profile=frozenProfile({...entry.profile,browserEngine:profile.browserEngine}),entry.runtime?.setBrowserEngine(profile.browserEngine)),profile.permissionPreset!==void 0&&(entry.profile=frozenProfile({...entry.profile,permissionPreset:profile.permissionPreset}),entry.runtime?.setPermissionPreset(profile.permissionPreset)),entry.lastCommandAt=now,wasParked&&(entry.lifecycleMutex=entry.lifecycleMutex.then(()=>entry.runtime?.emitAttachmentEvent("session_resumed")),await entry.lifecycleMutex),{sessionId:handle,durableSessionId:entry.durableSessionId,sessionPath:entry.sessionPath,attached:!0}}function beginPendingClaim(pending,sessionPath){let settled=Promise.withResolvers();return pending.set(sessionPath,settled.promise),()=>{pending.get(sessionPath)===settled.promise&&pending.delete(sessionPath),settled.resolve()}}async function takeCrossGenerationClaim(reservations,pending,pathReservations,sessionPath){let settle=beginPendingClaim(pending,sessionPath),holder;try{holder=await pathReservations.claim(sessionPath)}catch(cause){throw reservations.delete(sessionPath),settle(),cause}if(holder===void 0)return settle;throw reservations.delete(sessionPath),settle(),new RpcSessionRegistryError("session_path_in_use",void 0,{owner:holder,retry_after_ms:SESSION_PATH_RETRY_AFTER_MS})}async function settlePendingClaim(pending,sessionPath,graceMs){let timer,late=new Promise(resolve=>{timer=setTimeout(()=>resolve("late"),graceMs)});try{for(let claim=pending.get(sessionPath);claim!==void 0;claim=pending.get(sessionPath))if(await Promise.race([claim.then(()=>"settled"),late])==="late")throw new RpcSessionRegistryError("session_path_in_use","another open of this path is still taking its claim",{reason:"claim_in_progress",retry_after_ms:SESSION_PATH_RETRY_AFTER_MS})}finally{clearTimeout(timer)}}function syncRuntimeMetadata(entries,reservations,pathReservations){for(let entry of entries){let manager=entry.runtime?.session.sessionManager;if(!manager)continue;let currentPath=manager.getSessionFile(),currentKey=currentPath?canonicalSessionPath(currentPath):void 0;(currentPath!==entry.sessionPath||currentKey!==entry.reservationKey)&&(entry.reservationKey&&(reservations.delete(entry.reservationKey),pathReservations?.release(entry.reservationKey)),currentKey&&(reservations.add(currentKey),pathReservations?.claim(currentKey,entry.attachments>0)),entry.reservationKey=currentKey,entry.sessionPath=currentPath),entry.durableSessionId=manager.getSessionId(),entry.cwd=manager.getCwd()}}async function settleClosingReservation(entries,sessionPath,closeGraceMs){let closing=[...entries].find(entry=>entry.reservationKey===sessionPath&&entry.state==="closing");if(!closing?.closeCompletion)return;let deadline;try{await Promise.race([closing.closeCompletion,new Promise(resolve=>{deadline=setTimeout(resolve,closeGraceMs)})])}finally{deadline&&clearTimeout(deadline)}}import{existsSync as existsSync2}from"node:fs";function resolveMovedProfile(requested){let profile={...requested,cwd:resolveMovedPath(requested.cwd),...requested.sessionPath?{sessionPath:resolveMovedPath(requested.sessionPath)}:{}};if(profile.sessionPath!==requested.sessionPath&&profile.sessionPath&&!existsSync2(profile.sessionPath))throw new RpcSessionRegistryError("open_failed",`moved session file does not exist: ${profile.sessionPath}`);return profile}import{existsSync as existsSync3}from"node:fs";function createEntrySwitchSession(entry,createRuntime,syncRuntimeMetadata2){return(sessionPath,options)=>{let operation=entry.lifecycleMutex.then(async()=>{if(entry.state!=="open"||!entry.runtime)throw new RpcSessionRegistryError("unknown_session");let runtime=entry.runtime,cwdOverride=options?.cwdOverride,cwdChanged=cwdOverride!==void 0&&runtime.session.sessionManager.getCwd()!==cwdOverride,result=await runtime.switchSession(sessionPath,options);if(result.cancelled||!cwdChanged)return result;let replacement=new AgentSessionRuntime(runtime.session,runtime.services,createRuntime,[...runtime.diagnostics],runtime.modelFallbackMessage,runtime.launchProfile);return replacement.setRebindSession(entry.rebindSession),ClientAdmissions.sealQueuedOnReplace(replacement),EffectLedger.sealOnReplace(replacement),runtime.releaseSessionHold(),entry.runtime=replacement,syncRuntimeMetadata2(),result});return entry.lifecycleMutex=operation.then(()=>{},()=>{}),operation}}function buildOpeningEntry(input){let{profile,sessionPath,requestedDurableId,options}=input,isResume=sessionPath!==void 0&&existsSync3(sessionPath),sessionStartEvent=isResume?{type:"session_start",reason:"resume"}:void 0,storedProfile=frozenProfile({...profile,...sessionPath?{sessionPath}:{}}),runtimeProfile=isResume?frozenProfile({...storedProfile,creationModel:void 0,initialThinkingLevel:void 0}):storedProfile,settleOpen,openCompletion=new Promise((resolve,reject)=>{settleOpen={resolve,reject}});openCompletion.catch(()=>{});let entry={state:"opening",scope:new ProviderScope,profile:storedProfile,...sessionIdentity(storedProfile),sessionPath,reservationKey:sessionPath,cwd:storedProfile.cwd,attachments:1,retainOnDisconnect:options?.retainOnDisconnect===!0,lastCommandAt:input.now,lifecycleMutex:Promise.resolve(),openCompletion};return entry.switchSession=createEntrySwitchSession(entry,input.createRuntime,input.sync),requestedDurableId!==void 0&&(entry.durableSessionId=requestedDurableId),{entry,storedProfile,runtimeProfile,sessionStartEvent,settleOpen}}function sessionIsWriting(entry){return entry.worker?.busy===!0||entry.runtime?.session.isSessionBusy===!0}function reportDetachedFailure(handle,cause){process.stderr.write(`senpi rpc session ${handle} teardown failed: ${String(cause)}
4
+ `),await rm(file,{force:!0}))}}return entries}function clearHandoverParkedSession(daemonDir,sessionPath){return enqueueMutation(()=>rm(entryFile(daemonDir,sessionPath),{force:!0}))}function dropHandoverParkedSessionIfFileGone(daemonDir,sessionPath){return existsSync(sessionPath)?Promise.resolve():clearHandoverParkedSession(daemonDir,sessionPath)}import{isAbsolute as isAbsolute2}from"node:path";import{access}from"node:fs/promises";import{isAbsolute}from"node:path";var MAX_WARM_PROFILES=64;function profileKey(profile){let context=Object.entries(profile.sessionContext??{}).sort(([a],[b])=>a<b?-1:a>b?1:0);return JSON.stringify([profile.cwd,profile.sessionKind??"interactive",context])}var HostWarmer=class{constructor(load){this.warm=new Set,this.loading=new Map,this.load=load}async run(profile){let key=profileKey(profile);if(this.warm.has(key))return"already_warm";let pending=this.loading.get(key);return pending===void 0&&(pending=this.loadOnce(key,profile),this.loading.set(key,pending)),await pending,"warmed"}async loadOnce(key,profile){try{if(await this.load(profile),this.warm.add(key),this.warm.size>MAX_WARM_PROFILES){let oldest=this.warm.values().next().value;oldest!==void 0&&this.warm.delete(oldest)}}finally{this.loading.delete(key)}}};function createRegistryWarm(prepare,host){let warmer=new HostWarmer(async profile=>{await access(profile.cwd);let launchProfile={cwd:profile.cwd,...profile.sessionKind!==void 0?{sessionKind:profile.sessionKind}:{},...profile.sessionContext!==void 0?{sessionContext:Object.freeze({...profile.sessionContext})}:{}},scope=new ProviderScope;try{await runWithProviderScope(scope,()=>prepare({cwd:profile.cwd,agentDir:host.agentDir,launchProfile:Object.freeze(launchProfile),...host.mcpRegistry!==void 0?{mcpRegistry:host.mcpRegistry}:{}}))}finally{scope.close()}});return profile=>warmer.run(profile)}function refusal(command,code){return{id:command.id,type:"response",command:"warm",success:!1,error:code}}async function answerWarm(command,host){if(host.draining)return refusal(command,"host_draining");let kindError=sessionKindError(command.kind);if(kindError)return refusal(command,`${RPC_ERROR_INVALID_SESSION_KIND}: ${kindError}`);let contextError=sessionContextError(command.context);if(contextError)return refusal(command,`${RPC_ERROR_INVALID_SESSION_CONTEXT}: ${contextError}`);if(host.warm===void 0)return{id:command.id,type:"response",command:"warm",success:!0,data:{state:"unsupported"}};let sessionContext=host.hostContext?{...command.context,...host.hostContext}:command.context,cwd=command.cwd??host.cwd;if(!isAbsolute(cwd))return refusal(command,RPC_ERROR_INVALID_PATH);try{let state=await host.warm({cwd,...command.kind!==void 0?{sessionKind:command.kind}:{},...sessionContext!==void 0?{sessionContext}:{}});return{id:command.id,type:"response",command:"warm",success:!0,data:{state}}}catch(cause){return refusal(command,`${RPC_ERROR_WARM_FAILED}: ${cause instanceof Error?cause.message:String(cause)}`)}}var RpcSessionRegistryError=class extends Error{constructor(code,reason,detail){super(code==="open_failed"&&reason?`${code}: ${reason}`:code),this.code=code,this.name="RpcSessionRegistryError",detail&&(this.detail=detail)}};function frozenProfile(profile){return Object.freeze({...profile,...profile.holderEndpoint?{holderEndpoint:Object.freeze({...profile.holderEndpoint})}:{},...profile.creationModel?{creationModel:Object.freeze({...profile.creationModel})}:{},...profile.sessionContext?{sessionContext:Object.freeze({...profile.sessionContext})}:{},...profile.retryFallback?{retryFallback:Object.freeze({modelFallback:profile.retryFallback.modelFallback,fallbackChains:Object.freeze(Object.fromEntries(Object.entries(profile.retryFallback.fallbackChains).map(([key,entries])=>[key,Object.freeze([...entries])])))})}:{}})}function sessionIdentity(profile){return{kind:profile.sessionKind??"interactive",context:profile.sessionContext??EMPTY_SESSION_CONTEXT}}function assertRequestedModelResolved(profile,diagnostics){let requested=profile.creationModel;if(requested===void 0)return;let unresolved=diagnostics.find(diagnostic=>diagnostic.code==="model_unresolved");if(unresolved!==void 0)throw new RpcSessionRegistryError("open_failed",`model_unavailable: ${unresolved.message}`,{reason:"model_unavailable",requestedModel:`${requested.provider}/${requested.modelId}`})}var observations=new Set(["get_state","get_effect_status","get_pending_inputs","get_messages","get_entries","get_tree","get_fork_messages","get_last_assistant_text","get_session_stats","resolve_path","get_steering_messages","get_follow_up_messages","get_available_models","get_available_thinking_levels","get_fast_mode","get_commands","get_loaded_surfaces","get_media","get_auth_providers","get_provider_accounts","memory_report","eval_cells.list","eval_cells.peek"]);function refreshesSessionActivity(command){return!observations.has(command)}var DEFAULT_OPEN_IN_PROGRESS_WAIT_MS=45e3,OPEN_IN_PROGRESS_WAIT_RETRY_MS=2e3;function openInProgressWaitMs(){let override=Number(process.env.SENPI_OPEN_IN_PROGRESS_WAIT_MS);return Number.isFinite(override)&&override>0?override:DEFAULT_OPEN_IN_PROGRESS_WAIT_MS}var OpenInProgressWaitError=class extends Error{};function openingOwner(sessionPath){return{instanceId:hostInstanceId(),pid:process.pid,processStartTime:null,sessionPath,attached:!0,current:!0}}function waitWithDeadline(openCompletion,waitMs){let timer;return Promise.race([openCompletion,new Promise((_resolve,reject)=>{timer=setTimeout(()=>reject(new OpenInProgressWaitError),waitMs)})]).finally(()=>{timer!==void 0&&clearTimeout(timer)})}async function attachToOpenSession(entries,sessionPath,profile,options,pathReservations,now){let existing=[...entries].find(([,entry2])=>entry2.reservationKey===sessionPath&&entry2.state==="open");if(!existing){let inFlight=[...entries].find(([,entry2])=>entry2.reservationKey===sessionPath&&entry2.state==="opening");if(inFlight?.[1].openCompletion!==void 0){try{await waitWithDeadline(inFlight[1].openCompletion,openInProgressWaitMs())}catch(cause){throw cause instanceof OpenInProgressWaitError?new RpcSessionRegistryError("session_path_in_use","the session is still opening",{reason:"open_in_progress",retry_after_ms:OPEN_IN_PROGRESS_WAIT_RETRY_MS,owner:openingOwner(sessionPath)}):new RpcSessionRegistryError("session_path_in_use","the in-flight open failed",{reason:"open_failed",retry_after_ms:OPEN_IN_PROGRESS_WAIT_RETRY_MS})}return attachToOpenSession(entries,sessionPath,profile,options,pathReservations,now)}throw new RpcSessionRegistryError("session_path_in_use","the session is still being released",{reason:"path_still_held",retry_after_ms:OPEN_IN_PROGRESS_WAIT_RETRY_MS})}let[handle,entry]=existing,wasParked=entry.retainOnDisconnect===!0&&entry.attachments===0;if(entry.attachments+=1,entry.detachedAt=void 0,pathReservations?.setAttached(sessionPath,!0),options?.retainOnDisconnect&&(entry.retainOnDisconnect=!0),!entry.durableSessionId)throw new RpcSessionRegistryError("session_path_in_use");return profile.promptSurface!==void 0&&profile.promptSurface!==entry.profile.promptSurface&&(entry.profile=frozenProfile({...entry.profile,promptSurface:profile.promptSurface}),entry.runtime?.setPromptSurface(profile.promptSurface)),profile.browserEngine!==void 0&&profile.browserEngine!==entry.profile.browserEngine&&(entry.profile=frozenProfile({...entry.profile,browserEngine:profile.browserEngine}),entry.runtime?.setBrowserEngine(profile.browserEngine)),profile.permissionPreset!==void 0&&(entry.profile=frozenProfile({...entry.profile,permissionPreset:profile.permissionPreset}),entry.runtime?.setPermissionPreset(profile.permissionPreset)),entry.lastCommandAt=now,wasParked&&(entry.lifecycleMutex=entry.lifecycleMutex.then(()=>entry.runtime?.emitAttachmentEvent("session_resumed")),await entry.lifecycleMutex),{sessionId:handle,durableSessionId:entry.durableSessionId,sessionPath:entry.sessionPath,attached:!0}}function beginPendingClaim(pending,sessionPath){let settled=Promise.withResolvers();return pending.set(sessionPath,settled.promise),()=>{pending.get(sessionPath)===settled.promise&&pending.delete(sessionPath),settled.resolve()}}async function takeCrossGenerationClaim(reservations,pending,pathReservations,sessionPath){let settle=beginPendingClaim(pending,sessionPath),holder;try{holder=await pathReservations.claim(sessionPath)}catch(cause){throw reservations.delete(sessionPath),settle(),cause}if(holder===void 0)return settle;throw reservations.delete(sessionPath),settle(),new RpcSessionRegistryError("session_path_in_use",void 0,{owner:holder,retry_after_ms:SESSION_PATH_RETRY_AFTER_MS})}async function settlePendingClaim(pending,sessionPath,graceMs){let timer,late=new Promise(resolve=>{timer=setTimeout(()=>resolve("late"),graceMs)});try{for(let claim=pending.get(sessionPath);claim!==void 0;claim=pending.get(sessionPath))if(await Promise.race([claim.then(()=>"settled"),late])==="late")throw new RpcSessionRegistryError("session_path_in_use","another open of this path is still taking its claim",{reason:"claim_in_progress",retry_after_ms:SESSION_PATH_RETRY_AFTER_MS})}finally{clearTimeout(timer)}}function syncRuntimeMetadata(entries,reservations,pathReservations){for(let entry of entries){let manager=entry.runtime?.session.sessionManager;if(!manager)continue;let currentPath=manager.getSessionFile(),currentKey=currentPath?canonicalSessionPath(currentPath):void 0;(currentPath!==entry.sessionPath||currentKey!==entry.reservationKey)&&(entry.reservationKey&&(reservations.delete(entry.reservationKey),pathReservations?.release(entry.reservationKey)),currentKey&&(reservations.add(currentKey),pathReservations?.claim(currentKey,entry.attachments>0)),entry.reservationKey=currentKey,entry.sessionPath=currentPath),entry.durableSessionId=manager.getSessionId(),entry.cwd=manager.getCwd()}}async function settleClosingReservation(entries,sessionPath,closeGraceMs){let closing=[...entries].find(entry=>entry.reservationKey===sessionPath&&entry.state==="closing");if(!closing?.closeCompletion)return;let deadline;try{await Promise.race([closing.closeCompletion,new Promise(resolve=>{deadline=setTimeout(resolve,closeGraceMs)})])}finally{deadline&&clearTimeout(deadline)}}import{existsSync as existsSync2}from"node:fs";function resolveMovedProfile(requested){let profile={...requested,cwd:resolveMovedPath(requested.cwd),...requested.sessionPath?{sessionPath:resolveMovedPath(requested.sessionPath)}:{}};if(profile.sessionPath!==requested.sessionPath&&profile.sessionPath&&!existsSync2(profile.sessionPath))throw new RpcSessionRegistryError("open_failed",`moved session file does not exist: ${profile.sessionPath}`);return profile}import{existsSync as existsSync3}from"node:fs";function createEntrySwitchSession(entry,createRuntime,syncRuntimeMetadata2){return(sessionPath,options)=>{let operation=entry.lifecycleMutex.then(async()=>{if(entry.state!=="open"||!entry.runtime)throw new RpcSessionRegistryError("unknown_session");let runtime=entry.runtime,cwdOverride=options?.cwdOverride,cwdChanged=cwdOverride!==void 0&&runtime.session.sessionManager.getCwd()!==cwdOverride,result=await runtime.switchSession(sessionPath,options);if(result.cancelled||!cwdChanged)return result;let replacement=new AgentSessionRuntime(runtime.session,runtime.services,createRuntime,[...runtime.diagnostics],runtime.modelFallbackMessage,runtime.launchProfile);return replacement.setRebindSession(entry.rebindSession),ClientAdmissions.sealQueuedOnReplace(replacement),EffectLedger.sealOnReplace(replacement),runtime.releaseSessionHold(),entry.runtime=replacement,syncRuntimeMetadata2(),result});return entry.lifecycleMutex=operation.then(()=>{},()=>{}),operation}}function buildOpeningEntry(input){let{profile,sessionPath,requestedDurableId,options}=input,isResume=sessionPath!==void 0&&existsSync3(sessionPath),sessionStartEvent=isResume?{type:"session_start",reason:"resume"}:void 0,storedProfile=frozenProfile({...profile,...sessionPath?{sessionPath}:{}}),runtimeProfile=isResume?frozenProfile({...storedProfile,creationModel:void 0,initialThinkingLevel:void 0}):storedProfile,settleOpen,openCompletion=new Promise((resolve,reject)=>{settleOpen={resolve,reject}});openCompletion.catch(()=>{});let entry={state:"opening",scope:new ProviderScope,profile:storedProfile,...sessionIdentity(storedProfile),sessionPath,reservationKey:sessionPath,cwd:storedProfile.cwd,attachments:1,retainOnDisconnect:options?.retainOnDisconnect===!0,lastCommandAt:input.now,lifecycleMutex:Promise.resolve(),openCompletion};return entry.switchSession=createEntrySwitchSession(entry,input.createRuntime,input.sync),requestedDurableId!==void 0&&(entry.durableSessionId=requestedDurableId),{entry,storedProfile,runtimeProfile,sessionStartEvent,settleOpen}}function sessionIsWriting(entry){return entry.worker?.busy===!0||entry.runtime?.session.isSessionBusy===!0}function reportDetachedFailure(handle,cause){process.stderr.write(`senpi rpc session ${handle} teardown failed: ${String(cause)}
5
5
  `)}function beginSessionClose(host,handle,onRole,options){let entry=host.get(handle);if(!entry)throw new RpcSessionRegistryError("unknown_session");if(entry.state==="closing")return onRole?.(!1),entry;if(entry.state!=="open")throw new RpcSessionRegistryError("unknown_session");return entry.attachments-=1,entry.attachments>0?entry:options?.detach&&entry.retainOnDisconnect?(entry.attachments=0,entry.detachedAt??=host.now(),entry.reservationKey&&!sessionIsWriting(entry)&&host.markDetached(entry.reservationKey),entry):(entry.state="closing",onRole?.(!0),entry.closeCompletion=new Promise(resolve=>{entry.closeResolve=resolve}),entry)}async function releaseWithinGrace(host,handle,key){let timer,late=new Promise(resolve=>{timer=setTimeout(()=>resolve("late"),host.closeGraceMs)}),removal=host.releaseReservation(key).then(()=>"removed",cause=>(reportDetachedFailure(handle,cause),"failed")),outcome=await Promise.race([removal,late]);clearTimeout(timer),outcome==="late"&&reportDetachedFailure(handle,new Error(`session path reservation was not removed within ${host.closeGraceMs} ms; closing anyway`))}function closeSession(host,handle){return beginSessionClose(host,handle).state!=="closing"?Promise.resolve():closeMarkedSession(host,handle)}function closeMarkedSession(host,handle){host.sync();let entry=host.get(handle);if(entry?.state!=="closing")throw new RpcSessionRegistryError("unknown_session");let completion=entry.closeCompletion;if(!completion)return Promise.resolve();if(entry.closeStarted)return completion;entry.closeStarted=!0;let previousLifecycle=entry.lifecycleMutex,releaseTimer,released=!1,disposePromise,scopeClosed=!1,disposeOnce=()=>disposePromise||(disposePromise=Promise.resolve(entry.runtime?.dispose()),disposePromise),closeScopeOnce=async()=>{scopeClosed||(scopeClosed=!0,await disposeOnce().catch(()=>{}),await entry.scope.close?.())},release=async()=>{released||(released=!0,releaseTimer&&clearTimeout(releaseTimer),entry.reservationKey&&await releaseWithinGrace(host,handle,entry.reservationKey),entry.state="closed",host.delete(handle))},graceful=(async()=>{await previousLifecycle;try{await entry.runtime?.session.abort()}catch(cause){reportDetachedFailure(handle,cause)}try{await entry.runtime?.session.waitForIdle()}catch(cause){reportDetachedFailure(handle,cause)}try{await disposeOnce()}catch(cause){reportDetachedFailure(handle,cause)}try{await closeScopeOnce()}catch(cause){reportDetachedFailure(handle,cause)}})(),settled=!1,finish=async()=>{settled||(settled=!0,await release(),entry.closeResolve?.())};return releaseTimer=setTimeout(()=>{disposeOnce().catch(cause=>reportDetachedFailure(handle,cause)),closeScopeOnce().catch(cause=>reportDetachedFailure(handle,cause)),graceful.catch(cause=>reportDetachedFailure(handle,cause)),finish()},host.closeGraceMs),graceful.then(finish,cause=>(reportDetachedFailure(handle,cause),finish())),completion}var RpcSessionRegistry=class{constructor(options){this.entries=new Map,this.reservations=new Set,this.pendingClaims=new Map,this.nextHandle=0,options.createRuntime.prepare&&(this.warm=createRegistryWarm(options.createRuntime.prepare,{agentDir:options.agentDir,...options.mcpRegistry!==void 0?{mcpRegistry:options.mcpRegistry}:{}})),this.options=options.mcpRegistry===void 0?options:{...options,createRuntime:runtimeOptions=>options.createRuntime({...runtimeOptions,mcpRegistry:options.mcpRegistry})},this.now=options.now??Date.now,this.closeGraceMs=options.closeGraceMs??1e4,this.teardownHost={closeGraceMs:this.closeGraceMs,get:handle=>this.entries.get(handle),delete:handle=>{let deleted=this.entries.delete(handle);return this.options.onSizeChange?.(this.entries.size),deleted},releaseReservation:async key=>{await this.options.pathReservations?.release(key),this.reservations.delete(key)},markDetached:key=>this.options.pathReservations?.setAttached(key,!1),now:()=>this.now(),sync:()=>this.syncRuntimeMetadata()}}get size(){return this.entries.size}holderPids(observedStarts){return this.options.pathReservations?.holderPids?.(observedStarts)??Promise.resolve([])}async openSession(requested,options){this.validateProfile(requested);let profile=resolveMovedProfile(requested);this.syncRuntimeMetadata();let sessionPath=profile.sessionPath?canonicalSessionPath(profile.sessionPath):void 0,requestedDurableId=profile.durableSessionId;if(requestedDurableId!==void 0){for(let entry2 of this.entries.values())if(entry2.state!=="closed"&&entry2.durableSessionId===requestedDurableId&&!(sessionPath!==void 0&&entry2.reservationKey===sessionPath))throw new RpcSessionRegistryError("session_id_in_use")}if(sessionPath){await settleClosingReservation(this.entries.values(),sessionPath,this.closeGraceMs);let deadline=Date.now()+this.closeGraceMs;for(;this.pendingClaims.has(sessionPath);)await settlePendingClaim(this.pendingClaims,sessionPath,Math.max(0,deadline-Date.now()))}if(sessionPath&&this.reservations.has(sessionPath))return attachToOpenSession(this.entries,sessionPath,profile,options,this.options.pathReservations,this.now());if(options?.attachOnly)throw new RpcSessionRegistryError("session_not_held",void 0,{reason:"session_not_held",action:"rediscover_holder"});let claimSettled;sessionPath&&(this.reservations.add(sessionPath),this.options.pathReservations&&(claimSettled=await takeCrossGenerationClaim(this.reservations,this.pendingClaims,this.options.pathReservations,sessionPath)));let handle=`rpc-${++this.nextHandle}`,opening;try{opening=buildOpeningEntry({profile,sessionPath,requestedDurableId,options,now:this.now(),createRuntime:this.options.createRuntime,sync:()=>this.syncRuntimeMetadata()})}catch(cause){try{sessionPath&&(this.reservations.delete(sessionPath),await this.options.pathReservations?.release(sessionPath))}catch(releaseCause){process.stderr.write(`senpi rpc open of ${sessionPath} could not release its claim: ${String(releaseCause)}
6
6
  `)}finally{claimSettled?.()}throw cause}let{entry,storedProfile,runtimeProfile,sessionStartEvent,settleOpen}=opening;this.entries.set(handle,entry),claimSettled?.(),this.options.onSizeChange?.(this.entries.size);try{let newSessionOptions=requestedDurableId!==void 0?{id:requestedDurableId}:void 0,manager=sessionPath?this.options.sessionFileLoad==="blocking"?SessionManager.open(sessionPath,void 0,storedProfile.cwd,newSessionOptions):await SessionManager.openAsync(sessionPath,void 0,storedProfile.cwd,newSessionOptions,this.options.createSlicer?.()):SessionManager.create(storedProfile.cwd,void 0,newSessionOptions);return entry.runtime=await runWithProviderScope(entry.scope,()=>createAgentSessionRuntime(this.options.createRuntime,{cwd:manager.getCwd(),agentDir:this.options.agentDir,sessionManager:manager,sessionStartEvent,launchProfile:runtimeProfile})),assertRequestedModelResolved(runtimeProfile,entry.runtime.diagnostics),ClientAdmissions.sealQueuedOnReplace(entry.runtime),EffectLedger.sealOnReplace(entry.runtime),entry.durableSessionId=manager.getSessionId(),entry.sessionPath??=manager.getSessionFile(),entry.state="open",settleOpen.resolve(),{sessionId:handle,durableSessionId:entry.durableSessionId,sessionPath:entry.sessionPath}}catch(error2){try{await entry.runtime?.dispose()}catch{}finally{try{await entry.scope.close?.()}finally{this.entries.delete(handle),this.options.onSizeChange?.(this.entries.size),sessionPath&&await releaseWithinGrace(this.teardownHost,handle,sessionPath)}}if(error2 instanceof RpcSessionRegistryError)throw settleOpen.reject(error2),error2;let wrapped=new RpcSessionRegistryError("open_failed",error2 instanceof Error?error2.message:void 0);throw settleOpen.reject(wrapped),wrapped}}peek(handle){return this.entries.get(handle)}getForCommand(handle,command){let entry=this.entries.get(handle);if(!entry)throw new RpcSessionRegistryError("unknown_session");if(entry.state==="closing"&&!["abort","abort_bash","extension_ui_response","extension_ui_progress"].includes(command))throw new RpcSessionRegistryError("session_closing");if(entry.state!=="open"&&entry.state!=="closing")throw new RpcSessionRegistryError("unknown_session");return(entry.attachments>0||refreshesSessionActivity(command))&&(entry.lastCommandAt=this.now()),entry}beginClose(handle,onRole,options){return beginSessionClose(this.teardownHost,handle,onRole,options)}async close(handle){return closeSession(this.teardownHost,handle)}async closeMarked(handle){return closeMarkedSession(this.teardownHost,handle)}list(){this.syncRuntimeMetadata();let now=this.now();return[...this.entries].map(([sessionId,entry])=>({sessionId,durableSessionId:entry.durableSessionId,sessionPath:entry.sessionPath,cwd:entry.cwd,name:entry.runtime?.session.sessionManager.getSessionName(),kind:entry.kind,context:publishedSessionContext(entry.context,entry.contextOverlay),attachments:Math.max(0,entry.attachments),status:entry.state==="quarantined"?"closing":entry.state,idleMs:Math.max(0,now-entry.lastCommandAt)}))}syncRuntimeMetadata(){syncRuntimeMetadata(this.entries.values(),this.reservations,this.options.pathReservations)}validateProfile(profile){if(!isAbsolute2(profile.cwd)||profile.sessionPath!==void 0&&!isAbsolute2(profile.sessionPath))throw new RpcSessionRegistryError("invalid_path");if(profile.durableSessionId!==void 0)try{assertValidSessionId(profile.durableSessionId)}catch(cause){throw new RpcSessionRegistryError("invalid_session_id",String(cause))}}};var HANDOVER_PARKED_REOPEN_BUDGET_MS=12e4,HANDOVER_PARKED_REOPEN_POLL_MS=250,HANDOVER_PARKED_REOPEN_MAX_ATTEMPTS=8,HANDOVER_PARKED_REOPEN_QUIET_STREAK=8;async function reopenHandoverParkedSessions(open,agentDir,socket,holder){let daemonDir=createHostDaemonPaths({socket,agentDir}).dir,deadline=Date.now()+HANDOVER_PARKED_REOPEN_BUDGET_MS,reopenAttempts=new Map,heldPolls=new Map,emptyStreak=0,sawAnyPark=!1;for(;;){if(holder?.shouldReopen!==void 0&&!holder.shouldReopen())return;let parked=await inheritedParks(daemonDir,holder);for(let entry of parked)sawAnyPark=!0,await reopenOne(daemonDir,open,entry,reopenAttempts,heldPolls,holder);if(emptyStreak=(await inheritedParks(daemonDir,holder)).length===0?emptyStreak+1:0,sawAnyPark&&emptyStreak>=HANDOVER_PARKED_REOPEN_QUIET_STREAK||Date.now()>=deadline)return;await new Promise(resolve=>setTimeout(resolve,HANDOVER_PARKED_REOPEN_POLL_MS))}}async function inheritedParks(daemonDir,holder){return(await readHandoverParkedSessions(daemonDir)).filter(entry=>entry.parkedBy===void 0||entry.parkedBy!==holder?.hostInstance)}async function reopenOne(daemonDir,open,entry,attempts,heldPolls,holder){if(await dropHandoverParkedSessionIfFileGone(daemonDir,entry.sessionPath),!existsSync4(entry.sessionPath)){process.stderr.write(`senpi rpc successor dropped a parked session whose file is gone: ${entry.sessionPath}
7
7
  `);return}try{if(await open(entry),holder?.shouldReopen!==void 0&&!holder.shouldReopen())return;await clearHandoverParkedSession(daemonDir,entry.sessionPath)}catch(cause){if(cause instanceof RpcSessionRegistryError&&cause.code==="session_path_in_use"){let polls=(heldPolls?.get(entry.sessionPath)??0)+1;heldPolls?.set(entry.sessionPath,polls),(polls===1||polls%40===0)&&process.stderr.write(`senpi rpc successor reopen parked session ${entry.sessionPath} waiting on the holder: ${String(cause)}
@@ -13,8 +13,8 @@ import{SessionEventWriter,answerSetSessionContext,answerSubscribeSessions,answer
13
13
  `))}};function startHostObservers(router,writer,options){let loopLag=new LoopLagWatchdog({emit:record=>writer.broadcastHostRecord(record)}),kernels=readCodemodeKernelRows,memory=new HostMemorySampler({emit:record=>writer.broadcastHostRecord(record),sessions:()=>router.sessionCount,onPressure:pressure=>router.setMemoryPressure(pressure),readKernels:kernels,...options.onIdlePressure?{onIdlePressure:options.onIdlePressure}:{}});router.setHostMemoryView({mainHeapBytes:readMainThreadHeapBytes,kernels});let{trim}=options;return loopLag.start(),memory.start(),trim.start(),{stop:()=>{loopLag.stop(),memory.stop(),trim.stop()}}}function createZeroSessionTrim(writer,sessions){return new ZeroSessionTrimmer({emit:record=>writer.broadcastHostRecord(record),sessions})}async function detachConnection(command,connectionId,release){if(connectionId===void 0)return{id:command.id,type:"response",command:"detach_connection",success:!1,error:"detach_connection needs a socket connection"};let deferred=await release(connectionId);return{id:command.id,type:"response",command:"detach_connection",success:!0,data:{deferred:[...deferred]}}}var UNLOAD_SESSION_CAPABILITY="unload_session",SUBSCRIPTION_LIMITS_CAPABILITY="subscription_limits",RESOLVE_PATH_CAPABILITY="resolve_path";function multiSessionHostCapabilities(options){return[...new Set(["multi_session","expected_host_instance",AUTO_TITLE_SESSIONS_CAPABILITY,MEDIA_PLACEHOLDERS_CAPABILITY,DURABLE_CLIENT_MESSAGE_ID_CAPABILITY,EFFECT_LEDGER_CAPABILITY,SUBSCRIPTION_LIMITS_CAPABILITY,RESOLVE_PATH_CAPABILITY,STEER_WHEN_IDLE_CAPABILITY,CONTINUE_FROM_LEAF_CAPABILITY,EVAL_CELLS_CAPABILITY,AUTH_KEY_VERIFY_CAPABILITY,QUEUED_MESSAGE_REVISION_CAPABILITY,SESSION_HELD_CAPABILITY,RETAIN_ON_DISCONNECT_CAPABILITY,DETACH_CONNECTION_CAPABILITY,UNLOAD_SESSION_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY,SESSION_STATUS_CAPABILITY,AUTO_TITLE_PER_SESSION_CAPABILITY,DURABLE_SESSION_ID_CAPABILITY,MOVED_PATH_GUARD_CAPABILITY,PROMPT_SURFACE_CAPABILITY,PROMPT_SURFACE_CHAT_CAPABILITY,BROWSER_ENGINE_CAPABILITY,RETRY_FALLBACK_PROFILE_CAPABILITY,ACCEPT_EDITS_PERMISSION_PRESET_CAPABILITY,AUTO_PERMISSION_PRESET_CAPABILITY,...options.warm?[WARM_CAPABILITY]:[],toolRuntimeCapability(options.toolRuntime),...options.negotiated])]}var THINKING_LEVELS=["off","minimal","low","medium","high","xhigh","max"],thinkingLevelOf=value=>THINKING_LEVELS.find(level=>level===value);function parkedEntryFromProfile(session,profile,hostContextKeys){let clientContext=profile?.sessionContext===void 0?void 0:Object.fromEntries(Object.entries(profile.sessionContext).filter(([key])=>!hostContextKeys.includes(key)));return{sessionPath:session.sessionPath,...session.durableSessionId!==void 0?{durableSessionId:session.durableSessionId}:{},retainOnDisconnect:!0,...profile?.cwd!==void 0?{cwd:profile.cwd}:{},...profile?.creationModel!==void 0?{model:profile.creationModel}:{},...profile?.initialThinkingLevel!==void 0?{thinkingLevel:profile.initialThinkingLevel}:{},...profile?.permissionPreset!==void 0?{permissionPreset:profile.permissionPreset}:{},...profile?.promptSurface!==void 0?{promptSurface:profile.promptSurface}:{},...profile?.browserEngine!==void 0?{browserEngine:profile.browserEngine}:{},...profile?.sessionKind!==void 0?{sessionKind:profile.sessionKind}:{},...clientContext!==void 0&&Object.keys(clientContext).length>0?{sessionContext:clientContext}:{},...profile?.autoTitle!==void 0?{autoTitle:profile.autoTitle}:{},...profile?.retryFallback!==void 0?{retryFallback:profile.retryFallback}:{}}}function parkedOpenCommand(entry){let thinkingLevel=thinkingLevelOf(entry.thinkingLevel);return entry.thinkingLevel!==void 0&&thinkingLevel===void 0&&process.stderr.write(`senpi rpc successor reopens ${entry.sessionPath} without its unknown thinking level "${entry.thinkingLevel}"
14
14
  `),{type:"open_session",sessionPath:entry.sessionPath,...entry.cwd!==void 0?{cwd:entry.cwd}:{},...entry.durableSessionId!==void 0?{durableSessionId:entry.durableSessionId}:{},...entry.model!==void 0?{provider:entry.model.provider,modelId:entry.model.modelId}:{},...thinkingLevel!==void 0?{thinkingLevel}:{},...entry.permissionPreset!==void 0?{permissionPreset:entry.permissionPreset}:{},...entry.promptSurface!==void 0?{promptSurface:entry.promptSurface}:{},...entry.browserEngine!==void 0?{browserEngine:entry.browserEngine}:{},...entry.sessionKind!==void 0?{kind:entry.sessionKind}:{},...entry.sessionContext!==void 0?{context:entry.sessionContext}:{},...entry.autoTitle!==void 0?{auto_title:entry.autoTitle}:{},...entry.retryFallback!==void 0?{retryFallback:entry.retryFallback}:{},retain_on_disconnect:entry.retainOnDisconnect}}async function createRpcSessionBinding(sessionId,entry,writer,requestClose,options={}){if(entry.worker)return entry.worker.bind(sessionId,writer,requestClose,options);if(!entry.runtime)throw new Error("Session runtime was not created");let toolSpans=createToolAttributionSpans(sessionId),enqueueRecords=chunk=>{for(let line of chunk.split(`
15
15
  `)){if(!line)continue;let record=JSON.parse(line);toolSpans.observe(record),writer.enqueue(sessionId,record)}},runtimeHost=new Proxy({},{get(_target,property){if(property==="switchSession"&&entry.switchSession)return entry.switchSession;if(property==="setRebindSession")return callback=>{entry.rebindSession=callback,entry.runtime?.setRebindSession(callback)};let runtime=entry.runtime;if(!runtime)throw new Error("Session runtime was not created");let value=Reflect.get(runtime,property,runtime);return typeof value=="function"?value.bind(runtime):value}}),droppedAfterClose=!1,handler=await runWithProviderScope(entry.scope,async()=>{let writeInScope=bindToProviderScope(enqueueRecords),taggedSink={writeRaw:chunk=>{if(entry.scope.state==="closed"){droppedAfterClose||process.stderr.write(`senpi rpc host: dropped a record for closed session ${sessionId} at ${new Date().toISOString()}
16
- `),droppedAfterClose=!0;return}writeInScope(chunk)},waitForBackpressure:bindToProviderScope(async()=>{})};return createRpcConnectionHandler(runtimeHost,taggedSink,{sessionId,shutdownHandler:bindToProviderScope(requestClose),disposeRuntime:!1,eventFlushScheduler:flush=>flush(),publishLoadedSurfacesChanged:(previous,digest)=>{entry.scope.state!=="closed"&&writer.publishLoadedSurfacesChanged(sessionId,previous,digest)},...options})});return await handler.ready,{handle:command=>runWithProviderScope(entry.scope,()=>handler.handleInputLine(JSON.stringify(command))),cancelPendingExtensionUiRequests:()=>runWithProviderScope(entry.scope,()=>handler.cancelPendingExtensionUiRequests()),pendingPrompts:()=>handler.pendingPrompts(),dispose:()=>(toolSpans.closeAll(),runWithProviderScope(entry.scope,()=>handler.dispose()))}}import{execFile}from"node:child_process";var READ_ONLY_OR_CONTROL=new Set(["get_state","get_effect_status","get_steering_messages","get_follow_up_messages","get_available_models","get_available_thinking_levels","get_fast_mode","get_session_stats","resolve_path","get_fork_messages","get_entries","get_tree","get_last_assistant_text","get_messages","get_media","get_commands","get_loaded_surfaces","get_auth_providers","get_provider_accounts","memory_report","eval_cells.list","eval_cells.peek","eval_cells.stop","export_html","export_jsonl","abort","interrupt","abort_compaction","abort_branch_summary","abort_retry","abort_bash","clear_queue","check_reload_veto","cleanup_bash_output","set_client_info","extension_ui_response","extension_ui_progress"]);function readProcessStarts(){let windows=process.platform==="win32",command=windows?"powershell.exe":"ps",args=windows?["-NoProfile","-NonInteractive","-Command",'Get-CimInstance Win32_Process -ErrorAction Stop | ForEach-Object { if ($null -ne $_.CreationDate) { "{0} {1}" -f $_.ProcessId, $_.CreationDate.ToUniversalTime().ToString("o") } }']:["-axo","pid=,lstart="];return new Promise(resolve=>{execFile(command,args,{timeout:windows?5e3:1e3,maxBuffer:4*1024*1024,windowsHide:!0,...windows?{}:{env:{...process.env,LC_ALL:"C",LANG:"C"}}},(error2,stdout)=>{if(error2)return resolve(void 0);let starts=new Map;for(let line of stdout.split(`
17
- `)){let row=/^\s*(\d+)\s+(.+)$/.exec(line);if(!row)continue;let start=processStartTimeMs(row[2]);start!==void 0&&starts.set(Number(row[1]),start)}resolve(starts)})})}function sessionHeldCheck(resolveDaemonPids){let daemonPids,processStarts,pidStarts=new Map,observedStarts=new Map;return async(sessionFile,sessionId)=>{let holders=await foreignSessionHolders(sessionFile,sessionId,{readProcessStartMs:pid=>{let probe=pidStarts.get(pid);return probe||(probe=(async()=>{process.platform!=="linux"&&(processStarts??=readProcessStarts());let start=(await processStarts)?.get(pid)??await readProcessStartMs(pid);return observedStarts.set(pid,start),start})(),pidStarts.set(pid,probe)),probe}});if(holders.length===0)return;daemonPids??=resolveDaemonPids?.(observedStarts)??Promise.resolve([]);let family=await daemonPids,foreign=holders.filter(holder=>!family.includes(holder.pid));if(foreign.length>0)throw new RpcSessionRegistryError(RPC_ERROR_SESSION_HELD,void 0,{holders:foreign.map(({pid,cwd,host_socket,host_instance})=>({pid,...cwd===void 0?{}:{cwd},...host_socket===void 0?{}:{host_socket},...host_instance===void 0?{}:{host_instance}}))})}}async function dispatchSessionBinding(command,entry,binding,acknowledgePrompt,daemonPids){if(!binding)throw new RpcSessionRegistryError("unknown_session");if(!READ_ONLY_OR_CONTROL.has(command.type)){let assertSessionNotHeld=sessionHeldCheck(daemonPids),state=entry.worker?.snapshot?.state;await assertSessionNotHeld(entry.runtime?.session.sessionFile??state?.sessionFile??entry.sessionPath,entry.runtime?.session.sessionId??state?.sessionId??entry.durableSessionId),"sessionPath"in command&&await assertSessionNotHeld(command.sessionPath)}command.type==="prompt"&&acknowledgePrompt(),await binding.handle(command)}var NOTHING_DROPPED={deliveries:[],user_messages:[]};function takeQueuedInput(session){let admittedBefore=session.externalAdmission.list().pending,cleared=session.clearQueue({abortWillFollow:!0}),stillAdmitted=new Set(session.externalAdmission.list().pending);return{deliveries:admittedBefore.filter(deliveryId=>!stillAdmitted.has(deliveryId)),user_messages:cleared.ordered.map(queued=>queued.text)}}async function abortAndSettle(port,sessionId,session){session.abortBash();let stopStarts=session.subscribe(event=>{event.type==="agent_start"&&session.abort()}),deadline,expired=new Promise(resolve=>{deadline=setTimeout(resolve,1e4)});try{await Promise.race([Promise.allSettled([session.abort().then(()=>session.waitForIdle()),port.otherRequestsSettled(sessionId),...port.pendingPrompts(sessionId)]),expired])}finally{clearTimeout(deadline),stopStarts()}}var SESSION_RELEASED_ENTRY_TYPE="session_released",RELEASED_ADMISSION_CLOSED="release_session handed this session to another runtime; deliver there instead (admission is closed here)",RELEASE_QUEUED_HINT="queued user input is still owed a turn; release with interrupt: true to take it out and receive it in dropped.user_messages";async function releaseSession(port,command){if(command.reason!=="takeover")return refusal2(command.id,RPC_ERROR_INVALID_RELEASE_REASON);if(port.draining())return refusal2(command.id,RPC_ERROR_HOST_DRAINING);let first=releasable(port,command,void 0);if(!("session"in first))return first;let busy=busySignals(port,command.sessionId,first.session),interrupted=busy.length>0;if(interrupted&&command.interrupt!==!0)return refusal2(command.id,busyCode(busy),{attachments:first.attachments,...busyData(busy)});let admission=first.session.externalAdmission,dropped=NOTHING_DROPPED,answer2;try{interrupted&&(admission.close(RELEASED_ADMISSION_CLOSED),dropped=takeQueuedInput(first.session),await abortAndSettle(port,command.sessionId,first.session));let manager=first.session.sessionManager;return manager.isTranscriptFlushed()||await manager.persistHeaderNow(),answer2=await claimAndRelease(port,command,interrupted,dropped),answer2}catch(cause){return answer2=refusal2(command.id,RPC_ERROR_RELEASE_FAILED,{detail:cause instanceof Error?cause.message:String(cause),...interrupted?{interrupted:!0,dropped}:{}}),answer2}finally{answer2?.success!==!0&&admission.reopen()}}async function claimAndRelease(port,command,interrupted,dropped){let taken=interrupted?{interrupted:!0,dropped}:void 0,ready=releasable(port,command,taken);if(!("session"in ready))return ready;let stillBusy=busySignals(port,command.sessionId,ready.session);if(stillBusy.length>0)return refusal2(command.id,busyCode(stillBusy),{attachments:ready.attachments,...busyData(stillBusy),interrupted,...taken});let admission=ready.session.externalAdmission;admission.close(RELEASED_ADMISSION_CLOSED);try{ready.session.sessionManager.appendCustomEntry(SESSION_RELEASED_ENTRY_TYPE,{reason:command.reason,interrupted,attachments:ready.attachments,host_instance:port.hostInstance??null,released_at:new Date().toISOString()})}catch(cause){throw admission.reopen(),cause}return await port.tearDown(command.sessionId,ready.sessionPath)?{id:command.id,type:"response",command:"release_session",success:!0,data:{released:!0,session_path:ready.sessionPath,attachments:ready.attachments,dropped}}:refusal2(command.id,RPC_ERROR_SESSION_CLOSING,taken)}function busySignals(port,sessionId,session){let activity=session.activitySnapshot,signals=[];return activity.isStreaming&&signals.push("turn"),port.pendingPrompts(sessionId).length>0&&signals.push("prompt"),session.pendingMessageCount>0&&signals.push("queued"),session.externalAdmission.list().pending.length>0&&signals.push("delivery"),activity.isBashRunning&&signals.push("bash"),activity.isCompacting&&signals.push("compaction"),activity.hasSessionWork&&signals.push("session_work"),signals.length===0&&isHandoffBusy(activity)&&signals.push("activity"),port.otherRequests(sessionId)>0&&signals.push("request"),signals}function busyData(signals){return signals.includes("queued")?{busy:signals,retry_with:{interrupt:!0},hint:RELEASE_QUEUED_HINT}:{busy:signals}}function busyCode(signals){return signals.some(signal=>signal==="turn"||signal==="prompt"||signal==="queued"||signal==="delivery")?RPC_ERROR_TURN_ACTIVE:RPC_ERROR_SESSION_BUSY}function releasable(port,command,taken){let refuse=(code,data)=>refusal2(command.id,code,data||taken?{...data,...taken}:void 0),entry;try{entry=port.lookup(command.sessionId)}catch(cause){return refuse(port.code(cause))}if(entry.state!=="open")return refuse(RPC_ERROR_SESSION_CLOSING);let session=entry.runtime?.session;if(session===void 0)return refuse(RPC_ERROR_RELEASE_UNSUPPORTED,{detail:"worker_runtime"});let sessionPath=entry.sessionPath??session.sessionFile;return sessionPath===void 0?refuse(RPC_ERROR_RELEASE_UNSUPPORTED,{detail:"no_session_file"}):entry.attachments>0&&command.force!==!0?refuse(RPC_ERROR_ATTACHED,{attachments:entry.attachments}):{session,sessionPath,attachments:entry.attachments}}function refusal2(id,code,data){return{id,type:"response",command:"release_session",success:!1,error:code,...data&&{errorCode:code,errorData:data}}}var DETACHED_RETIREMENT_GRACE_MS=5e3;function selectSweepEvictions(registry,now,idleEvictionMs,hasPendingRequest=()=>!1){let idle=[],orphaned=[];for(let{sessionId,status,sessionPath}of registry.list()){if(status!=="open")continue;let entry=registry.peek(sessionId);if(!entry)continue;if(entry.attachments===0&&sessionPath!==void 0&&sessionDirectoryRemoved(sessionPath)){orphaned.push(sessionId);continue}if(!Number.isFinite(idleEvictionMs)||hasPendingRequest(sessionId))continue;let session=entry.runtime?.session;if(entry.worker?.busy||session?.isSessionBusy){entry.lastCommandAt=now;continue}if(entry.attachments>0){now-entry.lastCommandAt>=idleEvictionMs&&idle.push(sessionId);continue}if(entry.kind==="worker"&&entry.retainOnDisconnect&&session?.sessionManager.isTranscriptFlushed()){if(session.pendingMessageCount>0||session.externalAdmission.list().pending.length>0)continue;if(entry.detachedAt!==void 0){if(now-entry.detachedAt<DETACHED_RETIREMENT_GRACE_MS)continue;idle.push(sessionId);continue}}now-entry.lastCommandAt>=idleEvictionMs&&idle.push(sessionId)}return{idle,orphaned}}var CHILD_TASK_SOURCE=/^senpi-task/,ACTIONS={extension_work:"let the named work finish, or unload with force: true (it is stopped, not resumed on reopen)",turn_active:"wait for the turn to end, or unload with interrupt: true to stop it first",work_pending:"wait for the work to finish, or unload with interrupt: true",children_live:'wait for the child tasks, or unload with children: "detach" to leave them running',attached:"ask the other clients to detach, or unload with force: true (they receive session_parked)"};async function unloadSession(port,command){if(port.draining())return answer(command,refused({reason:"host_draining",detail:"this host is draining and parks every session itself"}));let first=loaded(port,command.sessionId);if("reason"in first)return answer(command,refused(first));let{effectId}=command;if(effectId!==void 0){let begun=await beginEffect({session:first.session,by:port.by,sessionId:command.sessionId},"unload",{...command,effectId});if(!isEffectBegin(begun))return begun;if("replay"in begun)return answer(command,{outcome:begun.replay.state==="failed"?"refused":"unloaded",...refusalFields(begun.replay.outcome),...effectAnswer(begun.replay,command.sessionId,!0)})}let blocked=blockers(port,command,first.session,first.durableSessionId),standing=blocked.find(refusal3=>!interruptible(refusal3)||command.interrupt!==!0);return standing!==void 0?fail(command,first.session,standing):(blocked.length>0&&await abortAndSettle(port,command.sessionId,first.session),claimAndUnload(port,command))}async function claimAndUnload(port,command){let ready=loaded(port,command.sessionId);if("reason"in ready)return answer(command,refused(ready));let stillBlocked=blockers(port,command,ready.session,ready.durableSessionId);if(stillBlocked.length>0)return fail(command,ready.session,stillBlocked[0]);command.clearQueue===!0&&(ClientAdmissions.clearQueuedFor(ready.session),ready.session.clearQueue());let effect=command.effectId===void 0?void 0:EffectLedger.forSession(ready.session).transition(command.effectId,"done",{disposition:"unloaded"});return await port.tearDown(command.sessionId,ready.sessionPath)?answer(command,{outcome:"unloaded",sessionPath:ready.sessionPath,...effect===void 0?{}:effectAnswer(effect,command.sessionId)}):answer(command,{outcome:"refused",reason:"session_closing",detail:"another close of this session finished first"})}function interruptible(refusal3){return refusal3.reason==="turn_active"||refusal3.reason==="work_pending"}function blockers(port,command,session,durableSessionId){let found=[],activity=session.activitySnapshot,running=[activity.isStreaming&&"an agent run",port.pendingPrompts(command.sessionId).length>0&&"a prompt about to start",activity.isCompacting&&"compaction",activity.hasSessionWork&&"session work"].filter(label=>typeof label=="string");running.length>0&&found.push({reason:"turn_active",detail:running.join(", "),action:ACTIONS.turn_active});let pending=[activity.isBashRunning&&"a bash command",session.externalAdmission.list().pending.length>0&&"an admitted delivery not yet written",port.otherRequests(command.sessionId)>0&&"another request for this session"].filter(label=>typeof label=="string");pending.length>0&&found.push({reason:"work_pending",detail:pending.join(", "),action:ACTIONS.work_pending});let sources=session.activeWakeSources,childSources=sources.filter(source=>CHILD_TASK_SOURCE.test(source)),otherSources=sources.filter(source=>!CHILD_TASK_SOURCE.test(source));otherSources.length>0&&command.force!==!0&&found.push({reason:"extension_work",detail:`work published by ${otherSources.join(", ")}`,action:ACTIONS.extension_work});let childSessions=port.openChildSessions(durableSessionId);if(command.children!=="detach"&&(childSources.length>0||childSessions>0)){let what=childSessions>0?`${childSessions} child session(s) open on this host`:"child tasks still working";found.push({reason:"children_live",detail:what,action:ACTIONS.children_live})}let others=port.otherAttachments(command.sessionId);return others>0&&command.force!==!0&&found.push({reason:"attached",detail:`${others} other client(s) attached`,action:ACTIONS.attached}),found}function loaded(port,sessionId){let entry;try{entry=port.lookup(sessionId)}catch(cause){return{reason:"unsupported",detail:port.code(cause)}}if(entry.state!=="open")return{reason:"session_closing",detail:"the session is already closing"};let session=entry.runtime?.session;if(session===void 0)return{reason:"unsupported",detail:"a worker isolate owns this session's runtime"};let sessionPath=entry.sessionPath??session.sessionFile;return sessionPath===void 0?{reason:"unsupported",detail:"the session has no file to reopen it by",action:"send a prompt first so the session is written, or close it instead"}:{session,sessionPath,durableSessionId:session.sessionManager.getSessionId()}}function fail(command,session,refusal3){if(command.effectId===void 0)return answer(command,refused(refusal3));let status=EffectLedger.forSession(session).transition(command.effectId,"failed",{outcome:{kind:"refused",reason:refusal3.reason,detail:refusal3.detail,...refusal3.action===void 0?{}:{action:refusal3.action}}});return answer(command,{...refused(refusal3),...effectAnswer(status,command.sessionId)})}function refusalFields(outcome){return outcome?.reason===void 0?{}:{reason:outcome.reason,...outcome.detail===void 0?{}:{detail:outcome.detail},...outcome.action===void 0?{}:{action:outcome.action}}}function refused(refusal3){return{outcome:"refused",reason:refusal3.reason,detail:refusal3.detail,...refusal3.action===void 0?{}:{action:refusal3.action}}}function answer(command,data){return{id:command.id,type:"response",command:"unload_session",success:!0,data}}var DRAIN_SWEEP_MS=50;function error(id,command,code,data){return{id,type:"response",command,success:!1,error:code,...data&&{errorCode:code,errorData:data}}}var SessionCommandRouter=class{constructor(registry,writer,defaults,createBinding=createRpcSessionBinding,connectionOptions={},idle){if(this.bindings=new Map,this.sessionsByConnection=new Map,this.opensByConnection=new Map,this.releasedConnections=new Set,this.pendingCapabilities=new Map,this.finalizations=new Map,this.draining=!1,this.handoffParks=0,this.drainExitRequested=!1,this.handoffClosed=new Set,this.activeRequests=new Map,this.requestSettledListeners=new Map,this.memoryPressure=!1,this.stopLimitBroadcast=subscriptionLimits.subscribe(limits=>writer.broadcastHostRecord({type:"subscription_limits",...limits})),this.registry=registry,this.writer=writer,this.defaults=defaults,this.createBinding=createBinding,this.connectionOptions=connectionOptions,this.idleNow=idle?.now??Date.now,this.idleEvictionMs=idle?.idleEvictionMs??Number.POSITIVE_INFINITY,this.emptyExitMs=idle?.emptyExitMs??Number.POSITIVE_INFINITY,this.onEmptyExit=idle?.onEmptyExit,this.onHandoffParked=idle?.onHandoffParked,this.handoverParkedDir=idle?.handoverParkedDir,this.canExitWhenEmpty=idle?.canExitWhenEmpty,writer.status.setSource(registryStatusSource(registry)),writer.status.setLastEffectProvider(sessionId=>{let session=this.registry.peek(sessionId)?.runtime?.session;if(session===void 0)return;let latest=latestSessionEffect(session);return latest===void 0?void 0:{effectId:latest.effectId,kind:latest.kind,state:latest.state}}),writer.afterRecord=sessionId=>{let session=this.registry.peek(sessionId)?.runtime?.session;if(session!==void 0)for(let status of drainSessionEffects(session))this.writer.status.publishEffect(sessionId,status)},this.uninstallEffectSink=installSessionEffectSink({owns:session=>this.routingIdOf(session)!==void 0,flush:(session,statuses)=>{let sessionId=this.routingIdOf(session);if(sessionId!==void 0)for(let status of statuses)this.writer.status.publishEffect(sessionId,status)}}),Number.isFinite(this.idleEvictionMs)||Number.isFinite(this.emptyExitMs)){let tickMs=Math.max(20,Math.min(5e3,Math.min(this.idleEvictionMs,this.emptyExitMs)/4));this.sweepTimer=setInterval(()=>this.sweepIdleSessions(),tickMs),this.sweepTimer.unref?.()}}get sessionCount(){return this.registry.size}setHostMemoryView(view){this.hostMemoryView=view}sessionMemory(sessionId){let view=this.hostMemoryView;if(view===void 0)return{main_heap_bytes:0,kernel_heap_bytes:0,kernel_count:0};let kernels=view.kernels().filter(kernel=>kernel.sessionId===sessionId),kernelHeapBytes=0;for(let kernel of kernels)kernelHeapBytes+=kernel.liveBytes;return{main_heap_bytes:view.mainHeapBytes(),kernel_heap_bytes:kernelHeapBytes,kernel_count:kernels.length}}beginDrain(){this.draining=!0,this.stopSweep(),this.drainTimer===void 0&&!this.drainExitRequested&&(this.drainTimer=setInterval(()=>this.sweepDrain(),DRAIN_SWEEP_MS),this.drainTimer.unref?.()),this.sweepDrain()}sweepDrain(){if(this.activeRequests.has(void 0))return;let verdicts=readDrainVerdicts(this.registry,sessionId=>this.activeRequests.has(sessionId));if(verdicts){for(let sessionId of verdicts.gone)this.parkForHandoff(sessionId,"session_dir_removed");for(let sessionId of verdicts.park)this.parkForHandoff(sessionId,"handoff_parked");this.registry.size>0||this.handoffParks>0||this.finalizations.size>0||(this.drainTimer!==void 0&&(clearInterval(this.drainTimer),this.drainTimer=void 0),this.stopSweep(),!this.drainExitRequested&&(this.drainExitRequested=!0,this.onEmptyExit?.()))}}parkForHandoff(sessionId,reason){this.handoffClosed.add(sessionId),this.handoffParks++,this.evictIdleSession(sessionId,reason).catch(cause=>{process.stderr.write(`senpi rpc handoff park ${sessionId} failed: ${String(cause)}
16
+ `),droppedAfterClose=!0;return}writeInScope(chunk)},waitForBackpressure:bindToProviderScope(async()=>{})};return createRpcConnectionHandler(runtimeHost,taggedSink,{sessionId,shutdownHandler:bindToProviderScope(requestClose),disposeRuntime:!1,eventFlushScheduler:flush=>flush(),publishLoadedSurfacesChanged:(previous,digest)=>{entry.scope.state!=="closed"&&writer.publishLoadedSurfacesChanged(sessionId,previous,digest)},...options})});return await handler.ready,{handle:command=>runWithProviderScope(entry.scope,()=>handler.handleInputLine(JSON.stringify(command))),cancelPendingExtensionUiRequests:()=>runWithProviderScope(entry.scope,()=>handler.cancelPendingExtensionUiRequests()),pendingPrompts:()=>handler.pendingPrompts(),dispose:()=>(toolSpans.closeAll(),runWithProviderScope(entry.scope,()=>handler.dispose()))}}import{execFile}from"node:child_process";var READ_ONLY_OR_CONTROL=new Set(["get_state","get_effect_status","get_pending_inputs","get_steering_messages","get_follow_up_messages","get_available_models","get_available_thinking_levels","get_fast_mode","get_session_stats","resolve_path","get_fork_messages","get_entries","get_tree","get_last_assistant_text","get_messages","get_media","get_commands","get_loaded_surfaces","get_auth_providers","get_provider_accounts","memory_report","eval_cells.list","eval_cells.peek","eval_cells.stop","export_html","export_jsonl","abort","interrupt","abort_compaction","abort_branch_summary","abort_retry","abort_bash","clear_queue","check_reload_veto","cleanup_bash_output","set_client_info","extension_ui_response","extension_ui_progress"]);function readProcessStarts(){let windows=process.platform==="win32",command=windows?"powershell.exe":"ps",args=windows?["-NoProfile","-NonInteractive","-Command",'Get-CimInstance Win32_Process -ErrorAction Stop | ForEach-Object { if ($null -ne $_.CreationDate) { "{0} {1}" -f $_.ProcessId, $_.CreationDate.ToUniversalTime().ToString("o") } }']:["-axo","pid=,lstart="];return new Promise(resolve=>{execFile(command,args,{timeout:windows?5e3:1e3,maxBuffer:4*1024*1024,windowsHide:!0,...windows?{}:{env:{...process.env,LC_ALL:"C",LANG:"C"}}},(error2,stdout)=>{if(error2)return resolve(void 0);let starts=new Map;for(let line of stdout.split(`
17
+ `)){let row=/^\s*(\d+)\s+(.+)$/.exec(line);if(!row)continue;let start=processStartTimeMs(row[2]);start!==void 0&&starts.set(Number(row[1]),start)}resolve(starts)})})}function sessionHeldCheck(resolveDaemonPids){let daemonPids,processStarts,pidStarts=new Map,observedStarts=new Map;return async(sessionFile,sessionId)=>{let holders=await foreignSessionHolders(sessionFile,sessionId,{readProcessStartMs:pid=>{let probe=pidStarts.get(pid);return probe||(probe=(async()=>{process.platform!=="linux"&&(processStarts??=readProcessStarts());let start=(await processStarts)?.get(pid)??await readProcessStartMs(pid);return observedStarts.set(pid,start),start})(),pidStarts.set(pid,probe)),probe}});if(holders.length===0)return;daemonPids??=resolveDaemonPids?.(observedStarts)??Promise.resolve([]);let family=await daemonPids,foreign=holders.filter(holder=>!family.includes(holder.pid));if(foreign.length>0)throw new RpcSessionRegistryError(RPC_ERROR_SESSION_HELD,void 0,{holders:foreign.map(({pid,cwd,host_socket,host_instance})=>({pid,...cwd===void 0?{}:{cwd},...host_socket===void 0?{}:{host_socket},...host_instance===void 0?{}:{host_instance}}))})}}async function dispatchSessionBinding(command,entry,binding,acknowledgePrompt,daemonPids){if(!binding)throw new RpcSessionRegistryError("unknown_session");if(!READ_ONLY_OR_CONTROL.has(command.type)){let assertSessionNotHeld=sessionHeldCheck(daemonPids),state=entry.worker?.snapshot?.state;await assertSessionNotHeld(entry.runtime?.session.sessionFile??state?.sessionFile??entry.sessionPath,entry.runtime?.session.sessionId??state?.sessionId??entry.durableSessionId),"sessionPath"in command&&await assertSessionNotHeld(command.sessionPath)}command.type==="prompt"&&acknowledgePrompt(),await binding.handle(command)}var NOTHING_DROPPED={deliveries:[],user_messages:[]};function takeQueuedInput(session){let admittedBefore=session.externalAdmission.list().pending,cleared=session.clearQueue({abortWillFollow:!0}),stillAdmitted=new Set(session.externalAdmission.list().pending);return{deliveries:admittedBefore.filter(deliveryId=>!stillAdmitted.has(deliveryId)),user_messages:cleared.ordered.map(queued=>queued.text)}}async function abortAndSettle(port,sessionId,session){session.abortBash();let stopStarts=session.subscribe(event=>{event.type==="agent_start"&&session.abort()}),deadline,expired=new Promise(resolve=>{deadline=setTimeout(resolve,1e4)});try{await Promise.race([Promise.allSettled([session.abort().then(()=>session.waitForIdle()),port.otherRequestsSettled(sessionId),...port.pendingPrompts(sessionId)]),expired])}finally{clearTimeout(deadline),stopStarts()}}var SESSION_RELEASED_ENTRY_TYPE="session_released",RELEASED_ADMISSION_CLOSED="release_session handed this session to another runtime; deliver there instead (admission is closed here)",RELEASE_QUEUED_HINT="queued user input is still owed a turn; release with interrupt: true to take it out and receive it in dropped.user_messages";async function releaseSession(port,command){let validMove=command.reason==="move"&&typeof command.moveId=="string"&&command.moveId!=="";if(command.reason!=="takeover"&&!validMove)return refusal2(command.id,RPC_ERROR_INVALID_RELEASE_REASON);if(port.draining())return refusal2(command.id,RPC_ERROR_HOST_DRAINING);let first=releasable(port,command,void 0);if(!("session"in first))return first;let busy=busySignals(port,command.sessionId,first.session),interrupted=busy.length>0;if(interrupted&&command.interrupt!==!0)return refusal2(command.id,busyCode(busy),{attachments:first.attachments,...busyData(busy)});let admission=first.session.externalAdmission,dropped=NOTHING_DROPPED,answer2;try{interrupted&&(admission.close(RELEASED_ADMISSION_CLOSED),dropped=takeQueuedInput(first.session),await abortAndSettle(port,command.sessionId,first.session),await first.session.whenQueueClearRecorded());let manager=first.session.sessionManager;return manager.isTranscriptFlushed()||await manager.persistHeaderNow(),answer2=await claimAndRelease(port,command,interrupted,dropped),answer2}catch(cause){return cause instanceof SessionMovedAwayError?(answer2=refusal2(command.id,cause.code,{detail:cause.message}),answer2):(answer2=refusal2(command.id,RPC_ERROR_RELEASE_FAILED,{detail:cause instanceof Error?cause.message:String(cause),...interrupted?{interrupted:!0,dropped}:{}}),answer2)}finally{answer2?.success!==!0&&admission.reopen()}}async function claimAndRelease(port,command,interrupted,dropped){let taken=interrupted?{interrupted:!0,dropped}:void 0,ready=releasable(port,command,taken);if(!("session"in ready))return ready;let stillBusy=busySignals(port,command.sessionId,ready.session);if(stillBusy.length>0)return refusal2(command.id,busyCode(stillBusy),{attachments:ready.attachments,...busyData(stillBusy),interrupted,...taken});let admission=ready.session.externalAdmission;admission.close(RELEASED_ADMISSION_CLOSED);try{ready.session.sessionManager.appendCustomEntry(SESSION_RELEASED_ENTRY_TYPE,{reason:command.reason,...command.reason==="move"?{move_id:command.moveId,target:command.target??"",session_id:ready.session.sessionManager.getSessionId()}:{},interrupted,attachments:ready.attachments,host_instance:port.hostInstance??null,released_at:new Date().toISOString()})}catch(cause){throw admission.reopen(),cause}return await port.tearDown(command.sessionId,ready.sessionPath)?{id:command.id,type:"response",command:"release_session",success:!0,data:{released:!0,session_path:ready.sessionPath,attachments:ready.attachments,dropped}}:refusal2(command.id,RPC_ERROR_SESSION_CLOSING,taken)}function busySignals(port,sessionId,session){let activity=session.activitySnapshot,signals=[];return activity.isStreaming&&signals.push("turn"),port.pendingPrompts(sessionId).length>0&&signals.push("prompt"),session.pendingMessageCount>0&&signals.push("queued"),session.externalAdmission.list().pending.length>0&&signals.push("delivery"),activity.isBashRunning&&signals.push("bash"),activity.isCompacting&&signals.push("compaction"),activity.hasSessionWork&&signals.push("session_work"),signals.length===0&&isHandoffBusy(activity)&&signals.push("activity"),port.otherRequests(sessionId)>0&&signals.push("request"),signals}function busyData(signals){return signals.includes("queued")?{busy:signals,retry_with:{interrupt:!0},hint:RELEASE_QUEUED_HINT}:{busy:signals}}function busyCode(signals){return signals.some(signal=>signal==="turn"||signal==="prompt"||signal==="queued"||signal==="delivery")?RPC_ERROR_TURN_ACTIVE:RPC_ERROR_SESSION_BUSY}function releasable(port,command,taken){let refuse=(code,data)=>refusal2(command.id,code,data||taken?{...data,...taken}:void 0),entry;try{entry=port.lookup(command.sessionId)}catch(cause){return refuse(port.code(cause))}if(entry.state!=="open")return refuse(RPC_ERROR_SESSION_CLOSING);let session=entry.runtime?.session;if(session===void 0)return refuse(RPC_ERROR_RELEASE_UNSUPPORTED,{detail:"worker_runtime"});let sessionPath=entry.sessionPath??session.sessionFile;return sessionPath===void 0?refuse(RPC_ERROR_RELEASE_UNSUPPORTED,{detail:"no_session_file"}):entry.attachments>0&&command.force!==!0?refuse(RPC_ERROR_ATTACHED,{attachments:entry.attachments}):{session,sessionPath,attachments:entry.attachments}}function refusal2(id,code,data){return{id,type:"response",command:"release_session",success:!1,error:code,...data&&{errorCode:code,errorData:data}}}var DETACHED_RETIREMENT_GRACE_MS=5e3;function selectSweepEvictions(registry,now,idleEvictionMs,hasPendingRequest=()=>!1){let idle=[],orphaned=[];for(let{sessionId,status,sessionPath}of registry.list()){if(status!=="open")continue;let entry=registry.peek(sessionId);if(!entry)continue;if(entry.attachments===0&&sessionPath!==void 0&&sessionDirectoryRemoved(sessionPath)){orphaned.push(sessionId);continue}if(!Number.isFinite(idleEvictionMs)||hasPendingRequest(sessionId))continue;let session=entry.runtime?.session;if(entry.worker?.busy||session?.isSessionBusy){entry.lastCommandAt=now;continue}if(entry.attachments>0){now-entry.lastCommandAt>=idleEvictionMs&&idle.push(sessionId);continue}if(entry.kind==="worker"&&entry.retainOnDisconnect&&session?.sessionManager.isTranscriptFlushed()){if(session.pendingMessageCount>0||session.externalAdmission.list().pending.length>0)continue;if(entry.detachedAt!==void 0){if(now-entry.detachedAt<DETACHED_RETIREMENT_GRACE_MS)continue;idle.push(sessionId);continue}}now-entry.lastCommandAt>=idleEvictionMs&&idle.push(sessionId)}return{idle,orphaned}}var CHILD_TASK_SOURCE=/^senpi-task/,ACTIONS={extension_work:"let the named work finish, or unload with force: true (it is stopped, not resumed on reopen)",turn_active:"wait for the turn to end, or unload with interrupt: true to stop it first",work_pending:"wait for the work to finish, or unload with interrupt: true",children_live:'wait for the child tasks, or unload with children: "detach" to leave them running',attached:"ask the other clients to detach, or unload with force: true (they receive session_parked)"};async function unloadSession(port,command){if(port.draining())return answer(command,refused({reason:"host_draining",detail:"this host is draining and parks every session itself"}));let first=loaded(port,command.sessionId);if("reason"in first)return answer(command,refused(first));let{effectId}=command;if(effectId!==void 0){let begun=await beginEffect({session:first.session,by:port.by,sessionId:command.sessionId},"unload",{...command,effectId});if(!isEffectBegin(begun))return begun;if("replay"in begun)return answer(command,{outcome:begun.replay.state==="failed"?"refused":"unloaded",...refusalFields(begun.replay.outcome),...effectAnswer(begun.replay,command.sessionId,!0)})}let blocked=blockers(port,command,first.session,first.durableSessionId),standing=blocked.find(refusal3=>!interruptible(refusal3)||command.interrupt!==!0);return standing!==void 0?fail(command,first.session,standing):(blocked.length>0&&await abortAndSettle(port,command.sessionId,first.session),claimAndUnload(port,command))}async function claimAndUnload(port,command){let ready=loaded(port,command.sessionId);if("reason"in ready)return answer(command,refused(ready));let stillBlocked=blockers(port,command,ready.session,ready.durableSessionId);if(stillBlocked.length>0)return fail(command,ready.session,stillBlocked[0]);command.clearQueue===!0&&(ClientAdmissions.clearQueuedFor(ready.session),ready.session.clearQueue());let effect=command.effectId===void 0?void 0:EffectLedger.forSession(ready.session).transition(command.effectId,"done",{disposition:"unloaded"});return await port.tearDown(command.sessionId,ready.sessionPath)?answer(command,{outcome:"unloaded",sessionPath:ready.sessionPath,...effect===void 0?{}:effectAnswer(effect,command.sessionId)}):answer(command,{outcome:"refused",reason:"session_closing",detail:"another close of this session finished first"})}function interruptible(refusal3){return refusal3.reason==="turn_active"||refusal3.reason==="work_pending"}function blockers(port,command,session,durableSessionId){let found=[],activity=session.activitySnapshot,running=[activity.isStreaming&&"an agent run",port.pendingPrompts(command.sessionId).length>0&&"a prompt about to start",activity.isCompacting&&"compaction",activity.hasSessionWork&&"session work"].filter(label=>typeof label=="string");running.length>0&&found.push({reason:"turn_active",detail:running.join(", "),action:ACTIONS.turn_active});let pending=[activity.isBashRunning&&"a bash command",session.externalAdmission.list().pending.length>0&&"an admitted delivery not yet written",port.otherRequests(command.sessionId)>0&&"another request for this session"].filter(label=>typeof label=="string");pending.length>0&&found.push({reason:"work_pending",detail:pending.join(", "),action:ACTIONS.work_pending});let sources=session.activeWakeSources,childSources=sources.filter(source=>CHILD_TASK_SOURCE.test(source)),otherSources=sources.filter(source=>!CHILD_TASK_SOURCE.test(source));otherSources.length>0&&command.force!==!0&&found.push({reason:"extension_work",detail:`work published by ${otherSources.join(", ")}`,action:ACTIONS.extension_work});let childSessions=port.openChildSessions(durableSessionId);if(command.children!=="detach"&&(childSources.length>0||childSessions>0)){let what=childSessions>0?`${childSessions} child session(s) open on this host`:"child tasks still working";found.push({reason:"children_live",detail:what,action:ACTIONS.children_live})}let others=port.otherAttachments(command.sessionId);return others>0&&command.force!==!0&&found.push({reason:"attached",detail:`${others} other client(s) attached`,action:ACTIONS.attached}),found}function loaded(port,sessionId){let entry;try{entry=port.lookup(sessionId)}catch(cause){return{reason:"unsupported",detail:port.code(cause)}}if(entry.state!=="open")return{reason:"session_closing",detail:"the session is already closing"};let session=entry.runtime?.session;if(session===void 0)return{reason:"unsupported",detail:"a worker isolate owns this session's runtime"};let sessionPath=entry.sessionPath??session.sessionFile;return sessionPath===void 0?{reason:"unsupported",detail:"the session has no file to reopen it by",action:"send a prompt first so the session is written, or close it instead"}:{session,sessionPath,durableSessionId:session.sessionManager.getSessionId()}}function fail(command,session,refusal3){if(command.effectId===void 0)return answer(command,refused(refusal3));let status=EffectLedger.forSession(session).transition(command.effectId,"failed",{outcome:{kind:"refused",reason:refusal3.reason,detail:refusal3.detail,...refusal3.action===void 0?{}:{action:refusal3.action}}});return answer(command,{...refused(refusal3),...effectAnswer(status,command.sessionId)})}function refusalFields(outcome){return outcome?.reason===void 0?{}:{reason:outcome.reason,...outcome.detail===void 0?{}:{detail:outcome.detail},...outcome.action===void 0?{}:{action:outcome.action}}}function refused(refusal3){return{outcome:"refused",reason:refusal3.reason,detail:refusal3.detail,...refusal3.action===void 0?{}:{action:refusal3.action}}}function answer(command,data){return{id:command.id,type:"response",command:"unload_session",success:!0,data}}var DRAIN_SWEEP_MS=50;function error(id,command,code,data){return{id,type:"response",command,success:!1,error:code,...data&&{errorCode:code,errorData:data}}}var SessionCommandRouter=class{constructor(registry,writer,defaults,createBinding=createRpcSessionBinding,connectionOptions={},idle){if(this.bindings=new Map,this.sessionsByConnection=new Map,this.opensByConnection=new Map,this.releasedConnections=new Set,this.pendingCapabilities=new Map,this.finalizations=new Map,this.draining=!1,this.handoffParks=0,this.drainExitRequested=!1,this.handoffClosed=new Set,this.activeRequests=new Map,this.requestSettledListeners=new Map,this.memoryPressure=!1,this.stopLimitBroadcast=subscriptionLimits.subscribe(limits=>writer.broadcastHostRecord({type:"subscription_limits",...limits})),this.registry=registry,this.writer=writer,this.defaults=defaults,this.createBinding=createBinding,this.connectionOptions=connectionOptions,this.idleNow=idle?.now??Date.now,this.idleEvictionMs=idle?.idleEvictionMs??Number.POSITIVE_INFINITY,this.emptyExitMs=idle?.emptyExitMs??Number.POSITIVE_INFINITY,this.onEmptyExit=idle?.onEmptyExit,this.onHandoffParked=idle?.onHandoffParked,this.handoverParkedDir=idle?.handoverParkedDir,this.canExitWhenEmpty=idle?.canExitWhenEmpty,writer.status.setSource(registryStatusSource(registry)),writer.status.setLastEffectProvider(sessionId=>{let session=this.registry.peek(sessionId)?.runtime?.session;if(session===void 0)return;let latest=latestSessionEffect(session);return latest===void 0?void 0:{effectId:latest.effectId,kind:latest.kind,state:latest.state}}),writer.afterRecord=sessionId=>{let session=this.registry.peek(sessionId)?.runtime?.session;if(session!==void 0)for(let status of drainSessionEffects(session))this.writer.status.publishEffect(sessionId,status)},this.uninstallEffectSink=installSessionEffectSink({owns:session=>this.routingIdOf(session)!==void 0,flush:(session,statuses)=>{let sessionId=this.routingIdOf(session);if(sessionId!==void 0)for(let status of statuses)this.writer.status.publishEffect(sessionId,status)}}),Number.isFinite(this.idleEvictionMs)||Number.isFinite(this.emptyExitMs)){let tickMs=Math.max(20,Math.min(5e3,Math.min(this.idleEvictionMs,this.emptyExitMs)/4));this.sweepTimer=setInterval(()=>this.sweepIdleSessions(),tickMs),this.sweepTimer.unref?.()}}get sessionCount(){return this.registry.size}setHostMemoryView(view){this.hostMemoryView=view}sessionMemory(sessionId){let view=this.hostMemoryView;if(view===void 0)return{main_heap_bytes:0,kernel_heap_bytes:0,kernel_count:0};let kernels=view.kernels().filter(kernel=>kernel.sessionId===sessionId),kernelHeapBytes=0;for(let kernel of kernels)kernelHeapBytes+=kernel.liveBytes;return{main_heap_bytes:view.mainHeapBytes(),kernel_heap_bytes:kernelHeapBytes,kernel_count:kernels.length}}beginDrain(){this.draining=!0,this.stopSweep(),this.drainTimer===void 0&&!this.drainExitRequested&&(this.drainTimer=setInterval(()=>this.sweepDrain(),DRAIN_SWEEP_MS),this.drainTimer.unref?.()),this.sweepDrain()}sweepDrain(){if(this.activeRequests.has(void 0))return;let verdicts=readDrainVerdicts(this.registry,sessionId=>this.activeRequests.has(sessionId));if(verdicts){for(let sessionId of verdicts.gone)this.parkForHandoff(sessionId,"session_dir_removed");for(let sessionId of verdicts.park)this.parkForHandoff(sessionId,"handoff_parked");this.registry.size>0||this.handoffParks>0||this.finalizations.size>0||(this.drainTimer!==void 0&&(clearInterval(this.drainTimer),this.drainTimer=void 0),this.stopSweep(),!this.drainExitRequested&&(this.drainExitRequested=!0,this.onEmptyExit?.()))}}parkForHandoff(sessionId,reason){this.handoffClosed.add(sessionId),this.handoffParks++,this.evictIdleSession(sessionId,reason).catch(cause=>{process.stderr.write(`senpi rpc handoff park ${sessionId} failed: ${String(cause)}
18
18
  `)}).finally(()=>{this.handoffParks--,this.sweepDrain()})}setMemoryPressure(pressure){this.memoryPressure=pressure}handle(command){let sessionId="sessionId"in command?command.sessionId:void 0;return this.draining&&sessionId!==void 0&&this.handoffClosed.has(sessionId)?Promise.resolve(void 0):this.draining&&command.type==="open_session"?Promise.resolve(error(command.id,command.type,"host_draining")):command.type==="warm"?answerWarm(command,{draining:this.draining,warm:this.registry.warm,cwd:this.defaults.cwd,hostContext:this.defaults.hostContext}):(this.activeRequests.set(sessionId,(this.activeRequests.get(sessionId)??0)+1),runWithSessionAttribution({sessionId},()=>this.dispatch(command)).finally(()=>{let remaining=(this.activeRequests.get(sessionId)??1)-1;if(remaining>0?this.activeRequests.set(sessionId,remaining):this.activeRequests.delete(sessionId),sessionId!==void 0)for(let listener of this.requestSettledListeners.get(sessionId)??[])listener();this.draining&&this.sweepDrain()}))}async dispatch(command){if(command.type==="get_protocol_info"){let capabilities=multiSessionHostCapabilities({warm:this.registry.warm!==void 0,toolRuntime:this.defaults.toolRuntime??"in-process",negotiated:this.connectionOptions?.capabilities??[]});return{id:command.id,type:"response",command:"get_protocol_info",success:!0,data:{protocolVersion:1,serverVersion:VERSION,capabilities,mode:"multi",...protocolIdentity(),memory_pressure:this.memoryPressure}}}if(command.type==="get_subscription_limits")return{id:command.id,type:"response",command:"get_subscription_limits",success:!0,data:{accounts:subscriptionLimits.snapshot()}};if(command.type==="list_sessions"){let withMemory=this.registry.list().map(row=>({...row,memory:this.sessionMemory(row.sessionId)})),sessions=command.include_workers===!0?withMemory:withMemory.filter(row=>row.kind!=="worker").map(({context:_context,...row})=>row);return{id:command.id,type:"response",command:"list_sessions",success:!0,data:{sessions}}}if(command.type==="detach_connection")return detachConnection(command,this.writer.currentConnection(),id=>this.releaseConnection(id));if(command.type==="open_session")return this.openWithBarrier(command);if(command.type==="close_session")return this.close(command);if(command.type==="release_session")return releaseSession({draining:()=>this.draining,hostInstance:this.defaults.hostContext?.host_instance,lookup:sessionId2=>this.registry.getForCommand(sessionId2,"release_session"),code:cause=>this.code(cause),otherRequests:sessionId2=>Math.max(0,(this.activeRequests.get(sessionId2)??1)-1),otherRequestsSettled:sessionId2=>this.otherRequestsSettled(sessionId2),pendingPrompts:sessionId2=>this.bindings.get(sessionId2)?.pendingPrompts?.()??[],tearDown:(sessionId2,sessionPath)=>this.tearDownReleased(sessionId2,sessionPath)},command);if(command.type==="unload_session"){let caller=this.writer.currentConnection();return unloadSession({draining:()=>this.draining,by:{connectionId:caller??"host"},lookup:sessionId2=>this.registry.getForCommand(sessionId2,"unload_session"),code:cause=>this.code(cause),otherRequests:sessionId2=>Math.max(0,(this.activeRequests.get(sessionId2)??1)-1),otherRequestsSettled:sessionId2=>this.otherRequestsSettled(sessionId2),pendingPrompts:sessionId2=>this.bindings.get(sessionId2)?.pendingPrompts?.()??[],otherAttachments:sessionId2=>{let attachments=Math.max(0,this.registry.peek(sessionId2)?.attachments??0);return caller!==void 0&&this.sessionsByConnection.get(caller)?.has(sessionId2)===!0?Math.max(0,attachments-1):attachments},openChildSessions:durableSessionId=>this.registry.list().filter(row=>row.durableSessionId!==durableSessionId&&(row.context?.parent_session_id===durableSessionId||row.context?.root_session_id===durableSessionId)).length,tearDown:(sessionId2,sessionPath)=>this.tearDownUnloaded(sessionId2,sessionPath)},command)}if(command.type==="set_client_info"&&!command.sessionId){let connection=this.writer.currentConnection();return connection!==void 0&&(this.pendingCapabilities.set(connection,command.capabilities??[]),this.writer.setConnectionCapabilities(connection,command.capabilities??[])),{id:command.id,type:"response",command:"set_client_info",success:!0}}if(command.type==="subscribe_sessions"){let connection=this.writer.currentConnection(),{answer:answer2,activate}=answerSubscribeSessions(command,connection,this.writer.status);if(activate!==void 0&&connection!==void 0){(async()=>{await this.writer.enqueueControl(answer2,connection),await new Promise(resolve=>queueMicrotask(resolve));try{this.writer.hasConnection(connection)?this.writer.status.activate(activate):this.writer.status.unsubscribe(connection,activate)}catch(cause){process.stderr.write(`senpi rpc subscription activation failed: ${String(cause)}
19
19
  `)}})().catch(cause=>{this.writer.status.unsubscribe(connection,activate),process.stderr.write(`senpi rpc subscribe answer could not be delivered: ${String(cause)}
20
20
  `)});return}return answer2}if(command.type==="unsubscribe_sessions")return answerUnsubscribeSessions(command,this.writer.currentConnection(),this.writer.status);if(command.type==="get_effect_status"&&!command.sessionId&&command.sessionPath!==void 0)return answerEffectFromTranscript(command.id,command.sessionPath,command.effectId);if(!command.sessionId)return error(command.id,command.type,RPC_ERROR_MISSING_SESSION_ID);let sessionId=command.sessionId;if(command.type==="set_session_context")return this.setSessionContext(command);try{let entry=this.registry.getForCommand(sessionId,command.type);await dispatchSessionBinding(command,entry,this.bindings.get(sessionId),()=>this.acknowledgePrompt(command.id,sessionId),observedStarts=>this.registry.holderPids?.(observedStarts)??Promise.resolve([]));return}catch(cause){return error(command.id,command.type,this.code(cause),this.detail(cause))}}setSessionContext(command){let owner=this.writer.currentConnection();if(owner!==void 0&&this.sessionsByConnection.get(owner)?.has(command.sessionId)!==!0)return notAttachedRefusal(command);try{let entry=this.registry.getForCommand(command.sessionId,command.type);return answerSetSessionContext(command,entry,this.writer.status)}catch(cause){return error(command.id,command.type,this.code(cause),this.detail(cause))}}async dispose(){this.stopLimitBroadcast(),this.drainExitRequested=!0,this.stopSweep(),this.drainTimer!==void 0&&clearInterval(this.drainTimer),await Promise.all([...this.bindings.entries()].map(async([sessionId,binding])=>{let claim=this.tryClaimClose(sessionId,{drainAttachments:!0});claim&&(claim.finalizer?await this.finalizeClose(sessionId,binding,()=>this.writer.closeSession(sessionId,{type:"response",command:"close_session",success:!0,data:{}},"host_shutdown")):await this.finalizations.get(sessionId)?.promise,this.writer.forgetSession(sessionId))})),this.bindings.clear(),this.uninstallEffectSink?.(),this.uninstallEffectSink=void 0}sweepIdleSessions(){let now=this.idleNow(),idleEvictionMs=this.memoryPressure?this.idleEvictionMs/2:this.idleEvictionMs,verdicts=selectSweepEvictions(this.registry,now,idleEvictionMs,sessionId=>this.activeRequests.has(sessionId)||(this.bindings.get(sessionId)?.pendingPrompts?.().length??0)>0);for(let sessionId of verdicts.orphaned)this.evictIdleSession(sessionId,"session_dir_removed");for(let sessionId of verdicts.idle)this.evictIdleSession(sessionId);Number.isFinite(this.emptyExitMs)&&(this.registry.size===0&&(this.canExitWhenEmpty?.()??!0)?this.emptySince===void 0?this.emptySince=now:now-this.emptySince>=this.emptyExitMs&&(this.stopSweep(),this.onEmptyExit?.()):this.emptySince=void 0)}async evictIdleSession(sessionId,reason){let retained=this.registry.peek(sessionId),parkedPath=retained?.retainOnDisconnect===!0||reason==="handoff_parked"?retained?.sessionPath:void 0,handoff=reason==="handoff_parked"||reason==="session_dir_removed"&&this.draining,owners=handoff?[...this.sessionsByConnection].filter(([,owned])=>owned.has(sessionId)).map(([connection])=>connection):[],claim=this.tryClaimClose(sessionId,{drainAttachments:!0});if(!claim)return;this.handoverParkedDir!==void 0&&parkedPath!==void 0&&retained?.retainOnDisconnect===!0&&retained.sessionPath!==void 0&&await recordHandoverParkedSession(this.handoverParkedDir,{...parkedEntryFromProfile({sessionPath:retained.sessionPath,...retained.durableSessionId!==void 0?{durableSessionId:retained.durableSessionId}:{}},retained.profile,Object.keys(this.defaults.hostContext??{})),parkedBy:this.defaults.hostContext?.host_instance??hostInstanceId()}).catch(cause=>{process.stderr.write(`senpi rpc handover park record ${sessionId} failed: ${String(cause)}