@code-yeongyu/senpi 2026.11.2-3 → 2026.11.3-2

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 (307) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/bundle/chunks/anthropic-messages-LJAKRKMX.js +11 -0
  3. package/dist/bundle/chunks/{args-AOI4NEA6.js → args-GQTXDYS3.js} +1 -1
  4. package/dist/bundle/chunks/{azure-openai-responses-YLBBQXI7.js → azure-openai-responses-HDEKTPMZ.js} +1 -1
  5. package/dist/bundle/chunks/chatgpt-subscription.js +10 -2
  6. package/dist/bundle/chunks/{chunk-ED7VJGL4.js → chunk-2PGSRQBF.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-LMIETUPG.js → chunk-3LDASCJN.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-PIAY636U.js → chunk-3QPE75AR.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-FQZZGSYH.js → chunk-4ZGQUOBV.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-S2M5D5GS.js → chunk-5BMIET5O.js} +2 -2
  11. package/dist/bundle/chunks/{chunk-XLLQJALL.js → chunk-67M7HKXO.js} +1 -1
  12. package/dist/bundle/chunks/chunk-6ISOXWH2.js +2 -0
  13. package/dist/bundle/chunks/{chunk-IWM5QRAE.js → chunk-6NPK2O3C.js} +2 -2
  14. package/dist/bundle/chunks/{chunk-FO56LSUK.js → chunk-7C4W5HMU.js} +1 -1
  15. package/dist/bundle/chunks/chunk-7KIHKE2T.js +2 -0
  16. package/dist/bundle/chunks/{chunk-BW4YXS7X.js → chunk-A4KOQUHT.js} +1 -1
  17. package/dist/bundle/chunks/{chunk-FJSJUVQQ.js → chunk-A5PZGQCP.js} +3 -3
  18. package/dist/bundle/chunks/{chunk-TBARMJ75.js → chunk-AVP6DDBF.js} +1 -1
  19. package/dist/bundle/chunks/{chunk-KVPRQ5KN.js → chunk-B3GTID4P.js} +1 -1
  20. package/dist/bundle/chunks/{chunk-2XBKE2BZ.js → chunk-BIWFWGUA.js} +1 -1
  21. package/dist/bundle/chunks/{chunk-6LDUM5CL.js → chunk-DCI4QOUX.js} +1 -1
  22. package/dist/bundle/chunks/{chunk-2YFPDNNP.js → chunk-DNZKKG4V.js} +1 -1
  23. package/dist/bundle/chunks/{chunk-W2V7RIBF.js → chunk-E7SA75PP.js} +1 -1
  24. package/dist/bundle/chunks/{chunk-YWD54RHU.js → chunk-EBZ6IP4V.js} +1 -1
  25. package/dist/bundle/chunks/{chunk-N4TSAHRL.js → chunk-EVTTLPIY.js} +1 -1
  26. package/dist/bundle/chunks/{chunk-J2OBN7TI.js → chunk-G5XUGK4B.js} +1 -1
  27. package/dist/bundle/chunks/{chunk-IHOQR7TU.js → chunk-GKP34H3C.js} +2 -2
  28. package/dist/bundle/chunks/{chunk-PP52OWBB.js → chunk-GLTOBXZY.js} +1 -1
  29. package/dist/bundle/chunks/{chunk-ZSVWKOAJ.js → chunk-IJGXAACA.js} +263 -237
  30. package/dist/bundle/chunks/{chunk-LGO25HPL.js → chunk-JCTODLUP.js} +1 -1
  31. package/dist/bundle/chunks/{chunk-3ESZE3DG.js → chunk-KHBCZ6TR.js} +1 -1
  32. package/dist/bundle/chunks/chunk-KJR3XXMI.js +2 -0
  33. package/dist/bundle/chunks/{chunk-TVMW2SUP.js → chunk-KY4V3TSO.js} +2 -2
  34. package/dist/bundle/chunks/{chunk-T5ZJ2Q4O.js → chunk-MCXOJHN2.js} +1 -1
  35. package/dist/bundle/chunks/{chunk-GIY7PGOH.js → chunk-NKI7L5UM.js} +3 -3
  36. package/dist/bundle/chunks/{chunk-L3V65XW7.js → chunk-OD7RT7G7.js} +1 -1
  37. package/dist/bundle/chunks/{chunk-NYXXKS6D.js → chunk-OOU3BRUY.js} +3 -2
  38. package/dist/bundle/chunks/{chunk-LPHUMR6R.js → chunk-OT6ALXSJ.js} +1 -1
  39. package/dist/bundle/chunks/{chunk-XGBRBCIQ.js → chunk-Q5CKFBQT.js} +1 -1
  40. package/dist/bundle/chunks/{chunk-F7GBSQRV.js → chunk-QPYDQ4QK.js} +1 -1
  41. package/dist/bundle/chunks/{chunk-7FUO655J.js → chunk-QSMT5KVJ.js} +1 -1
  42. package/dist/bundle/chunks/{chunk-SAZ6E74O.js → chunk-RUOTFZQR.js} +1 -1
  43. package/dist/bundle/chunks/chunk-RWF6IJQL.js +448 -0
  44. package/dist/bundle/chunks/{chunk-P4AT7SBE.js → chunk-S5Y7NEHB.js} +1 -1
  45. package/dist/bundle/chunks/{chunk-QLTQ3UUI.js → chunk-SCBTASM4.js} +1 -1
  46. package/dist/bundle/chunks/chunk-SJWTZ3Z2.js +2 -0
  47. package/dist/bundle/chunks/{chunk-ISZ4EWIS.js → chunk-SODMQEHO.js} +1 -1
  48. package/dist/bundle/chunks/{chunk-WEGTCUO3.js → chunk-SQAQEITV.js} +1 -1
  49. package/dist/bundle/chunks/{chunk-UFVZTQKN.js → chunk-TQQG5L4D.js} +1 -1
  50. package/dist/bundle/chunks/{chunk-662SCMTH.js → chunk-U6A4X3FV.js} +1 -1
  51. package/dist/bundle/chunks/{chunk-ACIFXWJ6.js → chunk-UHUM55TR.js} +1 -1
  52. package/dist/bundle/chunks/{chunk-L5OFGHDA.js → chunk-USKWGPA6.js} +1 -1
  53. package/dist/bundle/chunks/{chunk-7ORS33CE.js → chunk-VDDJADPV.js} +1 -1
  54. package/dist/bundle/chunks/{chunk-R65P6LAT.js → chunk-VIHXG53S.js} +1 -1
  55. package/dist/bundle/chunks/{chunk-SGS76663.js → chunk-VPVD5G32.js} +1 -1
  56. package/dist/bundle/chunks/chunk-WO6I5PRF.js +3 -0
  57. package/dist/bundle/chunks/{chunk-ETCYVVVO.js → chunk-WVEIJ437.js} +1 -1
  58. package/dist/bundle/chunks/{chunk-VRWJJMHO.js → chunk-XKFG4N3Z.js} +1 -1
  59. package/dist/bundle/chunks/{chunk-57MRFI6E.js → chunk-XMWPCJU6.js} +1 -1
  60. package/dist/bundle/chunks/{chunk-GDPWQJDQ.js → chunk-XPSXUKSD.js} +1 -1
  61. package/dist/bundle/chunks/{chunk-FNBEICAA.js → chunk-YI6KRJDC.js} +1 -1
  62. package/dist/bundle/chunks/{chunk-UURGXV5B.js → chunk-YP47G4YP.js} +1 -1
  63. package/dist/bundle/chunks/{chunk-TXOR5BQL.js → chunk-YRYDCKUI.js} +1 -1
  64. package/dist/bundle/chunks/{chunk-QAM6AXA2.js → chunk-YTKZSGMQ.js} +12 -9
  65. package/dist/bundle/chunks/{chunk-V36CXIIB.js → chunk-YXL3PNTL.js} +1 -1
  66. package/dist/bundle/chunks/chunk-Z7HTHT6K.js +2 -0
  67. package/dist/bundle/chunks/{chunk-27XEDYQA.js → chunk-ZTPG27EJ.js} +1 -1
  68. package/dist/bundle/chunks/{cli-main-534A3WSC.js → cli-main-RN7YB427.js} +1 -1
  69. package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-FC7QLRU2.js → cloudflare-workers-ai-system-one-N5KFNKK4.js} +1 -1
  70. package/dist/bundle/chunks/credential-accounts-BJX55MTT.js +2 -0
  71. package/dist/bundle/chunks/devin.js +10 -2
  72. package/dist/bundle/chunks/{dispatch-UY6LBJJE.js → dispatch-M7UAPGVY.js} +1 -1
  73. package/dist/bundle/chunks/{google-generative-ai-7PQ4QRHJ.js → google-generative-ai-2TZSCSIS.js} +1 -1
  74. package/dist/bundle/chunks/{google-vertex-DY7EO4EJ.js → google-vertex-7NJJOI7V.js} +1 -1
  75. package/dist/bundle/chunks/{health-write-EB4CPHXN.js → health-write-YUSPVH7U.js} +1 -1
  76. package/dist/bundle/chunks/{help-fast-path-U2PSNNWO.js → help-fast-path-DWCA77QP.js} +1 -1
  77. package/dist/bundle/chunks/host-command-KJXUTSQ7.js +2 -0
  78. package/dist/bundle/chunks/{host-lifecycle-TGG7KGQH.js → host-lifecycle-QHIJ4G2K.js} +1 -1
  79. package/dist/bundle/chunks/host-lifecycle.js +1 -1
  80. package/dist/bundle/chunks/{host-session-command-PWVPQ2OV.js → host-session-command-IPH3WXSG.js} +1 -1
  81. package/dist/bundle/chunks/{host-socket-request-F2R5P34M.js → host-socket-request-XPXJV3CS.js} +1 -1
  82. package/dist/bundle/chunks/interactive-mode-XUXMDYLA.js +2 -0
  83. package/dist/bundle/chunks/{list-tips-3D3A6GFK.js → list-tips-XJY7EL5S.js} +1 -1
  84. package/dist/bundle/chunks/{login-health-7G2DZVOV.js → login-health-226NO44U.js} +1 -1
  85. package/dist/bundle/chunks/main-P7PKMJUG.js +2 -0
  86. package/dist/bundle/chunks/{mistral-conversations-6F2RAIB2.js → mistral-conversations-QMHMHSUF.js} +1 -1
  87. package/dist/bundle/chunks/{multi-session-host-7E26R5JF.js → multi-session-host-ZQY4AN46.js} +4 -4
  88. package/dist/bundle/chunks/{native-loader-NMDTMHMA.js → native-loader-A6DNMGCK.js} +1 -1
  89. package/dist/bundle/chunks/openai-chatgpt.js +11 -3
  90. package/dist/bundle/chunks/{openai-codex-responses-VNBMMIL3.js → openai-codex-responses-GUAHKQE2.js} +1 -1
  91. package/dist/bundle/chunks/{openai-completions-JLR32APM.js → openai-completions-UPRTFM54.js} +1 -1
  92. package/dist/bundle/chunks/{openai-images-LEBNERSM.js → openai-images-IKWNS6VB.js} +1 -1
  93. package/dist/bundle/chunks/{openai-responses-JCDUNMHA.js → openai-responses-AXN5NUHH.js} +1 -1
  94. package/dist/bundle/chunks/openrouter.js +10 -2
  95. package/dist/bundle/chunks/{package-manager-cli-CBSDV36M.js → package-manager-cli-PP7L2Q5M.js} +1 -1
  96. package/dist/bundle/chunks/radius.js +10 -2
  97. package/dist/bundle/chunks/{rg-engine-JDUYBM6L.js → rg-engine-VRSXT6HG.js} +1 -1
  98. package/dist/bundle/chunks/{role-LP6LVNCY.js → role-L5J7ZPCF.js} +1 -1
  99. package/dist/bundle/chunks/rotation-stream-6INZXQFC.js +2 -0
  100. package/dist/bundle/chunks/rpc-mode-W4UATRAT.js +2 -0
  101. package/dist/bundle/chunks/{rpc-monitor-source-5TUR27NY.js → rpc-monitor-source-RMMUPBMS.js} +1 -1
  102. package/dist/bundle/chunks/{run-attached-tui-PVLUHHJX.js → run-attached-tui-RLXFGCEP.js} +1 -1
  103. package/dist/bundle/chunks/{schedule-command-W45NYTTK.js → schedule-command-ZNFEJNTT.js} +1 -1
  104. package/dist/bundle/chunks/{session-control-endpoint-LFLUNALC.js → session-control-endpoint-TWTONJWF.js} +1 -1
  105. package/dist/bundle/chunks/{session-picker-OZUINLD7.js → session-picker-KRUVCHOV.js} +1 -1
  106. package/dist/bundle/chunks/session-slot-NJOZCOHQ.js +2 -0
  107. package/dist/bundle/chunks/session-worker.js +492 -461
  108. package/dist/bundle/chunks/{state-store-SZARKD36.js → state-store-ZAFZ4JOM.js} +1 -1
  109. package/dist/bundle/chunks/{typesafe-system-one-5JYDJK6S.js → typesafe-system-one-CICIRAYN.js} +1 -1
  110. package/dist/bundle/cli.js +2 -2
  111. package/dist/bundle/host-supervisor.js +1 -1
  112. package/dist/bundle/index.js +1 -1
  113. package/dist/bundle/rpc-entry.js +1 -1
  114. package/dist/bundle/runtime-manifest.json +1 -1
  115. package/dist/core/agent-session.d.ts +8 -0
  116. package/dist/core/agent-session.js +73 -63
  117. package/dist/core/auth-storage.d.ts +19 -0
  118. package/dist/core/auth-storage.js +99 -24
  119. package/dist/core/auth-store-load-error.d.ts +29 -0
  120. package/dist/core/auth-store-load-error.js +74 -0
  121. package/dist/core/brand.d.ts +2 -0
  122. package/dist/core/brand.js +1 -0
  123. package/dist/core/credential-pool/classify.d.ts +3 -2
  124. package/dist/core/credential-pool/classify.js +10 -3
  125. package/dist/core/credential-pool/failover.d.ts +8 -0
  126. package/dist/core/credential-pool/failover.js +18 -5
  127. package/dist/core/credential-pool/rotation-stream.d.ts +1 -1
  128. package/dist/core/credential-pool/rotation-stream.js +2 -7
  129. package/dist/core/credential-pool/session-slot.d.ts +20 -0
  130. package/dist/core/credential-pool/session-slot.js +26 -0
  131. package/dist/core/credential-recovery-revision.d.ts +10 -0
  132. package/dist/core/credential-recovery-revision.js +19 -0
  133. package/dist/core/dynamic-prompt/build.d.ts +2 -1
  134. package/dist/core/dynamic-prompt/build.js +1 -2
  135. package/dist/core/dynamic-prompt/handoff.d.ts +1 -1
  136. package/dist/core/dynamic-prompt/handoff.js +9 -9
  137. package/dist/core/dynamic-prompt/identity.js +1 -1
  138. package/dist/core/dynamic-prompt/intent-gate.d.ts +1 -1
  139. package/dist/core/dynamic-prompt/intent-gate.js +8 -8
  140. package/dist/core/dynamic-prompt/policies.d.ts +1 -1
  141. package/dist/core/dynamic-prompt/policies.js +5 -7
  142. package/dist/core/dynamic-prompt/style.js +5 -5
  143. package/dist/core/dynamic-prompt/tool-section.d.ts +5 -0
  144. package/dist/core/dynamic-prompt/tool-section.js +8 -6
  145. package/dist/core/dynamic-prompt/verification.d.ts +6 -6
  146. package/dist/core/dynamic-prompt/verification.js +12 -12
  147. package/dist/core/dynamic-prompt/working-task.d.ts +1 -1
  148. package/dist/core/dynamic-prompt/working-task.js +3 -3
  149. package/dist/core/dynamic-prompt/workstation.js +1 -1
  150. package/dist/core/execution/executor-body.d.ts +22 -0
  151. package/dist/core/execution/executor-body.js +73 -0
  152. package/dist/core/execution/executor-freeze.d.ts +17 -0
  153. package/dist/core/execution/executor-freeze.js +53 -0
  154. package/dist/core/execution/executor-pipeline.d.ts +9 -0
  155. package/dist/core/execution/executor-pipeline.js +25 -0
  156. package/dist/core/execution/executor-types.d.ts +82 -0
  157. package/dist/core/execution/executor-types.js +2 -0
  158. package/dist/core/execution/executor.d.ts +8 -0
  159. package/dist/core/execution/executor.js +216 -0
  160. package/dist/core/extensions/builtin/anthropic-subscription/account-block-log.d.ts +15 -0
  161. package/dist/core/extensions/builtin/anthropic-subscription/account-block-log.js +18 -0
  162. package/dist/core/extensions/builtin/anthropic-subscription/affinity.d.ts +9 -1
  163. package/dist/core/extensions/builtin/anthropic-subscription/affinity.js +15 -4
  164. package/dist/core/extensions/builtin/anthropic-subscription/failover.d.ts +7 -1
  165. package/dist/core/extensions/builtin/anthropic-subscription/failover.js +19 -2
  166. package/dist/core/extensions/builtin/anthropic-subscription/guidance.d.ts +8 -2
  167. package/dist/core/extensions/builtin/anthropic-subscription/guidance.js +25 -1
  168. package/dist/core/extensions/builtin/anthropic-subscription/provider-diagnostic.d.ts +9 -0
  169. package/dist/core/extensions/builtin/anthropic-subscription/provider-diagnostic.js +59 -0
  170. package/dist/core/extensions/builtin/anthropic-subscription/session-registry-pump.d.ts +13 -0
  171. package/dist/core/extensions/builtin/anthropic-subscription/session-registry-pump.js +64 -2
  172. package/dist/core/extensions/builtin/anthropic-subscription/session-registry-wiring.js +7 -0
  173. package/dist/core/extensions/builtin/anthropic-subscription/session-stream.js +5 -1
  174. package/dist/core/extensions/builtin/anthropic-subscription/session-turn-attempt.d.ts +7 -0
  175. package/dist/core/extensions/builtin/anthropic-subscription/session-turn-attempt.js +28 -1
  176. package/dist/core/extensions/builtin/anthropic-subscription/session-turn-types.d.ts +2 -0
  177. package/dist/core/extensions/builtin/anthropic-subscription/stream-guidance.js +5 -3
  178. package/dist/core/extensions/builtin/anthropic-subscription/stream.js +4 -0
  179. package/dist/core/extensions/builtin/bash-timeout/index.d.ts +1 -1
  180. package/dist/core/extensions/builtin/bash-timeout/index.js +3 -28
  181. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts +0 -11
  182. package/dist/core/extensions/builtin/bash-timeout/timeout.js +0 -11
  183. package/dist/core/extensions/builtin/btw/index.js +3 -1
  184. package/dist/core/extensions/builtin/cache-keepalive/index.js +3 -1
  185. package/dist/core/extensions/builtin/compaction/index.js +1 -1
  186. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +3 -1
  187. package/dist/core/extensions/builtin/compaction/openai-remote.js +1 -1
  188. package/dist/core/extensions/builtin/compaction/speculative.js +3 -2
  189. package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.js +3 -1
  190. package/dist/core/extensions/builtin/cursor-cli-oauth/native-bootstrap.js +3 -1
  191. package/dist/core/extensions/builtin/imagegen/index.d.ts +0 -1
  192. package/dist/core/extensions/builtin/imagegen/index.js +0 -11
  193. package/dist/core/extensions/builtin/look-at/runner.js +3 -1
  194. package/dist/core/extensions/builtin/mcp/auth/callback.js +3 -4
  195. package/dist/core/extensions/builtin/mcp/auth/oauth-provider.js +2 -1
  196. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +5 -5
  197. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +5 -5
  198. package/dist/core/extensions/builtin/prompt-preset/glm-5.d.ts +1 -1
  199. package/dist/core/extensions/builtin/prompt-preset/glm-5.js +1 -1
  200. package/dist/core/extensions/builtin/terminal/extension.js +8 -1
  201. package/dist/core/extensions/builtin/terminal/notify.js +9 -3
  202. package/dist/core/extensions/builtin/terminal/prompt.d.ts +7 -1
  203. package/dist/core/extensions/builtin/terminal/prompt.js +27 -60
  204. package/dist/core/extensions/builtin/terminal/tools/bash.js +10 -2
  205. package/dist/core/extensions/builtin/todotools/normalize.d.ts +20 -3
  206. package/dist/core/extensions/builtin/todotools/normalize.js +251 -5
  207. package/dist/core/extensions/builtin/todotools/prompt.d.ts +2 -2
  208. package/dist/core/extensions/builtin/todotools/prompt.js +5 -5
  209. package/dist/core/extensions/builtin/todotools/tools/todo.js +9 -8
  210. package/dist/core/extensions/builtin/webfetch/webfetch/tool.js +0 -5
  211. package/dist/core/extensions/builtin/websearch/index.js +9 -4
  212. package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts +2 -0
  213. package/dist/core/extensions/builtin/websearch/websearch/tool.js +3 -1
  214. package/dist/core/model-registry.d.ts +10 -2
  215. package/dist/core/model-registry.js +12 -4
  216. package/dist/core/model-runtime.d.ts +8 -0
  217. package/dist/core/model-runtime.js +39 -1
  218. package/dist/core/provider-failure.d.ts +6 -0
  219. package/dist/core/provider-failure.js +6 -2
  220. package/dist/core/retry-fallback/controller-types.d.ts +7 -0
  221. package/dist/core/retry-fallback/controller.d.ts +2 -0
  222. package/dist/core/retry-fallback/controller.js +13 -4
  223. package/dist/core/retry-fallback/credential-recovery.d.ts +18 -0
  224. package/dist/core/retry-fallback/credential-recovery.js +32 -0
  225. package/dist/core/retry-fallback/exhaustion.d.ts +18 -0
  226. package/dist/core/retry-fallback/exhaustion.js +20 -0
  227. package/dist/core/retry-fallback/settings.d.ts +8 -1
  228. package/dist/core/retry-fallback/settings.js +12 -6
  229. package/dist/core/session-log.js +1 -1
  230. package/dist/core/settings-manager.js +4 -1
  231. package/dist/core/system-prompt.js +1 -1
  232. package/dist/core/tools/bash.d.ts +3 -1
  233. package/dist/core/tools/bash.js +14 -4
  234. package/dist/core/tools/edit.d.ts +1 -1
  235. package/dist/core/tools/edit.js +1 -6
  236. package/dist/core/tools/grep/index.js +2 -3
  237. package/dist/core/tools/powershell.d.ts +1 -1
  238. package/dist/core/tools/powershell.js +1 -1
  239. package/dist/core/tools/read.d.ts +1 -1
  240. package/dist/core/tools/read.js +1 -1
  241. package/dist/core/tools/write.d.ts +1 -1
  242. package/dist/core/tools/write.js +1 -1
  243. package/dist/engine-trust/shell-trust.d.ts +36 -0
  244. package/dist/engine-trust/shell-trust.js +44 -0
  245. package/dist/engine-trust/transport-failure.d.ts +12 -0
  246. package/dist/engine-trust/transport-failure.js +48 -0
  247. package/dist/modes/interactive/interactive-mode.js +9 -3
  248. package/dist/modes/print-mode.js +2 -1
  249. package/dist/modes/rpc/compact-catalog-families.d.ts +5 -2
  250. package/dist/modes/rpc/compact-catalog-families.js +5 -2
  251. package/dist/modes/rpc/compact-catalog-registry.d.ts +9 -1
  252. package/dist/modes/rpc/compact-catalog-registry.js +9 -2
  253. package/dist/modes/rpc/compact-recovery-manifest-kinds.d.ts +17 -0
  254. package/dist/modes/rpc/compact-recovery-manifest-kinds.js +21 -0
  255. package/dist/modes/rpc/compact-recovery-manifest-shape.d.ts +7 -0
  256. package/dist/modes/rpc/compact-recovery-manifest.js +11 -3
  257. package/dist/modes/rpc/compact-socket-commands.js +6 -0
  258. package/dist/modes/rpc/connection-handler.js +24 -6
  259. package/dist/modes/rpc/connection-question-bridge.d.ts +3 -1
  260. package/dist/modes/rpc/connection-question-bridge.js +4 -1
  261. package/dist/modes/rpc/connection-roles.d.ts +8 -0
  262. package/dist/modes/rpc/connection-roles.js +18 -0
  263. package/dist/modes/rpc/effect-commands.d.ts +1 -0
  264. package/dist/modes/rpc/loopless-execute-grant.d.ts +20 -0
  265. package/dist/modes/rpc/loopless-execute-grant.js +26 -0
  266. package/dist/modes/rpc/loopless-runtime-settings.d.ts +30 -0
  267. package/dist/modes/rpc/loopless-runtime-settings.js +69 -0
  268. package/dist/modes/rpc/loopless-tool-call.d.ts +12 -0
  269. package/dist/modes/rpc/loopless-tool-call.js +22 -0
  270. package/dist/modes/rpc/method-classes-schema-session.d.ts +4 -0
  271. package/dist/modes/rpc/method-classes-schema-session.js +1 -0
  272. package/dist/modes/rpc/method-classes-schema.d.ts +4 -0
  273. package/dist/modes/rpc/protocol-identity.js +2 -0
  274. package/dist/modes/rpc/remote-origin.d.ts +31 -0
  275. package/dist/modes/rpc/remote-origin.js +58 -0
  276. package/dist/modes/rpc/rpc-protocol-info-types.d.ts +8 -0
  277. package/dist/modes/rpc/rpc-question-types.d.ts +7 -0
  278. package/dist/modes/rpc/rpc-question-types.js +0 -3
  279. package/dist/modes/rpc/rpc-read-response-types.d.ts +2 -1
  280. package/dist/modes/rpc/rpc-session-command-types.d.ts +3 -0
  281. package/dist/modes/rpc/rpc-session-state-types.d.ts +10 -0
  282. package/dist/modes/rpc/rpc-types.d.ts +1 -1
  283. package/dist/modes/rpc/runtime-factory-loopless.d.ts +57 -0
  284. package/dist/modes/rpc/runtime-factory-loopless.js +131 -0
  285. package/dist/modes/rpc/session-registry.js +12 -3
  286. package/dist/modes/rpc/session-worker-client.js +2 -0
  287. package/dist/modes/rpc/session-worker-protocol.d.ts +3 -0
  288. package/dist/modes/rpc/session-worker.js +2 -0
  289. package/docs/development.md +1 -1
  290. package/docs/engine-socket/fixtures/admission-routes/c-baseline.json +3 -3
  291. package/docs/engine-socket/fixtures/admission-routes/h-legacy.json +1 -1
  292. package/docs/engine-socket/fixtures/admission-routes/i-reset-stream.json +3 -3
  293. package/docs/engine-socket/fixtures/recovery-manifest/index.json +32 -0
  294. package/docs/engine-socket/fixtures/recovery-manifest/one-partial-family.json +118 -0
  295. package/docs/rpc.md +95 -3
  296. package/package.json +6 -6
  297. package/dist/bundle/chunks/anthropic-messages-WUPLDYD6.js +0 -10
  298. package/dist/bundle/chunks/chunk-7UC4W2T2.js +0 -2
  299. package/dist/bundle/chunks/chunk-O4GRBX4R.js +0 -3
  300. package/dist/bundle/chunks/chunk-R23WXN4L.js +0 -448
  301. package/dist/bundle/chunks/chunk-W5NLCRB3.js +0 -2
  302. package/dist/bundle/chunks/credential-accounts-OAK2E5O2.js +0 -2
  303. package/dist/bundle/chunks/host-command-WJIMRBGN.js +0 -2
  304. package/dist/bundle/chunks/interactive-mode-NPHFDPGH.js +0 -2
  305. package/dist/bundle/chunks/main-I6FJAFUP.js +0 -2
  306. package/dist/bundle/chunks/rotation-stream-ZDCNHIBE.js +0 -2
  307. package/dist/bundle/chunks/rpc-mode-GBBTN2WP.js +0 -2
@@ -1,4 +1,4 @@
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
2
  import{TOOL_CHILD_ROLE_ENV,channelEnvPresent}from"./chunk-UKSFF47T.js";var role=process.env[TOOL_CHILD_ROLE_ENV];if(role!==void 0&&role!==""){if(role==="launch-shim"){let{runLaunchShimRole}=await import("./launch-shim-role-Q6NG2YCV.js");runLaunchShimRole()}role!=="tool-child"&&(process.stderr.write(`senpi: unknown internal role ${JSON.stringify(role)}
3
3
  `),process.exit(70)),channelEnvPresent(process.env)||(process.stderr.write(`tool-child: channel unavailable
4
- `),process.exit(70));let{runToolChildRole}=await import("./role-LP6LVNCY.js");await runToolChildRole()}
4
+ `),process.exit(70));let{runToolChildRole}=await import("./role-L5J7ZPCF.js");await runToolChildRole()}
@@ -1,7 +1,8 @@
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{listHostEndpoints}from"./chunk-XGBRBCIQ.js";import{BUILTIN_PATH_PREFIX}from"./chunk-QMRJYMNH.js";import{PROBE_REQUEST_ID,connectAndAsk,isRecord as isRecord2,readAnswer,requestOnSocket}from"./chunk-WEGTCUO3.js";import{claimOwnerIsLive,hostChildAlive,isGenerationId,logUnknownHostIdentity,provenOwner,readDrainWatch,readGenerationRegistration,readHostRegistration,readSessionPathClaims,releaseGeneration,resolveHostPolicy,writeDrainRequest,writeStopIntent}from"./chunk-6LDUM5CL.js";import{HOST_DAEMON_LAYOUT,canonicalEndpointPath,createHostDaemonPaths,generationPaths,hostDaemonDirectoryPaths,isRecord,parseJson,readFileOrUndefined,sameEndpoint,writeStateFile}from"./chunk-FNBEICAA.js";import{OBSERVE_REQUEST_FIELD,gcRpcPublicKeys}from"./chunk-E6UCZ7E5.js";import{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV}from"./chunk-UYO5Z35O.js";import{parseArgs,resolveSessionRuntime}from"./chunk-27XEDYQA.js";import{acquireOwnershipSafeLock,readSocketSecret,resolveSocketTransportAddress,socketSecretPath}from"./chunk-QEESHRTS.js";import{APP_NAME,VERSION,getAgentDir,isBunBinary}from"./chunk-ISZ4EWIS.js";import{ProcessIdentityUnreadableError,parseDaemonPidFile,processIsLive,processMatchesPidFile,processStartTimeMs,readProcessStartTime}from"./chunk-O5RYI3IW.js";var CALVER=/^(\d+)\.(\d+)\.(\d+)(?:-(\d+))?/;function engineBuildIdentityFrom(build){let match=CALVER.exec(build.version),epoch=Number.isSafeInteger(build.epoch)&&build.epoch!==void 0&&build.epoch>0?build.epoch:0,sha7=build.sha7??"";return{text:epoch===0?build.version:`${build.version}+${epoch}${sha7===""?"":`.${sha7}`}`,ordinal:[match?Number(match[1]):0,match?Number(match[2]):0,match?Number(match[3]):0,match?.[4]?Number(match[4]):0,epoch],scheme:epoch===0?"nodef":"epoch"}}var BUILT=engineBuildIdentityFrom({version:VERSION,epoch:typeof SENPI_BUILD_EPOCH=="number"?SENPI_BUILD_EPOCH:0,sha7:typeof SENPI_BUILD_SHA7=="string"?SENPI_BUILD_SHA7:""});function engineBuildIdentity(){return BUILT}function compareEngineOrdinal(a,b){for(let index=0;index<4;index++)if(a.ordinal[index]!==b.ordinal[index])return a.ordinal[index]>b.ordinal[index]?1:-1;return a.scheme!=="epoch"||b.scheme!=="epoch"||a.ordinal[4]===b.ordinal[4]?0:a.ordinal[4]>b.ordinal[4]?1:-1}import*as crypto from"node:crypto";var CUSTOM_UNSUPPORTED_CAPABILITY="custom_unsupported",EXTENSION_EVENTS_CAPABILITY="extension_events",EVAL_CELLS_CAPABILITY="eval_cells",AUTO_TITLE_SESSIONS_CAPABILITY="auto_title_sessions",CONTINUE_FROM_LEAF_CAPABILITY="continue_from_leaf",SESSION_HELD_CAPABILITY="session_held",RESUME_SESSION_CAPABILITY="resume_session",ATTENDED_CAPABILITY="attended",MEDIA_PLACEHOLDERS_CAPABILITY="media_placeholders",COMPACT_EVENTS_CAPABILITY="compact_events",QUESTION_CAPABILITY="question",TOOL_BARRIER_CAPABILITY="tool_barrier",SESSION_RELOCATION_CAPABILITY="session_relocation",RETAIN_ON_DISCONNECT_CAPABILITY="retain_on_disconnect",DETACH_CONNECTION_CAPABILITY="detach_connection",INTERACTIVE_USER_CAPABILITY="interactive_user",OBSERVE_READS_CAPABILITY="observe_reads",ENTRIES_TAIL_CAPABILITY="entries_tail",TUI_OBSERVER_CAPABILITY="tui_observer",TASK_PARENT_CAPABILITY="task_parent",SESSION_CONTEXT_CAPABILITY="session_context",SESSION_KIND_CAPABILITY="session_kind",SESSION_STATUS_CAPABILITY="session_status",AUTO_TITLE_PER_SESSION_CAPABILITY="auto_title_per_session",WARM_CAPABILITY="warm",DURABLE_SESSION_ID_CAPABILITY="durable_session_id",MOVED_PATH_GUARD_CAPABILITY="moved_path_guard",PROMPT_SURFACE_CAPABILITY="prompt_surface",BROWSER_ENGINE_CAPABILITY="browser_engine",SESSION_ENV_CAPABILITY="session_env",RETRY_FALLBACK_PROFILE_CAPABILITY="retry_fallback_profile",RETRY_FALLBACK_COMMAND_CAPABILITY="retry_fallback_command",PROMPT_SURFACE_CHAT_CAPABILITY="prompt_surface_chat",RPC_CLIENT_CAPABILITIES_ENV="SENPI_RPC_CLIENT_CAPABILITIES";function parseClientCapabilities(value){return value?value.split(",").map(part=>part.trim()).filter(part=>part.length>0):[]}var DEFAULT_CUSTOM_EXTENSION_LABEL="custom UI component";function buildCustomUnsupportedRequest(capabilities,extensionName){if(!capabilities?.includes(CUSTOM_UNSUPPORTED_CAPABILITY))return;let name=extensionName.trim()||DEFAULT_CUSTOM_EXTENSION_LABEL;return{type:"extension_ui_request",id:crypto.randomUUID(),method:"custom_unsupported",extensionName:name}}var AUTH_KEY_VERIFY_CAPABILITY="auth_key_verify",PROVIDER_ACCOUNT_TEST_CAPABILITY="provider_account_test",QUEUED_MESSAGE_REVISION_CAPABILITY="queued_message_revision";import{createHash}from"node:crypto";import{existsSync}from"node:fs";import{readdir,readFile,realpath,stat}from"node:fs/promises";import{basename,dirname,join,relative,sep}from"node:path";import{fileURLToPath}from"node:url";var RUNTIME_IDENTITY_HANDOVER_CAPABILITY="runtime_identity_handover",RUNTIME_BUILD_ID=/^sha256:[0-9a-f]{64}$/,EXCLUDED_FILE=/\.(?:d\.[cm]?ts|map)$/,EXCLUDED_NAMES=new Set(["node_modules","runtime-manifest.json","runtime-snapshot.json"]),READ_CONCURRENCY=32;function parseRuntimeBuildId(value){return typeof value=="string"&&RUNTIME_BUILD_ID.test(value)?value:void 0}async function computeRuntimeBuildId(input){let source=input.source??loadedRuntimeSource(),plugins=await Promise.all(input.profile.extensions.map(path=>extensionDigest(path))),manifest={schema:1,flavour:source.flavour,platform:input.platform??process.platform,arch:input.arch??process.arch,engine:input.engine??engineBuildIdentity().text,runtime:await treeDigest(source.root),plugins:plugins.sort(),profile:{multi_session:input.profile.multi_session,session_runtime:input.profile.session_runtime}};return`sha256:${sha256(JSON.stringify(manifest))}`}function loadedRuntimeSource(){if(isBunBinary)return{flavour:"compiled",root:process.execPath};let moduleDir=dirname(fileURLToPath(import.meta.url)),packageRoot=nearestPackageRoot(moduleDir),[top,next]=relative(packageRoot,moduleDir).split(sep);return top==="dist"?{flavour:"packaged",root:join(packageRoot,next==="bundle"?join("dist","bundle"):"dist")}:{flavour:"dev",root:join(packageRoot,top??"")}}function nearestPackageRoot(start){for(let dir=start;;dir=dirname(dir)){if(existsSync(join(dir,"package.json")))return dir;if(dirname(dir)===dir)return start}}function extensionDigest(path){let name=basename(path);return name.startsWith(BUILTIN_PATH_PREFIX)?Promise.resolve(sha256(name)):treeDigest(path)}async function treeDigest(root){let files=[];(await stat(root)).isFile()?files.push(["",root]):await collect(await realpath(root),"",files,new Set);let digests=await mapLimited(files,READ_CONCURRENCY,async([path,file])=>[path,sha256(await readFile(file))]);return digests.sort(([a],[b])=>a<b?-1:a>b?1:0),sha256(JSON.stringify(digests))}async function collect(dir,prefix,files,seen){if(seen.has(dir))return;seen.add(dir);let entries=(await readdir(dir,{withFileTypes:!0})).sort((a,b)=>a.name<b.name?-1:a.name>b.name?1:0);for(let entry of entries){if(entry.name.startsWith(".")||EXCLUDED_NAMES.has(entry.name))continue;let path=join(dir,entry.name),name=prefix===""?entry.name:`${prefix}/${entry.name}`,kind=entry.isSymbolicLink()?await stat(path).catch(()=>{}):entry;kind!==void 0&&(kind.isDirectory()?await collect(await realpath(path),name,files,seen):kind.isFile()&&!EXCLUDED_FILE.test(entry.name)&&files.push([name,path]))}}async function mapLimited(items,limit,map){let results=new Array(items.length),next=0,worker=async()=>{for(let index=next++;index<items.length;index=next++)results[index]=await map(items[index])};return await Promise.all(Array.from({length:Math.min(limit,items.length)},worker)),results}function sha256(data){return createHash("sha256").update(data).digest("hex")}var STATES=["not_started","ready","unavailable"];function pathIdentityResolverStatus(resolver){let detail=resolver.unavailable;return detail!==void 0?{state:"unavailable",detail}:{state:resolver.snapshot===void 0?"not_started":"ready",detail:null}}function isState(value){return STATES.some(state=>state===value)}function parsePathIdentityResolverStatus(value){if(typeof value!="object"||value===null)return;let{state,detail}=value;if(isState(state))return{state,detail:typeof detail=="string"?detail:null}}function parseHostProtocolInfo(data){if(!isRecord3(data)||typeof data.serverVersion!="string"||!Array.isArray(data.capabilities)||!data.capabilities.every(entry=>typeof entry=="string"))return;let ordinal=parseOrdinal(data.engineOrdinal),launchProfile=parseLaunchProfile(data.launch_profile),runtimeBuildId=parseRuntimeBuildId(data.runtimeBuildId),pathIdentityResolver=parsePathIdentityResolverStatus(data.path_identity_resolver);return{protocolVersion:typeof data.protocolVersion=="number"?data.protocolVersion:0,serverVersion:data.serverVersion,capabilities:data.capabilities,...(data.lifecycle==="ready"||data.lifecycle==="stopping")&&{lifecycle:data.lifecycle},...typeof data.instanceId=="string"&&{instanceId:data.instanceId},...typeof data.generation=="number"&&Number.isSafeInteger(data.generation)&&{generation:data.generation},...typeof data.engineVersion=="string"&&{engineVersion:data.engineVersion},...ordinal&&{engineOrdinal:ordinal},...launchProfile&&{launch_profile:launchProfile},...typeof data.memory_pressure=="boolean"&&{memory_pressure:data.memory_pressure},...pathIdentityResolver!==void 0&&{path_identity_resolver:pathIdentityResolver},...runtimeBuildId!==void 0&&{runtimeBuildId},...typeof data.agentDir=="string"&&data.agentDir!==""&&{agentDir:data.agentDir},...isRecord3(data.handover)&&{handover:data.handover}}}function parseOrdinal(value){if(!(!Array.isArray(value)||value.length!==5||!value.every(part=>typeof part=="number")))return[value[0],value[1],value[2],value[3],value[4]]}function parseLaunchProfile(value){if(!isRecord3(value)||typeof value.profile_id!="string"||!isRecord3(value.core))return;let{extensions,multi_session,session_runtime}=value.core;if(!(!Array.isArray(extensions)||!extensions.every(entry=>typeof entry=="string"))&&typeof multi_session=="boolean"&&!(session_runtime!=="in-process"&&session_runtime!=="worker"))return{profile_id:value.profile_id,core:{extensions,multi_session,session_runtime}}}function isRecord3(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function describeHostHolder(holder){let engine=holder.engineVersion===null?"an unrecorded engine":`engine ${holder.engineVersion}`,profile=holder.launchProfileId===null?"":`, launch profile ${holder.launchProfileId}`,writer=holder.writerPid===null||holder.writerPid===holder.pid?"":`, started by pid ${holder.writerPid}`;return`pid ${holder.pid}, ${engine}${profile}${writer}`}var HOST_PROTOCOL_VERSION=1,GENERATION_HANDOFF_CAPABILITY="generation_handoff",REQUIRED_HOST_CAPABILITIES=["multi_session",EXTENSION_EVENTS_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY],HostEnsureRefusedError=class extends Error{constructor(socket,reason,host,detail,holder){let heldBy=holder?` (held by ${describeHostHolder(holder)})`:"";super(`RPC socket ${socket} refused: ${reason} - ${refusalDetail(reason,host)}${detail?`: ${detail}`:""}${heldBy}`),this.name="HostEnsureRefusedError",this.socket=socket,this.reason=reason,this.detail=detail,this.holder=holder}};function refusalDetail(reason,host){switch(reason){case"protocol":return`the running host speaks protocol version ${host?.protocolVersion??"unknown"}, this build speaks ${HOST_PROTOCOL_VERSION}`;case"capability":{let missing=REQUIRED_HOST_CAPABILITIES.filter(capability=>!host?.capabilities.includes(capability));return`the running host is missing ${JSON.stringify(missing)}; it owns the socket, so no second host is started`}case"foreign_writer":return"another process registered the host on this socket; it accepts connections but did not answer as a host, and this one may not signal it - stop that host explicitly (host stop --force), then ensure again";case"legacy_host":return"a host from before the per-socket daemon directory is still running; it is drained and replaced only while it holds no session, and no second host is started beside it";case"host_busy":return"its socket accepts connections but did not answer inside the probe budget: a live host under load, which is never ended to make room for a replacement";case"host_stopping":return"this generation is stopping; wait for its exit before launching a successor";case"endpoint_occupied":return"another process accepts connections on this socket but does not answer as a host, and no host registration names it; it is never removed while it listens, so quit the process holding it and ensure again";case"host_stalled":return"nothing reaches its socket, but its process is alive and its own loop-lag watchdog measured a recent stall: a stalled host is still serving its sessions, so it is neither stopped nor replaced";default:return assertNever(reason)}}function decideHostAction(client,host,policy){if(host===void 0)return{action:"start",reason:client.startedByUs?"restart_own_host":"no_host",upgradeable:!1};if(host.lifecycle==="stopping")return{action:"refuse",reason:"host_stopping",upgradeable:!1};if(host.protocolVersion!==client.protocolVersion)return{action:"refuse",reason:"protocol",upgradeable:!1};if(!client.requiredCapabilities.every(capability=>host.capabilities.includes(capability)))return policy==="fallback"?{action:"fallback",reason:"capability",upgradeable:!1}:{action:"refuse",reason:"capability",upgradeable:!1};let upgradeable=client.platform!=="win32"&&host.capabilities.includes(GENERATION_HANDOFF_CAPABILITY);if(policy==="fallback"&&host.engineVersion!==client.identity.text)return{action:"fallback",reason:"engine_mismatch",upgradeable};let warning=profileWarning(client,host);return client.platform==="win32"?{action:"reuse",reason:"win32_attach_only",upgradeable:!1,...warning&&{warning}}:upgradeable?policy==="upgrade"&&client.launchProfile&&host.launch_profile&&supersedes(client,host)?{action:"handoff",reason:sameRelease(client.identity.ordinal,host.engineOrdinal)?"profile":"newer_engine",upgradeable:!0}:{action:"reuse",reason:"compatible",upgradeable,...warning&&{warning}}:{action:"reuse",reason:"handoff_unsupported",upgradeable:!1,...warning&&{warning}}}function supersedes(client,host){if(host.engineOrdinal===void 0)return!1;let hostIdentity={text:host.engineVersion??"",ordinal:host.engineOrdinal,scheme:host.engineOrdinal[4]>0?"epoch":"nodef"};return compareEngineOrdinal(client.identity,hostIdentity)<=0?!1:covers(client.launchProfile,host.launch_profile)}function profileWarning(client,host){if(client.launchProfile===void 0||host.launch_profile===void 0)return"profile_mismatch_attached";if(client.launchProfile.profile_id===host.launch_profile.profile_id)return;let clientCoversHost=covers(client.launchProfile,host.launch_profile);if(!(clientCoversHost&&covers(host.launch_profile,client.launchProfile)))return clientCoversHost?"profile_mismatch_attached":"profile_narrower_attached"}function extensionRole(extension){let segments=extension.split(/[\\/]+/),pluginAt=segments.lastIndexOf("plugin");return pluginAt<0?extension:segments.slice(pluginAt).join("/")}function covers(candidate,running){if(candidate===void 0||running===void 0)return!1;let candidateRoles=new Set(candidate.core.extensions.map(extensionRole));return running.core.extensions.every(extension=>candidateRoles.has(extensionRole(extension)))}function sameRelease(candidate,running){return running!==void 0&&candidate.slice(0,4).every((part,index)=>part===running[index])}function assertNever(value){throw new Error(`unreachable host decision: ${JSON.stringify(value)}`)}import{createHash as createHash2,randomUUID as randomUUID2}from"node:crypto";import{resolve}from"node:path";var INSTANCE_ID=resolveInstanceId(process.env[HOST_INSTANCE_ID_ENV]);function resolveInstanceId(value){return value!==void 0&&value.trim()!==""?value:randomUUID2()}function hostInstanceId(){return INSTANCE_ID}var cachedProfile;function hostGeneration(env){let value=env[HOST_GENERATION_ENV];return value!==void 0&&/^\d+$/.test(value)?Number(value):0}function hostLaunchProfile(argv,cwd){let parsed=parseArgs([...argv],{grokNeoEnabled:!1}),core={extensions:[...new Set((parsed.extensions??[]).map(path=>resolve(cwd,path)))].sort(),multi_session:parsed.multiSession===!0,session_runtime:resolveSessionRuntime(parsed)},canonical=JSON.stringify({extensions:core.extensions,multi_session:core.multi_session,session_runtime:core.session_runtime});return{profile_id:createHash2("sha256").update(canonical).digest("hex"),core}}function socketHostLaunchProfile(hostArgs,cwd){return hostLaunchProfile(["--mode","rpc","--multi-session","--listen","unix://",...hostArgs],cwd)}function protocolIdentity(agentDir=resolve(getAgentDir())){cachedProfile??=hostLaunchProfile(process.argv.slice(2),process.cwd());let build=engineBuildIdentity();return{instanceId:INSTANCE_ID,generation:hostGeneration(process.env),engineVersion:build.text,engineOrdinal:build.ordinal,launch_profile:cachedProfile,agentDir}}function holdAttachment(socket){return socket.removeAllListeners("data"),socket.resume(),socket.on("error",()=>socket.destroy()),socket.unref(),{release:()=>socket.destroy()}}var DEFAULT_PROBE_TIMEOUT_MS=1e4;function probeHost(options){return probeProtocolInfo(options.socket,options.timeoutMs??DEFAULT_PROBE_TIMEOUT_MS,options)}async function probeProtocolInfo(socketPath,timeoutMs,options={}){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info"},timeoutMs,options);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function observeProtocolInfo(socketPath,timeoutMs,options={}){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info",[OBSERVE_REQUEST_FIELD]:!0},timeoutMs,options);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function holdProtocolInfo(socketPath,timeoutMs,options={}){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs,!0,options),info=outcome.answer===void 0?void 0:parseHostProtocolInfo(outcome.answer);if(outcome.kept===void 0)return;let hold=holdAttachment(outcome.kept);if(info!==void 0)return{info,hold};hold.release()}async function probeSocketReachable(socketPath,timeoutMs,options={}){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs,!1,options)).connected}async function probeSessionCount(socketPath,timeoutMs,options={}){return sessionCountOf(await requestOnSocket(socketPath,{type:"list_sessions",include_workers:!0},timeoutMs,options))}async function holdSessionCount(socketPath,timeoutMs,options={}){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"list_sessions",include_workers:!0},timeoutMs,!0,options),kept=outcome.kept;if(kept===void 0)return;let sessions=sessionCountOf(outcome.answer);if(sessions===void 0){kept.destroy();return}let asked=0;return{sessions,recount:recountTimeoutMs=>askAgain(kept,`${PROBE_REQUEST_ID}-recount-${++asked}`,recountTimeoutMs),close:()=>kept.destroy()}}function askAgain(socket,id,timeoutMs){return new Promise(resolveCount=>{let buffer="",finish=count=>{clearTimeout(timeout),socket.off("data",onData),socket.off("close",onClose),resolveCount(count)},onClose=()=>finish(void 0),onData=chunk=>{buffer+=chunk.toString("utf8");for(let newline=buffer.indexOf(`
2
+ import{listHostEndpoints}from"./chunk-Q5CKFBQT.js";import{BUILTIN_PATH_PREFIX}from"./chunk-QMRJYMNH.js";import{PROBE_REQUEST_ID,connectAndAsk,isRecord as isRecord2,readAnswer,requestOnSocket}from"./chunk-SQAQEITV.js";import{claimOwnerIsLive,hostChildAlive,isGenerationId,logUnknownHostIdentity,provenOwner,readDrainWatch,readGenerationRegistration,readHostRegistration,readSessionPathClaims,releaseGeneration,resolveHostPolicy,writeDrainRequest,writeStopIntent}from"./chunk-DCI4QOUX.js";import{HOST_DAEMON_LAYOUT,canonicalEndpointPath,createHostDaemonPaths,generationPaths,hostDaemonDirectoryPaths,isRecord,parseJson,readFileOrUndefined,sameEndpoint,writeStateFile}from"./chunk-YI6KRJDC.js";import{OBSERVE_REQUEST_FIELD,gcRpcPublicKeys}from"./chunk-E6UCZ7E5.js";import{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV}from"./chunk-UYO5Z35O.js";import{parseArgs,resolveSessionRuntime}from"./chunk-ZTPG27EJ.js";import{acquireOwnershipSafeLock,readSocketSecret,resolveSocketTransportAddress,socketSecretPath}from"./chunk-QEESHRTS.js";import{APP_NAME,VERSION,getAgentDir,isBunBinary}from"./chunk-SODMQEHO.js";import{ProcessIdentityUnreadableError,parseDaemonPidFile,processIsLive,processMatchesPidFile,processStartTimeMs,readProcessStartTime}from"./chunk-O5RYI3IW.js";var CALVER=/^(\d+)\.(\d+)\.(\d+)(?:-(\d+))?/;function engineBuildIdentityFrom(build){let match=CALVER.exec(build.version),epoch=Number.isSafeInteger(build.epoch)&&build.epoch!==void 0&&build.epoch>0?build.epoch:0,sha7=build.sha7??"";return{text:epoch===0?build.version:`${build.version}+${epoch}${sha7===""?"":`.${sha7}`}`,ordinal:[match?Number(match[1]):0,match?Number(match[2]):0,match?Number(match[3]):0,match?.[4]?Number(match[4]):0,epoch],scheme:epoch===0?"nodef":"epoch"}}var BUILT=engineBuildIdentityFrom({version:VERSION,epoch:typeof SENPI_BUILD_EPOCH=="number"?SENPI_BUILD_EPOCH:0,sha7:typeof SENPI_BUILD_SHA7=="string"?SENPI_BUILD_SHA7:""});function engineBuildIdentity(){return BUILT}function compareEngineOrdinal(a,b){for(let index=0;index<4;index++)if(a.ordinal[index]!==b.ordinal[index])return a.ordinal[index]>b.ordinal[index]?1:-1;return a.scheme!=="epoch"||b.scheme!=="epoch"||a.ordinal[4]===b.ordinal[4]?0:a.ordinal[4]>b.ordinal[4]?1:-1}import*as crypto from"node:crypto";var CUSTOM_UNSUPPORTED_CAPABILITY="custom_unsupported",EXTENSION_EVENTS_CAPABILITY="extension_events",EVAL_CELLS_CAPABILITY="eval_cells",AUTO_TITLE_SESSIONS_CAPABILITY="auto_title_sessions",CONTINUE_FROM_LEAF_CAPABILITY="continue_from_leaf",SESSION_HELD_CAPABILITY="session_held",RESUME_SESSION_CAPABILITY="resume_session",ATTENDED_CAPABILITY="attended",MEDIA_PLACEHOLDERS_CAPABILITY="media_placeholders",COMPACT_EVENTS_CAPABILITY="compact_events",QUESTION_CAPABILITY="question",TOOL_BARRIER_CAPABILITY="tool_barrier",SESSION_RELOCATION_CAPABILITY="session_relocation",RETAIN_ON_DISCONNECT_CAPABILITY="retain_on_disconnect",DETACH_CONNECTION_CAPABILITY="detach_connection",INTERACTIVE_USER_CAPABILITY="interactive_user",OBSERVE_READS_CAPABILITY="observe_reads",ENTRIES_TAIL_CAPABILITY="entries_tail",TUI_OBSERVER_CAPABILITY="tui_observer",TASK_PARENT_CAPABILITY="task_parent",SESSION_CONTEXT_CAPABILITY="session_context",SESSION_KIND_CAPABILITY="session_kind",SESSION_STATUS_CAPABILITY="session_status",AUTO_TITLE_PER_SESSION_CAPABILITY="auto_title_per_session",WARM_CAPABILITY="warm",DURABLE_SESSION_ID_CAPABILITY="durable_session_id",MOVED_PATH_GUARD_CAPABILITY="moved_path_guard",PROMPT_SURFACE_CAPABILITY="prompt_surface",BROWSER_ENGINE_CAPABILITY="browser_engine",SESSION_ENV_CAPABILITY="session_env",RETRY_FALLBACK_PROFILE_CAPABILITY="retry_fallback_profile",RETRY_FALLBACK_COMMAND_CAPABILITY="retry_fallback_command",PROMPT_SURFACE_CHAT_CAPABILITY="prompt_surface_chat",RPC_CLIENT_CAPABILITIES_ENV="SENPI_RPC_CLIENT_CAPABILITIES";function parseClientCapabilities(value){return value?value.split(",").map(part=>part.trim()).filter(part=>part.length>0):[]}var DEFAULT_CUSTOM_EXTENSION_LABEL="custom UI component";function buildCustomUnsupportedRequest(capabilities,extensionName){if(!capabilities?.includes(CUSTOM_UNSUPPORTED_CAPABILITY))return;let name=extensionName.trim()||DEFAULT_CUSTOM_EXTENSION_LABEL;return{type:"extension_ui_request",id:crypto.randomUUID(),method:"custom_unsupported",extensionName:name}}var AUTH_KEY_VERIFY_CAPABILITY="auth_key_verify",PROVIDER_ACCOUNT_TEST_CAPABILITY="provider_account_test",QUEUED_MESSAGE_REVISION_CAPABILITY="queued_message_revision";import{createHash}from"node:crypto";import{existsSync}from"node:fs";import{readdir,readFile,realpath,stat}from"node:fs/promises";import{basename,dirname,join,relative,sep}from"node:path";import{fileURLToPath}from"node:url";var RUNTIME_IDENTITY_HANDOVER_CAPABILITY="runtime_identity_handover",RUNTIME_BUILD_ID=/^sha256:[0-9a-f]{64}$/,EXCLUDED_FILE=/\.(?:d\.[cm]?ts|map)$/,EXCLUDED_NAMES=new Set(["node_modules","runtime-manifest.json","runtime-snapshot.json"]),READ_CONCURRENCY=32;function parseRuntimeBuildId(value){return typeof value=="string"&&RUNTIME_BUILD_ID.test(value)?value:void 0}async function computeRuntimeBuildId(input){let source=input.source??loadedRuntimeSource(),plugins=await Promise.all(input.profile.extensions.map(path=>extensionDigest(path))),manifest={schema:1,flavour:source.flavour,platform:input.platform??process.platform,arch:input.arch??process.arch,engine:input.engine??engineBuildIdentity().text,runtime:await treeDigest(source.root),plugins:plugins.sort(),profile:{multi_session:input.profile.multi_session,session_runtime:input.profile.session_runtime}};return`sha256:${sha256(JSON.stringify(manifest))}`}function loadedRuntimeSource(){if(isBunBinary)return{flavour:"compiled",root:process.execPath};let moduleDir=dirname(fileURLToPath(import.meta.url)),packageRoot=nearestPackageRoot(moduleDir),[top,next]=relative(packageRoot,moduleDir).split(sep);return top==="dist"?{flavour:"packaged",root:join(packageRoot,next==="bundle"?join("dist","bundle"):"dist")}:{flavour:"dev",root:join(packageRoot,top??"")}}function nearestPackageRoot(start){for(let dir=start;;dir=dirname(dir)){if(existsSync(join(dir,"package.json")))return dir;if(dirname(dir)===dir)return start}}function extensionDigest(path){let name=basename(path);return name.startsWith(BUILTIN_PATH_PREFIX)?Promise.resolve(sha256(name)):treeDigest(path)}async function treeDigest(root){let files=[];(await stat(root)).isFile()?files.push(["",root]):await collect(await realpath(root),"",files,new Set);let digests=await mapLimited(files,READ_CONCURRENCY,async([path,file])=>[path,sha256(await readFile(file))]);return digests.sort(([a],[b])=>a<b?-1:a>b?1:0),sha256(JSON.stringify(digests))}async function collect(dir,prefix,files,seen){if(seen.has(dir))return;seen.add(dir);let entries=(await readdir(dir,{withFileTypes:!0})).sort((a,b)=>a.name<b.name?-1:a.name>b.name?1:0);for(let entry of entries){if(entry.name.startsWith(".")||EXCLUDED_NAMES.has(entry.name))continue;let path=join(dir,entry.name),name=prefix===""?entry.name:`${prefix}/${entry.name}`,kind=entry.isSymbolicLink()?await stat(path).catch(()=>{}):entry;kind!==void 0&&(kind.isDirectory()?await collect(await realpath(path),name,files,seen):kind.isFile()&&!EXCLUDED_FILE.test(entry.name)&&files.push([name,path]))}}async function mapLimited(items,limit,map){let results=new Array(items.length),next=0,worker=async()=>{for(let index=next++;index<items.length;index=next++)results[index]=await map(items[index])};return await Promise.all(Array.from({length:Math.min(limit,items.length)},worker)),results}function sha256(data){return createHash("sha256").update(data).digest("hex")}var STATES=["not_started","ready","unavailable"];function pathIdentityResolverStatus(resolver){let detail=resolver.unavailable;return detail!==void 0?{state:"unavailable",detail}:{state:resolver.snapshot===void 0?"not_started":"ready",detail:null}}function isState(value){return STATES.some(state=>state===value)}function parsePathIdentityResolverStatus(value){if(typeof value!="object"||value===null)return;let{state,detail}=value;if(isState(state))return{state,detail:typeof detail=="string"?detail:null}}function parseHostProtocolInfo(data){if(!isRecord3(data)||typeof data.serverVersion!="string"||!Array.isArray(data.capabilities)||!data.capabilities.every(entry=>typeof entry=="string"))return;let ordinal=parseOrdinal(data.engineOrdinal),launchProfile=parseLaunchProfile(data.launch_profile),runtimeBuildId=parseRuntimeBuildId(data.runtimeBuildId),pathIdentityResolver=parsePathIdentityResolverStatus(data.path_identity_resolver);return{protocolVersion:typeof data.protocolVersion=="number"?data.protocolVersion:0,serverVersion:data.serverVersion,capabilities:data.capabilities,...(data.lifecycle==="ready"||data.lifecycle==="stopping")&&{lifecycle:data.lifecycle},...typeof data.instanceId=="string"&&{instanceId:data.instanceId},...typeof data.generation=="number"&&Number.isSafeInteger(data.generation)&&{generation:data.generation},...typeof data.engineVersion=="string"&&{engineVersion:data.engineVersion},...ordinal&&{engineOrdinal:ordinal},...launchProfile&&{launch_profile:launchProfile},...typeof data.memory_pressure=="boolean"&&{memory_pressure:data.memory_pressure},...pathIdentityResolver!==void 0&&{path_identity_resolver:pathIdentityResolver},...runtimeBuildId!==void 0&&{runtimeBuildId},...typeof data.agentDir=="string"&&data.agentDir!==""&&{agentDir:data.agentDir},...isRecord3(data.handover)&&{handover:data.handover}}}function parseOrdinal(value){if(!(!Array.isArray(value)||value.length!==5||!value.every(part=>typeof part=="number")))return[value[0],value[1],value[2],value[3],value[4]]}function parseLaunchProfile(value){if(!isRecord3(value)||typeof value.profile_id!="string"||!isRecord3(value.core))return;let{extensions,multi_session,session_runtime}=value.core;if(!(!Array.isArray(extensions)||!extensions.every(entry=>typeof entry=="string"))&&typeof multi_session=="boolean"&&!(session_runtime!=="in-process"&&session_runtime!=="worker"))return{profile_id:value.profile_id,core:{extensions,multi_session,session_runtime}}}function isRecord3(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function describeHostHolder(holder){let engine=holder.engineVersion===null?"an unrecorded engine":`engine ${holder.engineVersion}`,profile=holder.launchProfileId===null?"":`, launch profile ${holder.launchProfileId}`,writer=holder.writerPid===null||holder.writerPid===holder.pid?"":`, started by pid ${holder.writerPid}`;return`pid ${holder.pid}, ${engine}${profile}${writer}`}var HOST_PROTOCOL_VERSION=1,GENERATION_HANDOFF_CAPABILITY="generation_handoff",REQUIRED_HOST_CAPABILITIES=["multi_session",EXTENSION_EVENTS_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY],HostEnsureRefusedError=class extends Error{constructor(socket,reason,host,detail,holder){let heldBy=holder?` (held by ${describeHostHolder(holder)})`:"";super(`RPC socket ${socket} refused: ${reason} - ${refusalDetail(reason,host)}${detail?`: ${detail}`:""}${heldBy}`),this.name="HostEnsureRefusedError",this.socket=socket,this.reason=reason,this.detail=detail,this.holder=holder}};function refusalDetail(reason,host){switch(reason){case"protocol":return`the running host speaks protocol version ${host?.protocolVersion??"unknown"}, this build speaks ${HOST_PROTOCOL_VERSION}`;case"capability":{let missing=REQUIRED_HOST_CAPABILITIES.filter(capability=>!host?.capabilities.includes(capability));return`the running host is missing ${JSON.stringify(missing)}; it owns the socket, so no second host is started`}case"foreign_writer":return"another process registered the host on this socket; it accepts connections but did not answer as a host, and this one may not signal it - stop that host explicitly (host stop --force), then ensure again";case"legacy_host":return"a host from before the per-socket daemon directory is still running; it is drained and replaced only while it holds no session, and no second host is started beside it";case"host_busy":return"its socket accepts connections but did not answer inside the probe budget: a live host under load, which is never ended to make room for a replacement";case"host_stopping":return"this generation is stopping; wait for its exit before launching a successor";case"endpoint_occupied":return"another process accepts connections on this socket but does not answer as a host, and no host registration names it; it is never removed while it listens, so quit the process holding it and ensure again";case"host_stalled":return"nothing reaches its socket, but its process is alive and its own loop-lag watchdog measured a recent stall: a stalled host is still serving its sessions, so it is neither stopped nor replaced";default:return assertNever(reason)}}function decideHostAction(client,host,policy){if(host===void 0)return{action:"start",reason:client.startedByUs?"restart_own_host":"no_host",upgradeable:!1};if(host.lifecycle==="stopping")return{action:"refuse",reason:"host_stopping",upgradeable:!1};if(host.protocolVersion!==client.protocolVersion)return{action:"refuse",reason:"protocol",upgradeable:!1};if(!client.requiredCapabilities.every(capability=>host.capabilities.includes(capability)))return policy==="fallback"?{action:"fallback",reason:"capability",upgradeable:!1}:{action:"refuse",reason:"capability",upgradeable:!1};let upgradeable=client.platform!=="win32"&&host.capabilities.includes(GENERATION_HANDOFF_CAPABILITY);if(policy==="fallback"&&host.engineVersion!==client.identity.text)return{action:"fallback",reason:"engine_mismatch",upgradeable};let warning=profileWarning(client,host);return client.platform==="win32"?{action:"reuse",reason:"win32_attach_only",upgradeable:!1,...warning&&{warning}}:upgradeable?policy==="upgrade"&&client.launchProfile&&host.launch_profile&&supersedes(client,host)?{action:"handoff",reason:sameRelease(client.identity.ordinal,host.engineOrdinal)?"profile":"newer_engine",upgradeable:!0}:{action:"reuse",reason:"compatible",upgradeable,...warning&&{warning}}:{action:"reuse",reason:"handoff_unsupported",upgradeable:!1,...warning&&{warning}}}function supersedes(client,host){if(host.engineOrdinal===void 0)return!1;let hostIdentity={text:host.engineVersion??"",ordinal:host.engineOrdinal,scheme:host.engineOrdinal[4]>0?"epoch":"nodef"};return compareEngineOrdinal(client.identity,hostIdentity)<=0?!1:covers(client.launchProfile,host.launch_profile)}function profileWarning(client,host){if(client.launchProfile===void 0||host.launch_profile===void 0)return"profile_mismatch_attached";if(client.launchProfile.profile_id===host.launch_profile.profile_id)return;let clientCoversHost=covers(client.launchProfile,host.launch_profile);if(!(clientCoversHost&&covers(host.launch_profile,client.launchProfile)))return clientCoversHost?"profile_mismatch_attached":"profile_narrower_attached"}function extensionRole(extension){let segments=extension.split(/[\\/]+/),pluginAt=segments.lastIndexOf("plugin");return pluginAt<0?extension:segments.slice(pluginAt).join("/")}function covers(candidate,running){if(candidate===void 0||running===void 0)return!1;let candidateRoles=new Set(candidate.core.extensions.map(extensionRole));return running.core.extensions.every(extension=>candidateRoles.has(extensionRole(extension)))}function sameRelease(candidate,running){return running!==void 0&&candidate.slice(0,4).every((part,index)=>part===running[index])}function assertNever(value){throw new Error(`unreachable host decision: ${JSON.stringify(value)}`)}import{createHash as createHash3,randomUUID as randomUUID2}from"node:crypto";import{resolve}from"node:path";import{createHash as createHash2}from"node:crypto";var RPC_METHOD_CLASSES_VERSION=1,DYNAMIC="dynamic",ENTRY_AUTHORSHIP={message:"user_role_only",thinking_level_change:"engine",configuration_update:"engine",model_change:"engine",model_change_rejected:"engine",usage:"engine",compaction:"engine",branch_summary:"engine",custom:"engine",custom_message:"engine",context_edit:"engine",label:"engine",session_info:"engine"},USER_ROLE="user";function appendEntryClass(record){let entry=Reflect.get(record,"entry");if(typeof entry!="object"||entry===null)return"device_admin";let entryType=Reflect.get(entry,"type");if(typeof entryType!="string"||!Object.hasOwn(ENTRY_AUTHORSHIP,entryType)||ENTRY_AUTHORSHIP[entryType]!=="user_role_only")return"device_admin";let message=Reflect.get(entry,"message");return typeof message!="object"||message===null?"device_admin":Reflect.get(message,"role")===USER_ROLE?"drive":"device_admin"}function namesAny(record,fields){return fields.some(field=>Object.hasOwn(record,field)&&Reflect.get(record,field)!==void 0)}function openSessionClass(record){return namesAny(record,["sessionPath","cwd","permissionPreset","browserEngine","env"])?"device_admin":"thread"}function thinkingLevelClass(record){return Reflect.get(record,"scope")==="turn"?"drive":"device_admin"}function effectStatusClass(record){return namesAny(record,["sessionPath"])?"device_admin":"observe"}function promptClass(record){let message=Reflect.get(record,"message");return typeof message!="string"?"device_admin":Reflect.get(record,"expandPromptTemplates")===!1?"drive":message.startsWith("/")?"device_admin":"drive"}function idleStartClass(record){if(Reflect.get(record,"whenIdle")!=="start")return"drive";let message=Reflect.get(record,"message");return typeof message!="string"||message.startsWith("/")?"device_admin":"drive"}function newSessionClass(record){return namesAny(record,["parentSession"])?"device_admin":"thread"}var RPC_METHOD_CLASS={get_protocol_info:"observe",get_subscription_limits:"observe",list_sessions:"observe",get_state:"observe",get_snapshot:"observe",get_entries:"observe",get_messages:"observe",get_tree:"observe",get_fork_messages:"observe",get_last_assistant_text:"observe",get_session_stats:"observe",get_effect_status:{classify:effectStatusClass,version:1},get_pending_inputs:"observe",get_follow_up_messages:"observe",get_steering_messages:"observe",get_commands:"observe",get_loaded_surfaces:"observe",get_available_models:"observe",get_available_thinking_levels:"observe",get_model_thinking_level:"observe",get_fast_mode:"observe",get_media:"observe",memory_report:"observe","eval_cells.list":"observe","eval_cells.peek":"observe",prompt:{classify:promptClass,version:1},steer:{classify:idleStartClass,version:1},follow_up:{classify:idleStartClass,version:1},abort:"drive",interrupt:"drive",abort_retry:"drive",abort_compaction:"drive",abort_branch_summary:"drive",compact:"drive",clear_queue:"drive",dequeue_message:"drive",edit_queued_message:"drive",hold_input:"drive",withdraw_held_input:"drive",append_user_message:"drive",edit_user_message:"drive",continue_from_leaf:"drive",navigate_tree:"drive",set_label:"drive",set_session_name:"drive",set_thinking_level:{classify:thinkingLevelClass,version:1},set_auto_compaction:"drive",set_retry_fallback:"drive",pause_for_run:"drive",resume_for_run:"drive",wake:"drive",release_tool_barrier:"drive",request_self_settle:"drive","eval_cells.stop":"drive",append_session_entry:{classify:appendEntryClass,version:1},extension_ui_response:"answer",extension_ui_progress:"answer",new_session:{classify:newSessionClass,version:1},open_session:{classify:openSessionClass,version:2},resume_session:"thread",fork:"thread",clone:"thread",close_session:"thread",unload_session:"thread",set_session_context:"thread",attach_session:"thread",bash:"device_admin",abort_bash:"device_admin",record_bash_result:"device_admin",cleanup_bash_output:"device_admin",extension_request:"device_admin",reload:"device_admin",check_reload_veto:"device_admin",resolve_path:"device_admin",login_start:"device_admin",login_cancel:"device_admin",login_api_key:"device_admin",logout:"device_admin",verify_api_key:"device_admin",get_auth_providers:"device_admin",get_provider_accounts:"device_admin",account_order:"device_admin",account_pin:"device_admin",account_remove:"device_admin",test_provider_account:"device_admin",set_favorite_models:"device_admin",set_scoped_models:"device_admin",set_model:"device_admin",cycle_model:"device_admin",cycle_thinking_level:"device_admin",set_fast_mode:"device_admin",set_steering_mode:"device_admin",set_follow_up_mode:"device_admin",set_auto_retry:"device_admin",edit_assistant_message:"device_admin",send_custom_message:"device_admin",switch_session:"device_admin",import_jsonl:"device_admin",export_html:"device_admin",export_jsonl:"device_admin",set_client_info:"connection_local",subscribe_sessions:"connection_local",unsubscribe_sessions:"connection_local",record_user_activity:"connection_local",detach_connection:"connection_local",release_session:"connection_local",warm:"connection_local",host_response:"connection_local",release_attachment:"connection_local",reclaim_session:"connection_local",move_session:"connection_local",get_recovery_page:"connection_local",release_recovery:"connection_local",cancel_attempt:"connection_local",reset_stream:"connection_local"};function rpcMethodClassesDigest(table){let lines=Object.entries(table).map(([type,methodClass])=>`${type}=${methodClass}
3
+ `).sort();return createHash2("sha256").update(lines.join("")).digest("hex")}function digestValue(entry){return typeof entry=="string"?entry:`${DYNAMIC}@${entry.version}`}var RPC_METHOD_CLASSES_DIGEST=rpcMethodClassesDigest(Object.fromEntries(Object.entries(RPC_METHOD_CLASS).map(([type,entry])=>[type,digestValue(entry)])));var INSTANCE_ID=resolveInstanceId(process.env[HOST_INSTANCE_ID_ENV]);function resolveInstanceId(value){return value!==void 0&&value.trim()!==""?value:randomUUID2()}function hostInstanceId(){return INSTANCE_ID}var cachedProfile;function hostGeneration(env){let value=env[HOST_GENERATION_ENV];return value!==void 0&&/^\d+$/.test(value)?Number(value):0}function hostLaunchProfile(argv,cwd){let parsed=parseArgs([...argv],{grokNeoEnabled:!1}),core={extensions:[...new Set((parsed.extensions??[]).map(path=>resolve(cwd,path)))].sort(),multi_session:parsed.multiSession===!0,session_runtime:resolveSessionRuntime(parsed)},canonical=JSON.stringify({extensions:core.extensions,multi_session:core.multi_session,session_runtime:core.session_runtime});return{profile_id:createHash3("sha256").update(canonical).digest("hex"),core}}function socketHostLaunchProfile(hostArgs,cwd){return hostLaunchProfile(["--mode","rpc","--multi-session","--listen","unix://",...hostArgs],cwd)}function protocolIdentity(agentDir=resolve(getAgentDir())){cachedProfile??=hostLaunchProfile(process.argv.slice(2),process.cwd());let build=engineBuildIdentity();return{instanceId:INSTANCE_ID,generation:hostGeneration(process.env),engineVersion:build.text,engineOrdinal:build.ordinal,launch_profile:cachedProfile,agentDir,method_classes:{version:RPC_METHOD_CLASSES_VERSION,digest:RPC_METHOD_CLASSES_DIGEST}}}function holdAttachment(socket){return socket.removeAllListeners("data"),socket.resume(),socket.on("error",()=>socket.destroy()),socket.unref(),{release:()=>socket.destroy()}}var DEFAULT_PROBE_TIMEOUT_MS=1e4;function probeHost(options){return probeProtocolInfo(options.socket,options.timeoutMs??DEFAULT_PROBE_TIMEOUT_MS,options)}async function probeProtocolInfo(socketPath,timeoutMs,options={}){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info"},timeoutMs,options);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function observeProtocolInfo(socketPath,timeoutMs,options={}){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info",[OBSERVE_REQUEST_FIELD]:!0},timeoutMs,options);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function holdProtocolInfo(socketPath,timeoutMs,options={}){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs,!0,options),info=outcome.answer===void 0?void 0:parseHostProtocolInfo(outcome.answer);if(outcome.kept===void 0)return;let hold=holdAttachment(outcome.kept);if(info!==void 0)return{info,hold};hold.release()}async function probeSocketReachable(socketPath,timeoutMs,options={}){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs,!1,options)).connected}async function probeSessionCount(socketPath,timeoutMs,options={}){return sessionCountOf(await requestOnSocket(socketPath,{type:"list_sessions",include_workers:!0},timeoutMs,options))}async function holdSessionCount(socketPath,timeoutMs,options={}){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"list_sessions",include_workers:!0},timeoutMs,!0,options),kept=outcome.kept;if(kept===void 0)return;let sessions=sessionCountOf(outcome.answer);if(sessions===void 0){kept.destroy();return}let asked=0;return{sessions,recount:recountTimeoutMs=>askAgain(kept,`${PROBE_REQUEST_ID}-recount-${++asked}`,recountTimeoutMs),close:()=>kept.destroy()}}function askAgain(socket,id,timeoutMs){return new Promise(resolveCount=>{let buffer="",finish=count=>{clearTimeout(timeout),socket.off("data",onData),socket.off("close",onClose),resolveCount(count)},onClose=()=>finish(void 0),onData=chunk=>{buffer+=chunk.toString("utf8");for(let newline=buffer.indexOf(`
3
4
  `);newline!==-1;newline=buffer.indexOf(`
4
5
  `)){let answer=readAnswer(buffer.slice(0,newline),id);if(buffer=buffer.slice(newline+1),answer!==void 0){finish(sessionCountOf(answer));return}}},timeout=setTimeout(()=>finish(void 0),timeoutMs);if(socket.destroyed){finish(void 0);return}socket.on("data",onData),socket.once("close",onClose),socket.write(`${JSON.stringify({id,type:"list_sessions",include_workers:!0})}
5
- `)})}function sessionCountOf(reply){return isRecord2(reply)&&Array.isArray(reply.sessions)?reply.sessions.length:void 0}import{createHash as createHash3}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{tmpdir}from"node:os";import{dirname as dirname2,join as join2}from"node:path";var LOCK_BUSY_WAIT_MS=100;function hostEnsureLockTarget(socket){return join2(tmpdir(),"senpi-rpc-host-locks",createSocketLockName(socket))}async function acquireHostEnsureLock(socket,waitMs){let lockTarget=hostEnsureLockTarget(socket);return await mkdir(dirname2(lockTarget),{recursive:!0}),await writeFile(lockTarget,"",{flag:"a",mode:384}),acquireOwnershipSafeLock(`${lockTarget}.lock`,hostEnsureLockOptions(waitMs))}function hostEnsureLockOptions(waitMs){return{retries:{retries:Math.ceil(waitMs/LOCK_BUSY_WAIT_MS),minTimeout:20,maxTimeout:LOCK_BUSY_WAIT_MS}}}function createSocketLockName(socket){return createHash3("sha256").update(socketLockAddress(socket),"utf8").digest("hex").slice(0,32)}function socketLockAddress(socket){return process.platform==="win32"||socket.startsWith("\0")?resolveSocketTransportAddress(socket,process.platform):canonicalEndpointPath(socket)}import{randomUUID as randomUUID3}from"node:crypto";import{access,link,readdir as readdir2,rm}from"node:fs/promises";async function electPointer(paths,options={}){let text=await readFileOrUndefined(paths.pointerFile).catch(()=>{});if(text!==void 0){let instanceId=parseJson(text)?.instance_id;return typeof instanceId=="string"?{state:"current",instanceId,candidates:[]}:{state:"missing",instanceId:null,candidates:[]}}let candidates=await provenLiveGenerations(paths),ids=candidates.map(candidate=>candidate.instanceId),[only]=candidates;return only===void 0||candidates.length>1||options.write===!1?{state:"missing",instanceId:null,candidates:ids}:await linkPointer(paths,only)?{state:"elected",instanceId:only.instanceId,candidates:ids}:electPointer(paths,{write:!1})}async function provenLiveGenerations(paths){let found=[];for(let instanceId of(await readdir2(paths.generationsDir).catch(()=>[])).sort()){let generation=generationPaths(paths,instanceId);if(await exists(generation.stopIntentFile)||await exists(generation.drainRequestFile))continue;let text=await readFileOrUndefined(generation.pidFile).catch(()=>{}),record=text===void 0?void 0:parseDaemonPidFile(text),parsed=parseJson(text);if(record===void 0||record.processStartTime===null||parsed?.instance_id!==instanceId||typeof parsed.socket!="string"||!sameEndpoint(parsed.socket,paths.socket))continue;let identity={pid:record.pid,processStartTime:record.processStartTime};await processMatchesPidFile(identity,readProcessStartTime).catch(()=>!1)&&found.push({instanceId,writer:parsed.writer})}return found}async function linkPointer(paths,candidate){let staged=`${paths.pointerFile}.elect-${process.pid}-${randomUUID3()}.tmp`;try{return await writeStateFile(staged,{layout:HOST_DAEMON_LAYOUT,instance_id:candidate.instanceId,generation_dir:generationPaths(paths,candidate.instanceId).relativeDir,...isRecord(candidate.writer)&&{writer:candidate.writer}}),await link(staged,paths.pointerFile),!0}catch{return!1}finally{await rm(staged,{force:!0}).catch(()=>{})}}async function exists(path){return access(path).then(()=>!0,()=>!1)}import{dirname as dirname3,join as join3}from"node:path";var LEGACY_PROBE_TIMEOUT_MS=1e4,DRAIN_POLL_MS=50;async function retireIdleLegacyHost(paths,probe,drainTimeoutMs=LEGACY_PROBE_TIMEOUT_MS){let judged=await judgeLegacyHost(paths,probe);if(judged.verdict==="absent")return;if(judged.verdict==="held")return judged.detail;let{record,socket}=judged.host;if(!await drainAndWait(record,probe,drainTimeoutMs))return`pid ${record.pid} (${socket}) was asked to drain and is still running after ${drainTimeoutMs}ms; retry once it exits`}async function readLegacyHost(paths){let text=await readFileOrUndefined(paths.legacyPidFile),record=text===void 0?void 0:parseDaemonPidFile(text);if(record===void 0)return;let stamped=parseJson(text)?.socket;return{record,socket:typeof stamped=="string"?stamped:join3(dirname3(paths.flatDir),"rpc","rpc.sock")}}async function provenLegacyOwner(paths,socket){let legacy=await readLegacyHost(paths),startTime=legacy?.record.processStartTime;if(!legacy||startTime===null||startTime===void 0||!sameEndpoint(legacy.socket,socket))return;let identity={pid:legacy.record.pid,processStartTime:startTime};return await processMatchesPidFile(identity,readProcessStartTime).catch(error=>(error instanceof ProcessIdentityUnreadableError&&logUnknownHostIdentity("legacy_host.pid",identity.pid),!1))?identity:void 0}async function judgeLegacyHost(paths,probe,platform=process.platform){let host=await readLegacyHost(paths);if(host===void 0)return{verdict:"absent"};let{pid}=host.record,identity=await processMatchesPidFile(host.record,probe).then(owns=>owns?"proven":"gone",error=>{if(error instanceof ProcessIdentityUnreadableError)return"unreadable";throw error});if(identity==="gone")return{verdict:"absent"};let where=`pid ${pid} (${host.socket})`;if(identity==="unreadable")return logUnknownHostIdentity("legacy_host.pid",pid),{verdict:"held",detail:`${where} cannot be proven to be the process its record names; stop it by hand`};if(platform==="win32")return{verdict:"held",detail:`${where} cannot be drained on win32; it exits once idle, then retry`};let protocol=await probeProtocolInfo(host.socket,LEGACY_PROBE_TIMEOUT_MS);if(!protocol?.capabilities.includes(GENERATION_HANDOFF_CAPABILITY))return{verdict:"held",detail:`${where} ${protocol?"cannot drain":"does not answer"}; it is never signalled - stop it by hand, then retry`};let sessions=await probeSessionCount(host.socket,LEGACY_PROBE_TIMEOUT_MS);return sessions===0?{verdict:"idle",host}:{verdict:"held",detail:busyLegacyHostDetail(pid,host.socket,sessions)}}function busyLegacyHostDetail(pid,socket,sessions){return`pid ${pid} (${socket}) holds ${describeSessions(sessions)}; run \`${APP_NAME} host stop --drain --socket ${socket}\` to let it finish that work and exit, then retry`}function describeSessions(sessions){return sessions===void 0?"an unknown number of sessions":`${sessions} open session${sessions===1?"":"s"}`}async function drainAndWait(record,probe,timeoutMs){try{process.kill(record.pid,"SIGUSR1")}catch(error){if(!(error instanceof Error&&"code"in error&&error.code==="ESRCH"))throw error}let stillRunning=()=>processMatchesPidFile(record,probe,processIsLive,{attempts:1}).catch(error=>{if(error instanceof ProcessIdentityUnreadableError)return!0;throw error}),deadline=Date.now()+timeoutMs;for(;await stillRunning();){if(Date.now()>deadline)return!1;await new Promise(resolve2=>setTimeout(resolve2,DRAIN_POLL_MS))}return!0}var EXIT_POLL_MS=100;async function drainHost(paths,options){let named=options.instanceId;if(named!==void 0&&!isGenerationId(named))return{action:"refuse",reason:"unknown_owner"};let registered=named===void 0?await readHostRegistration(paths):await readGenerationRegistration(paths,named),owner=await provenOwner(registered,options.socket);if(owner!==void 0){let generation=generationPaths(paths,owner.instanceId);if((await readDrainWatch(generation.drainWatchFile))?.pid===owner.pid)return await writeDrainRequest(generation.drainRequestFile,{sender:{pid:process.pid,kind:"stop"},reason:"operator_drain"}).catch(cause=>{if(cause.code!=="ENOENT")throw cause}),drained({...owner},options.waitMs)}if(named!==void 0&&owner===void 0)return{action:"refuse",reason:"unknown_owner"};let pid=owner?.pid??(await provenLegacyOwner(paths,options.socket))?.pid;if(pid===void 0)return{action:"refuse",reason:"unknown_owner"};let host=await probeProtocolInfo(options.socket,options.timeoutMs??1e4),answersAsTarget=named===void 0||host?.instanceId===named;return!host?.capabilities.includes(GENERATION_HANDOFF_CAPABILITY)||!answersAsTarget||process.platform==="win32"?{action:"refuse",reason:"drain_unsupported"}:(signalDrain(pid),drained(owner??{pid,processStartTime:void 0},options.waitMs))}async function drained(owner,waitMs){let base={action:"drained",pid:owner.pid,...owner.instanceId&&{instanceId:owner.instanceId}};return waitMs===void 0?base:{...base,exited:await waitForExit(owner,waitMs)}}async function waitForExit(owner,waitMs){let deadline=Date.now()+waitMs;for(;;){if(await exitedNow(owner))return!0;if(Date.now()>=deadline)return!1;await new Promise(resolve2=>setTimeout(resolve2,EXIT_POLL_MS))}}async function exitedNow(owner){if(!processIsLive(owner.pid))return!0;if(owner.processStartTime===void 0)return!1;let identity={pid:owner.pid,processStartTime:owner.processStartTime};return processMatchesPidFile(identity,readProcessStartTime).then(same=>!same,error=>{if(error instanceof ProcessIdentityUnreadableError)return!1;throw error})}function signalDrain(pid){try{process.kill(pid,"SIGUSR1")}catch(error){if(error instanceof Error&&"code"in error&&error.code==="ESRCH")return;throw error}}import{stat as stat2}from"node:fs/promises";function processStartTimeIsUnreadable(){return process.platform==="win32"}var STOP_START_TIME_BUDGET_MS=1e4;function readLiveStartTime(pid){return readProcessStartTime(pid,process.platform,STOP_START_TIME_BUDGET_MS)}async function startedBeforeRegistration(pid,registrationFile){let live=await readLiveStartTime(pid).catch(()=>{}),startedMs=live===void 0?void 0:processStartTimeMs(live);if(startedMs===void 0)return!1;let written=await stat2(registrationFile).catch(()=>{});return written!==void 0&&startedMs<=written.mtimeMs}function parseHostStopGeneration(text){let value=parseJson(text);if(!(!value||typeof value.instanceId!="string"||value.instanceId.length===0||typeof value.generation!="number"||!Number.isSafeInteger(value.generation)||value.generation<0||typeof value.pid!="number"||!Number.isSafeInteger(value.pid)||value.pid<=0||!(value.processStartTime===null||typeof value.processStartTime=="string"&&value.processStartTime.length>0)))return{instanceId:value.instanceId,generation:value.generation,pid:value.pid,processStartTime:value.processStartTime}}function compareStopGeneration(registered,expected){if(registered?.instanceId!==expected.instanceId||registered.generation!==expected.generation||registered.record.pid!==expected.pid)return"stale";let recorded=registered.record.processStartTime;return recorded!==null&&expected.processStartTime!==null?recorded===expected.processStartTime?"proven":"stale":recorded===null&&expected.processStartTime===null&&processStartTimeIsUnreadable()?"bound_without_start_time":"unprovable"}async function stopHost(options){if(options.expectedGeneration!==void 0&&options.drain===!0)throw new TypeError("stopHost: expectedGeneration binds a hard stop and cannot be combined with drain");if(options.expectedGeneration===void 0)return stopHostLocked(options);let release=await acquireHostEnsureLock(options.socket,3e4);try{return await stopHostLocked(options)}finally{await release()}}async function stopHostLocked(options){let paths=createHostDaemonPaths({socket:options.socket,...options.agentDir?{agentDir:options.agentDir}:{}});await electPointer(paths);let expected=options.expectedGeneration;if(expected!==void 0){let refusal=generationRefusal(compareStopGeneration(await readHostRegistration(paths),expected));if(refusal!==void 0)return refusal}if(options.drain===!0)return drainHost(paths,{socket:options.socket,...options.instanceId!==void 0&&{instanceId:options.instanceId},...options.waitMs!==void 0&&{waitMs:options.waitMs},...options.timeoutMs!==void 0&&{timeoutMs:options.timeoutMs}});let owner=expected===void 0?await provenOwner(await readHostRegistration(paths),options.socket):void 0;if(expected===void 0&&!owner)return{action:"refuse",reason:"unknown_owner"};let host=await probeProtocolInfo(options.socket,options.timeoutMs??1e4),sessions=await probeSessionCount(options.socket,options.timeoutMs??1e4);if(options.force!==!0&&host!==void 0&&sessions!==void 0&&sessions>0)return{action:"refuse",reason:"sessions_live"};if(options.requireAnswer===!0&&(host===void 0||sessions===void 0))return{action:"refuse",reason:"sessions_live"};let target=expected===void 0?owner:await recheckedTarget(paths,options.socket,expected,host);return target===void 0?{action:"refuse",reason:"unknown_owner"}:"action"in target?target:(await writeStopIntent(generationPaths(paths,target.instanceId),{sender:{pid:process.pid,kind:"stop"},targetPid:target.pid,reason:"operator_stop",signal:"SIGTERM",at:new Date().toISOString()}),signalGeneration(target.pid,"SIGTERM")||await releaseGeneration(paths,{instanceId:target.instanceId,pid:target.pid}),{action:"stopped",pid:target.pid})}function generationRefusal(match){if(match==="stale")return{action:"refuse",reason:"stale_generation"};if(match==="unprovable")return{action:"refuse",reason:"unknown_owner"}}async function staleStopGeneration(socket,agentDir,expected){let paths=createHostDaemonPaths({socket,...agentDir?{agentDir}:{}});return generationRefusal(compareStopGeneration(await readHostRegistration(paths),expected))}async function recheckedTarget(paths,socket,expected,host){let current=await readHostRegistration(paths),match=compareStopGeneration(current,expected),refusal=generationRefusal(match);if(refusal!==void 0)return refusal;if(!(match==="proven"&&!await provenOwner(current,socket))){if(match==="bound_without_start_time"){if(current?.socket!==void 0&&!sameEndpoint(current.socket,socket)||!await startedBeforeRegistration(expected.pid,generationPaths(paths,expected.instanceId).pidFile))return;if(host?.instanceId!==void 0&&host.instanceId!==expected.instanceId)return{action:"refuse",reason:"stale_generation"}}return{pid:expected.pid,instanceId:expected.instanceId}}}function signalGeneration(pid,signal){try{return process.kill(pid,signal),!0}catch(error){if(error instanceof Error&&"code"in error&&error.code==="ESRCH")return!1;throw error}}import{lstat as lstat2,rm as rm2}from"node:fs/promises";import{dirname as dirname5,join as join6}from"node:path";import{lstat,readdir as readdir3}from"node:fs/promises";import{createConnection}from"node:net";import{basename as basename2,dirname as dirname4,join as join4}from"node:path";var SOCKET_PROBE_TIMEOUT_MS=2e3;async function endpointInUse(paths,socket){if(await anyGenerationLive(paths))return{inUse:"live_generation"};for(let claim of await readSessionPathClaims(paths.reservationsDir))if(await claimOwnerIsLive(claim.owner))return{inUse:"live_claim"};let silence=await socketSilence(socket);if(silence===void 0)return{inUse:"reachable"};let successors=(await socketSiblings(socket)).filter(name=>name.startsWith(`${basename2(socket)}.next-`));for(let successor of successors)if(await socketSilence(join4(dirname4(socket),successor))===void 0)return{inUse:"reachable"};return{inUse:void 0,silence}}async function socketSiblings(socket){let name=basename2(socket);return(await readdir3(dirname4(socket)).catch(()=>[])).filter(entry=>entry.startsWith(`${name}.next-`)||entry.startsWith(`${name}.shield-`))}async function anyGenerationLive(paths){for(let instanceId of await readdir3(paths.generationsDir).catch(()=>[])){if(await hostChildAlive(generationPaths(paths,instanceId)))return!0;let record=generationRecord(await readFileOrUndefined(generationPaths(paths,instanceId).pidFile));if(record!==void 0&&await recordIsLive(record))return!0}return!1}function generationRecord(text){if(text===void 0)return;let record=parseDaemonPidFile(text);if(record!==void 0)return record;let pid=parseJson(text)?.pid;return typeof pid=="number"&&Number.isInteger(pid)&&pid>0?{pid,processStartTime:null}:void 0}async function recordIsLive(record){try{return await processMatchesPidFile(record)}catch(error){if(error instanceof ProcessIdentityUnreadableError)return!0;throw error}}async function socketSilence(socket){let secret;return process.platform==="win32"&&(secret=await readSocketSecret(socketSecretPath(socket)).catch(()=>{}),secret===void 0)?"socket_absent":new Promise(resolveProbe=>{let connection=createConnection(resolveSocketTransportAddress(socket,process.platform,secret)),finish=value=>{clearTimeout(timeout),connection.destroy(),resolveProbe(value)},timeout=setTimeout(()=>finish(void 0),SOCKET_PROBE_TIMEOUT_MS);connection.once("connect",()=>finish(void 0)),connection.once("error",error=>{error.code==="ECONNREFUSED"?refusedBySocket(socket).then(finish):error.code==="ENOENT"?finish("socket_absent"):finish(void 0)})})}async function refusedBySocket(socket){if(process.platform==="win32"||socket.startsWith("\0"))return"socket_refused";try{return(await lstat(socket)).isSocket()?"socket_refused":void 0}catch(error){return error instanceof Error&&"code"in error&&error.code==="ENOENT"?"socket_absent":void 0}}import{execFile}from"node:child_process";import{readdir as readdir4,readFile as readFile2,readlink,realpath as realpath2}from"node:fs/promises";import{join as join5}from"node:path";var LSOF_TIMEOUT_MS=2e3,LINUX_ACCEPTCON_FLAG=65536;async function countPublicClients(supervisorPid,socket){let names=new Set([socket,await realpath2(socket).catch(()=>socket)]),descriptors=process.platform==="darwin"?await darwinDescriptors(supervisorPid,names):process.platform==="linux"?await linuxDescriptors(supervisorPid,names):void 0;if(!(descriptors===void 0||descriptors.listeners===0))return descriptors.total-descriptors.listeners}function darwinDescriptors(pid,names){return new Promise(resolve2=>{execFile("lsof",["-a","-p",String(pid),"-U","-w","-F","n"],{timeout:LSOF_TIMEOUT_MS},(error,stdout)=>{if(error)return resolve2(void 0);let total=stdout.split(`
6
+ `)})}function sessionCountOf(reply){return isRecord2(reply)&&Array.isArray(reply.sessions)?reply.sessions.length:void 0}import{createHash as createHash4}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{tmpdir}from"node:os";import{dirname as dirname2,join as join2}from"node:path";var LOCK_BUSY_WAIT_MS=100;function hostEnsureLockTarget(socket){return join2(tmpdir(),"senpi-rpc-host-locks",createSocketLockName(socket))}async function acquireHostEnsureLock(socket,waitMs){let lockTarget=hostEnsureLockTarget(socket);return await mkdir(dirname2(lockTarget),{recursive:!0}),await writeFile(lockTarget,"",{flag:"a",mode:384}),acquireOwnershipSafeLock(`${lockTarget}.lock`,hostEnsureLockOptions(waitMs))}function hostEnsureLockOptions(waitMs){return{retries:{retries:Math.ceil(waitMs/LOCK_BUSY_WAIT_MS),minTimeout:20,maxTimeout:LOCK_BUSY_WAIT_MS}}}function createSocketLockName(socket){return createHash4("sha256").update(socketLockAddress(socket),"utf8").digest("hex").slice(0,32)}function socketLockAddress(socket){return process.platform==="win32"||socket.startsWith("\0")?resolveSocketTransportAddress(socket,process.platform):canonicalEndpointPath(socket)}import{randomUUID as randomUUID3}from"node:crypto";import{access,link,readdir as readdir2,rm}from"node:fs/promises";async function electPointer(paths,options={}){let text=await readFileOrUndefined(paths.pointerFile).catch(()=>{});if(text!==void 0){let instanceId=parseJson(text)?.instance_id;return typeof instanceId=="string"?{state:"current",instanceId,candidates:[]}:{state:"missing",instanceId:null,candidates:[]}}let candidates=await provenLiveGenerations(paths),ids=candidates.map(candidate=>candidate.instanceId),[only]=candidates;return only===void 0||candidates.length>1||options.write===!1?{state:"missing",instanceId:null,candidates:ids}:await linkPointer(paths,only)?{state:"elected",instanceId:only.instanceId,candidates:ids}:electPointer(paths,{write:!1})}async function provenLiveGenerations(paths){let found=[];for(let instanceId of(await readdir2(paths.generationsDir).catch(()=>[])).sort()){let generation=generationPaths(paths,instanceId);if(await exists(generation.stopIntentFile)||await exists(generation.drainRequestFile))continue;let text=await readFileOrUndefined(generation.pidFile).catch(()=>{}),record=text===void 0?void 0:parseDaemonPidFile(text),parsed=parseJson(text);if(record===void 0||record.processStartTime===null||parsed?.instance_id!==instanceId||typeof parsed.socket!="string"||!sameEndpoint(parsed.socket,paths.socket))continue;let identity={pid:record.pid,processStartTime:record.processStartTime};await processMatchesPidFile(identity,readProcessStartTime).catch(()=>!1)&&found.push({instanceId,writer:parsed.writer})}return found}async function linkPointer(paths,candidate){let staged=`${paths.pointerFile}.elect-${process.pid}-${randomUUID3()}.tmp`;try{return await writeStateFile(staged,{layout:HOST_DAEMON_LAYOUT,instance_id:candidate.instanceId,generation_dir:generationPaths(paths,candidate.instanceId).relativeDir,...isRecord(candidate.writer)&&{writer:candidate.writer}}),await link(staged,paths.pointerFile),!0}catch{return!1}finally{await rm(staged,{force:!0}).catch(()=>{})}}async function exists(path){return access(path).then(()=>!0,()=>!1)}import{dirname as dirname3,join as join3}from"node:path";var LEGACY_PROBE_TIMEOUT_MS=1e4,DRAIN_POLL_MS=50;async function retireIdleLegacyHost(paths,probe,drainTimeoutMs=LEGACY_PROBE_TIMEOUT_MS){let judged=await judgeLegacyHost(paths,probe);if(judged.verdict==="absent")return;if(judged.verdict==="held")return judged.detail;let{record,socket}=judged.host;if(!await drainAndWait(record,probe,drainTimeoutMs))return`pid ${record.pid} (${socket}) was asked to drain and is still running after ${drainTimeoutMs}ms; retry once it exits`}async function readLegacyHost(paths){let text=await readFileOrUndefined(paths.legacyPidFile),record=text===void 0?void 0:parseDaemonPidFile(text);if(record===void 0)return;let stamped=parseJson(text)?.socket;return{record,socket:typeof stamped=="string"?stamped:join3(dirname3(paths.flatDir),"rpc","rpc.sock")}}async function provenLegacyOwner(paths,socket){let legacy=await readLegacyHost(paths),startTime=legacy?.record.processStartTime;if(!legacy||startTime===null||startTime===void 0||!sameEndpoint(legacy.socket,socket))return;let identity={pid:legacy.record.pid,processStartTime:startTime};return await processMatchesPidFile(identity,readProcessStartTime).catch(error=>(error instanceof ProcessIdentityUnreadableError&&logUnknownHostIdentity("legacy_host.pid",identity.pid),!1))?identity:void 0}async function judgeLegacyHost(paths,probe,platform=process.platform){let host=await readLegacyHost(paths);if(host===void 0)return{verdict:"absent"};let{pid}=host.record,identity=await processMatchesPidFile(host.record,probe).then(owns=>owns?"proven":"gone",error=>{if(error instanceof ProcessIdentityUnreadableError)return"unreadable";throw error});if(identity==="gone")return{verdict:"absent"};let where=`pid ${pid} (${host.socket})`;if(identity==="unreadable")return logUnknownHostIdentity("legacy_host.pid",pid),{verdict:"held",detail:`${where} cannot be proven to be the process its record names; stop it by hand`};if(platform==="win32")return{verdict:"held",detail:`${where} cannot be drained on win32; it exits once idle, then retry`};let protocol=await probeProtocolInfo(host.socket,LEGACY_PROBE_TIMEOUT_MS);if(!protocol?.capabilities.includes(GENERATION_HANDOFF_CAPABILITY))return{verdict:"held",detail:`${where} ${protocol?"cannot drain":"does not answer"}; it is never signalled - stop it by hand, then retry`};let sessions=await probeSessionCount(host.socket,LEGACY_PROBE_TIMEOUT_MS);return sessions===0?{verdict:"idle",host}:{verdict:"held",detail:busyLegacyHostDetail(pid,host.socket,sessions)}}function busyLegacyHostDetail(pid,socket,sessions){return`pid ${pid} (${socket}) holds ${describeSessions(sessions)}; run \`${APP_NAME} host stop --drain --socket ${socket}\` to let it finish that work and exit, then retry`}function describeSessions(sessions){return sessions===void 0?"an unknown number of sessions":`${sessions} open session${sessions===1?"":"s"}`}async function drainAndWait(record,probe,timeoutMs){try{process.kill(record.pid,"SIGUSR1")}catch(error){if(!(error instanceof Error&&"code"in error&&error.code==="ESRCH"))throw error}let stillRunning=()=>processMatchesPidFile(record,probe,processIsLive,{attempts:1}).catch(error=>{if(error instanceof ProcessIdentityUnreadableError)return!0;throw error}),deadline=Date.now()+timeoutMs;for(;await stillRunning();){if(Date.now()>deadline)return!1;await new Promise(resolve2=>setTimeout(resolve2,DRAIN_POLL_MS))}return!0}var EXIT_POLL_MS=100;async function drainHost(paths,options){let named=options.instanceId;if(named!==void 0&&!isGenerationId(named))return{action:"refuse",reason:"unknown_owner"};let registered=named===void 0?await readHostRegistration(paths):await readGenerationRegistration(paths,named),owner=await provenOwner(registered,options.socket);if(owner!==void 0){let generation=generationPaths(paths,owner.instanceId);if((await readDrainWatch(generation.drainWatchFile))?.pid===owner.pid)return await writeDrainRequest(generation.drainRequestFile,{sender:{pid:process.pid,kind:"stop"},reason:"operator_drain"}).catch(cause=>{if(cause.code!=="ENOENT")throw cause}),drained({...owner},options.waitMs)}if(named!==void 0&&owner===void 0)return{action:"refuse",reason:"unknown_owner"};let pid=owner?.pid??(await provenLegacyOwner(paths,options.socket))?.pid;if(pid===void 0)return{action:"refuse",reason:"unknown_owner"};let host=await probeProtocolInfo(options.socket,options.timeoutMs??1e4),answersAsTarget=named===void 0||host?.instanceId===named;return!host?.capabilities.includes(GENERATION_HANDOFF_CAPABILITY)||!answersAsTarget||process.platform==="win32"?{action:"refuse",reason:"drain_unsupported"}:(signalDrain(pid),drained(owner??{pid,processStartTime:void 0},options.waitMs))}async function drained(owner,waitMs){let base={action:"drained",pid:owner.pid,...owner.instanceId&&{instanceId:owner.instanceId}};return waitMs===void 0?base:{...base,exited:await waitForExit(owner,waitMs)}}async function waitForExit(owner,waitMs){let deadline=Date.now()+waitMs;for(;;){if(await exitedNow(owner))return!0;if(Date.now()>=deadline)return!1;await new Promise(resolve2=>setTimeout(resolve2,EXIT_POLL_MS))}}async function exitedNow(owner){if(!processIsLive(owner.pid))return!0;if(owner.processStartTime===void 0)return!1;let identity={pid:owner.pid,processStartTime:owner.processStartTime};return processMatchesPidFile(identity,readProcessStartTime).then(same=>!same,error=>{if(error instanceof ProcessIdentityUnreadableError)return!1;throw error})}function signalDrain(pid){try{process.kill(pid,"SIGUSR1")}catch(error){if(error instanceof Error&&"code"in error&&error.code==="ESRCH")return;throw error}}import{stat as stat2}from"node:fs/promises";function processStartTimeIsUnreadable(){return process.platform==="win32"}var STOP_START_TIME_BUDGET_MS=1e4;function readLiveStartTime(pid){return readProcessStartTime(pid,process.platform,STOP_START_TIME_BUDGET_MS)}async function startedBeforeRegistration(pid,registrationFile){let live=await readLiveStartTime(pid).catch(()=>{}),startedMs=live===void 0?void 0:processStartTimeMs(live);if(startedMs===void 0)return!1;let written=await stat2(registrationFile).catch(()=>{});return written!==void 0&&startedMs<=written.mtimeMs}function parseHostStopGeneration(text){let value=parseJson(text);if(!(!value||typeof value.instanceId!="string"||value.instanceId.length===0||typeof value.generation!="number"||!Number.isSafeInteger(value.generation)||value.generation<0||typeof value.pid!="number"||!Number.isSafeInteger(value.pid)||value.pid<=0||!(value.processStartTime===null||typeof value.processStartTime=="string"&&value.processStartTime.length>0)))return{instanceId:value.instanceId,generation:value.generation,pid:value.pid,processStartTime:value.processStartTime}}function compareStopGeneration(registered,expected){if(registered?.instanceId!==expected.instanceId||registered.generation!==expected.generation||registered.record.pid!==expected.pid)return"stale";let recorded=registered.record.processStartTime;return recorded!==null&&expected.processStartTime!==null?recorded===expected.processStartTime?"proven":"stale":recorded===null&&expected.processStartTime===null&&processStartTimeIsUnreadable()?"bound_without_start_time":"unprovable"}async function stopHost(options){if(options.expectedGeneration!==void 0&&options.drain===!0)throw new TypeError("stopHost: expectedGeneration binds a hard stop and cannot be combined with drain");if(options.expectedGeneration===void 0)return stopHostLocked(options);let release=await acquireHostEnsureLock(options.socket,3e4);try{return await stopHostLocked(options)}finally{await release()}}async function stopHostLocked(options){let paths=createHostDaemonPaths({socket:options.socket,...options.agentDir?{agentDir:options.agentDir}:{}});await electPointer(paths);let expected=options.expectedGeneration;if(expected!==void 0){let refusal=generationRefusal(compareStopGeneration(await readHostRegistration(paths),expected));if(refusal!==void 0)return refusal}if(options.drain===!0)return drainHost(paths,{socket:options.socket,...options.instanceId!==void 0&&{instanceId:options.instanceId},...options.waitMs!==void 0&&{waitMs:options.waitMs},...options.timeoutMs!==void 0&&{timeoutMs:options.timeoutMs}});let owner=expected===void 0?await provenOwner(await readHostRegistration(paths),options.socket):void 0;if(expected===void 0&&!owner)return{action:"refuse",reason:"unknown_owner"};let host=await probeProtocolInfo(options.socket,options.timeoutMs??1e4),sessions=await probeSessionCount(options.socket,options.timeoutMs??1e4);if(options.force!==!0&&host!==void 0&&sessions!==void 0&&sessions>0)return{action:"refuse",reason:"sessions_live"};if(options.requireAnswer===!0&&(host===void 0||sessions===void 0))return{action:"refuse",reason:"sessions_live"};let target=expected===void 0?owner:await recheckedTarget(paths,options.socket,expected,host);return target===void 0?{action:"refuse",reason:"unknown_owner"}:"action"in target?target:(await writeStopIntent(generationPaths(paths,target.instanceId),{sender:{pid:process.pid,kind:"stop"},targetPid:target.pid,reason:"operator_stop",signal:"SIGTERM",at:new Date().toISOString()}),signalGeneration(target.pid,"SIGTERM")||await releaseGeneration(paths,{instanceId:target.instanceId,pid:target.pid}),{action:"stopped",pid:target.pid})}function generationRefusal(match){if(match==="stale")return{action:"refuse",reason:"stale_generation"};if(match==="unprovable")return{action:"refuse",reason:"unknown_owner"}}async function staleStopGeneration(socket,agentDir,expected){let paths=createHostDaemonPaths({socket,...agentDir?{agentDir}:{}});return generationRefusal(compareStopGeneration(await readHostRegistration(paths),expected))}async function recheckedTarget(paths,socket,expected,host){let current=await readHostRegistration(paths),match=compareStopGeneration(current,expected),refusal=generationRefusal(match);if(refusal!==void 0)return refusal;if(!(match==="proven"&&!await provenOwner(current,socket))){if(match==="bound_without_start_time"){if(current?.socket!==void 0&&!sameEndpoint(current.socket,socket)||!await startedBeforeRegistration(expected.pid,generationPaths(paths,expected.instanceId).pidFile))return;if(host?.instanceId!==void 0&&host.instanceId!==expected.instanceId)return{action:"refuse",reason:"stale_generation"}}return{pid:expected.pid,instanceId:expected.instanceId}}}function signalGeneration(pid,signal){try{return process.kill(pid,signal),!0}catch(error){if(error instanceof Error&&"code"in error&&error.code==="ESRCH")return!1;throw error}}import{lstat as lstat2,rm as rm2}from"node:fs/promises";import{dirname as dirname5,join as join6}from"node:path";import{lstat,readdir as readdir3}from"node:fs/promises";import{createConnection}from"node:net";import{basename as basename2,dirname as dirname4,join as join4}from"node:path";var SOCKET_PROBE_TIMEOUT_MS=2e3;async function endpointInUse(paths,socket){if(await anyGenerationLive(paths))return{inUse:"live_generation"};for(let claim of await readSessionPathClaims(paths.reservationsDir))if(await claimOwnerIsLive(claim.owner))return{inUse:"live_claim"};let silence=await socketSilence(socket);if(silence===void 0)return{inUse:"reachable"};let successors=(await socketSiblings(socket)).filter(name=>name.startsWith(`${basename2(socket)}.next-`));for(let successor of successors)if(await socketSilence(join4(dirname4(socket),successor))===void 0)return{inUse:"reachable"};return{inUse:void 0,silence}}async function socketSiblings(socket){let name=basename2(socket);return(await readdir3(dirname4(socket)).catch(()=>[])).filter(entry=>entry.startsWith(`${name}.next-`)||entry.startsWith(`${name}.shield-`))}async function anyGenerationLive(paths){for(let instanceId of await readdir3(paths.generationsDir).catch(()=>[])){if(await hostChildAlive(generationPaths(paths,instanceId)))return!0;let record=generationRecord(await readFileOrUndefined(generationPaths(paths,instanceId).pidFile));if(record!==void 0&&await recordIsLive(record))return!0}return!1}function generationRecord(text){if(text===void 0)return;let record=parseDaemonPidFile(text);if(record!==void 0)return record;let pid=parseJson(text)?.pid;return typeof pid=="number"&&Number.isInteger(pid)&&pid>0?{pid,processStartTime:null}:void 0}async function recordIsLive(record){try{return await processMatchesPidFile(record)}catch(error){if(error instanceof ProcessIdentityUnreadableError)return!0;throw error}}async function socketSilence(socket){let secret;return process.platform==="win32"&&(secret=await readSocketSecret(socketSecretPath(socket)).catch(()=>{}),secret===void 0)?"socket_absent":new Promise(resolveProbe=>{let connection=createConnection(resolveSocketTransportAddress(socket,process.platform,secret)),finish=value=>{clearTimeout(timeout),connection.destroy(),resolveProbe(value)},timeout=setTimeout(()=>finish(void 0),SOCKET_PROBE_TIMEOUT_MS);connection.once("connect",()=>finish(void 0)),connection.once("error",error=>{error.code==="ECONNREFUSED"?refusedBySocket(socket).then(finish):error.code==="ENOENT"?finish("socket_absent"):finish(void 0)})})}async function refusedBySocket(socket){if(process.platform==="win32"||socket.startsWith("\0"))return"socket_refused";try{return(await lstat(socket)).isSocket()?"socket_refused":void 0}catch(error){return error instanceof Error&&"code"in error&&error.code==="ENOENT"?"socket_absent":void 0}}import{execFile}from"node:child_process";import{readdir as readdir4,readFile as readFile2,readlink,realpath as realpath2}from"node:fs/promises";import{join as join5}from"node:path";var LSOF_TIMEOUT_MS=2e3,LINUX_ACCEPTCON_FLAG=65536;async function countPublicClients(supervisorPid,socket){let names=new Set([socket,await realpath2(socket).catch(()=>socket)]),descriptors=process.platform==="darwin"?await darwinDescriptors(supervisorPid,names):process.platform==="linux"?await linuxDescriptors(supervisorPid,names):void 0;if(!(descriptors===void 0||descriptors.listeners===0))return descriptors.total-descriptors.listeners}function darwinDescriptors(pid,names){return new Promise(resolve2=>{execFile("lsof",["-a","-p",String(pid),"-U","-w","-F","n"],{timeout:LSOF_TIMEOUT_MS},(error,stdout)=>{if(error)return resolve2(void 0);let total=stdout.split(`
6
7
  `).filter(line=>line.startsWith("n")&&names.has(line.slice(1))).length;resolve2({total,listeners:total>0?1:0})})})}async function linuxDescriptors(pid,names){try{let inodes=new Set;for(let fd of await readdir4(join5("/proc",String(pid),"fd"))){let target=await readlink(join5("/proc",String(pid),"fd",fd)).catch(()=>""),inode=/^socket:\[(\d+)\]$/.exec(target)?.[1];inode!==void 0&&inodes.add(inode)}let total=0,listeners=0;for(let line of(await readFile2("/proc/net/unix","utf8")).split(`
7
8
  `).slice(1)){let fields=line.trim().split(/\s+/),[flags,inode,path]=[fields[3],fields[6],fields[7]];inode===void 0||path===void 0||!inodes.has(inode)||!names.has(path)||(total+=1,(Number.parseInt(flags??"0",16)&LINUX_ACCEPTCON_FLAG)!==0&&(listeners+=1))}return{total,listeners}}catch{return}}var STALE_ENGINE_GRACE_MS=10*6e4,PROBE_TIMEOUT_MS=2e3;async function judgeStaleEngine(socket,agentDir,client,options={}){let paths=createHostDaemonPaths({socket,agentDir}),owner=await provenOwner(await readHostRegistration(paths),socket);if(owner===void 0)return keep("stale_unproven_owner");let clients=await countPublicClients(owner.pid,socket),info=await observeProtocolInfo(socket,PROBE_TIMEOUT_MS);if(info===void 0)return keep("stale_unreachable");let hostOrdinal=info.engineOrdinal,hostIdentity=hostOrdinal===void 0?void 0:{text:info.engineVersion??"",ordinal:hostOrdinal,scheme:hostOrdinal[4]>0?"epoch":"nodef"};if(hostIdentity===void 0||compareEngineOrdinal(hostIdentity,client)!==-1)return keep("stale_not_older");let policy=resolveHostPolicy(parseJson(await readFileOrUndefined(paths.settingsFile)),{});if(policy.coldStart==="persistent")return keep("stale_persistent");if(await observedSessionCount(socket)!==0)return keep("stale_sessions");if((await readSessionPathClaims(paths.reservationsDir)).length>0)return keep("stale_claims");let startedAt=processStartTimeMs(owner.processStartTime),now=(options.now??Date.now)();return startedAt===void 0||now-startedAt<policy.idleExitMs+(options.graceMs??STALE_ENGINE_GRACE_MS)?keep("stale_young"):clients!==0?keep("stale_clients"):{stale:!0,pid:owner.pid}}function keep(reason){return{stale:!1,reason}}async function observedSessionCount(socket){let reply=await requestOnSocket(socket,{type:"list_sessions",include_workers:!0,[OBSERVE_REQUEST_FIELD]:!0},PROBE_TIMEOUT_MS);if(typeof reply!="object"||reply===null)return;let sessions=Reflect.get(reply,"sessions");return Array.isArray(sessions)?sessions.length:void 0}var GC_LOCK_WAIT_MS=2e3;async function gcHostEndpoints(agentDir,options={}){process.platform!=="win32"&&await gcRpcPublicKeys(agentDir);let removed=[],stopped=[],kept=[],wanted=kind=>options.kinds===void 0||options.kinds.includes(kind),legacy=wanted("rpc_host")?await legacyFlatDirectory(agentDir):void 0;legacy!==void 0&&kept.push({socket:null,dir:legacy,reason:"legacy_layout"});for(let endpoint of await listHostEndpoints(agentDir)){if(!wanted(endpoint.endpoint_kind))continue;if(endpoint.socket===null){kept.push({socket:null,dir:endpoint.dir,reason:"unknown_identity"});continue}let entry={socket:endpoint.socket,dir:endpoint.dir};try{let outcome=await gcEndpoint(endpoint.socket,endpoint.dir,options);"stopped"in outcome?stopped.push({...entry,reason:"stale_old_engine",pid:outcome.pid}):outcome.removed?outcome.skipped.length===0?removed.push({...entry,reason:outcome.reason}):removed.push({...entry,reason:outcome.reason,skipped:outcome.skipped}):kept.push({...entry,reason:outcome.reason})}catch(error){kept.push({...entry,reason:"failed",error:error instanceof Error?error.message:String(error)})}}return stopped.length===0?{removed,kept}:{removed,stopped,kept}}async function gcEndpoint(socket,dir,options){let release=await acquireEnsureLock(socket);if(release===void 0)return{removed:!1,reason:"locked"};try{await options._test?.afterLockAcquired?.(socket);let evidence=await endpointInUse(hostDaemonDirectoryPaths(dir),socket);if(evidence.inUse==="live_claim"||evidence.inUse!==void 0&&options.staleEngine===void 0)return{removed:!1,reason:evidence.inUse};if(evidence.inUse!==void 0)return await stopIfStale(socket,dir,evidence.inUse,options.staleEngine??{});let skipped=await removeEndpoint(socket,dir);return{removed:!0,reason:evidence.silence,skipped}}finally{await release()}}var NOT_A_CANDIDATE=new Set(["stale_unproven_owner","stale_unreachable","stale_not_older"]),STALE_STOP_TIMEOUT_MS=2e3;async function stopIfStale(socket,dir,inUse,options){let agentDir=dirname5(dirname5(dir)),verdict=await judgeStaleEngine(socket,agentDir,options.client??engineBuildIdentity(),options);if(!verdict.stale)return{removed:!1,reason:NOT_A_CANDIDATE.has(verdict.reason)?inUse:verdict.reason};let result=await stopHost({socket,agentDir,timeoutMs:STALE_STOP_TIMEOUT_MS,requireAnswer:!0});return result.action==="refuse"?{removed:!1,reason:result.reason==="unknown_owner"?"stale_unproven_owner":"stale_sessions"}:{removed:!1,stopped:!0,pid:result.pid}}async function removeEndpoint(socket,dir){let skipped=[];for(let sibling of await socketSiblings(socket)){let path=join6(dirname5(socket),sibling),entry=await lstat2(path).catch(error=>{if(!(error instanceof Error&&"code"in error&&error.code==="ENOENT"))throw error});entry?.isDirectory()?skipped.push({path,type:"directory"}):entry!==void 0&&await rm2(path,{force:!0})}return await rm2(socket,{force:!0}),await rm2(dir,{recursive:!0,force:!0}),skipped}async function acquireEnsureLock(socket){return acquireHostEnsureLock(socket,GC_LOCK_WAIT_MS).catch(()=>{})}async function legacyFlatDirectory(agentDir){let flatDir=join6(agentDir,"rpc-host-daemon");return parseJson(await readFileOrUndefined(join6(flatDir,"layout.json")).catch(()=>{}))?.layout===HOST_DAEMON_LAYOUT?void 0:await readFileOrUndefined(join6(flatDir,"host.pid")).catch(()=>{})!==void 0?flatDir:void 0}export{engineBuildIdentityFrom,engineBuildIdentity,compareEngineOrdinal,CUSTOM_UNSUPPORTED_CAPABILITY,EXTENSION_EVENTS_CAPABILITY,EVAL_CELLS_CAPABILITY,AUTO_TITLE_SESSIONS_CAPABILITY,CONTINUE_FROM_LEAF_CAPABILITY,SESSION_HELD_CAPABILITY,RESUME_SESSION_CAPABILITY,ATTENDED_CAPABILITY,MEDIA_PLACEHOLDERS_CAPABILITY,COMPACT_EVENTS_CAPABILITY,QUESTION_CAPABILITY,TOOL_BARRIER_CAPABILITY,SESSION_RELOCATION_CAPABILITY,RETAIN_ON_DISCONNECT_CAPABILITY,DETACH_CONNECTION_CAPABILITY,INTERACTIVE_USER_CAPABILITY,OBSERVE_READS_CAPABILITY,ENTRIES_TAIL_CAPABILITY,TUI_OBSERVER_CAPABILITY,TASK_PARENT_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY,SESSION_STATUS_CAPABILITY,AUTO_TITLE_PER_SESSION_CAPABILITY,WARM_CAPABILITY,DURABLE_SESSION_ID_CAPABILITY,MOVED_PATH_GUARD_CAPABILITY,PROMPT_SURFACE_CAPABILITY,BROWSER_ENGINE_CAPABILITY,SESSION_ENV_CAPABILITY,RETRY_FALLBACK_PROFILE_CAPABILITY,RETRY_FALLBACK_COMMAND_CAPABILITY,PROMPT_SURFACE_CHAT_CAPABILITY,RPC_CLIENT_CAPABILITIES_ENV,parseClientCapabilities,DEFAULT_CUSTOM_EXTENSION_LABEL,buildCustomUnsupportedRequest,AUTH_KEY_VERIFY_CAPABILITY,PROVIDER_ACCOUNT_TEST_CAPABILITY,QUEUED_MESSAGE_REVISION_CAPABILITY,pathIdentityResolverStatus,RUNTIME_IDENTITY_HANDOVER_CAPABILITY,computeRuntimeBuildId,parseHostProtocolInfo,HOST_PROTOCOL_VERSION,GENERATION_HANDOFF_CAPABILITY,REQUIRED_HOST_CAPABILITIES,HostEnsureRefusedError,decideHostAction,hostInstanceId,hostGeneration,hostLaunchProfile,socketHostLaunchProfile,protocolIdentity,DEFAULT_PROBE_TIMEOUT_MS,probeHost,probeProtocolInfo,observeProtocolInfo,holdProtocolInfo,probeSocketReachable,holdSessionCount,hostEnsureLockTarget,acquireHostEnsureLock,hostEnsureLockOptions,anyGenerationLive,judgeStaleEngine,electPointer,retireIdleLegacyHost,provenLegacyOwner,busyLegacyHostDetail,describeSessions,parseHostStopGeneration,stopHost,staleStopGeneration,signalGeneration,gcHostEndpoints,gcEndpoint};
@@ -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{shortHash}from"./chunk-ED7VJGL4.js";import{getInitialSystemMessage,getSystemMessageText}from"./chunk-TBARMJ75.js";var OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH=64,PREFIX_VERSION="senpi-responses-prefix-v1";function deriveOpenAIPromptCacheKey(modelId,context){let initial=getInitialSystemMessage(context.messages),tools=[...initial?.toolsAdded??[]].sort((a,b)=>a.name<b.name?-1:a.name>b.name?1:0),prefix=JSON.stringify([PREFIX_VERSION,modelId,initial===void 0?"":getSystemMessageText(initial),tools.map(({name,description,parameters,freeform,constrainedSampling})=>({name,description,parameters,freeform,constrainedSampling}))]);return clampOpenAIPromptCacheKey(`${PREFIX_VERSION}-${shortHash(prefix)}`)}function clampOpenAIPromptCacheKey(key){if(key===void 0)return;let chars=Array.from(key);return chars.length<=OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH?key:chars.slice(0,OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH).join("")}function applyChatGptSubscriptionCacheAffinityHeaders(headers,sessionId){sessionId&&(headers.set("session-id",sessionId),headers.set("thread-id",sessionId),headers.set("x-client-request-id",sessionId))}export{deriveOpenAIPromptCacheKey,clampOpenAIPromptCacheKey,applyChatGptSubscriptionCacheAffinityHeaders};
2
+ import{shortHash}from"./chunk-2PGSRQBF.js";import{getInitialSystemMessage,getSystemMessageText}from"./chunk-AVP6DDBF.js";var OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH=64,PREFIX_VERSION="senpi-responses-prefix-v1";function deriveOpenAIPromptCacheKey(modelId,context){let initial=getInitialSystemMessage(context.messages),tools=[...initial?.toolsAdded??[]].sort((a,b)=>a.name<b.name?-1:a.name>b.name?1:0),prefix=JSON.stringify([PREFIX_VERSION,modelId,initial===void 0?"":getSystemMessageText(initial),tools.map(({name,description,parameters,freeform,constrainedSampling})=>({name,description,parameters,freeform,constrainedSampling}))]);return clampOpenAIPromptCacheKey(`${PREFIX_VERSION}-${shortHash(prefix)}`)}function clampOpenAIPromptCacheKey(key){if(key===void 0)return;let chars=Array.from(key);return chars.length<=OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH?key:chars.slice(0,OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH).join("")}function applyChatGptSubscriptionCacheAffinityHeaders(headers,sessionId){sessionId&&(headers.set("session-id",sessionId),headers.set("thread-id",sessionId),headers.set("x-client-request-id",sessionId))}export{deriveOpenAIPromptCacheKey,clampOpenAIPromptCacheKey,applyChatGptSubscriptionCacheAffinityHeaders};
@@ -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{isTuiControlSocket}from"./chunk-GDPWQJDQ.js";import{HOST_DAEMON_LAYOUT,createHostDaemonPaths,hostDaemonDirectoryPaths,parseJson,readFileOrUndefined,socketNamesDirectory}from"./chunk-FNBEICAA.js";import{readdir}from"node:fs/promises";import{basename,join}from"node:path";var ENDPOINT_DIRECTORY_NAME=/^[0-9a-f]{16}$/;async function listHostEndpoints(agentDir){let flatDir=join(agentDir,"rpc-host-daemon");if(parseJson(await readFileOrUndefined(join(flatDir,"layout.json")).catch(()=>{}))?.layout!==HOST_DAEMON_LAYOUT)return[];let dirs=(await readdir(flatDir,{withFileTypes:!0}).catch(()=>[])).filter(entry=>entry.isDirectory()&&ENDPOINT_DIRECTORY_NAME.test(entry.name)).map(entry=>join(flatDir,entry.name)).sort(),endpoints=[];for(let dir of dirs)endpoints.push(await identifyEndpoint(dir));return endpoints}async function identifyEndpoint(dir){let paths=hostDaemonDirectoryPaths(dir),named=await recordNaming(paths.endpointFile,dir);if(named!==void 0)return{socket:named.socket,dir,identity:"endpoint",endpoint_kind:endpointKindOf(named.record)};let booted=await recordNaming(paths.settingsFile,dir);if(booted!==void 0)return{socket:booted.socket,dir,identity:"settings",endpoint_kind:"rpc_host"};let generations=await readdir(paths.generationsDir).catch(()=>[]);for(let instanceId of generations.sort()){let recorded=await recordNaming(join(paths.generationsDir,instanceId,"settings.json"),dir);if(recorded!==void 0)return{socket:recorded.socket,dir,identity:"generation-settings",endpoint_kind:"rpc_host"}}return{socket:null,dir,identity:"unknown",endpoint_kind:"rpc_host"}}async function endpointKindOfSocket(socket,agentDir){if(isTuiControlSocket(socket))return"tui";let paths=createHostDaemonPaths({socket,agentDir}),named=await recordNaming(paths.endpointFile,paths.dir);return named===void 0?"rpc_host":endpointKindOf(named.record)}function endpointKindOf(record){return record.endpoint_kind==="tui"?"tui":"rpc_host"}async function recordNaming(file,dir){let record=parseJson(await readFileOrUndefined(file).catch(()=>{})),socket=record?.socket;if(!(record===void 0||typeof socket!="string"||socket===""))return socketNamesDirectory(socket,basename(dir))?{socket,record}:void 0}export{listHostEndpoints,endpointKindOfSocket};
2
+ import{isTuiControlSocket}from"./chunk-XPSXUKSD.js";import{HOST_DAEMON_LAYOUT,createHostDaemonPaths,hostDaemonDirectoryPaths,parseJson,readFileOrUndefined,socketNamesDirectory}from"./chunk-YI6KRJDC.js";import{readdir}from"node:fs/promises";import{basename,join}from"node:path";var ENDPOINT_DIRECTORY_NAME=/^[0-9a-f]{16}$/;async function listHostEndpoints(agentDir){let flatDir=join(agentDir,"rpc-host-daemon");if(parseJson(await readFileOrUndefined(join(flatDir,"layout.json")).catch(()=>{}))?.layout!==HOST_DAEMON_LAYOUT)return[];let dirs=(await readdir(flatDir,{withFileTypes:!0}).catch(()=>[])).filter(entry=>entry.isDirectory()&&ENDPOINT_DIRECTORY_NAME.test(entry.name)).map(entry=>join(flatDir,entry.name)).sort(),endpoints=[];for(let dir of dirs)endpoints.push(await identifyEndpoint(dir));return endpoints}async function identifyEndpoint(dir){let paths=hostDaemonDirectoryPaths(dir),named=await recordNaming(paths.endpointFile,dir);if(named!==void 0)return{socket:named.socket,dir,identity:"endpoint",endpoint_kind:endpointKindOf(named.record)};let booted=await recordNaming(paths.settingsFile,dir);if(booted!==void 0)return{socket:booted.socket,dir,identity:"settings",endpoint_kind:"rpc_host"};let generations=await readdir(paths.generationsDir).catch(()=>[]);for(let instanceId of generations.sort()){let recorded=await recordNaming(join(paths.generationsDir,instanceId,"settings.json"),dir);if(recorded!==void 0)return{socket:recorded.socket,dir,identity:"generation-settings",endpoint_kind:"rpc_host"}}return{socket:null,dir,identity:"unknown",endpoint_kind:"rpc_host"}}async function endpointKindOfSocket(socket,agentDir){if(isTuiControlSocket(socket))return"tui";let paths=createHostDaemonPaths({socket,agentDir}),named=await recordNaming(paths.endpointFile,paths.dir);return named===void 0?"rpc_host":endpointKindOf(named.record)}function endpointKindOf(record){return record.endpoint_kind==="tui"?"tui":"rpc_host"}async function recordNaming(file,dir){let record=parseJson(await readFileOrUndefined(file).catch(()=>{})),socket=record?.socket;if(!(record===void 0||typeof socket!="string"||socket===""))return socketNamesDirectory(socket,basename(dir))?{socket,record}:void 0}export{listHostEndpoints,endpointKindOfSocket};
@@ -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{require_proper_lockfile}from"./chunk-GZVCRV7I.js";import{appendDebugLogEntry}from"./chunk-YWD54RHU.js";import{__toESM}from"./chunk-IKOFCODM.js";var import_proper_lockfile=__toESM(require_proper_lockfile(),1);import{createHash}from"node:crypto";import{basename}from"node:path";var FileLockLostError=class extends Error{constructor(path,cause){super(`File lock on ${basename(path)} was lost before the write committed: the lock was removed or reclaimed by another process. The write was skipped.`,{cause}),this.code="ELOCKLOST",this.name="FileLockLostError",this.path=path}};function lockLogFields(path){return{lock:basename(path),lockId:createHash("sha256").update(path).digest("hex").slice(0,12)}}function logLockEvent(header,fields){try{appendDebugLogEntry(header,JSON.stringify(fields))}catch{}}async function lockWithLossHandling(path,options={}){let{onLost,...lockOptions}=options,released=!1,lostError,releaseLock=await import_proper_lockfile.default.lock(path,{...lockOptions,onCompromised:error=>{if(released||lostError!==void 0)return;lostError=error;let fields=lockLogFields(lockOptions.lockfilePath??`${path}.lock`);logLockEvent("file lock lost while held",{event:"file_lock_lost",...fields,code:error.code});try{onLost?.(error)}catch(callbackError){logLockEvent("file lock onLost callback threw",{event:"file_lock_on_lost_threw",...fields,name:callbackError instanceof Error?callbackError.name:typeof callbackError,code:callbackError?.code})}}});return{release:async()=>{released||(released=!0,lostError===void 0&&await releaseLock())},lost:()=>lostError!==void 0,assertHeld:()=>{if(lostError!==void 0)throw new FileLockLostError(path,lostError)}}}export{lockWithLossHandling};
2
+ import{require_proper_lockfile}from"./chunk-GZVCRV7I.js";import{appendDebugLogEntry}from"./chunk-EBZ6IP4V.js";import{__toESM}from"./chunk-IKOFCODM.js";var import_proper_lockfile=__toESM(require_proper_lockfile(),1);import{createHash}from"node:crypto";import{basename}from"node:path";var FileLockLostError=class extends Error{constructor(path,cause){super(`File lock on ${basename(path)} was lost before the write committed: the lock was removed or reclaimed by another process. The write was skipped.`,{cause}),this.code="ELOCKLOST",this.name="FileLockLostError",this.path=path}};function lockLogFields(path){return{lock:basename(path),lockId:createHash("sha256").update(path).digest("hex").slice(0,12)}}function logLockEvent(header,fields){try{appendDebugLogEntry(header,JSON.stringify(fields))}catch{}}async function lockWithLossHandling(path,options={}){let{onLost,...lockOptions}=options,released=!1,lostError,releaseLock=await import_proper_lockfile.default.lock(path,{...lockOptions,onCompromised:error=>{if(released||lostError!==void 0)return;lostError=error;let fields=lockLogFields(lockOptions.lockfilePath??`${path}.lock`);logLockEvent("file lock lost while held",{event:"file_lock_lost",...fields,code:error.code});try{onLost?.(error)}catch(callbackError){logLockEvent("file lock onLost callback threw",{event:"file_lock_on_lost_threw",...fields,name:callbackError instanceof Error?callbackError.name:typeof callbackError,code:callbackError?.code})}}});return{release:async()=>{released||(released=!0,lostError===void 0&&await releaseLock())},lost:()=>lostError!==void 0,assertHeld:()=>{if(lostError!==void 0)throw new FileLockLostError(path,lostError)}}}export{lockWithLossHandling};
@@ -1,4 +1,4 @@
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{theme}from"./chunk-BW4YXS7X.js";import{Container,Input,Spacer,Text,getKeybindings,nextRenderRevision}from"./chunk-D2ROBVZ4.js";var DynamicBorder=class{constructor(color=str=>theme.fg("border",str)){this.revision=nextRenderRevision(),this.color=color}invalidate(){this.revision=nextRenderRevision()}getRenderRevision(){return this.revision}render(width){return[this.color("\u2500".repeat(Math.max(1,width)))]}};var KEY_DISPLAY_ALIASES=new Map([["escape","esc"]]);function formatKeyPart(part,options){let lowerPart=part.toLowerCase(),displayPart=KEY_DISPLAY_ALIASES.get(lowerPart)??(process.platform==="darwin"&&lowerPart==="alt"?"option":part);return options.capitalize?displayPart.charAt(0).toUpperCase()+displayPart.slice(1):displayPart}function formatKeyText(key,options={}){return key.split("/").map(k=>k.split("+").map(part=>formatKeyPart(part,options)).join("+")).join("/")}function formatKeys(keys,options={}){return keys.length===0?"":formatKeyText(keys.join("/"),options)}function keyText(keybinding){return formatKeys(getKeybindings().getKeys(keybinding))}function keyDisplayText(keybinding){return formatKeys(getKeybindings().getKeys(keybinding),{capitalize:!0})}function keyHint(keybinding,description){return theme.fg("dim",keyText(keybinding))+theme.fg("muted",` ${description}`)}function rawKeyHint(key,description){return theme.fg("dim",formatKeyText(key))+theme.fg("muted",` ${description}`)}var stdoutTakeoverState,stderrTakeoverState,visibleStderrObservation;var rawStdoutWriteTail=Promise.resolve();function getRawStdoutWrite(){return stdoutTakeoverState?stdoutTakeoverState.rawStdoutWrite:process.stdout.write.bind(process.stdout)}async function writeRawStdoutChunk(text){for(;;)try{await new Promise((resolve,reject)=>{try{getRawStdoutWrite()(text,error=>{error?reject(error):resolve()})}catch(error){reject(error instanceof Error?error:new Error(String(error)))}});return}catch(error){let writeError=error instanceof Error?error:new Error(String(error)),code=writeError.code;if(code!=="ENOBUFS"&&code!=="EAGAIN"&&code!=="EWOULDBLOCK")throw writeError;await new Promise(resolve=>setTimeout(resolve,10))}}function takeOverStdout(){if(stdoutTakeoverState)return;let rawStdoutWrite=process.stdout.write.bind(process.stdout),rawStderrWrite=process.stderr.write.bind(process.stderr),originalStdoutWrite=process.stdout.write;process.stdout.write=((chunk,encodingOrCallback,callback)=>typeof encodingOrCallback=="function"?rawStderrWrite(String(chunk),encodingOrCallback):rawStderrWrite(String(chunk),callback)),stdoutTakeoverState={rawStdoutWrite,rawStderrWrite,originalStdoutWrite}}function restoreStdout(){stdoutTakeoverState&&(process.stdout.write=stdoutTakeoverState.originalStdoutWrite,stdoutTakeoverState=void 0)}function stdioChunkToString(chunk,encoding){return typeof chunk=="string"?chunk:Buffer.from(chunk).toString(encoding)}function normalizeThrownError(error){return error instanceof Error?error:new Error(String(error))}function writeOriginalStderr(state,text){text.length!==0&&state.originalStderrWrite.call(process.stderr,text)}function observeVisibleStderrWrites(listener){if(!visibleStderrObservation){let original=stderrTakeoverState?.originalStderrWrite??process.stderr.write,listeners=new Set,writer=function(...args){for(let notify2 of listeners)notify2();return Reflect.apply(original,this,args)};visibleStderrObservation={original,writer,listeners},stderrTakeoverState?stderrTakeoverState.originalStderrWrite=writer:process.stderr.write=writer}let observation=visibleStderrObservation,notify=()=>listener();return observation.listeners.add(notify),()=>{!observation.listeners.delete(notify)||observation.listeners.size>0||(stderrTakeoverState?.originalStderrWrite===observation.writer&&(stderrTakeoverState.originalStderrWrite=observation.original),process.stderr.write===observation.writer&&(process.stderr.write=observation.original),visibleStderrObservation=void 0)}}function takeOverStderr(onHiddenDiagnostic,formatHiddenDiagnosticFallback){if(stderrTakeoverState)return;let originalStderrWrite=process.stderr.write;process.stderr.write=((chunk,encodingOrCallback,callback)=>{let text=stdioChunkToString(chunk,typeof encodingOrCallback=="string"?encodingOrCallback:void 0);try{stderrTakeoverState?.onHiddenDiagnostic?.(text)}catch(error){let state=stderrTakeoverState;if(state){let fallbackText=state.formatHiddenDiagnosticFallback?.(text)??text;writeOriginalStderr(state,fallbackText)}let writeError=normalizeThrownError(error);return typeof encodingOrCallback=="function"?encodingOrCallback(writeError):callback?.(writeError),!1}return typeof encodingOrCallback=="function"?encodingOrCallback(null):callback?.(null),!0}),stderrTakeoverState={formatHiddenDiagnosticFallback,originalStderrWrite,onHiddenDiagnostic}}function restoreStderr(){stderrTakeoverState&&(process.stderr.write=stderrTakeoverState.originalStderrWrite,stderrTakeoverState=void 0)}function isStdoutTakenOver(){return stdoutTakeoverState!==void 0}function writeRawStdout(text){text.length!==0&&(rawStdoutWriteTail=rawStdoutWriteTail.then(()=>writeRawStdoutChunk(text)),rawStdoutWriteTail.catch(()=>{process.exit(1)}))}async function waitForRawStdoutBackpressure(){for(;;){let tail=rawStdoutWriteTail;if(await tail,tail===rawStdoutWriteTail)return}}async function flushRawStdout(){await waitForRawStdoutBackpressure(),await writeRawStdoutChunk("")}var SecretInputUnavailableError=class extends Error{constructor(reason){super("This client cannot collect a secret; use the TUI or the host's settings route."),this.code="secret_input_unavailable",this.name="SecretInputUnavailableError",this.reason=reason}};function resolveSecretInputTimeout(opts){let timeout=opts?.timeout??18e5;if(!Number.isFinite(timeout)||timeout<=0)throw new Error("Invalid secret input timeout");return timeout}function armSecretInputDeadline(deadline,expire){let timer,check=()=>{let remaining=deadline-Date.now();remaining<=0?expire():timer=setTimeout(check,Math.min(remaining,2147483647))};return timer=setTimeout(check,Math.max(0,Math.min(deadline-Date.now(),2**31-1))),()=>clearTimeout(timer)}function isSecretInputValue(value){return!/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/u.test(value)}var CountdownTimer=class{constructor(timeoutMs,tui,onTick,onExpire){this.tui=tui,this.onTick=onTick,this.onExpire=onExpire,this.remainingSeconds=Math.ceil(timeoutMs/1e3),this.onTick(this.remainingSeconds),this.intervalId=setInterval(()=>{this.remainingSeconds--,this.onTick(this.remainingSeconds),this.tui?.requestRender(),this.remainingSeconds<=0&&(this.dispose(),this.onExpire())},1e3)}dispose(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=void 0)}};var ExtensionInputComponent=class extends Container{get focused(){return this._focused}set focused(value){this._focused=value,this.input.focused=value}constructor(title,_placeholder,onSubmit,onCancel,opts){if(super(),this._focused=!1,this.secret=opts?.secret===!0,this.onSubmitCallback=onSubmit,this.onCancelCallback=onCancel,this.baseTitle=title,this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.titleText=new Text(theme.fg("accent",title),1,0),this.addChild(this.titleText),opts?.description&&(this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("text",opts.description),1,0))),this.addChild(new Spacer(1)),this.secret){let deadline=opts?.deadlineAtMs??Date.now()+(opts?.timeout??18e5);this.secretTimer=armSecretInputDeadline(deadline,()=>this.onCancelCallback())}else opts?.timeout&&opts.timeout>0&&opts.tui&&(this.countdown=new CountdownTimer(opts.timeout,opts.tui,s=>this.titleText.setText(theme.fg("accent",`${this.baseTitle} (${s}s)`)),()=>this.onCancelCallback()));this.input=new Input({secret:this.secret,onInvalidInput:()=>this.titleText.setText(theme.fg("warning","Secret input must be a single line without control characters."))}),this.secret&&(this.input.onSubmit=value=>this.onSubmitCallback(value),this.input.onEscape=()=>this.onCancelCallback()),opts?.initialValue&&this.input.handleInput(opts.initialValue),this.addChild(this.input),this.addChild(new Spacer(1)),this.addChild(new Text(`${keyHint("tui.select.confirm","submit")} ${keyHint("tui.select.cancel","cancel")}`,1,0)),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder)}handleInput(keyData){if(this.secret){this.input.handleInput(keyData);return}let kb=getKeybindings();kb.matches(keyData,"tui.select.confirm")||keyData===`
2
+ import{theme}from"./chunk-A4KOQUHT.js";import{Container,Input,Spacer,Text,getKeybindings,nextRenderRevision}from"./chunk-D2ROBVZ4.js";var DynamicBorder=class{constructor(color=str=>theme.fg("border",str)){this.revision=nextRenderRevision(),this.color=color}invalidate(){this.revision=nextRenderRevision()}getRenderRevision(){return this.revision}render(width){return[this.color("\u2500".repeat(Math.max(1,width)))]}};var KEY_DISPLAY_ALIASES=new Map([["escape","esc"]]);function formatKeyPart(part,options){let lowerPart=part.toLowerCase(),displayPart=KEY_DISPLAY_ALIASES.get(lowerPart)??(process.platform==="darwin"&&lowerPart==="alt"?"option":part);return options.capitalize?displayPart.charAt(0).toUpperCase()+displayPart.slice(1):displayPart}function formatKeyText(key,options={}){return key.split("/").map(k=>k.split("+").map(part=>formatKeyPart(part,options)).join("+")).join("/")}function formatKeys(keys,options={}){return keys.length===0?"":formatKeyText(keys.join("/"),options)}function keyText(keybinding){return formatKeys(getKeybindings().getKeys(keybinding))}function keyDisplayText(keybinding){return formatKeys(getKeybindings().getKeys(keybinding),{capitalize:!0})}function keyHint(keybinding,description){return theme.fg("dim",keyText(keybinding))+theme.fg("muted",` ${description}`)}function rawKeyHint(key,description){return theme.fg("dim",formatKeyText(key))+theme.fg("muted",` ${description}`)}var stdoutTakeoverState,stderrTakeoverState,visibleStderrObservation;var rawStdoutWriteTail=Promise.resolve();function getRawStdoutWrite(){return stdoutTakeoverState?stdoutTakeoverState.rawStdoutWrite:process.stdout.write.bind(process.stdout)}async function writeRawStdoutChunk(text){for(;;)try{await new Promise((resolve,reject)=>{try{getRawStdoutWrite()(text,error=>{error?reject(error):resolve()})}catch(error){reject(error instanceof Error?error:new Error(String(error)))}});return}catch(error){let writeError=error instanceof Error?error:new Error(String(error)),code=writeError.code;if(code!=="ENOBUFS"&&code!=="EAGAIN"&&code!=="EWOULDBLOCK")throw writeError;await new Promise(resolve=>setTimeout(resolve,10))}}function takeOverStdout(){if(stdoutTakeoverState)return;let rawStdoutWrite=process.stdout.write.bind(process.stdout),rawStderrWrite=process.stderr.write.bind(process.stderr),originalStdoutWrite=process.stdout.write;process.stdout.write=((chunk,encodingOrCallback,callback)=>typeof encodingOrCallback=="function"?rawStderrWrite(String(chunk),encodingOrCallback):rawStderrWrite(String(chunk),callback)),stdoutTakeoverState={rawStdoutWrite,rawStderrWrite,originalStdoutWrite}}function restoreStdout(){stdoutTakeoverState&&(process.stdout.write=stdoutTakeoverState.originalStdoutWrite,stdoutTakeoverState=void 0)}function stdioChunkToString(chunk,encoding){return typeof chunk=="string"?chunk:Buffer.from(chunk).toString(encoding)}function normalizeThrownError(error){return error instanceof Error?error:new Error(String(error))}function writeOriginalStderr(state,text){text.length!==0&&state.originalStderrWrite.call(process.stderr,text)}function observeVisibleStderrWrites(listener){if(!visibleStderrObservation){let original=stderrTakeoverState?.originalStderrWrite??process.stderr.write,listeners=new Set,writer=function(...args){for(let notify2 of listeners)notify2();return Reflect.apply(original,this,args)};visibleStderrObservation={original,writer,listeners},stderrTakeoverState?stderrTakeoverState.originalStderrWrite=writer:process.stderr.write=writer}let observation=visibleStderrObservation,notify=()=>listener();return observation.listeners.add(notify),()=>{!observation.listeners.delete(notify)||observation.listeners.size>0||(stderrTakeoverState?.originalStderrWrite===observation.writer&&(stderrTakeoverState.originalStderrWrite=observation.original),process.stderr.write===observation.writer&&(process.stderr.write=observation.original),visibleStderrObservation=void 0)}}function takeOverStderr(onHiddenDiagnostic,formatHiddenDiagnosticFallback){if(stderrTakeoverState)return;let originalStderrWrite=process.stderr.write;process.stderr.write=((chunk,encodingOrCallback,callback)=>{let text=stdioChunkToString(chunk,typeof encodingOrCallback=="string"?encodingOrCallback:void 0);try{stderrTakeoverState?.onHiddenDiagnostic?.(text)}catch(error){let state=stderrTakeoverState;if(state){let fallbackText=state.formatHiddenDiagnosticFallback?.(text)??text;writeOriginalStderr(state,fallbackText)}let writeError=normalizeThrownError(error);return typeof encodingOrCallback=="function"?encodingOrCallback(writeError):callback?.(writeError),!1}return typeof encodingOrCallback=="function"?encodingOrCallback(null):callback?.(null),!0}),stderrTakeoverState={formatHiddenDiagnosticFallback,originalStderrWrite,onHiddenDiagnostic}}function restoreStderr(){stderrTakeoverState&&(process.stderr.write=stderrTakeoverState.originalStderrWrite,stderrTakeoverState=void 0)}function isStdoutTakenOver(){return stdoutTakeoverState!==void 0}function writeRawStdout(text){text.length!==0&&(rawStdoutWriteTail=rawStdoutWriteTail.then(()=>writeRawStdoutChunk(text)),rawStdoutWriteTail.catch(()=>{process.exit(1)}))}async function waitForRawStdoutBackpressure(){for(;;){let tail=rawStdoutWriteTail;if(await tail,tail===rawStdoutWriteTail)return}}async function flushRawStdout(){await waitForRawStdoutBackpressure(),await writeRawStdoutChunk("")}var SecretInputUnavailableError=class extends Error{constructor(reason){super("This client cannot collect a secret; use the TUI or the host's settings route."),this.code="secret_input_unavailable",this.name="SecretInputUnavailableError",this.reason=reason}};function resolveSecretInputTimeout(opts){let timeout=opts?.timeout??18e5;if(!Number.isFinite(timeout)||timeout<=0)throw new Error("Invalid secret input timeout");return timeout}function armSecretInputDeadline(deadline,expire){let timer,check=()=>{let remaining=deadline-Date.now();remaining<=0?expire():timer=setTimeout(check,Math.min(remaining,2147483647))};return timer=setTimeout(check,Math.max(0,Math.min(deadline-Date.now(),2**31-1))),()=>clearTimeout(timer)}function isSecretInputValue(value){return!/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/u.test(value)}var CountdownTimer=class{constructor(timeoutMs,tui,onTick,onExpire){this.tui=tui,this.onTick=onTick,this.onExpire=onExpire,this.remainingSeconds=Math.ceil(timeoutMs/1e3),this.onTick(this.remainingSeconds),this.intervalId=setInterval(()=>{this.remainingSeconds--,this.onTick(this.remainingSeconds),this.tui?.requestRender(),this.remainingSeconds<=0&&(this.dispose(),this.onExpire())},1e3)}dispose(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=void 0)}};var ExtensionInputComponent=class extends Container{get focused(){return this._focused}set focused(value){this._focused=value,this.input.focused=value}constructor(title,_placeholder,onSubmit,onCancel,opts){if(super(),this._focused=!1,this.secret=opts?.secret===!0,this.onSubmitCallback=onSubmit,this.onCancelCallback=onCancel,this.baseTitle=title,this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.titleText=new Text(theme.fg("accent",title),1,0),this.addChild(this.titleText),opts?.description&&(this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("text",opts.description),1,0))),this.addChild(new Spacer(1)),this.secret){let deadline=opts?.deadlineAtMs??Date.now()+(opts?.timeout??18e5);this.secretTimer=armSecretInputDeadline(deadline,()=>this.onCancelCallback())}else opts?.timeout&&opts.timeout>0&&opts.tui&&(this.countdown=new CountdownTimer(opts.timeout,opts.tui,s=>this.titleText.setText(theme.fg("accent",`${this.baseTitle} (${s}s)`)),()=>this.onCancelCallback()));this.input=new Input({secret:this.secret,onInvalidInput:()=>this.titleText.setText(theme.fg("warning","Secret input must be a single line without control characters."))}),this.secret&&(this.input.onSubmit=value=>this.onSubmitCallback(value),this.input.onEscape=()=>this.onCancelCallback()),opts?.initialValue&&this.input.handleInput(opts.initialValue),this.addChild(this.input),this.addChild(new Spacer(1)),this.addChild(new Text(`${keyHint("tui.select.confirm","submit")} ${keyHint("tui.select.cancel","cancel")}`,1,0)),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder)}handleInput(keyData){if(this.secret){this.input.handleInput(keyData);return}let kb=getKeybindings();kb.matches(keyData,"tui.select.confirm")||keyData===`
3
3
  `?this.onSubmitCallback(this.input.getValue()):kb.matches(keyData,"tui.select.cancel")?this.onCancelCallback():this.input.handleInput(keyData)}dispose(){this.countdown?.dispose(),this.secretTimer?.(),this.secret&&this.input.dispose(),this.onSubmitCallback=()=>{},this.onCancelCallback=()=>{}}};var ExtensionSelectorComponent=class _ExtensionSelectorComponent extends Container{static{this.DEFAULT_MAX_VISIBLE_OPTIONS=10}constructor(title,options,onSelect,onCancel,opts){super(),this.selectedIndex=0,this.answerSettled=!1,this.options=options,this.onSelectCallback=onSelect,this.onCancelCallback=onCancel,this.onToggleToolsExpanded=opts?.onToggleToolsExpanded,this.baseTitle=title,this.maxVisibleOptions=opts?.tui?Math.max(5,Math.floor(opts.tui.terminal.rows/2)):_ExtensionSelectorComponent.DEFAULT_MAX_VISIBLE_OPTIONS,this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.titleText=new Text(theme.fg("accent",theme.bold(title)),1,0),this.addChild(this.titleText),opts?.description&&(this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("text",opts.description),1,0))),this.addChild(new Spacer(1)),opts?.timeout&&opts.timeout>0&&opts.tui&&(this.countdown=new CountdownTimer(opts.timeout,opts.tui,s=>this.titleText.setText(theme.fg("accent",theme.bold(`${this.baseTitle} (${s}s)`))),()=>this.onCancelCallback())),this.listContainer=new Container,this.addChild(this.listContainer),this.addChild(new Spacer(1)),this.addChild(new Text(rawKeyHint("\u2191\u2193","navigate")+" "+keyHint("tui.select.confirm","select")+" "+keyHint("tui.select.cancel","cancel"),1,0)),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder),this.updateList()}updateList(){this.listContainer.clear();let count=this.options.length,startIndex=Math.max(0,Math.min(this.selectedIndex-Math.floor(this.maxVisibleOptions/2),count-this.maxVisibleOptions)),endIndex=Math.min(startIndex+this.maxVisibleOptions,count);startIndex>0&&this.listContainer.addChild(new Text(theme.fg("muted",` \u2026 ${startIndex} more above`),1,0));for(let i=startIndex;i<endIndex;i++){let text=i===this.selectedIndex?theme.fg("accent","\u2192 ")+theme.fg("accent",this.options[i]):` ${theme.fg("text",this.options[i])}`;this.listContainer.addChild(new Text(text,1,0))}endIndex<count&&this.listContainer.addChild(new Text(theme.fg("muted",` \u2026 ${count-endIndex} more below`),1,0))}handleInput(keyData){if(this.answerSettled)return;let kb=getKeybindings();if(kb.matches(keyData,"app.tools.expand"))this.onToggleToolsExpanded?.();else if(kb.matches(keyData,"tui.select.up")||keyData==="k")this.selectedIndex=Math.max(0,this.selectedIndex-1),this.updateList();else if(kb.matches(keyData,"tui.select.down")||keyData==="j")this.selectedIndex=Math.min(this.options.length-1,this.selectedIndex+1),this.updateList();else if(kb.matches(keyData,"tui.select.confirm")||keyData===`
4
4
  `){let selected=this.options[this.selectedIndex];selected&&this.onSelectCallback(selected)}else kb.matches(keyData,"tui.select.cancel")&&this.onCancelCallback()}dispose(){this.answerSettled=!0,this.countdown?.dispose()}};export{DynamicBorder,formatKeyText,keyText,keyDisplayText,keyHint,rawKeyHint,takeOverStdout,restoreStdout,observeVisibleStderrWrites,takeOverStderr,restoreStderr,isStdoutTakenOver,writeRawStdout,waitForRawStdoutBackpressure,flushRawStdout,SecretInputUnavailableError,resolveSecretInputTimeout,armSecretInputDeadline,isSecretInputValue,CountdownTimer,ExtensionInputComponent,ExtensionSelectorComponent};
@@ -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{lockWithLossHandling}from"./chunk-F7GBSQRV.js";import{external_exports}from"./chunk-KUPQO7MC.js";import{CredentialStoreBusyError,FILE_STORAGE_LOCK_OPTIONS,FILE_STORAGE_LOCK_RETRY_BUDGET_MS,isLockError}from"./chunk-7X72IACK.js";import{extractChatGptSubscriptionAccountId}from"./chunk-Y7QPP7BG.js";import{getAgentDir}from"./chunk-ISZ4EWIS.js";import{createHmac,randomBytes,randomUUID}from"node:crypto";import{existsSync as existsSync2,mkdirSync}from"node:fs";import{dirname,join}from"node:path";import{chmodSync,existsSync,readFileSync,renameSync,rmSync,statSync,writeFileSync}from"node:fs";var FILE_WRITE_OPTIONS={encoding:"utf-8",mode:384},RETRY_MIN_DELAY_MS=25,RETRY_MAX_DELAY_MS=250,queueTails=new Map;function readStateFile(path){try{return readFileSync(path,"utf-8")}catch(error){if(error instanceof Error&&"code"in error&&error.code==="ENOENT")return;throw error}}var TRANSIENT_RENAME_CODES=new Set(["EPERM","EBUSY","EACCES"]),RENAME_RETRY_DELAYS_MS=[10,20,40,80,160];function isTransientRenameError(error){return error instanceof Error&&"code"in error&&typeof error.code=="string"&&TRANSIENT_RENAME_CODES.has(error.code)}async function replaceFile(temporary,path){let startedAt=Date.now();for(let delayMs of[...RENAME_RETRY_DELAYS_MS,void 0])try{renameSync(temporary,path);return}catch(error){if(!isTransientRenameError(error))throw error;if(delayMs===void 0)throw new CredentialStoreBusyError(path,Date.now()-startedAt,error);await sleep(delayMs)}}async function writeStateFileAtomic(path,content){let temporary=`${path}.${process.pid}.tmp`;try{writeFileSync(temporary,content,FILE_WRITE_OPTIONS),existsSync(path)&&chmodSync(temporary,statSync(path).mode&511),await replaceFile(temporary,path)}catch(error){throw rmSync(temporary,{force:!0}),error}}function sleep(ms){return new Promise(resolve=>setTimeout(resolve,ms))}async function reachedBefore(turn,deadline){let timer,expired=new Promise(resolve=>{timer=setTimeout(()=>resolve(!1),Math.max(0,deadline-Date.now()))});try{return await Promise.race([turn.then(()=>!0),expired])}finally{clearTimeout(timer)}}async function lockFileBefore(path,startedAt,deadline){let attempt=0;for(;;)try{return await lockWithLossHandling(path,FILE_STORAGE_LOCK_OPTIONS)}catch(error){if(!isLockError(error))throw error;let remainingMs=deadline-Date.now();if(remainingMs<=0)throw new CredentialStoreBusyError(path,Date.now()-startedAt,error);let ceilingMs=Math.min(RETRY_MIN_DELAY_MS*2**attempt,RETRY_MAX_DELAY_MS);attempt++,await sleep(Math.min(remainingMs,Math.max(1,Math.random()*ceilingMs)))}}async function acquireStateFileLock(path,budgetMs){let startedAt=Date.now(),deadline=startedAt+budgetMs,previous=queueTails.get(path)??Promise.resolve(),endTurn=()=>{},turn=new Promise(resolve=>{endTurn=resolve}),tail=previous.then(()=>turn);queueTails.set(path,tail);let finishTurn=()=>{endTurn(),queueTails.get(path)===tail&&queueTails.delete(path)};try{if(!await reachedBefore(previous,deadline))throw new CredentialStoreBusyError(path,Date.now()-startedAt);let held=await lockFileBefore(path,startedAt,deadline);return{assertHeld:held.assertHeld,release:async()=>{try{await held.release()}finally{finishTurn()}}}}catch(error){throw finishTurn(),error}}var CREDENTIAL_POOL_STATE_FILENAME="credential-pool-state.json",HEX_256_BIT=/^[0-9a-f]{64}$/,leaseSchema=external_exports.looseObject({id:external_exports.string().min(1).max(128),expiresAt:external_exports.number().int().positive()}),slotStateSchema=external_exports.looseObject({stateVersion:external_exports.number().int().nonnegative(),blockedUntil:external_exports.number().int().positive().optional(),blockReason:external_exports.enum(["auth_error","rate_limit","account_disabled"]).optional(),failureCount:external_exports.number().int().nonnegative().optional(),lastSuccessAt:external_exports.number().int().positive().optional(),credentialRevision:external_exports.string().regex(HEX_256_BIT).optional(),lease:leaseSchema.optional(),modelBlocks:external_exports.record(external_exports.string().min(1),external_exports.looseObject({blockedUntil:external_exports.number().int().positive()})).optional()});var documentSchema=external_exports.looseObject({schemaVersion:external_exports.literal(1),installationKey:external_exports.string().regex(HEX_256_BIT),providers:external_exports.record(external_exports.string(),external_exports.looseObject({lanes:external_exports.record(external_exports.string(),external_exports.looseObject({slots:external_exports.record(external_exports.string(),slotStateSchema)}))}))});function credentialPoolStatePath(agentDir=getAgentDir()){return join(agentDir,CREDENTIAL_POOL_STATE_FILENAME)}function freshDocument(){return{schemaVersion:1,installationKey:randomBytes(32).toString("hex"),providers:{}}}function serialize(document){return JSON.stringify(document,null,2)}function parseDocument(content){if(content!==void 0)try{let parsed=documentSchema.safeParse(JSON.parse(content));return parsed.success?parsed.data:void 0}catch(error){if(error instanceof SyntaxError)return;throw error}}function applicableStoredState(persisted,revisions){if(persisted!==void 0){if(persisted.credentialRevision===revisions.material)return persisted;if(persisted.blockReason!=="auth_error")return persisted.credentialRevision===revisions.account?persisted:void 0}}function oauthAccountIdentity(access){if(access===void 0)return"";let accountId=extractChatGptSubscriptionAccountId(access);return accountId===void 0?"":`${accountId}\0${jwtSubject(access)??""}`}function jwtSubject(token){try{let encoded=token.split(".")[1];if(encoded===void 0)return;let base64=encoded.replaceAll("-","+").replaceAll("_","/"),payload=JSON.parse(atob(base64.padEnd(Math.ceil(base64.length/4)*4,"="))),subject=payload!==null&&typeof payload=="object"?Reflect.get(payload,"sub"):void 0;return typeof subject=="string"&&subject.length>0?subject:void 0}catch{return}}function slotHealth(state,now){return state?state.blockReason==="account_disabled"||state.blockedUntil!==void 0&&state.blockedUntil>now?"blocked":state.blockedUntil!==void 0&&state.lease!==void 0&&state.lease.expiresAt>now?"half_open":"ready":"ready"}var CredentialSlotRepository=class{constructor(path=credentialPoolStatePath(),options={}){this.path=path,this.lockWaitBudgetMs=options.lockWaitBudgetMs??FILE_STORAGE_LOCK_RETRY_BUDGET_MS}async readDocument(){let stored=parseDocument(readStateFile(this.path));if(stored!==void 0)return stored;try{return await this.withDocument(document=>({result:document}))}catch(error){if(error instanceof CredentialStoreBusyError)return freshDocument();throw error}}async withDocument(fn){existsSync2(this.path)||mkdirSync(dirname(this.path),{recursive:!0,mode:448});let lock=await acquireStateFileLock(this.path,this.lockWaitBudgetMs);try{let stored=parseDocument(readStateFile(this.path)),document=stored??freshDocument(),{result,next}=fn(document);return(next!==void 0||stored===void 0)&&(lock.assertHeld(),await writeStateFileAtomic(this.path,serialize(next??document))),result}finally{await lock.release()}}async installationKey(){return(await this.readDocument()).installationKey}async envCredentialRevision(envVarName,envValue){let key=await this.installationKey();return createHmac("sha256",key).update(`${envVarName}\0${envValue}`).digest("hex")}async storedCredentialRevision(providerId,slotName,material){let key=await this.installationKey();return createHmac("sha256",key).update(`${providerId}\0${slotName}\0${material.key??""}\0${material.access??""}\0${material.refresh??""}`).digest("hex")}async storedSlotRevisions(providerId,slotName,material){let key=await this.installationKey();return{account:createHmac("sha256",key).update(`account\0${providerId}\0${slotName}\0${material.key??""}\0${material.key===void 0?oauthAccountIdentity(material.access):""}`).digest("hex"),material:await this.storedCredentialRevision(providerId,slotName,material)}}async listSlots(providerId,laneId){return{...(await this.readDocument()).providers[providerId]?.lanes[laneId]?.slots}}async clearProvider(providerId){return(await this.readDocument()).providers[providerId]===void 0?!1:this.withDocument(document=>{if(document.providers[providerId]===void 0)return{result:!1};let{[providerId]:_retired,...providers}=document.providers;return{result:!0,next:{...document,providers}}})}async mutateSlotState(providerId,laneId,slotId,fn){return this.withDocument(document=>{let provider=document.providers[providerId]??{lanes:{}},lane=provider.lanes[laneId]??{slots:{}},current=lane.slots[slotId],mutated=fn(current),slots={...lane.slots},result;mutated===void 0?delete slots[slotId]:(result={...mutated,stateVersion:(current?.stateVersion??0)+1},slots[slotId]=result);let next={...document,providers:{...document.providers,[providerId]:{...provider,lanes:{...provider.lanes,[laneId]:{...lane,slots}}}}};return{result,next}})}};async function acquireHalfOpenLease(repository,providerId,laneId,slotId,options={}){let now=options.now??Date.now(),leaseTtlMs=options.leaseTtlMs??3e4,lease;return await repository.mutateSlotState(providerId,laneId,slotId,current=>{if(!current)return current;let expired=current.blockedUntil!==void 0&&current.blockedUntil<=now,leaseLive=current.lease!==void 0&&current.lease.expiresAt>now;return!expired||leaseLive?current:(lease={leaseId:randomUUID(),expiresAt:now+leaseTtlMs},{...current,lease:{id:lease.leaseId,expiresAt:lease.expiresAt}})}),lease}export{CREDENTIAL_POOL_STATE_FILENAME,credentialPoolStatePath,applicableStoredState,slotHealth,CredentialSlotRepository,acquireHalfOpenLease};
2
+ import{lockWithLossHandling}from"./chunk-QPYDQ4QK.js";import{external_exports}from"./chunk-KUPQO7MC.js";import{CredentialStoreBusyError,FILE_STORAGE_LOCK_OPTIONS,FILE_STORAGE_LOCK_RETRY_BUDGET_MS,isLockError}from"./chunk-7X72IACK.js";import{extractChatGptSubscriptionAccountId}from"./chunk-Y7QPP7BG.js";import{getAgentDir}from"./chunk-SODMQEHO.js";import{createHmac,randomBytes,randomUUID}from"node:crypto";import{existsSync as existsSync2,mkdirSync}from"node:fs";import{dirname,join}from"node:path";import{chmodSync,existsSync,readFileSync,renameSync,rmSync,statSync,writeFileSync}from"node:fs";var FILE_WRITE_OPTIONS={encoding:"utf-8",mode:384},RETRY_MIN_DELAY_MS=25,RETRY_MAX_DELAY_MS=250,queueTails=new Map;function readStateFile(path){try{return readFileSync(path,"utf-8")}catch(error){if(error instanceof Error&&"code"in error&&error.code==="ENOENT")return;throw error}}var TRANSIENT_RENAME_CODES=new Set(["EPERM","EBUSY","EACCES"]),RENAME_RETRY_DELAYS_MS=[10,20,40,80,160];function isTransientRenameError(error){return error instanceof Error&&"code"in error&&typeof error.code=="string"&&TRANSIENT_RENAME_CODES.has(error.code)}async function replaceFile(temporary,path){let startedAt=Date.now();for(let delayMs of[...RENAME_RETRY_DELAYS_MS,void 0])try{renameSync(temporary,path);return}catch(error){if(!isTransientRenameError(error))throw error;if(delayMs===void 0)throw new CredentialStoreBusyError(path,Date.now()-startedAt,error);await sleep(delayMs)}}async function writeStateFileAtomic(path,content){let temporary=`${path}.${process.pid}.tmp`;try{writeFileSync(temporary,content,FILE_WRITE_OPTIONS),existsSync(path)&&chmodSync(temporary,statSync(path).mode&511),await replaceFile(temporary,path)}catch(error){throw rmSync(temporary,{force:!0}),error}}function sleep(ms){return new Promise(resolve=>setTimeout(resolve,ms))}async function reachedBefore(turn,deadline){let timer,expired=new Promise(resolve=>{timer=setTimeout(()=>resolve(!1),Math.max(0,deadline-Date.now()))});try{return await Promise.race([turn.then(()=>!0),expired])}finally{clearTimeout(timer)}}async function lockFileBefore(path,startedAt,deadline){let attempt=0;for(;;)try{return await lockWithLossHandling(path,FILE_STORAGE_LOCK_OPTIONS)}catch(error){if(!isLockError(error))throw error;let remainingMs=deadline-Date.now();if(remainingMs<=0)throw new CredentialStoreBusyError(path,Date.now()-startedAt,error);let ceilingMs=Math.min(RETRY_MIN_DELAY_MS*2**attempt,RETRY_MAX_DELAY_MS);attempt++,await sleep(Math.min(remainingMs,Math.max(1,Math.random()*ceilingMs)))}}async function acquireStateFileLock(path,budgetMs){let startedAt=Date.now(),deadline=startedAt+budgetMs,previous=queueTails.get(path)??Promise.resolve(),endTurn=()=>{},turn=new Promise(resolve=>{endTurn=resolve}),tail=previous.then(()=>turn);queueTails.set(path,tail);let finishTurn=()=>{endTurn(),queueTails.get(path)===tail&&queueTails.delete(path)};try{if(!await reachedBefore(previous,deadline))throw new CredentialStoreBusyError(path,Date.now()-startedAt);let held=await lockFileBefore(path,startedAt,deadline);return{assertHeld:held.assertHeld,release:async()=>{try{await held.release()}finally{finishTurn()}}}}catch(error){throw finishTurn(),error}}var CREDENTIAL_POOL_STATE_FILENAME="credential-pool-state.json",HEX_256_BIT=/^[0-9a-f]{64}$/,leaseSchema=external_exports.looseObject({id:external_exports.string().min(1).max(128),expiresAt:external_exports.number().int().positive()}),slotStateSchema=external_exports.looseObject({stateVersion:external_exports.number().int().nonnegative(),blockedUntil:external_exports.number().int().positive().optional(),blockReason:external_exports.enum(["auth_error","rate_limit","account_disabled"]).optional(),failureCount:external_exports.number().int().nonnegative().optional(),lastSuccessAt:external_exports.number().int().positive().optional(),credentialRevision:external_exports.string().regex(HEX_256_BIT).optional(),lease:leaseSchema.optional(),modelBlocks:external_exports.record(external_exports.string().min(1),external_exports.looseObject({blockedUntil:external_exports.number().int().positive()})).optional()});var documentSchema=external_exports.looseObject({schemaVersion:external_exports.literal(1),installationKey:external_exports.string().regex(HEX_256_BIT),providers:external_exports.record(external_exports.string(),external_exports.looseObject({lanes:external_exports.record(external_exports.string(),external_exports.looseObject({slots:external_exports.record(external_exports.string(),slotStateSchema)}))}))});function credentialPoolStatePath(agentDir=getAgentDir()){return join(agentDir,CREDENTIAL_POOL_STATE_FILENAME)}function freshDocument(){return{schemaVersion:1,installationKey:randomBytes(32).toString("hex"),providers:{}}}function serialize(document){return JSON.stringify(document,null,2)}function parseDocument(content){if(content!==void 0)try{let parsed=documentSchema.safeParse(JSON.parse(content));return parsed.success?parsed.data:void 0}catch(error){if(error instanceof SyntaxError)return;throw error}}function applicableStoredState(persisted,revisions){if(persisted!==void 0){if(persisted.credentialRevision===revisions.material)return persisted;if(persisted.blockReason!=="auth_error")return persisted.credentialRevision===revisions.account?persisted:void 0}}function oauthAccountIdentity(access){if(access===void 0)return"";let accountId=extractChatGptSubscriptionAccountId(access);return accountId===void 0?"":`${accountId}\0${jwtSubject(access)??""}`}function jwtSubject(token){try{let encoded=token.split(".")[1];if(encoded===void 0)return;let base64=encoded.replaceAll("-","+").replaceAll("_","/"),payload=JSON.parse(atob(base64.padEnd(Math.ceil(base64.length/4)*4,"="))),subject=payload!==null&&typeof payload=="object"?Reflect.get(payload,"sub"):void 0;return typeof subject=="string"&&subject.length>0?subject:void 0}catch{return}}function slotHealth(state,now){return state?state.blockReason==="account_disabled"||state.blockedUntil!==void 0&&state.blockedUntil>now?"blocked":state.blockedUntil!==void 0&&state.lease!==void 0&&state.lease.expiresAt>now?"half_open":"ready":"ready"}var CredentialSlotRepository=class{constructor(path=credentialPoolStatePath(),options={}){this.path=path,this.lockWaitBudgetMs=options.lockWaitBudgetMs??FILE_STORAGE_LOCK_RETRY_BUDGET_MS}async readDocument(){let stored=parseDocument(readStateFile(this.path));if(stored!==void 0)return stored;try{return await this.withDocument(document=>({result:document}))}catch(error){if(error instanceof CredentialStoreBusyError)return freshDocument();throw error}}async withDocument(fn){existsSync2(this.path)||mkdirSync(dirname(this.path),{recursive:!0,mode:448});let lock=await acquireStateFileLock(this.path,this.lockWaitBudgetMs);try{let stored=parseDocument(readStateFile(this.path)),document=stored??freshDocument(),{result,next}=fn(document);return(next!==void 0||stored===void 0)&&(lock.assertHeld(),await writeStateFileAtomic(this.path,serialize(next??document))),result}finally{await lock.release()}}async installationKey(){return(await this.readDocument()).installationKey}async envCredentialRevision(envVarName,envValue){let key=await this.installationKey();return createHmac("sha256",key).update(`${envVarName}\0${envValue}`).digest("hex")}async storedCredentialRevision(providerId,slotName,material){let key=await this.installationKey();return createHmac("sha256",key).update(`${providerId}\0${slotName}\0${material.key??""}\0${material.access??""}\0${material.refresh??""}`).digest("hex")}async storedSlotRevisions(providerId,slotName,material){let key=await this.installationKey();return{account:createHmac("sha256",key).update(`account\0${providerId}\0${slotName}\0${material.key??""}\0${material.key===void 0?oauthAccountIdentity(material.access):""}`).digest("hex"),material:await this.storedCredentialRevision(providerId,slotName,material)}}async listSlots(providerId,laneId){return{...(await this.readDocument()).providers[providerId]?.lanes[laneId]?.slots}}async clearProvider(providerId){return(await this.readDocument()).providers[providerId]===void 0?!1:this.withDocument(document=>{if(document.providers[providerId]===void 0)return{result:!1};let{[providerId]:_retired,...providers}=document.providers;return{result:!0,next:{...document,providers}}})}async mutateSlotState(providerId,laneId,slotId,fn){return this.withDocument(document=>{let provider=document.providers[providerId]??{lanes:{}},lane=provider.lanes[laneId]??{slots:{}},current=lane.slots[slotId],mutated=fn(current),slots={...lane.slots},result;mutated===void 0?delete slots[slotId]:(result={...mutated,stateVersion:(current?.stateVersion??0)+1},slots[slotId]=result);let next={...document,providers:{...document.providers,[providerId]:{...provider,lanes:{...provider.lanes,[laneId]:{...lane,slots}}}}};return{result,next}})}};async function acquireHalfOpenLease(repository,providerId,laneId,slotId,options={}){let now=options.now??Date.now(),leaseTtlMs=options.leaseTtlMs??3e4,lease;return await repository.mutateSlotState(providerId,laneId,slotId,current=>{if(!current)return current;let expired=current.blockedUntil!==void 0&&current.blockedUntil<=now,leaseLive=current.lease!==void 0&&current.lease.expiresAt>now;return!expired||leaseLive?current:(lease={leaseId:randomUUID(),expiresAt:now+leaseTtlMs},{...current,lease:{id:lease.leaseId,expiresAt:lease.expiresAt}})}),lease}export{CREDENTIAL_POOL_STATE_FILENAME,credentialPoolStatePath,applicableStoredState,slotHealth,CredentialSlotRepository,acquireHalfOpenLease};