@code-yeongyu/senpi 2026.11.6-2 → 2026.11.9-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 (244) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/dist/bundle/chunks/{bun-extension-importer-RCGPQTI2.js → bun-extension-importer-GQ6IKEXD.js} +2 -2
  3. package/dist/bundle/chunks/{chunk-RQ6CHXQ2.js → chunk-3TZQXZKH.js} +1 -1
  4. package/dist/bundle/chunks/{chunk-QN2BHP3M.js → chunk-44BJPS5I.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-WGRKM3N6.js → chunk-45MVD7BU.js} +1 -1
  6. package/dist/bundle/chunks/chunk-4JIBEZZE.js +106 -0
  7. package/dist/bundle/chunks/{chunk-CF5OGBC4.js → chunk-4NYNMAYF.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-X5ZVYNOL.js → chunk-4UR6UFBH.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-LNPAT22L.js → chunk-527Q2UYM.js} +9 -8
  10. package/dist/bundle/chunks/{chunk-HLM46XEB.js → chunk-622VYTRI.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-D5MRJWUK.js → chunk-7CFORZPE.js} +221 -229
  12. package/dist/bundle/chunks/{chunk-GKAYPJ4E.js → chunk-7PROV6BB.js} +1 -1
  13. package/dist/bundle/chunks/{chunk-4E7GDG4H.js → chunk-7VMEE62L.js} +1 -1
  14. package/dist/bundle/chunks/{chunk-C7OKUC7L.js → chunk-K3UHGDUQ.js} +1 -1
  15. package/dist/bundle/chunks/{chunk-7III44PV.js → chunk-LHSWAJJL.js} +1 -1
  16. package/dist/bundle/chunks/{chunk-47PPZKPO.js → chunk-LM6DOWQH.js} +4 -4
  17. package/dist/bundle/chunks/chunk-LPYBKMPT.js +2 -0
  18. package/dist/bundle/chunks/{chunk-2FDW2LQL.js → chunk-M7GF73FO.js} +2 -2
  19. package/dist/bundle/chunks/{chunk-ECW7VBMB.js → chunk-NDSWTAYJ.js} +1 -1
  20. package/dist/bundle/chunks/{chunk-GSKCWXXG.js → chunk-Q6NR6644.js} +1 -1
  21. package/dist/bundle/chunks/{chunk-TIPKAMSS.js → chunk-SGAFIMAU.js} +1 -1
  22. package/dist/bundle/chunks/{chunk-7PSBD5KS.js → chunk-STGOYIXC.js} +1 -1
  23. package/dist/bundle/chunks/{chunk-DSWDJ7HT.js → chunk-WQ4RBPMS.js} +1 -1
  24. package/dist/bundle/chunks/chunk-XZDCMDUH.js +2 -0
  25. package/dist/bundle/chunks/{chunk-GNSMNSL7.js → chunk-Y5L4UFMI.js} +2 -2
  26. package/dist/bundle/chunks/{cli-main-T74YJGIF.js → cli-main-XBEFQW5A.js} +1 -1
  27. package/dist/bundle/chunks/{dispatch-BAK2YZKD.js → dispatch-VDIYSXQN.js} +1 -1
  28. package/dist/bundle/chunks/{hand-entry-AYRUGE2A.js → hand-entry-QFEY3JMQ.js} +1 -1
  29. package/dist/bundle/chunks/{headless-host-ES74ZB6M.js → headless-host-YXUGONR3.js} +1 -1
  30. package/dist/bundle/chunks/{host-command-YRXZE4TV.js → host-command-VHX2ILLM.js} +1 -1
  31. package/dist/bundle/chunks/{host-session-command-N7IN7ZDV.js → host-session-command-P3MRW63Z.js} +1 -1
  32. package/dist/bundle/chunks/interactive-mode-YGL3QHU6.js +2 -0
  33. package/dist/bundle/chunks/main-5SD4DHMC.js +2 -0
  34. package/dist/bundle/chunks/{multi-session-host-XSUJDHFZ.js → multi-session-host-PGRHY3JP.js} +20 -17
  35. package/dist/bundle/chunks/{package-manager-cli-GLUNPQJU.js → package-manager-cli-SADLU7QX.js} +1 -1
  36. package/dist/bundle/chunks/{role-RRFFHZF5.js → role-4BUU46VW.js} +3 -3
  37. package/dist/bundle/chunks/{rotation-stream-BN2YK2MC.js → rotation-stream-TODBIHXJ.js} +1 -1
  38. package/dist/bundle/chunks/rpc-mode-27TC7W6K.js +2 -0
  39. package/dist/bundle/chunks/{run-attached-tui-W236SEOR.js → run-attached-tui-MXCC5IZR.js} +1 -1
  40. package/dist/bundle/chunks/{runtime-session-OBXYK4PI.js → runtime-session-VO3X4OE3.js} +1 -1
  41. package/dist/bundle/chunks/{schedule-command-B2EJTBOE.js → schedule-command-MX56D6UE.js} +1 -1
  42. package/dist/bundle/chunks/{session-control-endpoint-YIMLHGLG.js → session-control-endpoint-IL6ERD4U.js} +1 -1
  43. package/dist/bundle/chunks/{session-picker-E6ZONUJB.js → session-picker-6VRC25MJ.js} +1 -1
  44. package/dist/bundle/chunks/session-worker.js +114 -110
  45. package/dist/bundle/cli.js +2 -2
  46. package/dist/bundle/index.js +1 -1
  47. package/dist/bundle/rpc-entry.js +1 -1
  48. package/dist/bundle/runtime-manifest.json +1 -1
  49. package/dist/core/agent-session-runtime.d.ts +2 -0
  50. package/dist/core/agent-session-runtime.js +9 -2
  51. package/dist/core/agent-session-services.d.ts +2 -0
  52. package/dist/core/agent-session-services.js +1 -0
  53. package/dist/core/agent-session.d.ts +32 -3
  54. package/dist/core/agent-session.js +142 -29
  55. package/dist/core/credential-pool/rotation-slots.d.ts +3 -3
  56. package/dist/core/credential-pool/state-store.d.ts +1 -1
  57. package/dist/core/egress/classify.d.ts +8 -3
  58. package/dist/core/egress/classify.js +177 -158
  59. package/dist/core/egress/console-redactor.d.ts +7 -0
  60. package/dist/core/egress/console-redactor.js +74 -0
  61. package/dist/core/egress/credentials.d.ts +73 -0
  62. package/dist/core/egress/credentials.js +20 -0
  63. package/dist/core/egress/device-custody.d.ts +1 -1
  64. package/dist/core/egress/device-custody.js +18 -15
  65. package/dist/core/egress/device-proxy-call.d.ts +59 -0
  66. package/dist/core/egress/device-proxy-call.js +148 -0
  67. package/dist/core/egress/device-proxy-lost-calls.d.ts +27 -0
  68. package/dist/core/egress/device-proxy-lost-calls.js +28 -0
  69. package/dist/core/egress/device-proxy-ports.d.ts +49 -0
  70. package/dist/core/egress/device-proxy-ports.js +2 -0
  71. package/dist/core/egress/device-proxy-request.d.ts +34 -0
  72. package/dist/core/egress/device-proxy-request.js +69 -0
  73. package/dist/core/egress/device-proxy-waits.d.ts +40 -0
  74. package/dist/core/egress/device-proxy-waits.js +67 -0
  75. package/dist/core/egress/device-proxy.d.ts +3 -0
  76. package/dist/core/egress/device-proxy.js +214 -0
  77. package/dist/core/egress/endpoint.js +2 -1
  78. package/dist/core/egress/entry-verify.d.ts +13 -0
  79. package/dist/core/egress/entry-verify.js +33 -0
  80. package/dist/core/egress/hpke.d.ts +63 -0
  81. package/dist/core/egress/hpke.js +192 -0
  82. package/dist/core/egress/key-policy-template.d.ts +7 -1
  83. package/dist/core/egress/ledger-schema.d.ts +80 -0
  84. package/dist/core/egress/ledger-schema.js +117 -0
  85. package/dist/core/egress/ledger.d.ts +55 -0
  86. package/dist/core/egress/ledger.js +159 -0
  87. package/dist/core/egress/pinned-infra.d.ts +23 -2
  88. package/dist/core/egress/pinned-infra.js +9 -2
  89. package/dist/core/egress/placement-claim.d.ts +69 -0
  90. package/dist/core/egress/placement-claim.js +115 -0
  91. package/dist/core/egress/pool-state.d.ts +18 -0
  92. package/dist/core/egress/pool-state.js +5 -0
  93. package/dist/core/egress/redact.d.ts +10 -0
  94. package/dist/core/egress/redact.js +134 -0
  95. package/dist/core/egress/sealed-format.d.ts +101 -0
  96. package/dist/core/egress/sealed-format.js +174 -0
  97. package/dist/core/egress/sealed-source.d.ts +35 -0
  98. package/dist/core/egress/sealed-source.js +140 -0
  99. package/dist/core/egress/verified-keys.js +1 -1
  100. package/dist/core/egress/wire.d.ts +228 -0
  101. package/dist/core/egress/wire.js +49 -0
  102. package/dist/core/extensions/builtin/ask-user/escape-residue.d.ts +50 -0
  103. package/dist/core/extensions/builtin/ask-user/escape-residue.js +113 -0
  104. package/dist/core/extensions/builtin/ask-user/extension.js +7 -1
  105. package/dist/core/extensions/builtin/ask-user/resume.js +2 -1
  106. package/dist/core/extensions/builtin/ask-user/tool.d.ts +3 -0
  107. package/dist/core/extensions/builtin/ask-user/tool.js +8 -0
  108. package/dist/core/extensions/builtin/goal/index.js +46 -0
  109. package/dist/core/extensions/builtin/goal/stop-pause.d.ts +1 -0
  110. package/dist/core/extensions/builtin/goal/stop-pause.js +4 -2
  111. package/dist/core/extensions/builtin/monitor-state-event.d.ts +26 -0
  112. package/dist/core/extensions/builtin/monitor-state-event.js +2 -0
  113. package/dist/core/extensions/builtin/permission-system/index.js +10 -4
  114. package/dist/core/extensions/builtin/permission-system/preset-registry.d.ts +2 -0
  115. package/dist/core/extensions/builtin/permission-system/preset-registry.js +11 -0
  116. package/dist/core/extensions/builtin/permission-system/settings.d.ts +2 -0
  117. package/dist/core/extensions/builtin/permission-system/settings.js +10 -1
  118. package/dist/core/extensions/builtin/terminal/background-age.d.ts +25 -0
  119. package/dist/core/extensions/builtin/terminal/background-age.js +91 -0
  120. package/dist/core/extensions/builtin/terminal/extension-state.d.ts +1 -1
  121. package/dist/core/extensions/builtin/terminal/extension-state.js +21 -3
  122. package/dist/core/extensions/builtin/terminal/notify.d.ts +6 -0
  123. package/dist/core/extensions/builtin/terminal/notify.js +39 -5
  124. package/dist/core/extensions/builtin/terminal/session-bundle.d.ts +9 -2
  125. package/dist/core/extensions/builtin/terminal/session-bundle.js +36 -1
  126. package/dist/core/extensions/builtin/terminal/settings.d.ts +2 -0
  127. package/dist/core/extensions/builtin/terminal/settings.js +8 -0
  128. package/dist/core/extensions/builtin/terminal/tools/background-auto-reap.d.ts +15 -0
  129. package/dist/core/extensions/builtin/terminal/tools/background-auto-reap.js +87 -0
  130. package/dist/core/extensions/builtin/terminal/tools/bash.d.ts +3 -1
  131. package/dist/core/extensions/builtin/terminal/tools/bash.js +44 -15
  132. package/dist/core/extensions/builtin/terminal/tools/child-placement.d.ts +8 -0
  133. package/dist/core/extensions/builtin/terminal/tools/child-placement.js +43 -6
  134. package/dist/core/extensions/builtin/terminal/tools/context.d.ts +14 -2
  135. package/dist/core/extensions/bun-extension-importer.js +4 -3
  136. package/dist/core/extensions/bun-extension-load-turns.d.ts +4 -0
  137. package/dist/core/extensions/bun-extension-load-turns.js +45 -0
  138. package/dist/core/extensions/bun-extension-registry.d.ts +1 -0
  139. package/dist/core/extensions/bun-extension-registry.js +19 -1
  140. package/dist/core/extensions/loader.js +5 -0
  141. package/dist/core/extensions/session-control-types.d.ts +15 -0
  142. package/dist/core/extensions/session-control-types.js +11 -0
  143. package/dist/core/extensions/session-dialog-api.d.ts +5 -0
  144. package/dist/core/extensions/session-dialog-api.js +13 -0
  145. package/dist/core/extensions/types.d.ts +14 -1
  146. package/dist/core/external-admission.d.ts +16 -2
  147. package/dist/core/external-admission.js +22 -4
  148. package/dist/core/permission-decision.d.ts +22 -0
  149. package/dist/core/permission-decision.js +53 -0
  150. package/dist/core/permission-mode.d.ts +56 -0
  151. package/dist/core/permission-mode.js +133 -0
  152. package/dist/core/retry-fallback/controller-types.d.ts +6 -0
  153. package/dist/core/retry-fallback/controller.d.ts +9 -0
  154. package/dist/core/retry-fallback/controller.js +34 -3
  155. package/dist/core/retry-fallback/unusable.d.ts +25 -1
  156. package/dist/core/retry-fallback/unusable.js +87 -2
  157. package/dist/core/retry-fallback/usage-limit.d.ts +6 -1
  158. package/dist/core/retry-fallback/usage-limit.js +12 -4
  159. package/dist/core/sdk.d.ts +6 -1
  160. package/dist/core/sdk.js +3 -0
  161. package/dist/core/session-log.js +1 -1
  162. package/dist/core/stall-warning.d.ts +41 -0
  163. package/dist/core/stall-warning.js +72 -0
  164. package/dist/core/terminal-settings.d.ts +1 -0
  165. package/dist/core/turn-origin.d.ts +31 -0
  166. package/dist/core/turn-origin.js +64 -0
  167. package/dist/modes/interactive/components/remote-delivery-message.d.ts +2 -1
  168. package/dist/modes/interactive/components/remote-delivery-message.js +13 -5
  169. package/dist/modes/rpc/admit-external-message-command.d.ts +37 -0
  170. package/dist/modes/rpc/admit-external-message-command.js +61 -0
  171. package/dist/modes/rpc/admit-external-message-wire.d.ts +42 -0
  172. package/dist/modes/rpc/admit-external-message-wire.js +55 -0
  173. package/dist/modes/rpc/client-input-handler.d.ts +2 -0
  174. package/dist/modes/rpc/client-input-handler.js +2 -0
  175. package/dist/modes/rpc/connection-handler.js +30 -5
  176. package/dist/modes/rpc/connection-roles.d.ts +6 -0
  177. package/dist/modes/rpc/connection-roles.js +13 -0
  178. package/dist/modes/rpc/delegated-drive-origin.d.ts +9 -0
  179. package/dist/modes/rpc/delegated-drive-origin.js +16 -0
  180. package/dist/modes/rpc/effect-commands.d.ts +7 -1
  181. package/dist/modes/rpc/host-bare-endpoint-registration.d.ts +7 -0
  182. package/dist/modes/rpc/host-bare-endpoint-registration.js +35 -0
  183. package/dist/modes/rpc/host-capabilities.d.ts +2 -0
  184. package/dist/modes/rpc/host-capabilities.js +3 -0
  185. package/dist/modes/rpc/host-handover-parked.d.ts +11 -0
  186. package/dist/modes/rpc/host-handover-parked.js +17 -0
  187. package/dist/modes/rpc/host-handover-reopen.js +18 -6
  188. package/dist/modes/rpc/host-handover-resident-writer.d.ts +16 -0
  189. package/dist/modes/rpc/host-handover-resident-writer.js +57 -0
  190. package/dist/modes/rpc/host-idle-handover.js +1 -0
  191. package/dist/modes/rpc/host-warm.d.ts +16 -1
  192. package/dist/modes/rpc/host-warm.js +33 -6
  193. package/dist/modes/rpc/method-classes-schema-delivery.d.ts +32 -0
  194. package/dist/modes/rpc/method-classes-schema-delivery.js +22 -0
  195. package/dist/modes/rpc/method-classes-schema-session.d.ts +36 -0
  196. package/dist/modes/rpc/method-classes-schema-session.js +3 -0
  197. package/dist/modes/rpc/method-classes-schema.d.ts +36 -0
  198. package/dist/modes/rpc/method-classes.d.ts +2 -0
  199. package/dist/modes/rpc/method-classes.js +4 -0
  200. package/dist/modes/rpc/multi-session-host.js +6 -1
  201. package/dist/modes/rpc/permission-preset-command.d.ts +6 -0
  202. package/dist/modes/rpc/permission-preset-command.js +27 -0
  203. package/dist/modes/rpc/rpc-input-validation.js +4 -3
  204. package/dist/modes/rpc/rpc-mutation-response-types.d.ts +7 -0
  205. package/dist/modes/rpc/rpc-response-types.d.ts +2 -1
  206. package/dist/modes/rpc/rpc-session-command-types.d.ts +6 -1
  207. package/dist/modes/rpc/rpc-session-event-types.d.ts +5 -2
  208. package/dist/modes/rpc/rpc-session-state-types.d.ts +2 -1
  209. package/dist/modes/rpc/rpc-session-state.js +2 -0
  210. package/dist/modes/rpc/session-attachment-commands.js +3 -3
  211. package/dist/modes/rpc/session-event-writer-connections.js +1 -0
  212. package/dist/modes/rpc/session-event-writer.d.ts +1 -1
  213. package/dist/modes/rpc/session-registry-attach.d.ts +0 -9
  214. package/dist/modes/rpc/session-registry-attach.js +16 -3
  215. package/dist/modes/rpc/session-registry-types.d.ts +2 -0
  216. package/dist/modes/rpc/session-registry.d.ts +2 -0
  217. package/dist/modes/rpc/session-registry.js +16 -3
  218. package/dist/modes/rpc/session-router-close.js +43 -6
  219. package/dist/modes/rpc/session-router-context.js +2 -0
  220. package/dist/modes/rpc/session-router-occupancy.js +2 -11
  221. package/dist/modes/rpc/session-router-open-profile.js +4 -0
  222. package/dist/modes/rpc/session-router-open.d.ts +1 -1
  223. package/dist/modes/rpc/session-router-open.js +6 -17
  224. package/dist/modes/rpc/session-router-residency.d.ts +24 -0
  225. package/dist/modes/rpc/session-router-residency.js +90 -0
  226. package/dist/modes/rpc/session-router-routing.js +7 -1
  227. package/dist/modes/rpc/session-status.js +4 -1
  228. package/dist/modes/rpc/session-worker.js +4 -0
  229. package/dist/modes/rpc/tool-child/terminal-jobs.d.ts +1 -0
  230. package/dist/modes/rpc/tool-child/terminal-jobs.js +17 -1
  231. package/dist/modes/rpc/worker-session-registry.js +5 -2
  232. package/docs/engine-socket/fixtures/admission-routes/h-legacy.json +1 -1
  233. package/docs/engine-socket/fixtures/rpc-inbound-samples.json +29 -2
  234. package/docs/extensions.md +12 -0
  235. package/docs/rpc.md +129 -12
  236. package/docs/terminal-tools.md +25 -1
  237. package/native/socket-secret/prebuilds/win32-arm64/senpi_socket_secret.win32-arm64.node +0 -0
  238. package/native/socket-secret/prebuilds/win32-x64/senpi_socket_secret.win32-x64.node +0 -0
  239. package/package.json +6 -6
  240. package/dist/bundle/chunks/chunk-C7HEEBFH.js +0 -2
  241. package/dist/bundle/chunks/chunk-XCMII2VQ.js +0 -98
  242. package/dist/bundle/chunks/interactive-mode-B5SQDLH7.js +0 -2
  243. package/dist/bundle/chunks/main-UQFVFCNY.js +0 -2
  244. package/dist/bundle/chunks/rpc-mode-JYN3E7P7.js +0 -2
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{DefaultResourceLoader,LEGACY_PI_CONFIG_FILES,ModelRuntime,cleanupWindowsSelfUpdateQuarantine,createProjectTrustContext,importLegacyPiConfig,isBuiltinExtension,quarantineWindowsNativeDependencies,resolveProjectTrusted}from"./chunk-D5MRJWUK.js";import"./chunk-X5ZVYNOL.js";import"./chunk-7PSBD5KS.js";import"./chunk-GSKCWXXG.js";import{DefaultPackageManager,SettingsManager}from"./chunk-WGRKM3N6.js";import"./chunk-CF5OGBC4.js";import"./chunk-GTJJ73DE.js";import"./chunk-FEQDJBDL.js";import"./chunk-C7OKUC7L.js";import"./chunk-H33A33M4.js";import{DynamicBorder,initTheme,keyHint,rawKeyHint,stopThemeWatcher,theme}from"./chunk-RQ6CHXQ2.js";import"./chunk-22YXCY7K.js";import"./chunk-3QPE75AR.js";import"./chunk-4GKU755E.js";import"./chunk-XCMII2VQ.js";import"./chunk-SJI6UB23.js";import"./chunk-436DNN4Z.js";import"./chunk-J2I56WLK.js";import"./chunk-TQHNFP77.js";import"./chunk-C7HEEBFH.js";import"./chunk-47PPZKPO.js";import"./chunk-MOVB6H22.js";import"./chunk-NH7SYIGN.js";import"./chunk-WAOGBBZR.js";import{ProjectTrustStore,hasTrustRequiringProjectResources}from"./chunk-VD7AKTGP.js";import"./chunk-Y3TMJV3J.js";import"./chunk-MTQQ2VQH.js";import"./chunk-2FDW2LQL.js";import"./chunk-HLM46XEB.js";import{BUILTIN_PATH_PREFIX}from"./chunk-QMRJYMNH.js";import"./chunk-Y7Z7XPUF.js";import"./chunk-54YTJCYZ.js";import{source_default}from"./chunk-26UBFF6N.js";import"./chunk-I5ASHSLZ.js";import"./chunk-2CNSCMYC.js";import"./chunk-7WYJAYHH.js";import{runtimeExecArgv}from"./chunk-I3PHVJAS.js";import"./chunk-R2Z7CX77.js";import"./chunk-EAEEM2KN.js";import"./chunk-YI6KRJDC.js";import"./chunk-DBQBJTMF.js";import"./chunk-SF4MQDKZ.js";import"./chunk-VPVD5G32.js";import"./chunk-H4QOEVS5.js";import"./chunk-PPQPV52D.js";import"./chunk-4E7GDG4H.js";import"./chunk-UBNUGVW6.js";import"./chunk-ADT36P7E.js";import"./chunk-KLAX467B.js";import"./chunk-J7FW7MED.js";import{lockWithLossHandling}from"./chunk-2EJ4BGBM.js";import{require_proper_lockfile}from"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import"./chunk-U3VOXCGP.js";import"./chunk-7X72IACK.js";import{appendHiddenTuiStdout}from"./chunk-MSDBBOB2.js";import"./chunk-WHQ2QPP5.js";import"./chunk-YUTUD26F.js";import"./chunk-WB4BUHOH.js";import"./chunk-6VWIMHMH.js";import"./chunk-SOMFLLPD.js";import"./chunk-KDUJCDLM.js";import"./chunk-YU2P3CAR.js";import"./chunk-ADOOQW3O.js";import"./chunk-KJR3XXMI.js";import"./chunk-IYL5E4QQ.js";import"./chunk-7THM57HH.js";import"./chunk-AC72EWI5.js";import"./chunk-RQFD6LG2.js";import"./chunk-LNPAT22L.js";import{Container,Input,Markdown,ProcessTerminal,Spacer,TUI,getKeybindings,matchesKey,truncateToWidth,visibleWidth}from"./chunk-TMXRR3N7.js";import{killProcessTree}from"./chunk-DSWDJ7HT.js";import"./chunk-GKAYPJ4E.js";import"./chunk-EVTTLPIY.js";import"./chunk-BPNSOZ2C.js";import"./chunk-DLAY7CIU.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-QTS2XGPQ.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-BMX2U22F.js";import"./chunk-6APXZK7W.js";import"./chunk-WOHQJ6JB.js";import{formatVersionCheckError,getLatestPiRelease,getPiUserAgent,isNewerPackageVersion}from"./chunk-GLTOBXZY.js";import"./chunk-ECW7VBMB.js";import"./chunk-ZOFZRJSL.js";import"./chunk-ZFIC2DZV.js";import"./chunk-YK3ZZCHI.js";import"./chunk-T2SMQPRE.js";import"./chunk-RUGTHELO.js";import"./chunk-42XRJQM6.js";import"./chunk-2SOVDETB.js";import"./chunk-IHES3JES.js";import"./chunk-5XHOHZIR.js";import"./chunk-HW6AAS3R.js";import{APP_COMMAND,APP_NAME,CONFIG_DIR_NAME,DISPLAY_VERSION,PACKAGE_NAME,VERSION,brandProfile,canonicalizePath,detectInstallMethod,getAgentDir,getCwdRelativePath,getInstallPackageDir,getSelfUpdateCommand,getSelfUpdateUnavailableInstruction,isLocalPath,resolvePath,spawnProcess,spawnProcessSync,waitForChildProcess}from"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-EYSV6A7S.js";import"./chunk-MIENF2YK.js";import"./chunk-OXNWERO4.js";import"./chunk-QN2BHP3M.js";import"./chunk-AOTHPTMU.js";import"./chunk-O5RYI3IW.js";import{__toESM}from"./chunk-IKOFCODM.js";import{existsSync as existsSync3,mkdirSync as mkdirSync3,mkdtempSync,readdirSync as readdirSync2,readFileSync as readFileSync2,renameSync as renameSync2,rmSync as rmSync2,writeFileSync as writeFileSync2}from"node:fs";import{join as join5,resolve as resolve3}from"node:path";var import_proper_lockfile=__toESM(require_proper_lockfile(),1);import{randomUUID}from"node:crypto";import{cpSync,existsSync as existsSync2,mkdirSync as mkdirSync2,readFileSync,renameSync,rmSync,writeFileSync}from"node:fs";import{homedir}from"node:os";import{dirname as dirname2,join as join3,relative as relative2,resolve as resolve2}from"node:path";import{existsSync,readdirSync}from"node:fs";import{join,relative,sep}from"node:path";var REQUIRED_BUILD_ARTIFACTS=["extensions/omo.js","runtime/lsp-daemon/dist/cli.js","runtime/lsp-daemon/dist/index.js","runtime/lsp-daemon/dist/.omo-runtime-manifest.json","scripts/install.mjs"];function walkFiles(rootDir){let files=[],pending=[rootDir];for(;pending.length>0;){let dir=pending.pop();if(dir===void 0)continue;let entries;try{entries=readdirSync(dir,{withFileTypes:!0})}catch(error){if(error instanceof Error)continue;throw error}for(let entry of entries){let full=join(dir,entry.name);entry.isDirectory()?pending.push(full):entry.isFile()&&files.push(full)}}return files}function collectArtifactInventory(pluginPath){let inventory=[],collectUnder=(relativeDir,filter)=>{for(let filePath of walkFiles(join(pluginPath,relativeDir))){let posixPath=relative(pluginPath,filePath).split(sep).join("/");(filter===void 0||filter(posixPath))&&inventory.push(posixPath)}};return collectUnder("extensions"),collectUnder(join("runtime","lsp-daemon","dist")),collectUnder("skills",posixPath=>posixPath.endsWith("/SKILL.md")),existsSync(join(pluginPath,"scripts","install.mjs"))&&inventory.push("scripts/install.mjs"),inventory.sort(),inventory}function currentRequiredBuildArtifactsExist(pluginPath){return findMissingBuildArtifacts(pluginPath).length===0}function findMissingBuildArtifacts(pluginPath){let missing=[];for(let required of REQUIRED_BUILD_ARTIFACTS)existsSync(join(pluginPath,required))||missing.push(required);let skillCount=0;try{for(let entry of readdirSync(join(pluginPath,"skills"),{withFileTypes:!0}))entry.isDirectory()&&existsSync(join(pluginPath,"skills",entry.name,"SKILL.md"))&&skillCount++}catch(error){if(!(error instanceof Error))throw error}return skillCount===0&&missing.push("skills/*/SKILL.md"),missing}import{createHash}from"node:crypto";var EXCLUDED_ROOT_PATHS=new Set([".agents",".claude",".codex",".cursor",".devcontainer",".env.example",".gitattributes",".github",".idea",".mcp.json",".omo",".opencode",".vscode","AGENTS.md","CHANGELOG.md","CLA.md","CLAUDE.md","CONTRIBUTING.md","LICENSE","LICENSE.md","ROADMAP.md","THIRD-PARTY-NOTICES.md","assets","docs"]);function isBuildInputRootPath(name){return!EXCLUDED_ROOT_PATHS.has(name)&&!name.startsWith("README")}function computeBuildInputsHashFromLsTree(lsTreeOutput){let hash=createHash("sha256");for(let entry of lsTreeOutput.split("\0")){let tabIndex=entry.indexOf(" ");if(tabIndex===-1)continue;let name=entry.slice(tabIndex+1);if(!isBuildInputRootPath(name))continue;let objectHash=entry.slice(0,tabIndex).split(" ")[2]??"";hash.update(`${objectHash} ${name}
2
+ import{DefaultResourceLoader,LEGACY_PI_CONFIG_FILES,ModelRuntime,cleanupWindowsSelfUpdateQuarantine,createProjectTrustContext,importLegacyPiConfig,isBuiltinExtension,quarantineWindowsNativeDependencies,resolveProjectTrusted}from"./chunk-7CFORZPE.js";import"./chunk-4UR6UFBH.js";import"./chunk-STGOYIXC.js";import"./chunk-Q6NR6644.js";import{DefaultPackageManager,SettingsManager}from"./chunk-45MVD7BU.js";import"./chunk-4NYNMAYF.js";import"./chunk-GTJJ73DE.js";import"./chunk-FEQDJBDL.js";import"./chunk-K3UHGDUQ.js";import"./chunk-H33A33M4.js";import{DynamicBorder,initTheme,keyHint,rawKeyHint,stopThemeWatcher,theme}from"./chunk-3TZQXZKH.js";import"./chunk-22YXCY7K.js";import"./chunk-3QPE75AR.js";import"./chunk-4GKU755E.js";import"./chunk-4JIBEZZE.js";import"./chunk-SJI6UB23.js";import"./chunk-436DNN4Z.js";import"./chunk-J2I56WLK.js";import"./chunk-TQHNFP77.js";import"./chunk-XZDCMDUH.js";import"./chunk-LM6DOWQH.js";import"./chunk-MOVB6H22.js";import"./chunk-NH7SYIGN.js";import"./chunk-WAOGBBZR.js";import{ProjectTrustStore,hasTrustRequiringProjectResources}from"./chunk-VD7AKTGP.js";import"./chunk-Y3TMJV3J.js";import"./chunk-MTQQ2VQH.js";import"./chunk-M7GF73FO.js";import"./chunk-622VYTRI.js";import{BUILTIN_PATH_PREFIX}from"./chunk-QMRJYMNH.js";import"./chunk-Y7Z7XPUF.js";import"./chunk-54YTJCYZ.js";import{source_default}from"./chunk-26UBFF6N.js";import"./chunk-I5ASHSLZ.js";import"./chunk-2CNSCMYC.js";import"./chunk-7WYJAYHH.js";import{runtimeExecArgv}from"./chunk-I3PHVJAS.js";import"./chunk-R2Z7CX77.js";import"./chunk-EAEEM2KN.js";import"./chunk-YI6KRJDC.js";import"./chunk-DBQBJTMF.js";import"./chunk-SF4MQDKZ.js";import"./chunk-VPVD5G32.js";import"./chunk-H4QOEVS5.js";import"./chunk-PPQPV52D.js";import"./chunk-7VMEE62L.js";import"./chunk-UBNUGVW6.js";import"./chunk-ADT36P7E.js";import"./chunk-KLAX467B.js";import"./chunk-J7FW7MED.js";import{lockWithLossHandling}from"./chunk-2EJ4BGBM.js";import{require_proper_lockfile}from"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import"./chunk-U3VOXCGP.js";import"./chunk-7X72IACK.js";import{appendHiddenTuiStdout}from"./chunk-MSDBBOB2.js";import"./chunk-WHQ2QPP5.js";import"./chunk-YUTUD26F.js";import"./chunk-WB4BUHOH.js";import"./chunk-6VWIMHMH.js";import"./chunk-SOMFLLPD.js";import"./chunk-KDUJCDLM.js";import"./chunk-YU2P3CAR.js";import"./chunk-ADOOQW3O.js";import"./chunk-KJR3XXMI.js";import"./chunk-IYL5E4QQ.js";import"./chunk-7THM57HH.js";import"./chunk-AC72EWI5.js";import"./chunk-RQFD6LG2.js";import"./chunk-527Q2UYM.js";import{Container,Input,Markdown,ProcessTerminal,Spacer,TUI,getKeybindings,matchesKey,truncateToWidth,visibleWidth}from"./chunk-TMXRR3N7.js";import"./chunk-LPYBKMPT.js";import{killProcessTree}from"./chunk-WQ4RBPMS.js";import"./chunk-7PROV6BB.js";import"./chunk-EVTTLPIY.js";import"./chunk-BPNSOZ2C.js";import"./chunk-DLAY7CIU.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-QTS2XGPQ.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-BMX2U22F.js";import"./chunk-6APXZK7W.js";import"./chunk-WOHQJ6JB.js";import{formatVersionCheckError,getLatestPiRelease,getPiUserAgent,isNewerPackageVersion}from"./chunk-GLTOBXZY.js";import"./chunk-NDSWTAYJ.js";import"./chunk-ZOFZRJSL.js";import"./chunk-ZFIC2DZV.js";import"./chunk-YK3ZZCHI.js";import"./chunk-T2SMQPRE.js";import"./chunk-RUGTHELO.js";import"./chunk-42XRJQM6.js";import"./chunk-2SOVDETB.js";import"./chunk-IHES3JES.js";import"./chunk-5XHOHZIR.js";import"./chunk-HW6AAS3R.js";import{APP_COMMAND,APP_NAME,CONFIG_DIR_NAME,DISPLAY_VERSION,PACKAGE_NAME,VERSION,brandProfile,canonicalizePath,detectInstallMethod,getAgentDir,getCwdRelativePath,getInstallPackageDir,getSelfUpdateCommand,getSelfUpdateUnavailableInstruction,isLocalPath,resolvePath,spawnProcess,spawnProcessSync,waitForChildProcess}from"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-EYSV6A7S.js";import"./chunk-MIENF2YK.js";import"./chunk-OXNWERO4.js";import"./chunk-44BJPS5I.js";import"./chunk-AOTHPTMU.js";import"./chunk-O5RYI3IW.js";import{__toESM}from"./chunk-IKOFCODM.js";import{existsSync as existsSync3,mkdirSync as mkdirSync3,mkdtempSync,readdirSync as readdirSync2,readFileSync as readFileSync2,renameSync as renameSync2,rmSync as rmSync2,writeFileSync as writeFileSync2}from"node:fs";import{join as join5,resolve as resolve3}from"node:path";var import_proper_lockfile=__toESM(require_proper_lockfile(),1);import{randomUUID}from"node:crypto";import{cpSync,existsSync as existsSync2,mkdirSync as mkdirSync2,readFileSync,renameSync,rmSync,writeFileSync}from"node:fs";import{homedir}from"node:os";import{dirname as dirname2,join as join3,relative as relative2,resolve as resolve2}from"node:path";import{existsSync,readdirSync}from"node:fs";import{join,relative,sep}from"node:path";var REQUIRED_BUILD_ARTIFACTS=["extensions/omo.js","runtime/lsp-daemon/dist/cli.js","runtime/lsp-daemon/dist/index.js","runtime/lsp-daemon/dist/.omo-runtime-manifest.json","scripts/install.mjs"];function walkFiles(rootDir){let files=[],pending=[rootDir];for(;pending.length>0;){let dir=pending.pop();if(dir===void 0)continue;let entries;try{entries=readdirSync(dir,{withFileTypes:!0})}catch(error){if(error instanceof Error)continue;throw error}for(let entry of entries){let full=join(dir,entry.name);entry.isDirectory()?pending.push(full):entry.isFile()&&files.push(full)}}return files}function collectArtifactInventory(pluginPath){let inventory=[],collectUnder=(relativeDir,filter)=>{for(let filePath of walkFiles(join(pluginPath,relativeDir))){let posixPath=relative(pluginPath,filePath).split(sep).join("/");(filter===void 0||filter(posixPath))&&inventory.push(posixPath)}};return collectUnder("extensions"),collectUnder(join("runtime","lsp-daemon","dist")),collectUnder("skills",posixPath=>posixPath.endsWith("/SKILL.md")),existsSync(join(pluginPath,"scripts","install.mjs"))&&inventory.push("scripts/install.mjs"),inventory.sort(),inventory}function currentRequiredBuildArtifactsExist(pluginPath){return findMissingBuildArtifacts(pluginPath).length===0}function findMissingBuildArtifacts(pluginPath){let missing=[];for(let required of REQUIRED_BUILD_ARTIFACTS)existsSync(join(pluginPath,required))||missing.push(required);let skillCount=0;try{for(let entry of readdirSync(join(pluginPath,"skills"),{withFileTypes:!0}))entry.isDirectory()&&existsSync(join(pluginPath,"skills",entry.name,"SKILL.md"))&&skillCount++}catch(error){if(!(error instanceof Error))throw error}return skillCount===0&&missing.push("skills/*/SKILL.md"),missing}import{createHash}from"node:crypto";var EXCLUDED_ROOT_PATHS=new Set([".agents",".claude",".codex",".cursor",".devcontainer",".env.example",".gitattributes",".github",".idea",".mcp.json",".omo",".opencode",".vscode","AGENTS.md","CHANGELOG.md","CLA.md","CLAUDE.md","CONTRIBUTING.md","LICENSE","LICENSE.md","ROADMAP.md","THIRD-PARTY-NOTICES.md","assets","docs"]);function isBuildInputRootPath(name){return!EXCLUDED_ROOT_PATHS.has(name)&&!name.startsWith("README")}function computeBuildInputsHashFromLsTree(lsTreeOutput){let hash=createHash("sha256");for(let entry of lsTreeOutput.split("\0")){let tabIndex=entry.indexOf(" ");if(tabIndex===-1)continue;let name=entry.slice(tabIndex+1);if(!isBuildInputRootPath(name))continue;let objectHash=entry.slice(0,tabIndex).split(" ")[2]??"";hash.update(`${objectHash} ${name}
3
3
  `)}return hash.digest("hex")}import{spawn}from"node:child_process";import{closeSync,mkdirSync,openSync}from"node:fs";import{dirname,join as join2,resolve}from"node:path";import{fileURLToPath}from"node:url";function omoLocalUpdateWorkerLogPath(agentDir){return join2(agentDir,"omo-local-update","worker.log")}function workerCommandArgs(force){let updateArgs=["update","--omo-local-update-worker",...force?["--force"]:[]];if(detectInstallMethod()==="bun-binary")return updateArgs;let modulePath=fileURLToPath(import.meta.url),extension=modulePath.endsWith(".ts")?".ts":".js",cliMainPath=resolve(dirname(modulePath),"..",`cli-main${extension}`);return[...runtimeExecArgv(),cliMainPath,...updateArgs]}var defaultSpawnWorker=request=>{let logPath=omoLocalUpdateWorkerLogPath(request.agentDir);try{mkdirSync(dirname(logPath),{recursive:!0});let logFd=openSync(logPath,"w");try{let child=spawn(process.execPath,workerCommandArgs(request.force),{detached:!0,env:process.env,stdio:["ignore",logFd,logFd]});return child.unref(),{ok:!0,pid:child.pid,logPath}}finally{closeSync(logFd)}}catch(error){return{ok:!1,message:error instanceof Error?error.message:String(error)}}};async function defaultRun(command,args,options){let child=spawnProcess(command,args,{cwd:options.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...options.env},detached:process.platform!=="win32",windowsHide:!0}),stdout="",stderr="";child.stdout.on("data",chunk=>{stdout+=chunk.toString()}),child.stderr.on("data",chunk=>{stderr+=chunk.toString()});let abort=new AbortController,timedOut=!1,pid=child.pid,timer=options.timeoutMs===void 0?void 0:setTimeout(()=>{timedOut=!0,pid!==void 0&&killProcessTree(pid),abort.abort()},options.timeoutMs);try{return{code:await waitForChildProcess(child,{signal:abort.signal}),stdout,stderr,timedOut}}finally{timer!==void 0&&clearTimeout(timer)}}function isKillSwitched(env){return env.SENPI_OMO_LOCAL_UPDATE==="0"}function defaultReadJson(path){try{return JSON.parse(readFileSync(path,"utf-8"))}catch{return}}function packageNameOf(json){if(typeof json!="object"||json===null)return;let name=json.name;return typeof name=="string"?name:void 0}function homeDir(){return process.env.HOME||homedir()}async function detectOmoLocalInstall(options){let readJson=options.readJson??defaultReadJson,exists=options.exists??existsSync2;if(options.packages)for(let entry of options.packages){let source=typeof entry=="string"?entry:entry.source;if(!isLocalPath(source))continue;let pluginPath=resolvePath(source,options.agentDir,{homeDir:homeDir(),trim:!0});if(packageNameOf(readJson(join3(pluginPath,"package.json")))!=="@code-yeongyu/omo-senpi")continue;let repoRoot=resolve2(pluginPath,"..","..",".."),omoSenpiPkgPath=join3(repoRoot,"packages","omo-senpi","package.json"),senpiTaskPkgPath=join3(repoRoot,"packages","senpi-task","package.json");if(!exists(omoSenpiPkgPath)||packageNameOf(readJson(omoSenpiPkgPath))!=="@oh-my-opencode/omo-senpi"||!exists(senpiTaskPkgPath)||packageNameOf(readJson(senpiTaskPkgPath))!=="@oh-my-opencode/senpi-task")continue;let topLevel;try{let result=await options.run("git",["-C",repoRoot,"rev-parse","--show-toplevel"],{});if(result.code!==0)continue;topLevel=result.stdout.trim()}catch{continue}if(!(topLevel===""||canonicalizePath(topLevel)!==canonicalizePath(repoRoot)))return{pluginPath,repoRoot}}}function omoLocalUpdateStampPath(agentDir){return join3(agentDir,"omo-local-update-state.json")}function readStamp(agentDir){let json=defaultReadJson(omoLocalUpdateStampPath(agentDir));if(typeof json!="object"||json===null)return;let candidate=json;if(typeof candidate.repoRoot!="string"||typeof candidate.sha!="string"||typeof candidate.omoSenpiTree!="string"||typeof candidate.senpiTaskTree!="string"||typeof candidate.buildInputsHash!="string"||typeof candidate.installedAt!="string"||!Array.isArray(candidate.artifacts))return;let artifacts=[];for(let artifact of candidate.artifacts){if(typeof artifact!="string")return;artifacts.push(artifact)}return{repoRoot:candidate.repoRoot,sha:candidate.sha,omoSenpiTree:candidate.omoSenpiTree,senpiTaskTree:candidate.senpiTaskTree,buildInputsHash:candidate.buildInputsHash,installedAt:candidate.installedAt,artifacts}}function writeStamp(agentDir,stamp){mkdirSync2(agentDir,{recursive:!0}),writeFileSync(omoLocalUpdateStampPath(agentDir),`${JSON.stringify(stamp,null,2)}
4
4
  `,"utf-8")}function shouldSkipUpdate(options){if(options.force)return!1;let stamp=options.stamp;return!stamp||stamp.repoRoot!==options.repoRoot||stamp.sha!==options.remoteSha&&stamp.buildInputsHash!==options.remoteBuildInputsHash||stamp.artifacts.length===0?!1:options.stampArtifactsExist}var OmoLocalStepError=class extends Error{constructor(stage,message,output){super(message),this.name="OmoLocalStepError",this.stage=stage,this.output=output}};function firstErrorLine(result){for(let text of[result.stderr,result.stdout])for(let line of text.split(`
5
5
  `)){let trimmed=line.trim();if(trimmed!=="")return trimmed}return"unknown error"}async function computeRemoteState(options){let{repoRoot,run}=options,git=(args,timeoutMs)=>run("git",args,{cwd:repoRoot,timeoutMs}),requireOk=async(args,timeoutMs)=>{let result=await git(args,timeoutMs);if(result.timedOut)throw new OmoLocalStepError("fetch",`git ${args.join(" ")} timed out`);if(result.code!==0)throw new OmoLocalStepError("fetch",`git ${args.join(" ")}: ${firstErrorLine(result)}`,`${result.stdout}${result.stderr}`);return result.stdout.trim()};await requireOk(["fetch","origin","dev"],12e4);let sha=await requireOk(["rev-parse","origin/dev"]);if(sha==="")throw new OmoLocalStepError("fetch","git rev-parse origin/dev: empty output");let subject=await requireOk(["log","-1","--format=%s","origin/dev"]),omoSenpiTree=await requireOk(["rev-parse","origin/dev:packages/omo-senpi"]),senpiTaskTree=await requireOk(["rev-parse","origin/dev:packages/senpi-task"]),buildInputsHash=computeBuildInputsHashFromLsTree(await requireOk(["ls-tree","-z","origin/dev"]));return{sha,subject,omoSenpiTree,senpiTaskTree,buildInputsHash}}function omoLocalUpdateLockPath(agentDir){return join3(agentDir,"omo-local-update.lock")}function omoLocalUpdateBuildWorktreePath(agentDir){return join3(agentDir,"omo-local-update","build-worktree")}function readLockFile(path){try{let json=JSON.parse(readFileSync(path,"utf-8"));return typeof json.pid!="number"||typeof json.nonce!="string"?void 0:{pid:json.pid,nonce:json.nonce}}catch{return}}function pidIsAlive(pid){try{return process.kill(pid,0),!0}catch(error){return error.code==="EPERM"}}function acquireOmoLocalLock(agentDir,log){mkdirSync2(agentDir,{recursive:!0});let path=omoLocalUpdateLockPath(agentDir),lock={path,pid:process.pid,nonce:randomUUID()},payload=JSON.stringify({pid:lock.pid,nonce:lock.nonce,startedAt:new Date().toISOString()}),tryCreate=()=>{try{return writeFileSync(path,payload,{flag:"wx"}),!0}catch(error){if(error.code==="EEXIST")return!1;throw error}},reportBusy=()=>{let existing2=readLockFile(path);log(source_default.dim(`OMO local plugin update already running (pid ${existing2?.pid??"unknown"}); skipping.`))};if(tryCreate())return lock;let existing=readLockFile(path);if(existing!==void 0&&pidIsAlive(existing.pid))return reportBusy();try{rmSync(path)}catch{}return tryCreate()?lock:reportBusy()}function releaseOmoLocalLock(lock){try{let existing=readLockFile(lock.path);existing!==void 0&&existing.pid===lock.pid&&existing.nonce===lock.nonce&&rmSync(lock.path)}catch{}}var OmoLocalBunMissingError=class extends Error{constructor(){super("bun not found on PATH"),this.name="OmoLocalBunMissingError"}};async function runBunStep(stage,args,worktree,run,timeoutMs){let result;try{result=await run("bun",args,{cwd:worktree,timeoutMs})}catch(error){throw error.code==="ENOENT"?new OmoLocalBunMissingError:new OmoLocalStepError(stage,`bun ${args.join(" ")} failed to start: ${error instanceof Error?error.message:String(error)}`)}let output=`${result.stdout}${result.stderr}`;if(result.timedOut)throw new OmoLocalStepError(stage,`bun ${args.join(" ")} timed out after ${Math.round(timeoutMs/1e3)}s`,output);if(result.code!==0)throw new OmoLocalStepError(stage,`bun ${args.join(" ")} exited with code ${result.code??"unknown"}`,output)}async function ensureBuildWorktree(options){let{worktree,repoRoot,sha,run}=options;if(existsSync2(worktree)){let commonDir=await run("git",["-C",worktree,"rev-parse","--git-common-dir"],{});if(commonDir.code===0&&commonDir.stdout.trim()!==""&&canonicalizePath(resolve2(worktree,commonDir.stdout.trim()))===canonicalizePath(join3(repoRoot,".git"))){let checkout=await run("git",["-C",worktree,"checkout","--detach","--force",sha],{});if(checkout.code!==0)throw new OmoLocalStepError("worktree",`git checkout --detach --force: ${firstErrorLine(checkout)}`,`${checkout.stdout}${checkout.stderr}`);return}((await run("git",["-C",repoRoot,"worktree","remove","--force",worktree],{})).code!==0||existsSync2(worktree))&&rmSync(worktree,{recursive:!0,force:!0})}mkdirSync2(dirname2(worktree),{recursive:!0});let add=await run("git",["-C",repoRoot,"worktree","add","--detach",worktree,sha],{});if(add.code===0)return;await run("git",["-C",repoRoot,"worktree","prune"],{});let retry=await run("git",["-C",repoRoot,"worktree","add","--detach",worktree,sha],{});if(retry.code!==0)throw new OmoLocalStepError("worktree",`git worktree add: ${firstErrorLine(retry)}`,`${add.stdout}${add.stderr}${retry.stdout}${retry.stderr}`)}var defaultFsSeam={cpSync:(source,destination)=>{cpSync(source,destination,{recursive:!0})},renameSync:(oldPath,newPath)=>{renameSync(oldPath,newPath)},rmSync:path=>{rmSync(path,{recursive:!0,force:!0})}},swapCounter=0;function swapPluginDir(options){let seam=options.fs??defaultFsSeam;swapCounter+=1;let tag=`${Date.now()}-${process.pid}-${swapCounter}`,staging=`${options.pluginPath}.staging-${tag}`,prev=`${options.pluginPath}.prev-${tag}`;seam.cpSync(options.sourceDir,staging),seam.renameSync(options.pluginPath,prev);try{seam.renameSync(staging,options.pluginPath)}catch(error){throw seam.renameSync(prev,options.pluginPath),seam.rmSync(staging),error}seam.rmSync(prev)}function firstLine(text){for(let line of text.split(`
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{MODULE_JOB_KIND,NOTICE_TAIL_MAX_CHARS,TERMINAL_CHILD_JOB_KINDS,TerminalManager,ToolChildJobError,childTerminalIdScope,controlFd,createBashInputTool,createBashOutputTool,createBashResizeTool,createKillBashTool,createModuleJobHandler,createPtyBashTool,goShimScript,runToolChild,sanitizeTerminalOutput,withControlPipe}from"./chunk-LNPAT22L.js";import"./chunk-TMXRR3N7.js";import{getShellConfig}from"./chunk-DSWDJ7HT.js";import"./chunk-GKAYPJ4E.js";import"./chunk-EVTTLPIY.js";import"./chunk-BPNSOZ2C.js";import"./chunk-DLAY7CIU.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-QTS2XGPQ.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-BMX2U22F.js";import"./chunk-WOHQJ6JB.js";import"./chunk-IHES3JES.js";import"./chunk-5XHOHZIR.js";import"./chunk-HW6AAS3R.js";import"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import{value_exports}from"./chunk-MIENF2YK.js";import"./chunk-OXNWERO4.js";import{SecretOutputRedactor}from"./chunk-AOTHPTMU.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";var PTY_GO_SHIM='stty -echo 2>/dev/null; IFS= read -r _go || exit 127; stty echo 2>/dev/null; exec "$0" "$@"';function parseArgs(value){let field=name=>typeof value=="object"&&value!==null?Reflect.get(value,name):void 0,cwd=field("cwd"),toolCallId=field("toolCallId"),env=field("env");if(typeof cwd!="string"||typeof toolCallId!="string"||typeof env!="object"||env===null)throw new ToolChildJobError("terminal_job_bad_args","a terminal job needs cwd, toolCallId and env");let shellPath=field("shellPath"),timeoutAction=field("timeoutAction");return{params:field("params"),toolCallId,cwd,env:Object.fromEntries(Object.entries(env).filter(entry=>typeof entry[1]=="string")),...typeof shellPath=="string"?{shellPath}:{},defaultCols:Number(field("defaultCols"))||0,defaultRows:Number(field("defaultRows"))||0,redactSecretsInOutput:field("redactSecretsInOutput")===!0,...timeoutAction==="background"||timeoutAction==="kill"?{timeoutAction}:{}}}function barrierFor(job){return{wrap:(command,args)=>({command:"/bin/sh",args:["-c",PTY_GO_SHIM,command,...args]}),async release(session){if(session.pid===void 0)throw new ToolChildJobError("terminal_spawn_failed","the PTY reported no pid");let gated=job.gate.request({jobId:job.jobId,origin:"terminal",api:"pty.spawn",containment:"own-group",lifetime:"owned",pid:session.pid,pgid:session.pid});session.onExit(exitCode=>job.gate.done(gated.launchId,exitCode===null?{}:{exitCode})),job.gate.skipsAckWait||await gated.acked,job.gate.invokeNow(gated.launchId),session.write(`go
3
- `)}}}function exitSummary(id,runtime){let output=sanitizeTerminalOutput(runtime.fullOutput()).trimEnd(),exit=runtime.exitResult;return{event:"background_exit",id,exit:exit===null?null:{exitCode:exit.exitCode,signal:exit.signal,cancelled:exit.cancelled,timedOut:exit.timedOut},output:output.length>NOTICE_TAIL_MAX_CHARS?output.slice(output.length-NOTICE_TAIL_MAX_CHARS-1):output}}function createTerminalJobHandlers(injected){let manager=injected,managerFor=generation=>(manager??=new TerminalManager({idScope:childTerminalIdScope(generation)}),manager),tell=(job,wake)=>{job.wake(TERMINAL_CHILD_JOB_KINDS.bash,wake).catch(error=>{process.stderr.write(`tool-child: terminal ${wake.event} for ${wake.id} not delivered: ${error instanceof Error?error.message:String(error)}
4
- `)})},contextFor=(args,job)=>({manager:managerFor(job.generation),...args.timeoutAction===void 0?{}:{timeoutAction:args.timeoutAction},onBackgroundStart:(id,description,startedAtMs)=>tell(job,{event:"background_start",id,description,startedAtMs}),onBackgroundExit:(id,runtime)=>tell(job,exitSummary(id,runtime)),cwd:args.cwd,...args.shellPath===void 0?{}:{shellPath:args.shellPath},defaultCols:args.defaultCols,defaultRows:args.defaultRows,redactSecretsInOutput:args.redactSecretsInOutput,getEnv:()=>({...args.env}),launchBarrier:barrierFor(job)}),run=create=>async(value,job)=>{let args=parseArgs(value),tool=create(contextFor(args,job));if(!value_exports.Check(tool.parameters,args.params))throw new ToolChildJobError("terminal_job_bad_args","the tool's parameters do not match its schema");let onUpdate=update=>{job.update(update).catch(error=>{process.stderr.write(`tool-child: ${args.toolCallId} update not sent: ${error instanceof Error?error.message:String(error)}
2
+ import{MODULE_JOB_KIND,NOTICE_TAIL_MAX_CHARS,TERMINAL_CHILD_JOB_KINDS,TerminalManager,ToolChildJobError,childTerminalIdScope,controlFd,createBashInputTool,createBashOutputTool,createBashResizeTool,createKillBashTool,createModuleJobHandler,createPtyBashTool,goShimScript,runToolChild,sanitizeTerminalOutput,withControlPipe}from"./chunk-527Q2UYM.js";import"./chunk-TMXRR3N7.js";import"./chunk-LPYBKMPT.js";import{getShellConfig}from"./chunk-WQ4RBPMS.js";import"./chunk-7PROV6BB.js";import"./chunk-EVTTLPIY.js";import"./chunk-BPNSOZ2C.js";import"./chunk-DLAY7CIU.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-QTS2XGPQ.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-BMX2U22F.js";import"./chunk-WOHQJ6JB.js";import"./chunk-IHES3JES.js";import"./chunk-5XHOHZIR.js";import"./chunk-HW6AAS3R.js";import"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import{value_exports}from"./chunk-MIENF2YK.js";import"./chunk-OXNWERO4.js";import{SecretOutputRedactor}from"./chunk-AOTHPTMU.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";var PTY_GO_SHIM='stty -echo 2>/dev/null; IFS= read -r _go || exit 127; stty echo 2>/dev/null; exec "$0" "$@"';function parseArgs(value){let field=name=>typeof value=="object"&&value!==null?Reflect.get(value,name):void 0,cwd=field("cwd"),toolCallId=field("toolCallId"),env=field("env");if(typeof cwd!="string"||typeof toolCallId!="string"||typeof env!="object"||env===null)throw new ToolChildJobError("terminal_job_bad_args","a terminal job needs cwd, toolCallId and env");let shellPath=field("shellPath"),timeoutAction=field("timeoutAction"),autoReap=field("backgroundAutoReapMinutes");return{params:field("params"),toolCallId,cwd,env:Object.fromEntries(Object.entries(env).filter(entry=>typeof entry[1]=="string")),...typeof shellPath=="string"?{shellPath}:{},defaultCols:Number(field("defaultCols"))||0,defaultRows:Number(field("defaultRows"))||0,redactSecretsInOutput:field("redactSecretsInOutput")===!0,...timeoutAction==="background"||timeoutAction==="kill"?{timeoutAction}:{},...typeof autoReap=="number"&&Number.isFinite(autoReap)?{backgroundAutoReapMinutes:autoReap}:{}}}function barrierFor(job){return{wrap:(command,args)=>({command:"/bin/sh",args:["-c",PTY_GO_SHIM,command,...args]}),async release(session){if(session.pid===void 0)throw new ToolChildJobError("terminal_spawn_failed","the PTY reported no pid");let gated=job.gate.request({jobId:job.jobId,origin:"terminal",api:"pty.spawn",containment:"own-group",lifetime:"owned",pid:session.pid,pgid:session.pid});session.onExit(exitCode=>job.gate.done(gated.launchId,exitCode===null?{}:{exitCode})),job.gate.skipsAckWait||await gated.acked,job.gate.invokeNow(gated.launchId),session.write(`go
3
+ `)}}}function exitSummary(id,runtime){let output=sanitizeTerminalOutput(runtime.fullOutput()).trimEnd(),exit=runtime.exitResult;return{event:"background_exit",id,exit:exit===null?null:{exitCode:exit.exitCode,signal:exit.signal,cancelled:exit.cancelled,timedOut:exit.timedOut},output:output.length>NOTICE_TAIL_MAX_CHARS?output.slice(output.length-NOTICE_TAIL_MAX_CHARS-1):output,...runtime.autoReapedAfterMinutes===void 0?{}:{autoReapedAfterMinutes:runtime.autoReapedAfterMinutes}}}function createTerminalJobHandlers(injected){let manager=injected,managerFor=generation=>(manager??=new TerminalManager({idScope:childTerminalIdScope(generation)}),manager),tell=(job,wake)=>{job.wake(TERMINAL_CHILD_JOB_KINDS.bash,wake).catch(error=>{process.stderr.write(`tool-child: terminal ${wake.event} for ${wake.id} not delivered: ${error instanceof Error?error.message:String(error)}
4
+ `)})},contextFor=(args,job)=>({manager:managerFor(job.generation),...args.timeoutAction===void 0?{}:{timeoutAction:args.timeoutAction},...args.backgroundAutoReapMinutes===void 0?{}:{backgroundAutoReapMinutes:args.backgroundAutoReapMinutes},onBackgroundStart:(id,description,startedAtMs,command,autoReapMinutes)=>tell(job,{event:"background_start",id,description,startedAtMs,...command===void 0?{}:{command},...autoReapMinutes===void 0?{}:{autoReapMinutes}}),onBackgroundExit:(id,runtime)=>tell(job,exitSummary(id,runtime)),onBackgroundReapFailed:(id,autoReapMinutes,reason)=>tell(job,{event:"background_reap_failed",id,autoReapMinutes,reason}),cwd:args.cwd,...args.shellPath===void 0?{}:{shellPath:args.shellPath},defaultCols:args.defaultCols,defaultRows:args.defaultRows,redactSecretsInOutput:args.redactSecretsInOutput,getEnv:()=>({...args.env}),launchBarrier:barrierFor(job)}),run=create=>async(value,job)=>{let args=parseArgs(value),tool=create(contextFor(args,job));if(!value_exports.Check(tool.parameters,args.params))throw new ToolChildJobError("terminal_job_bad_args","the tool's parameters do not match its schema");let onUpdate=update=>{job.update(update).catch(error=>{process.stderr.write(`tool-child: ${args.toolCallId} update not sent: ${error instanceof Error?error.message:String(error)}
5
5
  `)})};return tool.execute(args.toolCallId,args.params,job.signal,onUpdate,{cwd:args.cwd})};return{[TERMINAL_CHILD_JOB_KINDS.bash]:run(createPtyBashTool),[TERMINAL_CHILD_JOB_KINDS.output]:run(createBashOutputTool),[TERMINAL_CHILD_JOB_KINDS.input]:run(createBashInputTool),[TERMINAL_CHILD_JOB_KINDS.resize]:run(createBashResizeTool),[TERMINAL_CHILD_JOB_KINDS.kill]:run(createKillBashTool)}}import{access}from"node:fs/promises";import{constants as osConstants}from"node:os";import{spawn}from"node:child_process";import{once}from"node:events";import{Socket}from"node:net";async function launchOwnGroup(launch){if(process.platform==="win32")throw new Error("launchOwnGroup is POSIX-only; Windows launches are contained by the job");let callerStdio=[...launch.options?.stdio??["ignore","pipe","pipe"]],fd=controlFd(callerStdio),shim=spawn("/bin/sh",["-c",goShimScript(fd),launch.program,...launch.args],{...launch.options,detached:!0,stdio:withControlPipe(callerStdio,fd,"ignore","pipe")}),pid=shim.pid,exited=once(shim,"exit").then(([exitCode,signal])=>({exitCode,signal}));if(pid===void 0)throw new Error(`could not start ${launch.program}`);let gated=launch.gate.request({jobId:launch.jobId,origin:launch.origin,api:launch.api,containment:"own-group",lifetime:launch.lifetime??"owned",pid,pgid:pid});if(exited.then(({exitCode,signal})=>launch.gate.done(gated.launchId,{...exitCode===null?{}:{exitCode},...signal===null?{}:{signal}})),launch.gate.skipsAckWait||await Promise.race([gated.acked,exited]),shim.exitCode===null&&shim.signalCode===null){launch.gate.invokeNow(gated.launchId);let control=shim.stdio[fd];control instanceof Socket&&(control.on("error",()=>{}),exited.then(()=>control.destroy()),control.unref(),control.write(`go
6
6
  `))}return{launchId:gated.launchId,child:shim,exited}}var USER_BASH_JOB_KIND="user.bash";function parseUserBashArgs(value){let field=name=>typeof value=="object"&&value!==null?Reflect.get(value,name):void 0,command=field("command"),cwd=field("cwd"),env=field("env");if(typeof command!="string"||typeof cwd!="string"||typeof env!="object"||env===null)throw new ToolChildJobError("user_bash_bad_args","a user bash job needs command, cwd and env");let shellPath=field("shellPath"),timeoutSeconds=field("timeoutSeconds");return{command,cwd,redactSecretsInOutput:field("redactSecretsInOutput")===!0,env:Object.fromEntries(Object.entries(env).filter(entry=>typeof entry[1]=="string")),...typeof shellPath=="string"?{shellPath}:{},...typeof timeoutSeconds=="number"&&timeoutSeconds>0?{timeoutSeconds}:{}}}function streamClosed(stream){return stream==null?Promise.resolve():new Promise(resolveClosed=>{stream.once("end",()=>resolveClosed()),stream.once("close",()=>resolveClosed()),stream.once("error",()=>resolveClosed())})}function killGroup(pid){try{process.kill(-pid,"SIGKILL")}catch{}}async function runUserBash(args,job){await access(args.cwd).catch(()=>{throw new ToolChildJobError("user_bash_bad_cwd",`Working directory does not exist: ${args.cwd}
7
7
  Cannot execute bash commands.`)});let shell=getShellConfig(args.shellPath),fromStdin=shell.commandTransport==="stdin",launched=await launchOwnGroup({gate:job.gate,jobId:job.jobId,origin:"user_bash",api:"cp.spawn",program:shell.shell,args:fromStdin?shell.args:[...shell.args,args.command],options:{cwd:args.cwd,env:{...args.env},stdio:[fromStdin?"pipe":"ignore","pipe","pipe"]}}),{child}=launched;fromStdin&&(child.stdin?.on("error",()=>{}),child.stdin?.end(args.command));let sent=Promise.resolve(),updateFailure,redactors=args.redactSecretsInOutput?{stdout:{redactor:new SecretOutputRedactor,decoder:new TextDecoder},stderr:{redactor:new SecretOutputRedactor,decoder:new TextDecoder}}:void 0,send=(chunk,stream)=>{sent=sent.then(()=>job.update({data:chunk.toString("base64"),stream})).catch(error=>{updateFailure??=error})},forward=(chunk,stream)=>{let state=redactors?.[stream];if(!state)return send(chunk,stream);let text=state.redactor.push(state.decoder.decode(chunk,{stream:!0}));text&&send(Buffer.from(text),stream)};child.stdout?.on("data",chunk=>forward(chunk,"stdout")),child.stderr?.on("data",chunk=>forward(chunk,"stderr"));let drained=Promise.all([streamClosed(child.stdout),streamClosed(child.stderr)]),pid=child.pid,stop=()=>{pid!==void 0&&killGroup(pid)};job.signal.addEventListener("abort",stop,{once:!0});let timer=args.timeoutSeconds===void 0?void 0:setTimeout(stop,args.timeoutSeconds*1e3);try{let{exitCode,signal}=await launched.exited;if(await drained,redactors)for(let stream of["stdout","stderr"]){let{redactor,decoder}=redactors[stream],text=redactor.push(decoder.decode())+redactor.finish();text&&send(Buffer.from(text),stream)}if(await sent,job.signal.aborted)throw new ToolChildJobError("user_bash_aborted","aborted");if(updateFailure!==void 0)throw new ToolChildJobError("user_bash_output_lost",`output could not be sent: ${updateFailure instanceof Error?updateFailure.message:String(updateFailure)}`);return exitCode!==null?{exitCode}:{exitCode:signal===null?null:128+(osConstants.signals[signal]??0)}}finally{timer!==void 0&&clearTimeout(timer),job.signal.removeEventListener("abort",stop)}}function createUserBashJobHandler(){return(value,job)=>{if(process.platform==="win32")throw new ToolChildJobError("tool_child_platform_unsupported","user bash on the tool child is POSIX-only");return runUserBash(parseUserBashArgs(value),job)}}var TOOL_CHILD_JOB_HANDLERS={[MODULE_JOB_KIND]:createModuleJobHandler(),...createTerminalJobHandlers(),[USER_BASH_JOB_KIND]:createUserBashJobHandler()};async function runToolChildRole(){await runToolChild({handlers:TOOL_CHILD_JOB_HANDLERS}),process.exit(0)}export{TOOL_CHILD_JOB_HANDLERS,runToolChildRole};
@@ -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{STORE_BUSY,writeHealthUnlessStoreBusy}from"./chunk-LT353NSF.js";import{orderRotationSlots,pickRotationSlot,rememberHeadroomAccount,rememberedHeadroomAccount}from"./chunk-POEOCKX4.js";import{getConfigValueEnvVarNames,isCommittedRotationOutput,isRotationStreamStart,resolveConfigValue,rotationErrorFromEvent}from"./chunk-4E7GDG4H.js";import{emitProviderAccountFailover,emitProviderAccountsChanged,slotsOfOwnKind,subscriptionLimits}from"./chunk-UBNUGVW6.js";import{discoverEnvSlots}from"./chunk-ADT36P7E.js";import"./chunk-KLAX467B.js";import{acquireHalfOpenLease,applicableStoredState}from"./chunk-J7FW7MED.js";import"./chunk-2EJ4BGBM.js";import"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import"./chunk-U3VOXCGP.js";import"./chunk-7X72IACK.js";import"./chunk-MSDBBOB2.js";import{roundRobinState}from"./chunk-WHQ2QPP5.js";import{classifyCredentialFailure,runCredentialFailover}from"./chunk-YUTUD26F.js";import"./chunk-WB4BUHOH.js";import{activeModelBlockUntil,modelBlockKey,pruneModelBlocks,withModelBlock}from"./chunk-6VWIMHMH.js";import"./chunk-AC72EWI5.js";import"./chunk-RQFD6LG2.js";import"./chunk-DSWDJ7HT.js";import"./chunk-GKAYPJ4E.js";import"./chunk-EVTTLPIY.js";import"./chunk-BPNSOZ2C.js";import"./chunk-DLAY7CIU.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-QTS2XGPQ.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import{ConfigReferenceError}from"./chunk-OKMHSVCA.js";import{credentialPoolBlockedDiagnostic,sanitizeProviderDiagnostic}from"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-BMX2U22F.js";import"./chunk-WOHQJ6JB.js";import"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-IKOFCODM.js";import{createHash,randomUUID}from"node:crypto";async function releaseProbeLease(repository,providerId,lane,slotName,leaseId){await writeHealthUnlessStoreBusy(`lease release on ${slotName}`,()=>repository.mutateSlotState(providerId,lane,slotName,current=>{if(current?.lease?.id!==leaseId)return current;let{lease:_released,...rest}=current;return rest}))}async function releaseLeaseIfModelBlocked(repository,providerId,lane,slotName,leaseId,until){until!==void 0&&await releaseProbeLease(repository,providerId,lane,slotName,leaseId)}async function probeInFlight(repository,providerId,lane,slot,isApplicable,now){let state=(await repository.listSlots(providerId,lane))[slot.name],lease=isApplicable(state)?state?.lease:void 0;if(!(lease===void 0||lease.expiresAt<=now))return{...slot,blockedUntil:lease.expiresAt,blockReason:PROBE_IN_FLIGHT}}var PROBE_IN_FLIGHT="probe_in_flight";function probeLease(repository,providerId,lane,slotName,now){return writeHealthUnlessStoreBusy(`probe lease on ${slotName}`,()=>acquireHalfOpenLease(repository,providerId,lane,slotName,{now}))}function overlayState(slot,state){return state?{...slot,...state.blockedUntil===void 0?{}:{blockedUntil:state.blockedUntil},...state.blockReason===void 0?{}:{blockReason:state.blockReason},...state.failureCount===void 0?{}:{failureCount:state.failureCount},...state.lease===void 0?{}:{lease:state.lease}}:slot}function overlayModelBlock(slot,until){return until===void 0||slot.blockedUntil!==void 0&&slot.blockedUntil>=until?slot:{...slot,blockedUntil:until,blockReason:slot.blockReason??"rate_limit"}}var warnedSlotReferences=new Set;async function listRotationSlots(sources,options={}){let acquireLeases=options.acquireLeases!==!1,modelId=options.modelId,now=sources.now??Date.now,{providerId,credential,env,repository}=sources,policySlots=[],referenceError;for(let[name,ref]of Object.entries(sources.policy?.slots??{})){let envVarName=ref.env??`models.json:${name}`,key;try{key=ref.env!==void 0?env(ref.env):ref.value!==void 0?await resolveConfigValue(ref.value,typeof ref.value=="string"?{}:Object.fromEntries(getConfigValueEnvVarNames(ref.value).flatMap(variable=>{let value=env(variable);return value===void 0?[]:[[variable,value]]}))):void 0}catch(error){if(!(error instanceof ConfigReferenceError))throw error;let notice=`${error.field}: configuration reference ${error.reason}; skipping credential slot`;warnedSlotReferences.has(notice)||(warnedSlotReferences.add(notice),console.warn(notice)),referenceError??=error;continue}key&&policySlots.push({name,envVarName,key,source:"env"})}if(credential){let state=await repository.listSlots(providerId,"stored"),slots=[];for(let slot of slotsOfOwnKind(credential)){if(slot.signedOut===!0)continue;let persisted=state[slot.name],revisions=await repository.storedSlotRevisions(providerId,slot.name,{key:slot.key,access:slot.access,refresh:slot.refresh}),storedRevision=revisions.account,materialRevision=revisions.material,applicable=applicableStoredState(persisted,revisions),modelUntil=activeModelBlockUntil(applicable?.modelBlocks,modelId,now()),lease;if(acquireLeases&&modelUntil===void 0&&applicable?.blockedUntil!==void 0&&applicable.blockedUntil<=now()&&(lease=await probeLease(repository,providerId,"stored",slot.name,now()),lease===void 0)){let inFlight=await probeInFlight(repository,providerId,"stored",{name:slot.name,lane:"stored",pinned:credential.pinned===slot.name,storedRevision},state2=>state2?.credentialRevision===storedRevision,now());inFlight!==void 0&&slots.push(inFlight);continue}if(lease!==void 0&&lease!==STORE_BUSY){let leasedState=(await repository.listSlots(providerId,"stored"))[slot.name],leasedApplicable=applicableStoredState(leasedState,revisions),leasedModelUntil=activeModelBlockUntil(leasedApplicable?.modelBlocks,modelId,now());await releaseLeaseIfModelBlocked(repository,providerId,"stored",slot.name,lease.leaseId,leasedModelUntil),slots.push(overlayModelBlock(overlayState({name:slot.name,lane:"stored",pinned:credential.pinned===slot.name,storedRevision,materialRevision,...leasedModelUntil===void 0?{heldLeaseId:lease.leaseId}:{}},leasedApplicable),leasedModelUntil));continue}slots.push(overlayModelBlock(overlayState({name:slot.name,lane:"stored",pinned:credential.pinned===slot.name,storedRevision,materialRevision},applicable),modelUntil))}if(policySlots.length===0){if(slots.length===0&&referenceError!==void 0)throw referenceError;return slots}let namedSources={...sources,credential:void 0,policy:{...sources.policy,slots:{}}},namedSlots=await listEnvRotationSlots(namedSources,policySlots,acquireLeases,modelId);return[...slots,...namedSlots]}let envSlots=[...discoverEnvSlots(providerId,env),...policySlots];if(envSlots.length===0&&referenceError!==void 0)throw referenceError;return listEnvRotationSlots(sources,envSlots,acquireLeases,modelId)}async function listEnvRotationSlots(sources,envSlots,acquireLeases,modelId){if(envSlots.length===0)return[];let{providerId,repository}=sources,now=sources.now??Date.now,state=await repository.listSlots(providerId,"env"),slots=[];for(let slot of envSlots){let persisted=state[slot.name],revision=await repository.envCredentialRevision(slot.envVarName,slot.key),applicable=persisted?.credentialRevision===revision?persisted:void 0,modelUntil=activeModelBlockUntil(applicable?.modelBlocks,modelId,now()),heldLeaseId;if(acquireLeases&&modelUntil===void 0&&applicable?.blockedUntil!==void 0&&applicable.blockedUntil<=now()){let lease=await probeLease(repository,providerId,"env",slot.name,now());if(lease===void 0){let inFlight=await probeInFlight(repository,providerId,"env",{name:slot.name,lane:"env",envKey:slot.key,envVarName:slot.envVarName},state2=>state2?.credentialRevision===revision,now());inFlight!==void 0&&slots.push(inFlight);continue}if(lease!==STORE_BUSY){let leasedState=(await repository.listSlots(providerId,"env"))[slot.name];applicable=leasedState?.credentialRevision===revision?leasedState:void 0,modelUntil=activeModelBlockUntil(applicable?.modelBlocks,modelId,now()),await releaseLeaseIfModelBlocked(repository,providerId,"env",slot.name,lease.leaseId,modelUntil),modelUntil===void 0&&(heldLeaseId=lease.leaseId)}}slots.push(overlayModelBlock(overlayState({name:slot.name,lane:"env",envKey:slot.key,envVarName:slot.envVarName,...heldLeaseId===void 0?{}:{heldLeaseId}},applicable),modelUntil))}return slots}var sha256SlotHasher=input=>createHash("sha256").update(input).digest().readBigUInt64BE(0);function modelBlockPatch(family,modelId,blockedUntil,current,now,credentialRevision){let sameMaterial=current!==void 0&&current.credentialRevision===credentialRevision,{stateVersion:_stateVersion,...kept}=sameMaterial?current:{stateVersion:0};return{...kept,lease:void 0,...credentialRevision===void 0?{}:{credentialRevision},modelBlocks:withModelBlock(sameMaterial?current.modelBlocks:void 0,modelBlockKey(family,modelId),blockedUntil,now)}}function blockPatch(block,current,now,credentialRevision,policy,modelId){if(block.reason==="rate_limit"&&block.modelFamily!==void 0&&modelId!==void 0){let blockedUntil=now+Math.min(policy?.cooldownCapMs??block.cooldownMs,block.cooldownMs);return modelBlockPatch(block.modelFamily,modelId,blockedUntil,current,now,credentialRevision)}let failureCount=(current?.failureCount??0)+1,liveModelBlocks=current?.credentialRevision===credentialRevision?pruneModelBlocks(current?.modelBlocks,now):void 0,base={failureCount,...credentialRevision===void 0?{}:{credentialRevision},...current?.lastSuccessAt===void 0?{}:{lastSuccessAt:current.lastSuccessAt},...liveModelBlocks===void 0?{}:{modelBlocks:liveModelBlocks}};return block.reason==="rate_limit"?{...base,blockedUntil:now+Math.min(policy?.cooldownCapMs??block.cooldownMs,block.cooldownMs),blockReason:"rate_limit",...block.usageLimit?{usageLimit:!0}:{}}:block.reason==="auth_error"?{...base,blockedUntil:now+9e5,blockReason:"auth_error"}:{...base,blockReason:block.reason}}function withPoolRetryAt(event,retryAt){if(event.type!=="error")return event;let own=sanitizeProviderDiagnostic(event.error.providerDiagnostic),limit=own?.category==="rate_limit"||own?.category==="quota",unclassifiedLimit=own===void 0||own.category==="unknown"&&own.httpStatus===429;if(!limit&&!unclassifiedLimit)return event;let providerDiagnostic=own!==void 0&&limit?sanitizeProviderDiagnostic({...own,resetsAt:own.resetsAt??retryAt})??own:credentialPoolBlockedDiagnostic(retryAt);return providerDiagnostic===void 0?event:{...event,error:{...event.error,providerDiagnostic}}}function failoverReason(block){return block.reason==="account_disabled"?"billing":block.reason}function streamWithCredentialRotation(options){let{sources,runAttempt}=options,hasher=options.hasher??sha256SlotHasher,affinityKey=options.affinityKey??randomUUID(),useAffinity=sources.policy?.accountStrategy!==void 0||sources.policy?.affinity!==!1,pooled=sources.credential,now=sources.now??Date.now,rememberAffinity=useAffinity&&options.affinityKey!==void 0,roundRobin=sources.policy?.accountStrategy==="round-robin"?roundRobinState.session(sources.providerId,options.affinityKey):void 0,leaving;return runCredentialFailover({listSlots:()=>listRotationSlots(sources,options.modelId===void 0?{}:{modelId:options.modelId}),select:candidates=>{let remembered=roundRobin?.account??(rememberAffinity?rememberedHeadroomAccount(sources.repository,sources.providerId,affinityKey):void 0),policy={affinityKey,useAffinity,hasher,...pooled?.order===void 0?{}:{order:pooled.order},...sources.policy?.accountStrategy===void 0?{}:{strategy:sources.policy.accountStrategy},...roundRobin===void 0?{}:{roundRobinOffset:roundRobin.offset},headroom:{providerId:sources.providerId,limits:subscriptionLimits.snapshot(),now:now(),...remembered===void 0?{}:{remembered}}},winner=pickRotationSlot(candidates,policy);if(!winner)throw new Error("credential rotation selected from an empty candidate set");return roundRobin!==void 0?winner.pinned!==!0&&(roundRobin.account=winner.name):rememberAffinity&&winner.pinned!==!0&&(remembered!==void 0||winner!==orderRotationSlots(candidates,policy)[0])&&rememberHeadroomAccount(sources.repository,sources.providerId,affinityKey,winner.name),winner},runAttempt:slot=>(leaving!==void 0&&leaving.name!==slot.name&&emitProviderAccountFailover(sources.providerId,leaving.name,slot.name,failoverReason(leaving.block)),leaving=void 0,runAttempt(slot)),onRotate:({slot,block,committedOutput})=>{leaving=committedOutput?void 0:{name:slot.name,block}},isCommittedOutput:isCommittedRotationOutput,isStreamStart:isRotationStreamStart,errorFromEvent:rotationErrorFromEvent,withPoolRetryAt,classify:(error,context)=>classifyCredentialFailure(error,{...context,nowMs:now(),cooldownBaseMs:sources.policy?.cooldownBaseMs,cooldownCapMs:sources.policy?.cooldownCapMs}),onSuccess:async slot=>{let released=!1;await writeHealthUnlessStoreBusy(`success on ${slot.name}`,()=>sources.repository.mutateSlotState(sources.providerId,slot.lane,slot.name,current=>{if(!current)return;let modelBlocks=pruneModelBlocks(current.modelBlocks,now(),options.modelId);return released=current.blockedUntil!==void 0||current.blockReason!==void 0||Object.keys(modelBlocks??{}).length!==Object.keys(current.modelBlocks??{}).length,{...current,...slot.storedRevision===void 0?{}:{credentialRevision:slot.storedRevision},lastSuccessAt:now(),lease:void 0,blockedUntil:void 0,blockReason:void 0,usageLimit:void 0,failureCount:void 0,modelBlocks}}))!==STORE_BUSY&&released&&emitProviderAccountsChanged(sources.providerId)},releaseSlot:async slot=>{slot.heldLeaseId!==void 0&&await releaseProbeLease(sources.repository,sources.providerId,slot.lane,slot.name,slot.heldLeaseId)},persistBlock:async(slot,block)=>{let revision=slot.lane==="env"&&slot.envVarName!==void 0&&slot.envKey!==void 0?await sources.repository.envCredentialRevision(slot.envVarName,slot.envKey):block.reason==="auth_error"?slot.materialRevision:slot.storedRevision;await writeHealthUnlessStoreBusy(`${block.reason} block on ${slot.name}`,()=>sources.repository.mutateSlotState(sources.providerId,slot.lane,slot.name,current=>blockPatch(block,current,now(),revision,sources.policy,options.modelId)))!==STORE_BUSY&&emitProviderAccountsChanged(sources.providerId)},now})}export{listRotationSlots,sha256SlotHasher,streamWithCredentialRotation};
2
+ import{STORE_BUSY,writeHealthUnlessStoreBusy}from"./chunk-LT353NSF.js";import{orderRotationSlots,pickRotationSlot,rememberHeadroomAccount,rememberedHeadroomAccount}from"./chunk-POEOCKX4.js";import{getConfigValueEnvVarNames,isCommittedRotationOutput,isRotationStreamStart,resolveConfigValue,rotationErrorFromEvent}from"./chunk-7VMEE62L.js";import{emitProviderAccountFailover,emitProviderAccountsChanged,slotsOfOwnKind,subscriptionLimits}from"./chunk-UBNUGVW6.js";import{discoverEnvSlots}from"./chunk-ADT36P7E.js";import"./chunk-KLAX467B.js";import{acquireHalfOpenLease,applicableStoredState}from"./chunk-J7FW7MED.js";import"./chunk-2EJ4BGBM.js";import"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import"./chunk-U3VOXCGP.js";import"./chunk-7X72IACK.js";import"./chunk-MSDBBOB2.js";import{roundRobinState}from"./chunk-WHQ2QPP5.js";import{classifyCredentialFailure,runCredentialFailover}from"./chunk-YUTUD26F.js";import"./chunk-WB4BUHOH.js";import{activeModelBlockUntil,modelBlockKey,pruneModelBlocks,withModelBlock}from"./chunk-6VWIMHMH.js";import"./chunk-AC72EWI5.js";import"./chunk-RQFD6LG2.js";import"./chunk-WQ4RBPMS.js";import"./chunk-7PROV6BB.js";import"./chunk-EVTTLPIY.js";import"./chunk-BPNSOZ2C.js";import"./chunk-DLAY7CIU.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-QTS2XGPQ.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import{ConfigReferenceError}from"./chunk-OKMHSVCA.js";import{credentialPoolBlockedDiagnostic,sanitizeProviderDiagnostic}from"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-BMX2U22F.js";import"./chunk-WOHQJ6JB.js";import"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-IKOFCODM.js";import{createHash,randomUUID}from"node:crypto";async function releaseProbeLease(repository,providerId,lane,slotName,leaseId){await writeHealthUnlessStoreBusy(`lease release on ${slotName}`,()=>repository.mutateSlotState(providerId,lane,slotName,current=>{if(current?.lease?.id!==leaseId)return current;let{lease:_released,...rest}=current;return rest}))}async function releaseLeaseIfModelBlocked(repository,providerId,lane,slotName,leaseId,until){until!==void 0&&await releaseProbeLease(repository,providerId,lane,slotName,leaseId)}async function probeInFlight(repository,providerId,lane,slot,isApplicable,now){let state=(await repository.listSlots(providerId,lane))[slot.name],lease=isApplicable(state)?state?.lease:void 0;if(!(lease===void 0||lease.expiresAt<=now))return{...slot,blockedUntil:lease.expiresAt,blockReason:PROBE_IN_FLIGHT}}var PROBE_IN_FLIGHT="probe_in_flight";function probeLease(repository,providerId,lane,slotName,now){return writeHealthUnlessStoreBusy(`probe lease on ${slotName}`,()=>acquireHalfOpenLease(repository,providerId,lane,slotName,{now}))}function overlayState(slot,state){return state?{...slot,...state.blockedUntil===void 0?{}:{blockedUntil:state.blockedUntil},...state.blockReason===void 0?{}:{blockReason:state.blockReason},...state.failureCount===void 0?{}:{failureCount:state.failureCount},...state.lease===void 0?{}:{lease:state.lease}}:slot}function overlayModelBlock(slot,until){return until===void 0||slot.blockedUntil!==void 0&&slot.blockedUntil>=until?slot:{...slot,blockedUntil:until,blockReason:slot.blockReason??"rate_limit"}}var warnedSlotReferences=new Set;async function listRotationSlots(sources,options={}){let acquireLeases=options.acquireLeases!==!1,modelId=options.modelId,now=sources.now??Date.now,{providerId,credential,env,repository}=sources,policySlots=[],referenceError;for(let[name,ref]of Object.entries(sources.policy?.slots??{})){let envVarName=ref.env??`models.json:${name}`,key;try{key=ref.env!==void 0?env(ref.env):ref.value!==void 0?await resolveConfigValue(ref.value,typeof ref.value=="string"?{}:Object.fromEntries(getConfigValueEnvVarNames(ref.value).flatMap(variable=>{let value=env(variable);return value===void 0?[]:[[variable,value]]}))):void 0}catch(error){if(!(error instanceof ConfigReferenceError))throw error;let notice=`${error.field}: configuration reference ${error.reason}; skipping credential slot`;warnedSlotReferences.has(notice)||(warnedSlotReferences.add(notice),console.warn(notice)),referenceError??=error;continue}key&&policySlots.push({name,envVarName,key,source:"env"})}if(credential){let state=await repository.listSlots(providerId,"stored"),slots=[];for(let slot of slotsOfOwnKind(credential)){if(slot.signedOut===!0)continue;let persisted=state[slot.name],revisions=await repository.storedSlotRevisions(providerId,slot.name,{key:slot.key,access:slot.access,refresh:slot.refresh}),storedRevision=revisions.account,materialRevision=revisions.material,applicable=applicableStoredState(persisted,revisions),modelUntil=activeModelBlockUntil(applicable?.modelBlocks,modelId,now()),lease;if(acquireLeases&&modelUntil===void 0&&applicable?.blockedUntil!==void 0&&applicable.blockedUntil<=now()&&(lease=await probeLease(repository,providerId,"stored",slot.name,now()),lease===void 0)){let inFlight=await probeInFlight(repository,providerId,"stored",{name:slot.name,lane:"stored",pinned:credential.pinned===slot.name,storedRevision},state2=>state2?.credentialRevision===storedRevision,now());inFlight!==void 0&&slots.push(inFlight);continue}if(lease!==void 0&&lease!==STORE_BUSY){let leasedState=(await repository.listSlots(providerId,"stored"))[slot.name],leasedApplicable=applicableStoredState(leasedState,revisions),leasedModelUntil=activeModelBlockUntil(leasedApplicable?.modelBlocks,modelId,now());await releaseLeaseIfModelBlocked(repository,providerId,"stored",slot.name,lease.leaseId,leasedModelUntil),slots.push(overlayModelBlock(overlayState({name:slot.name,lane:"stored",pinned:credential.pinned===slot.name,storedRevision,materialRevision,...leasedModelUntil===void 0?{heldLeaseId:lease.leaseId}:{}},leasedApplicable),leasedModelUntil));continue}slots.push(overlayModelBlock(overlayState({name:slot.name,lane:"stored",pinned:credential.pinned===slot.name,storedRevision,materialRevision},applicable),modelUntil))}if(policySlots.length===0){if(slots.length===0&&referenceError!==void 0)throw referenceError;return slots}let namedSources={...sources,credential:void 0,policy:{...sources.policy,slots:{}}},namedSlots=await listEnvRotationSlots(namedSources,policySlots,acquireLeases,modelId);return[...slots,...namedSlots]}let envSlots=[...discoverEnvSlots(providerId,env),...policySlots];if(envSlots.length===0&&referenceError!==void 0)throw referenceError;return listEnvRotationSlots(sources,envSlots,acquireLeases,modelId)}async function listEnvRotationSlots(sources,envSlots,acquireLeases,modelId){if(envSlots.length===0)return[];let{providerId,repository}=sources,now=sources.now??Date.now,state=await repository.listSlots(providerId,"env"),slots=[];for(let slot of envSlots){let persisted=state[slot.name],revision=await repository.envCredentialRevision(slot.envVarName,slot.key),applicable=persisted?.credentialRevision===revision?persisted:void 0,modelUntil=activeModelBlockUntil(applicable?.modelBlocks,modelId,now()),heldLeaseId;if(acquireLeases&&modelUntil===void 0&&applicable?.blockedUntil!==void 0&&applicable.blockedUntil<=now()){let lease=await probeLease(repository,providerId,"env",slot.name,now());if(lease===void 0){let inFlight=await probeInFlight(repository,providerId,"env",{name:slot.name,lane:"env",envKey:slot.key,envVarName:slot.envVarName},state2=>state2?.credentialRevision===revision,now());inFlight!==void 0&&slots.push(inFlight);continue}if(lease!==STORE_BUSY){let leasedState=(await repository.listSlots(providerId,"env"))[slot.name];applicable=leasedState?.credentialRevision===revision?leasedState:void 0,modelUntil=activeModelBlockUntil(applicable?.modelBlocks,modelId,now()),await releaseLeaseIfModelBlocked(repository,providerId,"env",slot.name,lease.leaseId,modelUntil),modelUntil===void 0&&(heldLeaseId=lease.leaseId)}}slots.push(overlayModelBlock(overlayState({name:slot.name,lane:"env",envKey:slot.key,envVarName:slot.envVarName,...heldLeaseId===void 0?{}:{heldLeaseId}},applicable),modelUntil))}return slots}var sha256SlotHasher=input=>createHash("sha256").update(input).digest().readBigUInt64BE(0);function modelBlockPatch(family,modelId,blockedUntil,current,now,credentialRevision){let sameMaterial=current!==void 0&&current.credentialRevision===credentialRevision,{stateVersion:_stateVersion,...kept}=sameMaterial?current:{stateVersion:0};return{...kept,lease:void 0,...credentialRevision===void 0?{}:{credentialRevision},modelBlocks:withModelBlock(sameMaterial?current.modelBlocks:void 0,modelBlockKey(family,modelId),blockedUntil,now)}}function blockPatch(block,current,now,credentialRevision,policy,modelId){if(block.reason==="rate_limit"&&block.modelFamily!==void 0&&modelId!==void 0){let blockedUntil=now+Math.min(policy?.cooldownCapMs??block.cooldownMs,block.cooldownMs);return modelBlockPatch(block.modelFamily,modelId,blockedUntil,current,now,credentialRevision)}let failureCount=(current?.failureCount??0)+1,liveModelBlocks=current?.credentialRevision===credentialRevision?pruneModelBlocks(current?.modelBlocks,now):void 0,base={failureCount,...credentialRevision===void 0?{}:{credentialRevision},...current?.lastSuccessAt===void 0?{}:{lastSuccessAt:current.lastSuccessAt},...liveModelBlocks===void 0?{}:{modelBlocks:liveModelBlocks}};return block.reason==="rate_limit"?{...base,blockedUntil:now+Math.min(policy?.cooldownCapMs??block.cooldownMs,block.cooldownMs),blockReason:"rate_limit",...block.usageLimit?{usageLimit:!0}:{}}:block.reason==="auth_error"?{...base,blockedUntil:now+9e5,blockReason:"auth_error"}:{...base,blockReason:block.reason}}function withPoolRetryAt(event,retryAt){if(event.type!=="error")return event;let own=sanitizeProviderDiagnostic(event.error.providerDiagnostic),limit=own?.category==="rate_limit"||own?.category==="quota",unclassifiedLimit=own===void 0||own.category==="unknown"&&own.httpStatus===429;if(!limit&&!unclassifiedLimit)return event;let providerDiagnostic=own!==void 0&&limit?sanitizeProviderDiagnostic({...own,resetsAt:own.resetsAt??retryAt})??own:credentialPoolBlockedDiagnostic(retryAt);return providerDiagnostic===void 0?event:{...event,error:{...event.error,providerDiagnostic}}}function failoverReason(block){return block.reason==="account_disabled"?"billing":block.reason}function streamWithCredentialRotation(options){let{sources,runAttempt}=options,hasher=options.hasher??sha256SlotHasher,affinityKey=options.affinityKey??randomUUID(),useAffinity=sources.policy?.accountStrategy!==void 0||sources.policy?.affinity!==!1,pooled=sources.credential,now=sources.now??Date.now,rememberAffinity=useAffinity&&options.affinityKey!==void 0,roundRobin=sources.policy?.accountStrategy==="round-robin"?roundRobinState.session(sources.providerId,options.affinityKey):void 0,leaving;return runCredentialFailover({listSlots:()=>listRotationSlots(sources,options.modelId===void 0?{}:{modelId:options.modelId}),select:candidates=>{let remembered=roundRobin?.account??(rememberAffinity?rememberedHeadroomAccount(sources.repository,sources.providerId,affinityKey):void 0),policy={affinityKey,useAffinity,hasher,...pooled?.order===void 0?{}:{order:pooled.order},...sources.policy?.accountStrategy===void 0?{}:{strategy:sources.policy.accountStrategy},...roundRobin===void 0?{}:{roundRobinOffset:roundRobin.offset},headroom:{providerId:sources.providerId,limits:subscriptionLimits.snapshot(),now:now(),...remembered===void 0?{}:{remembered}}},winner=pickRotationSlot(candidates,policy);if(!winner)throw new Error("credential rotation selected from an empty candidate set");return roundRobin!==void 0?winner.pinned!==!0&&(roundRobin.account=winner.name):rememberAffinity&&winner.pinned!==!0&&(remembered!==void 0||winner!==orderRotationSlots(candidates,policy)[0])&&rememberHeadroomAccount(sources.repository,sources.providerId,affinityKey,winner.name),winner},runAttempt:slot=>(leaving!==void 0&&leaving.name!==slot.name&&emitProviderAccountFailover(sources.providerId,leaving.name,slot.name,failoverReason(leaving.block)),leaving=void 0,runAttempt(slot)),onRotate:({slot,block,committedOutput})=>{leaving=committedOutput?void 0:{name:slot.name,block}},isCommittedOutput:isCommittedRotationOutput,isStreamStart:isRotationStreamStart,errorFromEvent:rotationErrorFromEvent,withPoolRetryAt,classify:(error,context)=>classifyCredentialFailure(error,{...context,nowMs:now(),cooldownBaseMs:sources.policy?.cooldownBaseMs,cooldownCapMs:sources.policy?.cooldownCapMs}),onSuccess:async slot=>{let released=!1;await writeHealthUnlessStoreBusy(`success on ${slot.name}`,()=>sources.repository.mutateSlotState(sources.providerId,slot.lane,slot.name,current=>{if(!current)return;let modelBlocks=pruneModelBlocks(current.modelBlocks,now(),options.modelId);return released=current.blockedUntil!==void 0||current.blockReason!==void 0||Object.keys(modelBlocks??{}).length!==Object.keys(current.modelBlocks??{}).length,{...current,...slot.storedRevision===void 0?{}:{credentialRevision:slot.storedRevision},lastSuccessAt:now(),lease:void 0,blockedUntil:void 0,blockReason:void 0,usageLimit:void 0,failureCount:void 0,modelBlocks}}))!==STORE_BUSY&&released&&emitProviderAccountsChanged(sources.providerId)},releaseSlot:async slot=>{slot.heldLeaseId!==void 0&&await releaseProbeLease(sources.repository,sources.providerId,slot.lane,slot.name,slot.heldLeaseId)},persistBlock:async(slot,block)=>{let revision=slot.lane==="env"&&slot.envVarName!==void 0&&slot.envKey!==void 0?await sources.repository.envCredentialRevision(slot.envVarName,slot.envKey):block.reason==="auth_error"?slot.materialRevision:slot.storedRevision;await writeHealthUnlessStoreBusy(`${block.reason} block on ${slot.name}`,()=>sources.repository.mutateSlotState(sources.providerId,slot.lane,slot.name,current=>blockPatch(block,current,now(),revision,sources.policy,options.modelId)))!==STORE_BUSY&&emitProviderAccountsChanged(sources.providerId)},now})}export{listRotationSlots,sha256SlotHasher,streamWithCredentialRotation};
@@ -0,0 +1,2 @@
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{runRpcMode}from"./chunk-7CFORZPE.js";import"./chunk-4UR6UFBH.js";import"./chunk-STGOYIXC.js";import"./chunk-Q6NR6644.js";import"./chunk-45MVD7BU.js";import"./chunk-4NYNMAYF.js";import"./chunk-GTJJ73DE.js";import"./chunk-FEQDJBDL.js";import"./chunk-K3UHGDUQ.js";import"./chunk-H33A33M4.js";import"./chunk-3TZQXZKH.js";import"./chunk-22YXCY7K.js";import"./chunk-3QPE75AR.js";import"./chunk-4GKU755E.js";import"./chunk-4JIBEZZE.js";import"./chunk-SJI6UB23.js";import"./chunk-436DNN4Z.js";import"./chunk-J2I56WLK.js";import"./chunk-TQHNFP77.js";import"./chunk-XZDCMDUH.js";import"./chunk-LM6DOWQH.js";import"./chunk-MOVB6H22.js";import"./chunk-NH7SYIGN.js";import"./chunk-WAOGBBZR.js";import"./chunk-VD7AKTGP.js";import"./chunk-Y3TMJV3J.js";import"./chunk-MTQQ2VQH.js";import"./chunk-M7GF73FO.js";import"./chunk-622VYTRI.js";import"./chunk-QMRJYMNH.js";import"./chunk-Y7Z7XPUF.js";import"./chunk-54YTJCYZ.js";import"./chunk-26UBFF6N.js";import"./chunk-I5ASHSLZ.js";import"./chunk-2CNSCMYC.js";import"./chunk-7WYJAYHH.js";import"./chunk-I3PHVJAS.js";import"./chunk-R2Z7CX77.js";import"./chunk-EAEEM2KN.js";import"./chunk-YI6KRJDC.js";import"./chunk-DBQBJTMF.js";import"./chunk-SF4MQDKZ.js";import"./chunk-VPVD5G32.js";import"./chunk-H4QOEVS5.js";import"./chunk-PPQPV52D.js";import"./chunk-7VMEE62L.js";import"./chunk-UBNUGVW6.js";import"./chunk-ADT36P7E.js";import"./chunk-KLAX467B.js";import"./chunk-J7FW7MED.js";import"./chunk-2EJ4BGBM.js";import"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import"./chunk-U3VOXCGP.js";import"./chunk-7X72IACK.js";import"./chunk-MSDBBOB2.js";import"./chunk-WHQ2QPP5.js";import"./chunk-YUTUD26F.js";import"./chunk-WB4BUHOH.js";import"./chunk-6VWIMHMH.js";import"./chunk-SOMFLLPD.js";import"./chunk-KDUJCDLM.js";import"./chunk-YU2P3CAR.js";import"./chunk-ADOOQW3O.js";import"./chunk-KJR3XXMI.js";import"./chunk-IYL5E4QQ.js";import"./chunk-7THM57HH.js";import"./chunk-AC72EWI5.js";import"./chunk-RQFD6LG2.js";import"./chunk-527Q2UYM.js";import"./chunk-TMXRR3N7.js";import"./chunk-LPYBKMPT.js";import"./chunk-WQ4RBPMS.js";import"./chunk-7PROV6BB.js";import"./chunk-EVTTLPIY.js";import"./chunk-BPNSOZ2C.js";import"./chunk-DLAY7CIU.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-QTS2XGPQ.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-BMX2U22F.js";import"./chunk-6APXZK7W.js";import"./chunk-WOHQJ6JB.js";import"./chunk-GLTOBXZY.js";import"./chunk-NDSWTAYJ.js";import"./chunk-ZOFZRJSL.js";import"./chunk-ZFIC2DZV.js";import"./chunk-YK3ZZCHI.js";import"./chunk-T2SMQPRE.js";import"./chunk-RUGTHELO.js";import"./chunk-42XRJQM6.js";import"./chunk-2SOVDETB.js";import"./chunk-IHES3JES.js";import"./chunk-5XHOHZIR.js";import"./chunk-HW6AAS3R.js";import"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-EYSV6A7S.js";import"./chunk-MIENF2YK.js";import"./chunk-OXNWERO4.js";import"./chunk-44BJPS5I.js";import"./chunk-AOTHPTMU.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";export{runRpcMode};
@@ -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{AskUserQuestionComponent,AssistantMessageComponent,CustomEditor,ExtensionEditorComponent,UserMessageComponent,createChatViewport,createInteractiveTui}from"./chunk-C7OKUC7L.js";import{connectRpcClientSocket,requestDeadlineMs}from"./chunk-H33A33M4.js";import{ExtensionInputComponent,ExtensionSelectorComponent,getEditorTheme,initTheme,sharedMarkdownTheme,stopThemeWatcher,theme}from"./chunk-RQ6CHXQ2.js";import"./chunk-22YXCY7K.js";import{KeybindingsManager}from"./chunk-4GKU755E.js";import"./chunk-TQHNFP77.js";import"./chunk-C7HEEBFH.js";import"./chunk-26UBFF6N.js";import"./chunk-2CNSCMYC.js";import"./chunk-DBQBJTMF.js";import{MAX_RPC_LINE_CHARACTERS,attachJsonlLineReader,serializeJsonLine}from"./chunk-SF4MQDKZ.js";import"./chunk-KLAX467B.js";import"./chunk-MSDBBOB2.js";import"./chunk-6VWIMHMH.js";import"./chunk-YU2P3CAR.js";import{Container,Markdown,Text,TuiAltScreen,setKeybindings}from"./chunk-TMXRR3N7.js";import"./chunk-BPNSOZ2C.js";import"./chunk-DLAY7CIU.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import{markModeCrashHandler}from"./chunk-ZFIC2DZV.js";import"./chunk-RUGTHELO.js";import"./chunk-HW6AAS3R.js";import{getAgentDir}from"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";import{randomUUID as randomUUID2}from"node:crypto";import{randomUUID}from"node:crypto";var AttachRefusedError=class extends Error{constructor(code,message){super(message),this.name="AttachRefusedError",this.code=code}},AnswerRefusedError=class extends Error{constructor(code){super(`Answer refused: ${code}`),this.name="AnswerRefusedError",this.code=code}},ANSWER_DEADLINE_MS=3e4,AttachClient=class{constructor(onRecord,onDisconnect,options={}){this.pending=new Map,this.closed=!1,this.onRecord=onRecord,this.onDisconnect=onDisconnect,this.answerDeadlineMs=options.answerDeadlineMs??ANSWER_DEADLINE_MS}async connect(path){let socket=await connectRpcClientSocket(path,{});if(this.closed)throw socket.destroy(),new Error("Disconnected");this.socket=socket,this.stopReading=attachJsonlLineReader(socket,line=>this.receive(socket,line),{maxLineLength:MAX_RPC_LINE_CHARACTERS,onOversizedLine:()=>this.fail(socket,"the endpoint sent a record over the line limit")}),socket.once("error",()=>socket.destroy()),socket.once("close",()=>{this.socket=void 0,this.rejectPending(),this.closed||this.onDisconnect(this.failure)})}request(command){let id=randomUUID();return this.track(id,requestDeadlineMs(command),`No acknowledgement for ${command.type}; its outcome is unknown`,{...command,id})}async answer(sessionId,response){await this.track(response.id,this.answerDeadlineMs,"No acknowledgement for the answer",{...response,sessionId,answerId:randomUUID()})}close(){this.closed=!0,this.stopReading?.(),this.socket?.destroy(),this.socket=void 0,this.rejectPending()}track(id,deadlineMs,unanswered,record){return new Promise((resolve,reject)=>{let timer=setTimeout(()=>{this.pending.delete(id),reject(new Error(unanswered))},deadlineMs);if(this.pending.set(id,{resolve:answer=>{clearTimeout(timer),resolve(answer)},reject:error=>{clearTimeout(timer),reject(error)}}),this.socket?.writable&&!this.socket.destroyed){this.socket.write(serializeJsonLine(record));return}clearTimeout(timer),this.pending.delete(id),reject(new Error("Disconnected"))})}receive(socket,line){let record;try{record=JSON.parse(line)}catch{this.fail(socket,"the endpoint sent an unreadable record");return}if(record.type==="response"){let pending=record.id?this.pending.get(record.id):void 0;if(!pending)return;record.id&&this.pending.delete(record.id),record.success?pending.resolve(record):record.command==="extension_ui_response"?pending.reject(new AnswerRefusedError(record.error)):pending.reject(new Error(record.error));return}try{this.onRecord(record)}catch(error){this.fail(socket,`a ${record.type} record could not be shown (${error instanceof Error?error.message:String(error)})`)}}fail(socket,reason){this.failure??=reason,socket.destroy()}rejectPending(){for(let request of this.pending.values())request.reject(new Error("Disconnected; pending command outcome is unknown"));this.pending.clear()}};function remoteOriginLabel(request){let origin="remoteOrigin"in request?request.remoteOrigin:void 0;if(typeof origin!="object"||origin===null||!("deviceId"in origin))return;let name="deviceName"in origin&&typeof origin.deviceName=="string"?clean(origin.deviceName):"",id=typeof origin.deviceId=="string"?clean(origin.deviceId):"",device=name||id;return device?`Requested from ${device}`:void 0}var clean=value=>value.replace(/[\u0000-\u001f\u007f-\u009f]/g,"").trim(),AttachDialogs=class extends Container{constructor(ui,keys,answer,report,focusEditor){super(),this.queue=[],this.seen=new Set,this.settled=new Set,this.closed=!1,this.ui=ui,this.keys=keys,this.answer=answer,this.report=report,this.focusEditor=focusEditor}get active(){return this.current!==void 0}accept(request){this.seen.has(request.id)||["select","confirm","input","editor","question"].includes(request.method)&&(this.seen.add(request.id),this.queue.push(request),this.showNext())}resolve(id){this.settled.add(id);let index=this.queue.findIndex(request=>request.id===id);index>=0&&this.queue.splice(index,1),this.current?.request.id===id&&this.dismiss()}handleInput(data){this.current?.component.handleInput?.(data)}dispose(){this.closed=!0,this.queue.length=0,this.current?.component.dispose?.(),this.current=void 0,this.clear()}dismiss(){this.current?.component.dispose?.(),this.current=void 0,this.clear(),this.focusEditor(),this.showNext(),this.ui.requestRender()}submit(request,response){this.dismiss(),this.answer(response).catch(error=>{let code=error instanceof AnswerRefusedError?error.code:void 0;if(code==="question_already_resolved"||code==="unknown_extension_ui_request"){this.report(`Not accepted: ${code} (already settled)`);return}this.closed||this.settled.has(request.id)||(this.report(request.method==="input"&&request.secret?"Secret answer was not acknowledged. The outcome is unknown; enter a new answer only after checking.":`${error instanceof Error?error.message:String(error)}. Answer again.`),!(request.method==="input"&&request.secret&&(!(error instanceof AnswerRefusedError)||Date.now()>=(request.deadlineAtMs??0)))&&(this.queue.unshift(request),this.showNext(),this.ui.requestRender()))})}showNext(){if(this.current)return;let request=this.queue.shift();if(!request)return;let finish=response=>{this.current?.request.id===request.id&&this.submit(request,request.method==="input"&&request.secret?{...response,secret:!0,uiRequestId:request.id,id:crypto.randomUUID(),answerId:crypto.randomUUID()}:response)},cancel=()=>finish({type:"extension_ui_response",id:request.id,cancelled:!0}),component;switch(request.method){case"select":component=new ExtensionSelectorComponent(request.title,request.options,value=>finish({type:"extension_ui_response",id:request.id,value}),cancel,{tui:this.ui,timeout:request.timeout});break;case"confirm":component=new ExtensionSelectorComponent(request.title,["Yes","No"],value=>finish({type:"extension_ui_response",id:request.id,confirmed:value==="Yes"}),cancel,{tui:this.ui,timeout:request.timeout,description:request.message});break;case"input":if(request.secret&&(request.deadlineAtMs===void 0||request.deadlineAtMs<=Date.now())){this.settled.add(request.id),this.showNext();return}component=new ExtensionInputComponent(request.title,request.placeholder,value=>finish({type:"extension_ui_response",id:request.id,value}),cancel,{tui:this.ui,timeout:request.timeout,secret:request.secret,deadlineAtMs:request.deadlineAtMs});break;case"editor":component=new ExtensionEditorComponent(this.ui,this.keys,request.title,request.prefill,value=>finish({type:"extension_ui_response",id:request.id,value}),cancel);break;case"question":component=new AskUserQuestionComponent({requestId:request.requestId,questions:request.questions,waitForAnswer:request.waitForAnswer,timeoutMs:request.remainingMs},response=>response.status==="answered"||response.status==="comment-submitted"?finish({type:"extension_ui_response",id:request.id,answers:response.answers,comment:response.comment}):cancel(),{tui:this.ui,getDeadlineAtMs:()=>request.deadlineAtMs});break;default:return}this.current={request,component};let origin=remoteOriginLabel(request);origin&&this.addChild(new Text(theme.fg("warning",origin),1,0)),this.addChild(component),this.ui.setFocus(component),this.ui.requestRender()}};var RecordRenderer=class extends Container{constructor(){super(...arguments),this.rows=[],this.finalized=new Set,this.historyKeys=new Map}prepend(entries){let added=[];for(let entry of entries){if(entry.type!=="message")continue;let key=entry.id;this.historyKeys.set(this.messageKey(entry.message),key),this.finalized.add(key),!this.rows.some(row=>row.key===key)&&added.push({key,message:entry.message,component:this.component(entry.message)})}this.rows=[...added,...this.rows],this.rebuild()}accept(record){switch(record.type){case"message_start":if(this.finalized.has(this.key(record.message,record.entryId)))return;this.put(record.message,record.entryId);break;case"message_update":{if(record.message){this.put(record.message,record.entryId);break}let active=this.active;if(!active)return;let event=record.assistantMessageEvent,content=active.message.content;switch(event.type){case"text_start":content[event.contentIndex]={type:"text",text:""};break;case"thinking_start":content[event.contentIndex]={type:"thinking",thinking:""};break;case"text_delta":{let part=content[event.contentIndex];part?.type==="text"?part.text+=event.delta:content[event.contentIndex]={type:"text",text:event.delta};break}case"thinking_delta":{let part=content[event.contentIndex];part?.type==="thinking"?part.thinking+=event.delta:content[event.contentIndex]={type:"thinking",thinking:event.delta};break}case"toolcall_start":content[event.contentIndex]={type:"toolCall",id:event.id,name:event.toolName,arguments:{}};break;case"toolcall_end":content[event.contentIndex]=event.toolCall;break;default:break}active.message.usage=record.usage,active.component.updateContent(active.message);break}case"message_end":this.put(record.message,record.entryId),this.finalized.add(this.key(record.message,record.entryId)),this.active=void 0;break;default:break}}messageKey(message){return message.role==="toolResult"?`tool:${message.toolCallId}`:`${message.role}:${message.timestamp}`}key(message,entryId){return entryId??this.historyKeys.get(this.messageKey(message))??this.messageKey(message)}put(message,entryId){let key=this.key(message,entryId),existing=this.rows.find(row=>row.key===key)??this.rows.find(row=>!this.finalized.has(row.key)&&this.messageKey(row.message)===this.messageKey(message));if(message.role==="assistant"){let component=existing?.component instanceof AssistantMessageComponent?existing.component:new AssistantMessageComponent,snapshot=structuredClone(message);component.updateContent(snapshot),this.active={key,message:snapshot,component},existing?(existing.key=key,existing.component=component,existing.message=snapshot):this.rows.push({key,message:snapshot,component})}else existing?(existing.key=key,existing.message=message,existing.component=this.component(message)):this.rows.push({key,message,component:this.component(message)});this.rebuild()}component(message){switch(message.role){case"assistant":return new AssistantMessageComponent(message);case"user":{let text=typeof message.content=="string"?message.content:message.content.map(part=>part.type==="text"?part.text:"[image]").join(`
2
+ import{AskUserQuestionComponent,AssistantMessageComponent,CustomEditor,ExtensionEditorComponent,UserMessageComponent,createChatViewport,createInteractiveTui}from"./chunk-K3UHGDUQ.js";import{connectRpcClientSocket,requestDeadlineMs}from"./chunk-H33A33M4.js";import{ExtensionInputComponent,ExtensionSelectorComponent,getEditorTheme,initTheme,sharedMarkdownTheme,stopThemeWatcher,theme}from"./chunk-3TZQXZKH.js";import"./chunk-22YXCY7K.js";import{KeybindingsManager}from"./chunk-4GKU755E.js";import"./chunk-TQHNFP77.js";import"./chunk-XZDCMDUH.js";import"./chunk-26UBFF6N.js";import"./chunk-2CNSCMYC.js";import"./chunk-DBQBJTMF.js";import{MAX_RPC_LINE_CHARACTERS,attachJsonlLineReader,serializeJsonLine}from"./chunk-SF4MQDKZ.js";import"./chunk-KLAX467B.js";import"./chunk-MSDBBOB2.js";import"./chunk-6VWIMHMH.js";import"./chunk-YU2P3CAR.js";import{Container,Markdown,Text,TuiAltScreen,setKeybindings}from"./chunk-TMXRR3N7.js";import"./chunk-BPNSOZ2C.js";import"./chunk-DLAY7CIU.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import{markModeCrashHandler}from"./chunk-ZFIC2DZV.js";import"./chunk-RUGTHELO.js";import"./chunk-HW6AAS3R.js";import{getAgentDir}from"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";import{randomUUID as randomUUID2}from"node:crypto";import{randomUUID}from"node:crypto";var AttachRefusedError=class extends Error{constructor(code,message){super(message),this.name="AttachRefusedError",this.code=code}},AnswerRefusedError=class extends Error{constructor(code){super(`Answer refused: ${code}`),this.name="AnswerRefusedError",this.code=code}},ANSWER_DEADLINE_MS=3e4,AttachClient=class{constructor(onRecord,onDisconnect,options={}){this.pending=new Map,this.closed=!1,this.onRecord=onRecord,this.onDisconnect=onDisconnect,this.answerDeadlineMs=options.answerDeadlineMs??ANSWER_DEADLINE_MS}async connect(path){let socket=await connectRpcClientSocket(path,{});if(this.closed)throw socket.destroy(),new Error("Disconnected");this.socket=socket,this.stopReading=attachJsonlLineReader(socket,line=>this.receive(socket,line),{maxLineLength:MAX_RPC_LINE_CHARACTERS,onOversizedLine:()=>this.fail(socket,"the endpoint sent a record over the line limit")}),socket.once("error",()=>socket.destroy()),socket.once("close",()=>{this.socket=void 0,this.rejectPending(),this.closed||this.onDisconnect(this.failure)})}request(command){let id=randomUUID();return this.track(id,requestDeadlineMs(command),`No acknowledgement for ${command.type}; its outcome is unknown`,{...command,id})}async answer(sessionId,response){await this.track(response.id,this.answerDeadlineMs,"No acknowledgement for the answer",{...response,sessionId,answerId:randomUUID()})}close(){this.closed=!0,this.stopReading?.(),this.socket?.destroy(),this.socket=void 0,this.rejectPending()}track(id,deadlineMs,unanswered,record){return new Promise((resolve,reject)=>{let timer=setTimeout(()=>{this.pending.delete(id),reject(new Error(unanswered))},deadlineMs);if(this.pending.set(id,{resolve:answer=>{clearTimeout(timer),resolve(answer)},reject:error=>{clearTimeout(timer),reject(error)}}),this.socket?.writable&&!this.socket.destroyed){this.socket.write(serializeJsonLine(record));return}clearTimeout(timer),this.pending.delete(id),reject(new Error("Disconnected"))})}receive(socket,line){let record;try{record=JSON.parse(line)}catch{this.fail(socket,"the endpoint sent an unreadable record");return}if(record.type==="response"){let pending=record.id?this.pending.get(record.id):void 0;if(!pending)return;record.id&&this.pending.delete(record.id),record.success?pending.resolve(record):record.command==="extension_ui_response"?pending.reject(new AnswerRefusedError(record.error)):pending.reject(new Error(record.error));return}try{this.onRecord(record)}catch(error){this.fail(socket,`a ${record.type} record could not be shown (${error instanceof Error?error.message:String(error)})`)}}fail(socket,reason){this.failure??=reason,socket.destroy()}rejectPending(){for(let request of this.pending.values())request.reject(new Error("Disconnected; pending command outcome is unknown"));this.pending.clear()}};function remoteOriginLabel(request){let origin="remoteOrigin"in request?request.remoteOrigin:void 0;if(typeof origin!="object"||origin===null||!("deviceId"in origin))return;let name="deviceName"in origin&&typeof origin.deviceName=="string"?clean(origin.deviceName):"",id=typeof origin.deviceId=="string"?clean(origin.deviceId):"",device=name||id;return device?`Requested from ${device}`:void 0}var clean=value=>value.replace(/[\u0000-\u001f\u007f-\u009f]/g,"").trim(),AttachDialogs=class extends Container{constructor(ui,keys,answer,report,focusEditor){super(),this.queue=[],this.seen=new Set,this.settled=new Set,this.closed=!1,this.ui=ui,this.keys=keys,this.answer=answer,this.report=report,this.focusEditor=focusEditor}get active(){return this.current!==void 0}accept(request){this.seen.has(request.id)||["select","confirm","input","editor","question"].includes(request.method)&&(this.seen.add(request.id),this.queue.push(request),this.showNext())}resolve(id){this.settled.add(id);let index=this.queue.findIndex(request=>request.id===id);index>=0&&this.queue.splice(index,1),this.current?.request.id===id&&this.dismiss()}handleInput(data){this.current?.component.handleInput?.(data)}dispose(){this.closed=!0,this.queue.length=0,this.current?.component.dispose?.(),this.current=void 0,this.clear()}dismiss(){this.current?.component.dispose?.(),this.current=void 0,this.clear(),this.focusEditor(),this.showNext(),this.ui.requestRender()}submit(request,response){this.dismiss(),this.answer(response).catch(error=>{let code=error instanceof AnswerRefusedError?error.code:void 0;if(code==="question_already_resolved"||code==="unknown_extension_ui_request"){this.report(`Not accepted: ${code} (already settled)`);return}this.closed||this.settled.has(request.id)||(this.report(request.method==="input"&&request.secret?"Secret answer was not acknowledged. The outcome is unknown; enter a new answer only after checking.":`${error instanceof Error?error.message:String(error)}. Answer again.`),!(request.method==="input"&&request.secret&&(!(error instanceof AnswerRefusedError)||Date.now()>=(request.deadlineAtMs??0)))&&(this.queue.unshift(request),this.showNext(),this.ui.requestRender()))})}showNext(){if(this.current)return;let request=this.queue.shift();if(!request)return;let finish=response=>{this.current?.request.id===request.id&&this.submit(request,request.method==="input"&&request.secret?{...response,secret:!0,uiRequestId:request.id,id:crypto.randomUUID(),answerId:crypto.randomUUID()}:response)},cancel=()=>finish({type:"extension_ui_response",id:request.id,cancelled:!0}),component;switch(request.method){case"select":component=new ExtensionSelectorComponent(request.title,request.options,value=>finish({type:"extension_ui_response",id:request.id,value}),cancel,{tui:this.ui,timeout:request.timeout});break;case"confirm":component=new ExtensionSelectorComponent(request.title,["Yes","No"],value=>finish({type:"extension_ui_response",id:request.id,confirmed:value==="Yes"}),cancel,{tui:this.ui,timeout:request.timeout,description:request.message});break;case"input":if(request.secret&&(request.deadlineAtMs===void 0||request.deadlineAtMs<=Date.now())){this.settled.add(request.id),this.showNext();return}component=new ExtensionInputComponent(request.title,request.placeholder,value=>finish({type:"extension_ui_response",id:request.id,value}),cancel,{tui:this.ui,timeout:request.timeout,secret:request.secret,deadlineAtMs:request.deadlineAtMs});break;case"editor":component=new ExtensionEditorComponent(this.ui,this.keys,request.title,request.prefill,value=>finish({type:"extension_ui_response",id:request.id,value}),cancel);break;case"question":component=new AskUserQuestionComponent({requestId:request.requestId,questions:request.questions,waitForAnswer:request.waitForAnswer,timeoutMs:request.remainingMs},response=>response.status==="answered"||response.status==="comment-submitted"?finish({type:"extension_ui_response",id:request.id,answers:response.answers,comment:response.comment}):cancel(),{tui:this.ui,getDeadlineAtMs:()=>request.deadlineAtMs});break;default:return}this.current={request,component};let origin=remoteOriginLabel(request);origin&&this.addChild(new Text(theme.fg("warning",origin),1,0)),this.addChild(component),this.ui.setFocus(component),this.ui.requestRender()}};var RecordRenderer=class extends Container{constructor(){super(...arguments),this.rows=[],this.finalized=new Set,this.historyKeys=new Map}prepend(entries){let added=[];for(let entry of entries){if(entry.type!=="message")continue;let key=entry.id;this.historyKeys.set(this.messageKey(entry.message),key),this.finalized.add(key),!this.rows.some(row=>row.key===key)&&added.push({key,message:entry.message,component:this.component(entry.message)})}this.rows=[...added,...this.rows],this.rebuild()}accept(record){switch(record.type){case"message_start":if(this.finalized.has(this.key(record.message,record.entryId)))return;this.put(record.message,record.entryId);break;case"message_update":{if(record.message){this.put(record.message,record.entryId);break}let active=this.active;if(!active)return;let event=record.assistantMessageEvent,content=active.message.content;switch(event.type){case"text_start":content[event.contentIndex]={type:"text",text:""};break;case"thinking_start":content[event.contentIndex]={type:"thinking",thinking:""};break;case"text_delta":{let part=content[event.contentIndex];part?.type==="text"?part.text+=event.delta:content[event.contentIndex]={type:"text",text:event.delta};break}case"thinking_delta":{let part=content[event.contentIndex];part?.type==="thinking"?part.thinking+=event.delta:content[event.contentIndex]={type:"thinking",thinking:event.delta};break}case"toolcall_start":content[event.contentIndex]={type:"toolCall",id:event.id,name:event.toolName,arguments:{}};break;case"toolcall_end":content[event.contentIndex]=event.toolCall;break;default:break}active.message.usage=record.usage,active.component.updateContent(active.message);break}case"message_end":this.put(record.message,record.entryId),this.finalized.add(this.key(record.message,record.entryId)),this.active=void 0;break;default:break}}messageKey(message){return message.role==="toolResult"?`tool:${message.toolCallId}`:`${message.role}:${message.timestamp}`}key(message,entryId){return entryId??this.historyKeys.get(this.messageKey(message))??this.messageKey(message)}put(message,entryId){let key=this.key(message,entryId),existing=this.rows.find(row=>row.key===key)??this.rows.find(row=>!this.finalized.has(row.key)&&this.messageKey(row.message)===this.messageKey(message));if(message.role==="assistant"){let component=existing?.component instanceof AssistantMessageComponent?existing.component:new AssistantMessageComponent,snapshot=structuredClone(message);component.updateContent(snapshot),this.active={key,message:snapshot,component},existing?(existing.key=key,existing.component=component,existing.message=snapshot):this.rows.push({key,message:snapshot,component})}else existing?(existing.key=key,existing.message=message,existing.component=this.component(message)):this.rows.push({key,message,component:this.component(message)});this.rebuild()}component(message){switch(message.role){case"assistant":return new AssistantMessageComponent(message);case"user":{let text=typeof message.content=="string"?message.content:message.content.map(part=>part.type==="text"?part.text:"[image]").join(`
3
3
  `);return new UserMessageComponent(text)}case"toolResult":{let text=message.content.map(part=>part.type==="text"?part.text:"[image]").join(`
4
4
  `),result=new Container;return result.addChild(new Text(theme.fg("muted",message.toolName),1,0)),result.addChild(new Markdown(text,1,0,sharedMarkdownTheme())),result}default:return new Text("content"in message?String(message.content):message.role,1,0)}}rebuild(){this.clear();for(let row of this.rows)this.addChild(row.component)}};var ATTACH_CLIENT_CAPABILITIES=["interactive_user","question","grant_select","secret_input_v1"],WidthReporter=class{constructor(inner,onWidth){this.inner=inner,this.onWidth=onWidth}render(width){return this.onWidth(width),this.inner.render(width)}invalidate(){this.inner.invalidate()}};function validateAttachTerminal(inputIsTTY,outputIsTTY){if(!inputIsTTY||!outputIsTTY)throw new Error("--attach requires an interactive terminal on stdin and stdout")}var AttachedTui=class extends Container{constructor(ui,finish,options={}){super(),this.transcript=new RecordRenderer,this.statusText=new Text("Connecting",1,0),this.status=new WidthReporter(this.statusText,width=>this.reportWidth(width)),this.connected=!1,this.attached=!1,this.closing=!1,this.streaming=!1,this.buffering=[],this.ui=ui;let keys=KeybindingsManager.create();setKeybindings(keys),this.editor=new CustomEditor(ui,getEditorTheme(),keys),this.dialogs=new AttachDialogs(ui,keys,response=>this.sessionId?this.client.answer(this.sessionId,response):Promise.reject(new Error("Disconnected")),message=>this.showStatus(message),()=>ui.setFocus(this)),this.client=new AttachClient(record=>{record.sessionId&&record.sessionId!==this.sessionId||(this.buffering?this.buffering.push(record):this.record(record))},reason=>{this.connected=!1,this.dialogs.dispose(),ui.setFocus(this),this.showStatus(reason?`Disconnected: ${reason}`:"Disconnected")},{answerDeadlineMs:options.answerDeadlineMs}),this.editor.onSubmit=text=>{if(text.trim()==="/quit"){finish();return}this.perform(()=>this.submit(text),()=>{this.editor.getText()===""&&this.editor.setText(text)})},this.editor.onCtrlD=finish,this.editor.onAction("app.clear",finish),this.editor.onEscape=()=>this.perform(()=>this.abort()),this.addChild(this.transcript),this.addChild(this.status),this.addChild(this.dialogs),this.addChild(this.editor);let input=new Container;input.addChild(this.dialogs),input.addChild(this.editor),this.layoutRoot=createChatViewport({document:this.transcript,pendingMessages:new Container,status:this.status,editor:input,footer:new Text("/history /steer <text> /abort /quit",1,0),scrollbarTrackStyle:text=>theme.fg("scrollbarTrack",text),scrollbarThumbStyle:text=>theme.fg("scrollbarThumb",text)}).root}get focused(){return this.editor.focused}set focused(value){this.editor.focused=value}async connect(address,ref){let path=address.startsWith("unix://")?address.slice(7):address;if(!path||path.includes("://")||/^\\\\\.\\pipe\\/i.test(path))throw new Error("--attach needs a local socket path or a named pipe's logical filesystem path");try{await this.client.connect(path),this.connected=!0,this.width=this.ui.terminal.columns,await this.client.request({type:"set_client_info",width:this.width,capabilities:[...ATTACH_CLIENT_CAPABILITIES]});let listing=await this.client.request({type:"list_sessions",observe:!0});if(listing.command!=="list_sessions")throw new Error("Expected a session listing");let exact=listing.data.sessions.filter(row2=>row2.sessionId===ref||row2.durableSessionId===ref||row2.sessionPath===ref),matches=exact.length?exact:listing.data.sessions.filter(row2=>row2.durableSessionId?.startsWith(ref)),row=matches.length===1?matches[0]:void 0;if(!row?.durableSessionId)throw new Error(matches.length>1?"Ambiguous session reference":"No live session matches the reference");if(row.retain_on_disconnect!==!0)throw new AttachRefusedError("session_not_retained",`Session ${ref} is not retained on disconnect: the endpoint ends it when its last client leaves, so leaving this view could end it. Attach to a session opened with retain_on_disconnect.`);this.sessionId=row.sessionId,await this.client.request({type:"attach_session",sessionId:row.sessionId,durableSessionId:row.durableSessionId}),this.attached=!0;let subscribed=await this.client.request({type:"subscribe_sessions",sessions:{ids:[row.sessionId]},mirror:"all"}),state=await this.client.request({type:"get_state",sessionId:row.sessionId,observe:!0});if(state.command!=="get_state")throw new Error("Expected session state");this.state=state.data,this.streaming=state.data.isStreaming,await this.loadHistory();for(let dialog of[...state.data.pendingDialogs??[],...state.data.pendingQuestions??[]])this.dialogs.accept(dialog);if(this.showStatus(this.streaming?"Running":"Attached"),subscribed.command==="subscribe_sessions")for(let status of subscribed.data.snapshot)this.record(status);let buffered=this.buffering??[];this.buffering=void 0;for(let record of buffered)this.record(record)}catch(error){try{await this.close()}catch(releaseError){throw new AggregateError([error,releaseError],error instanceof Error?error.message:String(error))}throw error}}loadHistory(){return this.loadingHistory?this.loadingHistory:(this.loadingHistory=this.readHistory().finally(()=>{this.loadingHistory=void 0}),this.loadingHistory)}async readHistory(){if(!this.sessionId||!this.connected)return;let response=await this.client.request({type:"get_entries",sessionId:this.sessionId,tail:100,before:this.before,observe:!0});if(response.command!=="get_entries")throw new Error("Expected history entries");this.before=response.data.next_before,this.transcript.prepend(response.data.entries),this.ui.requestRender()}async submit(text){if(!this.connected||!this.sessionId)throw new Error("Disconnected; attach again to send input");if(text.trim()==="/history"){this.before&&await this.loadHistory();return}if(text.trim()==="/abort"){await this.abort();return}let steer=text.startsWith("/steer ")||this.streaming,message=text.startsWith("/steer ")?text.slice(7):text;message.trim()&&await this.client.request({type:steer?"steer":"prompt",sessionId:this.sessionId,message,clientMessageId:randomUUID2()})}async abort(){!this.sessionId||!this.connected||await this.client.request({type:"abort",sessionId:this.sessionId,intent:"stop",effectId:randomUUID2()})}async close(){if(!this.closing){this.closing=!0,this.dialogs.dispose();try{this.connected&&this.attached&&this.sessionId&&await this.client.request({type:"release_attachment",sessionId:this.sessionId})}finally{this.connected=!1,this.client.close()}}}handleInput(data){this.dialogs.active?this.dialogs.handleInput(data):this.editor.handleInput(data),this.ui.requestRender()}record(record){switch(this.transcript.accept(record),record.type){case"extension_ui_request":record.method==="notify"?this.showStatus(record.message):this.dialogs.accept(record);break;case"question_resolved":case"secret_input_settled":this.dialogs.resolve(record.id);break;case"session_status":this.streaming=record.status==="running",this.showStatus(record.status);break;case"agent_start":this.streaming=!0,this.showStatus("Running");break;case"agent_end":case"agent_settled":this.streaming=!1,this.showStatus("Attached");break;default:break}this.ui.requestRender()}reportWidth(width){!this.attached||!this.connected||width===this.width||(this.width=width,this.perform(async()=>{await this.client.request({type:"set_client_info",width})}))}showStatus(value){this.statusText.setText(theme.fg("muted",`${value}${this.state?.sessionName?` - ${this.state.sessionName}`:""}`)),this.ui.requestRender()}perform(action,onError){action().catch(error=>{onError?.(),this.showStatus(error instanceof Error?error.message:String(error))})}};async function runAttachedTui(options){validateAttachTerminal(process.stdin.isTTY,process.stdout.isTTY),initTheme(options.theme);let ui=createInteractiveTui({tuiMode:options.tuiMode??"regular",showHardwareCursor:!1,logDirectory:getAgentDir()}),restored=!1,restore=()=>{if(!restored){restored=!0;try{ui.stop()}finally{stopThemeWatcher()}}},crash=error=>{try{restore()}finally{console.error(error),process.exit(1)}};markModeCrashHandler(crash),process.prependListener("uncaughtException",crash),process.prependListener("unhandledRejection",crash);let finish=()=>{},done=new Promise(resolve=>{finish=resolve}),interrupt=()=>{},interrupted=new Promise(resolve=>{interrupt=()=>resolve("interrupted")}),view=new AttachedTui(ui,finish),leaving=!1,stop=exitCode=>{leaving&&(restore(),process.exit(exitCode)),leaving=!0,finish(),interrupt()},onSigterm=()=>stop(143),onSigint=()=>stop(130);process.on("SIGTERM",onSigterm),process.on("SIGINT",onSigint),ui.addChild(view),ui instanceof TuiAltScreen&&ui.setLayoutRoot(view.layoutRoot),ui.setFocus(view),ui.start();try{await Promise.race([view.connect(options.address,options.session).then(()=>"connected"),interrupted])==="connected"&&await done}finally{leaving=!0;try{restore()}finally{try{await view.close()}finally{process.off("SIGTERM",onSigterm),process.off("SIGINT",onSigint),process.off("uncaughtException",crash),process.off("unhandledRejection",crash)}}}}export{runAttachedTui};
@@ -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{processBootAtMs}from"./chunk-QN2BHP3M.js";import{DEFAULT_SCROLLBACK,MAX_SESSION_OUTPUT_CHARS,SecretOutputRedactor,loadPty}from"./chunk-AOTHPTMU.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";var pty=await loadPty(),RELEASED_SCREEN={cols:0,rows:0,visibleGrid:[],scrollback:[],cursor:{x:0,y:0}},TerminalRuntimeSession=class{constructor(command,options){this.finalScreen=null,this.decoder=new TextDecoder("utf-8",{fatal:!1}),this.buffer="",this.droppedChars=0,this.consumed=0,this.outputListeners=new Set,this.disposeListeners=new Set,this.unsubscribeData=null,this.lastScreenWrite=null,this.redactor=options.redactSecretsInOutput===!0?new SecretOutputRedactor:void 0,this.command=command,this.argv=[options.command??command,...options.args??[]],this.screen=new pty.TerminalScreen({cols:options.cols,rows:options.rows,scrollback:options.scrollback??DEFAULT_SCROLLBACK}),this.session=new pty.TerminalSession(options),this.unsubscribeData=this.session.onData(chunk=>{let text=this.decoder.decode(chunk,{stream:!0});this.ingest(this.redactor?this.redactor.push(text):text);let redactor=this.redactor;redactor&&(clearTimeout(this.redactionIdleTimer),this.redactionIdleTimer=setTimeout(()=>{this.redactionIdleTimer=void 0,this.ingest(redactor.flushIdle())},50),this.redactionIdleTimer.unref?.())}),this.screenRelease=new Promise(resolve=>{this.session.onExit(()=>{clearTimeout(this.redactionIdleTimer),this.redactionIdleTimer=void 0,this.redactor&&this.ingest(this.redactor.push(this.decoder.decode())+this.redactor.finish()),this.releaseScreen().catch(()=>{}).finally(resolve)})}),this.session.start(),this.startedAtMs=Date.now()}screenReleased(){return this.screenRelease}async releaseScreen(){let screen=this.screen;if(screen&&(await screen.flush().catch(()=>{}),this.screen===screen)){this.screen=null;try{this.finalScreen={...screen.snapshot(),scrollback:[]}}finally{screen.dispose()}}}get backend(){return this.session.backend}identity(){let pid=this.session.pid;if(pid===void 0)return;let processGroupId=this.session.processGroupId;return{pid,...processGroupId===void 0?{}:{processGroupId},startedAtMs:this.startedAtMs,bootAtMs:processBootAtMs(),argv:this.argv}}get exited(){return this.session.exited}get exitResult(){return this.session.exitResult}get totalChars(){return this.droppedChars+this.buffer.length}ingest(text){if(text.length!==0){if(this.screen&&this.ownScreenWrite(this.screen.feed(text)),this.buffer+=text,this.buffer.length>MAX_SESSION_OUTPUT_CHARS){let overflow=this.buffer.length-MAX_SESSION_OUTPUT_CHARS;this.buffer=this.buffer.slice(overflow),this.droppedChars+=overflow}for(let listener of this.outputListeners)try{listener(text)}catch{}}}onOutput(listener){return this.outputListeners.add(listener),()=>this.outputListeners.delete(listener)}onDispose(listener){return this.disposeListeners.add(listener),()=>this.disposeListeners.delete(listener)}readDelta(){let start=Math.max(this.consumed,this.droppedChars),dropped=Math.max(0,this.droppedChars-this.consumed),text=this.buffer.slice(start-this.droppedChars);return this.consumed=this.totalChars,{text,droppedChars:dropped}}fullOutput(){return this.buffer}snapshot(){return this.screen?this.screen.snapshot():this.finalScreen??RELEASED_SCREEN}resizeScreen(cols,rows){this.screen&&this.ownScreenWrite(this.screen.resize(cols,rows))}ownScreenWrite(written){written!==this.lastScreenWrite&&(this.lastScreenWrite=written,written.catch(()=>{}))}dispose(){clearTimeout(this.redactionIdleTimer),this.redactionIdleTimer=void 0,this.unsubscribeData?.(),this.unsubscribeData=null,this.outputListeners.clear(),this.screen?.dispose(),this.screen=null;let disposeListeners=[...this.disposeListeners];this.disposeListeners.clear();for(let listener of disposeListeners)listener()}};export{TerminalRuntimeSession};
2
+ import{processBootAtMs}from"./chunk-44BJPS5I.js";import{DEFAULT_SCROLLBACK,MAX_SESSION_OUTPUT_CHARS,SecretOutputRedactor,loadPty}from"./chunk-AOTHPTMU.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";var pty=await loadPty(),RELEASED_SCREEN={cols:0,rows:0,visibleGrid:[],scrollback:[],cursor:{x:0,y:0}},TerminalRuntimeSession=class{constructor(command,options){this.finalScreen=null,this.decoder=new TextDecoder("utf-8",{fatal:!1}),this.buffer="",this.droppedChars=0,this.consumed=0,this.outputListeners=new Set,this.disposeListeners=new Set,this.unsubscribeData=null,this.lastScreenWrite=null,this.redactor=options.redactSecretsInOutput===!0?new SecretOutputRedactor:void 0,this.command=command,this.argv=[options.command??command,...options.args??[]],this.screen=new pty.TerminalScreen({cols:options.cols,rows:options.rows,scrollback:options.scrollback??DEFAULT_SCROLLBACK}),this.session=new pty.TerminalSession(options),this.unsubscribeData=this.session.onData(chunk=>{let text=this.decoder.decode(chunk,{stream:!0});this.ingest(this.redactor?this.redactor.push(text):text);let redactor=this.redactor;redactor&&(clearTimeout(this.redactionIdleTimer),this.redactionIdleTimer=setTimeout(()=>{this.redactionIdleTimer=void 0,this.ingest(redactor.flushIdle())},50),this.redactionIdleTimer.unref?.())}),this.screenRelease=new Promise(resolve=>{this.session.onExit(()=>{clearTimeout(this.redactionIdleTimer),this.redactionIdleTimer=void 0,this.redactor&&this.ingest(this.redactor.push(this.decoder.decode())+this.redactor.finish()),this.releaseScreen().catch(()=>{}).finally(resolve)})}),this.session.start(),this.startedAtMs=Date.now()}screenReleased(){return this.screenRelease}async releaseScreen(){let screen=this.screen;if(screen&&(await screen.flush().catch(()=>{}),this.screen===screen)){this.screen=null;try{this.finalScreen={...screen.snapshot(),scrollback:[]}}finally{screen.dispose()}}}get backend(){return this.session.backend}identity(){let pid=this.session.pid;if(pid===void 0)return;let processGroupId=this.session.processGroupId;return{pid,...processGroupId===void 0?{}:{processGroupId},startedAtMs:this.startedAtMs,bootAtMs:processBootAtMs(),argv:this.argv}}get exited(){return this.session.exited}get exitResult(){return this.session.exitResult}get totalChars(){return this.droppedChars+this.buffer.length}ingest(text){if(text.length!==0){if(this.screen&&this.ownScreenWrite(this.screen.feed(text)),this.buffer+=text,this.buffer.length>MAX_SESSION_OUTPUT_CHARS){let overflow=this.buffer.length-MAX_SESSION_OUTPUT_CHARS;this.buffer=this.buffer.slice(overflow),this.droppedChars+=overflow}for(let listener of this.outputListeners)try{listener(text)}catch{}}}onOutput(listener){return this.outputListeners.add(listener),()=>this.outputListeners.delete(listener)}onDispose(listener){return this.disposeListeners.add(listener),()=>this.disposeListeners.delete(listener)}readDelta(){let start=Math.max(this.consumed,this.droppedChars),dropped=Math.max(0,this.droppedChars-this.consumed),text=this.buffer.slice(start-this.droppedChars);return this.consumed=this.totalChars,{text,droppedChars:dropped}}fullOutput(){return this.buffer}snapshot(){return this.screen?this.screen.snapshot():this.finalScreen??RELEASED_SCREEN}resizeScreen(cols,rows){this.screen&&this.ownScreenWrite(this.screen.resize(cols,rows))}ownScreenWrite(written){written!==this.lastScreenWrite&&(this.lastScreenWrite=written,written.catch(()=>{}))}dispose(){clearTimeout(this.redactionIdleTimer),this.redactionIdleTimer=void 0,this.unsubscribeData?.(),this.unsubscribeData=null,this.outputListeners.clear(),this.screen?.dispose(),this.screen=null;let disposeListeners=[...this.disposeListeners];this.disposeListeners.clear();for(let listener of disposeListeners)listener()}};export{TerminalRuntimeSession};
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{RUNNER_HEARTBEAT_INTERVAL_MS,RUNNER_HEARTBEAT_STALE_MS,cancelScheduledJob,deferWhileSessionOpen,execHookDelivery,listScheduledJobs,liveRunners,ownRunnerIdentity,removeRunnerLease,runDueJobs,scheduleDir,sessionResumeDelivery,writeRunnerLease}from"./chunk-7PSBD5KS.js";import"./chunk-GTJJ73DE.js";import"./chunk-26UBFF6N.js";import{resolveCliMainPath,runtimeExecArgv}from"./chunk-I3PHVJAS.js";import"./chunk-R2Z7CX77.js";import"./chunk-EAEEM2KN.js";import"./chunk-YI6KRJDC.js";import"./chunk-DBQBJTMF.js";import"./chunk-SF4MQDKZ.js";import"./chunk-U3VOXCGP.js";import"./chunk-SOMFLLPD.js";import"./chunk-DSWDJ7HT.js";import"./chunk-GKAYPJ4E.js";import"./chunk-EVTTLPIY.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-QTS2XGPQ.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-BMX2U22F.js";import"./chunk-WOHQJ6JB.js";import"./chunk-YK3ZZCHI.js";import"./chunk-T2SMQPRE.js";import"./chunk-RUGTHELO.js";import"./chunk-42XRJQM6.js";import"./chunk-5XHOHZIR.js";import"./chunk-HW6AAS3R.js";import{APP_NAME,getAgentDir,isBunBinary}from"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-QN2BHP3M.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";import{mkdirSync,watch}from"node:fs";import{join}from"node:path";function writeLine(value){process.stdout.write(`${JSON.stringify(value)}
2
+ import{RUNNER_HEARTBEAT_INTERVAL_MS,RUNNER_HEARTBEAT_STALE_MS,cancelScheduledJob,deferWhileSessionOpen,execHookDelivery,listScheduledJobs,liveRunners,ownRunnerIdentity,removeRunnerLease,runDueJobs,scheduleDir,sessionResumeDelivery,writeRunnerLease}from"./chunk-STGOYIXC.js";import"./chunk-GTJJ73DE.js";import"./chunk-26UBFF6N.js";import{resolveCliMainPath,runtimeExecArgv}from"./chunk-I3PHVJAS.js";import"./chunk-R2Z7CX77.js";import"./chunk-EAEEM2KN.js";import"./chunk-YI6KRJDC.js";import"./chunk-DBQBJTMF.js";import"./chunk-SF4MQDKZ.js";import"./chunk-U3VOXCGP.js";import"./chunk-SOMFLLPD.js";import"./chunk-WQ4RBPMS.js";import"./chunk-7PROV6BB.js";import"./chunk-EVTTLPIY.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-QTS2XGPQ.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-BMX2U22F.js";import"./chunk-WOHQJ6JB.js";import"./chunk-YK3ZZCHI.js";import"./chunk-T2SMQPRE.js";import"./chunk-RUGTHELO.js";import"./chunk-42XRJQM6.js";import"./chunk-5XHOHZIR.js";import"./chunk-HW6AAS3R.js";import{APP_NAME,getAgentDir,isBunBinary}from"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-44BJPS5I.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";import{mkdirSync,watch}from"node:fs";import{join}from"node:path";function writeLine(value){process.stdout.write(`${JSON.stringify(value)}
3
3
  `)}function resolveDelivery(options){let timeoutMs=options.timeoutSeconds*1e3;return options.exec!==void 0?{deliver:execHookDelivery(options.exec,timeoutMs),shouldDefer:void 0}:{deliver:sessionResumeDelivery({command:process.execPath,args:isBunBinary?[]:[...runtimeExecArgv(),resolveCliMainPath()]},timeoutMs),shouldDefer:deferWhileSessionOpen}}function reporter(){let deferred=new Map,invalid=new Map;return result=>{let ok=!0,stillInvalid=new Set;for(let event of result.events){if(event.event==="deferred"){if(deferred.get(event.id)===event.reason)continue;deferred.set(event.id,event.reason)}else if(event.event==="invalid"){if(stillInvalid.add(event.file),invalid.get(event.file)===event.error)continue;invalid.set(event.file,event.error)}else event.event==="fired"?(deferred.delete(event.id),event.outcome==="failed"&&(ok=!1)):event.event==="error"&&(ok=!1);writeLine(event)}for(let file of invalid.keys())stillInvalid.has(file)||invalid.delete(file);return ok}}async function guardedPass(pass){try{return await pass()}catch(error){return{events:[{event:"error",error:error instanceof Error?error.message:String(error)}],nextDueAt:void 0}}}async function runPasses(dir,options){let plan=resolveDelivery(options),owner=ownRunnerIdentity(),startedAt=Date.now(),lease=()=>writeRunnerLease(dir,{startedAt,watch:options.watch,exec:options.exec??null},Date.now()),report=reporter(),pass=()=>runDueJobs({dir,now:Date.now,deliver:plan.deliver,owner,concurrency:options.concurrency,deliveryTimeoutMs:options.timeoutSeconds*1e3,shouldDefer:plan.shouldDefer});await lease();let leaseFailing=!1,heartbeat=setInterval(()=>{lease().then(()=>{leaseFailing=!1},error=>{leaseFailing||writeLine({event:"lease_error",error:error instanceof Error?error.message:String(error)}),leaseFailing=!0})},RUNNER_HEARTBEAT_INTERVAL_MS),watcher,stopping=!1,wake,stop=()=>{stopping=!0,wake?.()};try{if(!options.watch)return report(await guardedPass(pass))?0:1;process.on("SIGTERM",stop),process.on("SIGINT",stop);let pendingDir=join(dir,"pending");for(mkdirSync(pendingDir,{recursive:!0,mode:448}),watcher=watch(pendingDir,()=>wake?.()),writeLine({event:"watching",pid:process.pid,dir,pollSeconds:options.pollSeconds});!stopping;){let rescan=!1,woken=new Promise(resolve=>{wake=()=>{rescan=!0,resolve()}}),result=await guardedPass(pass);if(report(result),stopping)break;if(rescan)continue;let untilDue=result.nextDueAt===void 0?Number.POSITIVE_INFINITY:result.nextDueAt-Date.now(),waitMs=Math.max(0,Math.min(options.pollSeconds*1e3,untilDue)),timer;await Promise.race([woken,new Promise(resolve=>timer=setTimeout(resolve,waitMs))]),clearTimeout(timer)}return writeLine({event:"stopped",pid:process.pid}),0}finally{clearInterval(heartbeat),watcher?.close(),process.off("SIGTERM",stop),process.off("SIGINT",stop),await removeRunnerLease(dir)}}var EXIT_OK=0,EXIT_FAILED=1,EXIT_USAGE=2,DEFAULT_POLL_SECONDS=60,DEFAULT_TIMEOUT_SECONDS=900,DEFAULT_CONCURRENCY=4,USAGE=`usage: ${APP_NAME} schedule <list|cancel|run> [options]
4
4
 
5
5
  list [--json] every scheduled prompt, all sessions
@@ -1,3 +1,3 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{SessionEventWriter,answerSubscribeSessions,answerUnsubscribeSessions,presenterContextReply,refusal,sessionRuntimeView,socketSink,startMcpPresenterControl}from"./chunk-GNSMNSL7.js";import{CONNECTION_ROLE_FIXED,ConnectionRoles,TerminalSealedSecrets,WakeScheduler,answerGetEntries,answeredUiRequestId,availableModelsData,buildRpcSessionState,getSnapshot,interruptRunningTurn,onProcessContinue,rpcCommandShapeError,runAbort,runGetEffectStatus,sessionUiAnswerLedger,settledQuestionStatus,subscribeSessionRecords,unansweredQuestionIds,unsupportedThinkingLevel,watchInbox}from"./chunk-XCMII2VQ.js";import"./chunk-SJI6UB23.js";import"./chunk-436DNN4Z.js";import"./chunk-J2I56WLK.js";import"./chunk-TQHNFP77.js";import"./chunk-C7HEEBFH.js";import"./chunk-MOVB6H22.js";import"./chunk-VD7AKTGP.js";import{ENTRIES_TAIL_CAPABILITY,INTERACTIVE_USER_CAPABILITY,OBSERVE_READS_CAPABILITY,SESSION_STATUS_CAPABILITY,TUI_OBSERVER_CAPABILITY,describeRpcMethodClasses,engineBuildIdentity,gcHostEndpoints}from"./chunk-HLM46XEB.js";import"./chunk-QMRJYMNH.js";import"./chunk-Y7Z7XPUF.js";import"./chunk-54YTJCYZ.js";import"./chunk-26UBFF6N.js";import"./chunk-I5ASHSLZ.js";import{tuiSocketName}from"./chunk-2CNSCMYC.js";import"./chunk-7WYJAYHH.js";import{acquireHostEnsureLock,thisProcessStartTime,writeHostRegistration}from"./chunk-EAEEM2KN.js";import{createDaemonDirectories,createHostDaemonPaths}from"./chunk-YI6KRJDC.js";import"./chunk-DBQBJTMF.js";import{MAX_RPC_LINE_CHARACTERS,attachJsonlLineReader,serializeJsonLine}from"./chunk-SF4MQDKZ.js";import"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import"./chunk-U3VOXCGP.js";import"./chunk-6VWIMHMH.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-RUGTHELO.js";import"./chunk-42XRJQM6.js";import{MAX_SOCKET_PATH_BYTES}from"./chunk-5XHOHZIR.js";import{authenticateSocket,createSocketSecret,resolveSocketTransportAddress,socketSecretPath}from"./chunk-HW6AAS3R.js";import{VERSION}from"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";import{randomUUID as randomUUID2}from"node:crypto";import{rm as rm3}from"node:fs/promises";var ControlAttachments=class{constructor(session,pendingQuestions,presenters){this.writer=new SessionEventWriter(()=>{}),this.roles=new ConnectionRoles,this.receipts=new Map,this.attached=new Set,this.session=session,this.presenters=presenters,this.writer.status.setSource({sessionIds:()=>[this.handle],entryView:id=>id===this.handle?this.entryView():void 0,view:id=>id===this.handle?{entry:this.entryView(),runtime:sessionRuntimeView(session,pendingQuestions())}:void 0}),this.writer.registerConnection(NULL_CONNECTION,{writeRaw:()=>{},waitForBackpressure:async()=>{}}),this.stopRecords=subscribeSessionRecords(session,record=>this.writer.enqueue(this.handle,record))}get handle(){return this.session.sessionId}opened(connection){this.writer.registerConnection(keyOf(connection),connection.transport),this.presenters?.opened(keyOf(connection),connection.transport)}closed(connection){let key=keyOf(connection);this.attached.delete(key)&&this.writer.status.publish(this.handle,"detach","client"),this.roles.release(key),this.presenters?.closed(key),this.writer.unregisterConnection(key)}detach(connection){let key=keyOf(connection);return this.attached.delete(key)?(this.presenters?.detach(key),this.writer.detachConnectionFromSession(key,this.handle),this.writer.status.publish(this.handle,"detach","client"),!0):!1}attach(connection){let key=keyOf(connection);return this.attached.has(key)?!1:(this.attached.add(key),this.presenters?.attach(key),this.writer.attachConnectionToSession(key,this.handle),this.writer.status.publish(this.handle,"attach","client"),!0)}isAttached(connection){return this.attached.has(keyOf(connection))}run(connection,task){return this.writer.withConnection(keyOf(connection),task)}respond(connection,answer2){this.writer.enqueueControl(answer2,keyOf(connection)).catch(()=>connection.transport.close?.())}dispose(){this.stopRecords()}entryView(){let manager=this.session.sessionManager,path=this.session.sessionFile,name=manager.getSessionName();return{state:"open",kind:"interactive",cwd:manager.getCwd(),attachments:1+this.attached.size,durableSessionId:this.session.sessionId,...path!==void 0?{sessionPath:path}:{},...name!==void 0?{name}:{},context:{}}}},NULL_CONNECTION="tui-null";function keyOf(connection){return`tui-${connection.id}`}import{realpathSync}from"node:fs";import{resolve}from"node:path";import{randomUUID}from"node:crypto";function idOf(command){return typeof command.id=="string"?command.id:void 0}function answered(id,command,data){return{...id===void 0?{}:{id},type:"response",command,success:!0,data}}function admitPrompt(context,command){let behavior=command.streamingBehavior;return behavior===void 0&&context.session.isStreaming?refusal(idOf(command),"prompt","session_busy",{reason:"a turn is running and the prompt names no streamingBehavior",action:'send it with streamingBehavior "steer" or "followUp", or as a steer/follow_up'}):admitInput(context,command,behavior==="followUp"?"followUp":"steer","start")}var UNSERVED_INPUT_FIELDS=["images","thinkingLevel","expandPromptTemplates","unknownCommandAsText","sessionTitlePrompt","enqueueOrder","chainCount"];function admitInput(context,command,deliverAs,whenIdle){let id=idOf(command),unserved=UNSERVED_INPUT_FIELDS.filter(field=>command[field]!==void 0);if(unserved.length>0)return refusal(id,command.type,"unsupported_field",{reason:`a terminal delivers input through its admission, which carries text only, not ${unserved.join(", ")}`,action:"send the message without those fields, or send it to a host session"});let message=command.message;if(typeof message!="string"||message.trim()==="")return refusal(id,command.type,"invalid_message",{reason:"message is empty",action:"send a non-empty message"});if(whenIdle!==void 0&&whenIdle!=="queue"&&whenIdle!=="start")return refusal(id,command.type,"invalid_when_idle",{reason:`whenIdle must be "queue" or "start", not ${JSON.stringify(whenIdle)}`,action:'send whenIdle: "queue" (the default) or "start"'});let admission=context.session.externalAdmission,clientMessageId=typeof command.clientMessageId=="string"?command.clientMessageId:void 0,fingerprint=JSON.stringify([command.type,message,deliverAs,whenIdle??null]),prior=clientMessageId===void 0?void 0:context.attachments.receipts.get(clientMessageId);if(prior!==void 0)return prior.fingerprint!==fingerprint?refusal(id,command.type,"client_message_id_conflict",{reason:`clientMessageId ${clientMessageId} was already used for different input`,action:"send new input with a new clientMessageId"}):answered(id,command.type,{disposition:prior.disposition,clientMessageId,replayed:!0,duplicate:!0,admission:prior.admission});let expected=typeof command.expected_turn_id=="number"?command.expected_turn_id:admission.turnEpoch,result=admission.admit({delivery_id:clientMessageId??`tui-rpc-${randomUUID()}`,text:message,sender:{kind:"external",platform:"rpc"},deliverAs,expected_turn_id:expected,whenIdle:whenIdle==="start"?"start":"queue"}),identity=clientMessageId===void 0?{}:{clientMessageId},admitted=disposition=>{if(clientMessageId===void 0)return answered(id,command.type,{disposition});let receipt={fingerprint,disposition,admission:{clientMessageId,durableSessionId:context.session.sessionId,disposition}};return context.attachments.receipts.set(clientMessageId,receipt),answered(id,command.type,{disposition,clientMessageId,admission:receipt.admission})};switch(result.kind){case"started":return admitted("started");case"steered":case"queued":return admitted("queued");case"already_admitted":return answered(id,command.type,{disposition:"queued",duplicate:!0,...identity});case"held_draft":return refusal(id,command.type,"held_draft",{reason:"the user is composing in this terminal, so nothing was delivered",action:"retry after the draft is sent or cleared"});case"turn_conflict":return refusal(id,command.type,"turn_conflict",{reason:`the turn moved on (now ${result.turn_epoch}); this steer named an earlier one`,action:"read get_state's turn_epoch and send it again"})}}import{chmod}from"node:fs/promises";import{createServer}from"node:net";async function listenControlSocket(socketPath,secret,handlers){let clients=new Set,nextConnection=0,server=createServer(socket=>{clients.add(socket),socket.once("close",()=>clients.delete(socket)),socket.on("error",()=>socket.destroy()),authenticateSocket(socket,secret,()=>acceptConnection(socket,++nextConnection,handlers))});return await new Promise((resolve2,reject)=>{server.once("error",reject),server.listen(resolveSocketTransportAddress(socketPath,process.platform,secret),()=>{server.off("error",reject),resolve2()})}),server.on("error",error=>handlers.listenerError(error)),process.platform!=="win32"&&await chmod(socketPath,384),{close:()=>closeServer(server,clients)}}function acceptConnection(socket,id,handlers){let connection={id,send:record=>{handlers.respond!==void 0?handlers.respond(connection,record):socket.destroyed||socket.write(serializeJsonLine(record))},transport:socketSink(socket)};handlers.opened?.(connection);let detach=attachJsonlLineReader(socket,line=>{answer(connection,line,handlers)},{maxLineLength:MAX_RPC_LINE_CHARACTERS,onOversizedLine:()=>connection.send(failure(void 0,"parse","RPC line exceeds the size limit."))});socket.once("close",()=>{detach(),handlers.closed(connection)})}async function answer(connection,line,handlers){let parsed;try{parsed=JSON.parse(line)}catch{connection.send(failure(void 0,"parse","Invalid JSON."));return}let shapeError=rpcCommandShapeError(parsed);if(shapeError!==void 0||!isCommand(parsed)){connection.send(failure(void 0,"parse",shapeError??"RPC command needs a string `type`."));return}let answer2=await handlers.command(connection,parsed);answer2!==null&&connection.send(answer2)}function isCommand(value){return typeof value=="object"&&value!==null&&"type"in value&&typeof value.type=="string"}function failure(id,command,error){return{...id===void 0?{}:{id},type:"response",command,success:!1,error}}function success(id,command,data){return{...id===void 0?{}:{id},type:"response",command,success:!0,...data===void 0?{}:{data}}}function closeServer(server,clients){for(let client of clients)client.destroy();return new Promise(resolve2=>server.close(()=>resolve2()))}import{rm}from"node:fs/promises";var TERMINAL_PRESENTER_COMMANDS=["mcp_presenter_context","mcp_form_presented","mcp_form_response","mcp_form_sync","mcp_presenter_secret_answer"];async function startTerminalPresenters(presenter){let surface=new TerminalPresenterSurface(presenter.local),started=await startMcpPresenterControl(surface,{enforcement:!0,account:presenter.account});return{surface,dispose:async()=>{started?.control.dispose(),started?.dir&&await rm(started.dir,{recursive:!0,force:!0})}}}function presents(capabilities){return capabilities.includes("interactive_user")&&capabilities.includes("mcp_form_presenter_v1")}function writePrivate(transport,record){try{return transport.writeRaw(serializeJsonLine(record)),!0}catch{return!1}}var TerminalPresenterSurface=class{constructor(local){this.sharedAuthority=!0,this.peers=new Map,this.local=local,this.authority=local.authority,this.binding=local.binding,this.sessionId=local.sessionId}attachSealedSecrets(source){let sealed=new TerminalSealedSecrets(source,this.sessionId,this.local.admit);return this.local.sealed=sealed,()=>{this.local.sealed===sealed&&(this.local.sealed=void 0),sealed.dispose()}}getMcpFormBinding(sessionId){return sessionId===this.sessionId?this.binding:void 0}findMcpPresenterConnection(nonce){for(let peer of this.peers.values())if(peer.sender?.nonce===nonce)return peer.sender}getConnectionCapabilities(id){return this.peers.get(id)?.capabilities}advertiseMcpPresenterControl(path){this.controlEndpoint=path}withdrawMcpPresenterControl(path){this.controlEndpoint===path&&(this.controlEndpoint=void 0)}opened(id,transport){this.peers.set(id,{transport,capabilities:[],attached:!1})}declare(id,capabilities){let peer=this.peers.get(id);if(peer){if(peer.capabilities=[...capabilities],!presents(capabilities)){peer.sender&&this.authority.withdraw(peer.sender);return}if(!peer.sender){let sender=this.authority.connect(id,frame=>this.peers.get(id)!==peer||!writePrivate(peer.transport,frame)?(this.authority.detach(sender),!1):(peer.transport.waitForBackpressure().catch(()=>this.authority.detach(sender)),!0));peer.sender=sender}peer.attached&&this.authority.attach(peer.sender,this.binding)}}attach(id){let peer=this.peers.get(id);peer&&(peer.attached=!0,peer.sender&&this.authority.attach(peer.sender,this.binding))}detach(id){let peer=this.peers.get(id);peer&&(peer.attached=!1,peer.sender&&this.authority.detach(peer.sender,this.binding))}closed(id){let sender=this.peers.get(id)?.sender;this.peers.delete(id),sender&&this.authority.detach(sender)}receive(id,frame){let peer=this.peers.get(id);if(!peer)return;if(frame.type==="mcp_presenter_secret_answer"){let lineId=typeof frame.id=="string"?{id:frame.id}:{};(this.local.sealed?.receive(id,frame)??Promise.resolve({error:"secret_answer_refused"})).catch(()=>({error:"secret_answer_refused"})).then(reply2=>{!writePrivate(peer.transport,{type:"mcp_presenter_secret_reply",...lineId,...reply2})&&peer.sender&&this.authority.detach(peer.sender)});return}let sender=peer.sender,reply=frame.type==="mcp_presenter_context"?presenterContextReply(this.authority,sender,frame,this.controlEndpoint):sender?this.authority.receive(sender,frame):{error:"presenter_not_authorized"},answer2={type:"mcp_form_reply",...typeof frame.id=="string"?{id:frame.id}:{},...reply};!writePrivate(peer.transport,answer2)&&sender&&this.authority.detach(sender)}};var TUI_RPC_COMMANDS=["open_session","get_snapshot","subscribe_sessions","unsubscribe_sessions","steer","follow_up","prompt","get_effect_status","set_client_info","attach_session","release_attachment","abort",...TERMINAL_PRESENTER_COMMANDS],STOP_REQUIRES_INTERACTIVE_CLIENT="stop_requires_interactive_client: declare interactive_user with set_client_info first";async function runTuiRpcCommand(context,connection,command){switch(command.type){case"get_snapshot":{let{attachments,session}=context;if(command.sessionId!==void 0&&command.sessionId!==attachments.handle)return{id:command.id,type:"response",command:command.type,success:!1,error:"unknown_session"};let snapshot=getSnapshot(session,{tail:command.tail,maxBytes:command.maxBytes},{enqueue:markerId=>attachments.run(connection,()=>attachments.writer.enqueue(attachments.handle,{type:"snapshot_marker",markerId}))});return"error"in snapshot?{id:command.id,type:"response",command:command.type,success:!1,error:snapshot.error}:answered(idOf(command),command.type,snapshot.data)}case"open_session":return openSession(context,connection,command);case"subscribe_sessions":return subscribe(context,connection,command);case"unsubscribe_sessions":return answerUnsubscribeSessions(command,keyOf(connection),context.attachments.writer.status);case"steer":case"follow_up":return admitInput(context,command,command.type==="steer"?"steer":"followUp",command.whenIdle);case"prompt":return admitPrompt(context,command);case"set_client_info":return setClientInfo(context,connection,command);case"attach_session":return attachSession(context,connection,command);case"release_attachment":return releaseAttachment(context,connection,command);case"abort":return abort(context,connection,command);case"mcp_presenter_context":case"mcp_form_presented":case"mcp_form_response":case"mcp_form_sync":case"mcp_presenter_secret_answer":return context.attachments.presenters?(context.attachments.presenters.receive(keyOf(connection),command),null):void 0;case"get_effect_status":return runGetEffectStatus({session:context.session,by:{connectionId:keyOf(connection)},sessionId:context.attachments.handle},command);default:return}}function openSession(context,connection,command){let{session,attachments}=context,ownPath=typeof command.sessionPath=="string"&&samePath(command.sessionPath,session.sessionFile),ownId=command.sessionId!==void 0&&command.sessionId===session.sessionId;return!ownPath&&!ownId?refusal(idOf(command),"open_session","terminal_single_session",{reason:"this terminal hosts one session and the request names another",action:"open it by this terminal's sessionPath, or open the other session on a host"}):(attachments.run(connection,()=>{attachments.attach(connection),attachments.writer.enqueue(attachments.handle,{id:command.id,type:"response",command:"open_session",success:!0,data:{sessionId:attachments.handle,state:buildRpcSessionState(session),attached:!0}})}),null)}function setClientInfo(context,connection,command){let capabilities=command.capabilities;return capabilities===void 0?success(command.id,"set_client_info"):!Array.isArray(capabilities)||!capabilities.every(entry=>typeof entry=="string")?failure(command.id,"set_client_info","capabilities must be an array of strings"):context.attachments.roles.declare(keyOf(connection),capabilities)!=="declared"?failure(command.id,"set_client_info",CONNECTION_ROLE_FIXED):(context.attachments.presenters?.declare(keyOf(connection),capabilities),success(command.id,"set_client_info"))}function attachSession(context,connection,command){let{session,attachments}=context,id=idOf(command);if(command.sessionId!==attachments.handle)return refusal(id,"attach_session","unknown_session",{reason:"this terminal hosts one session and the request names another",action:"attach with this terminal's sessionId from list_sessions"});let instanceMatches=command.expectedHostInstance===void 0||command.expectedHostInstance===context.instanceId;return command.durableSessionId!==session.sessionId||!instanceMatches?refusal(id,"attach_session","session_identity_mismatch",{reason:"durableSessionId or expectedHostInstance does not name this terminal's session",action:"read list_sessions and get_protocol_info again, then attach with their ids"}):command.takeover===!0?refusal(id,"attach_session","takeover_unsupported",{reason:"only a headless engine with a takeover ledger takes sessions over",action:"attach without takeover"}):(attachments.run(connection,()=>{attachments.attach(connection),attachments.writer.enqueue(attachments.handle,{id:command.id,type:"response",command:"attach_session",success:!0,data:{sessionId:attachments.handle,attached:!0}})}),null)}function releaseAttachment(context,connection,command){return command.sessionId!==context.attachments.handle||!context.attachments.detach(connection)?refusal(idOf(command),"release_attachment","session_not_attached",{reason:"this connection is not attached to that session",action:"attach first with attach_session or open_session"}):success(command.id,"release_attachment",{deferred:!1})}async function abort(context,connection,command){let key=keyOf(connection);if(command.intent==="stop"&&!context.attachments.roles.has(key,INTERACTIVE_USER_CAPABILITY))return failure(command.id,"abort",STOP_REQUIRES_INTERACTIVE_CLIENT);let{session}=context;return runAbort({session,by:{connectionId:key},sessionId:context.attachments.handle},command,()=>(command.intent==="stop"?session.stop():session.abort()).catch(cause=>{connection.send({type:"rpc_error",error:String(cause)})}))}function subscribe(context,connection,command){let{writer}=context.attachments,key=keyOf(connection),{answer:answer2,activate}=answerSubscribeSessions(command,key,writer.status);return activate===void 0?answer2:(writer.enqueueControl(answer2,key).then(()=>{writer.hasConnection(key)?writer.status.activate(activate):writer.status.unsubscribe(key,activate)}).catch(()=>writer.status.unsubscribe(key,activate)),null)}function samePath(requested,own){if(own===void 0)return!1;let canonical=path=>{try{return realpathSync(resolve(path))}catch{return resolve(path)}};return canonical(requested)===canonical(own)}var SESSION_CONTROL_COMMANDS=["get_available_models","get_available_thinking_levels","set_model","set_thinking_level","interrupt"];async function runSessionControlCommand(session,controls,command){let{id,type}=command;switch(type){case"get_available_models":return success(id,type,await availableModelsData(session));case"get_available_thinking_levels":return success(id,type,{levels:session.getAvailableThinkingLevels()});case"set_model":return await setModel(session,controls,command);case"set_thinking_level":{let level=session.getAvailableThinkingLevels().find(candidate=>candidate===command.level);return level===void 0?failure(id,type,unsupportedThinkingLevel(command.level)):(controls.selectThinkingLevel(level,command.scope!=="turn"),success(id,type))}case"interrupt":return success(id,type,await interruptRunningTurn(session,command.turnId,()=>controls.interruptTurn()));default:return}}async function setModel(session,controls,command){let{id,type}=command,model=(await session.modelRegistry.getAvailable()).find(candidate=>candidate.provider===command.provider&&candidate.id===command.modelId);if(model===void 0)return failure(id,type,`Model not found: ${String(command.provider)}/${String(command.modelId)}`);try{let change=await controls.selectModel(model);return success(id,type,{...model,systemPromptName:change?.systemPromptName})}catch(error){return failure(id,type,error instanceof Error?error.message:String(error))}}var TUI_CONTROL_CAPABILITY="tui_control",TUI_CONTROL_COMMANDS=["get_protocol_info","list_sessions","get_state","get_messages","get_entries","set_session_name","subscribe","wake","extension_ui_response",...SESSION_CONTROL_COMMANDS,...TUI_RPC_COMMANDS];async function runControlCommand(context,connection,command){let{id,type}=command,{session}=context;switch(type){case"get_protocol_info":{let build=engineBuildIdentity();return success(id,type,{protocolVersion:1,serverVersion:VERSION,capabilities:[TUI_CONTROL_CAPABILITY,SESSION_STATUS_CAPABILITY,TUI_OBSERVER_CAPABILITY,OBSERVE_READS_CAPABILITY,ENTRIES_TAIL_CAPABILITY,"snapshot_cursor","ui_answer_ledger"],mode:"tui",endpoint_kind:"tui",instanceId:context.instanceId,generation:0,engineVersion:build.text,engineOrdinal:build.ordinal,commands:TUI_CONTROL_COMMANDS,method_classes:describeRpcMethodClasses()})}case"list_sessions":return success(id,type,{sessions:[sessionRow(session)]});case"get_state":return success(id,type,{...buildRpcSessionState(session),turn_epoch:session.externalAdmission.turnEpoch,blocking_question:context.surface.blockingQuestion(),compacting:session.isCompacting,editor_has_draft:context.surface.draftHold()!==void 0,state_version:context.feed.stateVersion});case"get_messages":return success(id,type,{messages:session.messages});case"get_entries":return answerGetEntries(session,command);case"set_session_name":{let name=typeof command.name=="string"?command.name.trim():"";return name===""?failure(id,type,"Session name cannot be empty"):(session.setSessionName(name),success(id,type))}case"subscribe":{let cursor=typeof command.cursor=="number"?command.cursor:void 0;return success(id,type,{cursor:context.feed.subscribe(connection.id,cursor,connection.send)})}case"wake":{let ids=Array.isArray(command.delivery_ids)?command.delivery_ids.filter(entry=>typeof entry=="string"):void 0,result=await context.wake(ids);return success(id,type,{admitted:result.admitted??[]})}case"extension_ui_response":return answerQuestion(context,command);default:{let rpc=await runTuiRpcCommand(context,connection,command);return rpc!==void 0?rpc:await runSessionControlCommand(session,context.surface,command)??failure(id,type,"unsupported")}}}function sessionRow(session){let manager=session.sessionManager,created=manager.getHeader()?.timestamp??null,last=manager.getEntries().at(-1);return{sessionId:session.sessionId,sessionPath:session.sessionFile??null,session_file:session.sessionFile??null,kind:"interactive",surface:"tui",cwd:manager.getCwd(),name:session.sessionName??null,created_at:created,updated_at:last?.timestamp??created,attachments:1,retain_on_disconnect:!0}}function answerQuestion(context,command){if(command.secret===!0)return failure(command.id,"extension_ui_response","invalid_secret_response");let{surface,session}=context,ledger=sessionUiAnswerLedger(session),answerId=command.answerId;if(answerId!==void 0&&(typeof answerId!="string"||answerId.length<1||answerId.length>256))return failure(command.id,"extension_ui_response","invalid_answer_id");let frameId=command.id,requestId=answeredUiRequestId(command),receipt=requestId===void 0||answerId===void 0?void 0:ledger.lookup(requestId,answerId);if(receipt==="replay")return{...success(frameId,"extension_ui_response"),disposition:receipt};if(receipt==="already_answered")return{...failure(frameId,"extension_ui_response","already_answered"),disposition:receipt};let request=requestId===void 0?void 0:surface.pendingQuestion(requestId);if(requestId===void 0||request===void 0)return{...failure(frameId,"extension_ui_response",answerId===void 0?"unknown_request":"unknown_extension_ui_request"),disposition:"unknown"};let response=questionResponse(command,request.questions);return response==="question_incomplete"?failure(frameId,"extension_ui_response",response):response===void 0||!surface.answerQuestion(requestId,response)?failure(frameId,"extension_ui_response","invalid_response"):(ledger.record(requestId,answerId),{...success(frameId,"extension_ui_response"),disposition:"applied"})}function questionResponse(command,questions){if(command.cancelled===!0)return{status:"cancelled",cancelOrigin:"user",answers:{},unanswered:[]};let answers=command.answers;if(typeof answers!="object"||answers===null||Array.isArray(answers))return;let parsed={};for(let[question,value]of Object.entries(answers)){if(typeof value!="object"||value===null||!("selected"in value)||!Array.isArray(value.selected))return;let selected=value.selected.filter(entry=>typeof entry=="string"),text="text"in value&&typeof value.text=="string"?value.text:void 0;parsed[question]=text===void 0?{selected}:{selected,text}}let comment=typeof command.comment=="string"?command.comment:void 0,status=settledQuestionStatus(parsed,comment);if(status===void 0)return"question_incomplete";let unanswered=unansweredQuestionIds(questions,parsed);return{status,resolvedBy:"control_endpoint",answers:parsed,unanswered,...comment===void 0?{}:{comment}}}var ControlFeed=class{constructor(){this.seq=0,this.stateVersionValue=0,this.ring=[],this.subscribers=new Map}get stateVersion(){return this.stateVersionValue}publish(kind,data={}){kind==="state"&&(this.stateVersionValue+=1);let event={type:"session_control_event",seq:++this.seq,kind,data:kind==="state"?{...data,state_version:this.stateVersionValue}:data};this.ring.push(event),this.ring.length>256&&this.ring.shift();for(let send of this.subscribers.values())send(event)}subscribe(connection,cursor,send){if(this.subscribers.set(connection,send),cursor!==void 0)for(let event of this.ring)event.seq>cursor&&send(event);return this.seq}unsubscribe(connection){this.subscribers.delete(connection)}clear(){this.subscribers.clear()}};import{createHash}from"node:crypto";import{rmSync}from"node:fs";import{chmod as chmod2,lstat,mkdir,realpath,rm as rm2}from"node:fs/promises";import{tmpdir}from"node:os";import{dirname,join}from"node:path";var PRIVATE_DIRECTORY_MODE=448,REGISTRY_LOCK_WAIT_MS=5e3;async function resolveTuiSocket(agentDir,instanceId){let name=tuiSocketName(instanceId),primary=join(agentDir,"rpc","tui",name);if(process.platform==="win32"||Buffer.byteLength(primary)<=MAX_SOCKET_PATH_BYTES)return await makePrivateDirectory(dirname(primary)),primary;let fallbackName=`senpi-rpc-${createHash("sha256").update(agentDir).digest("hex").slice(0,8)}`,scopedRoot=join(tmpdir(),fallbackName),root=Buffer.byteLength(join(scopedRoot,"tui",name))<=MAX_SOCKET_PATH_BYTES?scopedRoot:join("/tmp",fallbackName),tuiRoot=join(root,"tui");await makePrivateDirectory(tuiRoot);for(let directory of[root,tuiRoot])await assertPrivateDirectory(directory);let fallback=join(tuiRoot,name);if(Buffer.byteLength(fallback)>MAX_SOCKET_PATH_BYTES)throw new Error(`socket path ${fallback} exceeds ${MAX_SOCKET_PATH_BYTES} bytes`);return fallback}async function makePrivateDirectory(directory){await mkdir(directory,{recursive:!0,mode:PRIVATE_DIRECTORY_MODE}),await chmod2(directory,PRIVATE_DIRECTORY_MODE)}async function assertPrivateDirectory(directory){let stat=await lstat(await realpath(directory)),ownedByUs=process.getuid===void 0||stat.uid===process.getuid();if(!stat.isDirectory()||!ownedByUs||(stat.mode&63)!==0)throw new Error(`alt_root_unsafe: ${directory} is not a private directory of this user`)}async function registerTuiEndpoint(options){let paths=createHostDaemonPaths({socket:options.socket,agentDir:options.agentDir}),release=await acquireHostEnsureLock(options.socket,REGISTRY_LOCK_WAIT_MS);try{await writeHostRegistration(paths,{record:{pid:process.pid,processStartTime:await thisProcessStartTime()},socket:options.socket,instanceId:options.instanceId,generation:0,launchProfileId:"tui",build:engineBuildIdentity()},{fresh:!0}),await createDaemonDirectories(paths,{kind:"tui"})}finally{await release()}return{paths,socket:options.socket}}async function unregisterTuiEndpoint(entry){let release=await acquireHostEnsureLock(entry.socket,REGISTRY_LOCK_WAIT_MS).catch(()=>{});try{await rm2(entry.socket,{force:!0}),await rm2(socketSecretPath(entry.socket),{force:!0}),await rm2(entry.paths.dir,{recursive:!0,force:!0})}finally{await release?.()}}function unregisterTuiEndpointSync(entry){rmSync(entry.socket,{force:!0}),rmSync(socketSecretPath(entry.socket),{force:!0}),rmSync(entry.paths.dir,{recursive:!0,force:!0})}var REPORT_TEXT_LIMIT=4e3;function activateControlEndpoint(parts){let{context,feed,wake}=parts,{session,surface}=context;session.externalAdmission.setEditorSource(()=>editorHold(context));let unsubscribeSession=session.subscribe(event=>{event.type==="agent_start"?feed.publish("state"):event.type==="agent_idle"?(feed.publish("completion",{turn_epoch:session.externalAdmission.turnEpoch}),feed.publish("state"),wake("idle")):event.type==="agent_end"||event.type==="queue_update"||event.type==="compaction_start"||event.type==="compaction_end"?feed.publish("state"):event.type==="message_end"&&event.message.role==="assistant"&&feed.publish("report",{text:assistantText(event.message).slice(0,REPORT_TEXT_LIMIT)})}),unsubscribeEmitted=session.externalAdmission.onEmitted(()=>{wake("emitted")}),unsubscribeInputs=session.externalAdmission.onInputsSettled(()=>queueMicrotask(()=>{wake("submission")})),stopContinue=onProcessContinue(()=>{wake("continue")}),exitCleanup=()=>unregisterTuiEndpointSync(parts.entry);process.once("exit",exitCleanup);let disposing,dispose=()=>(disposing??=(async()=>{process.removeListener("exit",exitCleanup),unsubscribeSession(),unsubscribeEmitted(),unsubscribeInputs(),stopContinue(),parts.stopInbox(),parts.scheduler.dispose(),feed.clear(),session.externalAdmission.setEditorSource(void 0),await parts.server.close(),await sessionReferenced(parts.options,surface)||await session.sessionManager.discardHeaderOnlyFile(),await unregisterTuiEndpoint(parts.entry)})(),disposing);return{socket:parts.entry.socket,wake:reason=>{wake(reason)},noteState:()=>feed.publish("state"),noteQuestions:()=>feed.publish("question",{pending:[...surface.pendingQuestionIds()]}),dispose}}function editorHold(context){let hold=context.surface.draftHold(),revision=context.editorRevision();return hold===void 0?{revision}:{hold_reason:hold,revision}}async function sessionReferenced(options,surface){if(options.isSessionReferenced===void 0)return!1;try{return await options.isSessionReferenced()}catch(error){return surface.notice(`control endpoint kept the session file: ${error instanceof Error?error.message:String(error)}`),!0}}function assistantText(message){return message.role!=="assistant"?"":message.content.flatMap(part=>part.type==="text"?[part.text]:[]).join(`
2
+ import{SessionEventWriter,answerSubscribeSessions,answerUnsubscribeSessions,presenterContextReply,refusal,sessionRuntimeView,socketSink,startMcpPresenterControl}from"./chunk-Y5L4UFMI.js";import{CONNECTION_ROLE_FIXED,ConnectionRoles,TerminalSealedSecrets,WakeScheduler,answerGetEntries,answeredUiRequestId,availableModelsData,buildRpcSessionState,getSnapshot,interruptRunningTurn,onProcessContinue,rpcCommandShapeError,runAbort,runGetEffectStatus,sessionUiAnswerLedger,settledQuestionStatus,subscribeSessionRecords,unansweredQuestionIds,unsupportedThinkingLevel,watchInbox}from"./chunk-4JIBEZZE.js";import"./chunk-SJI6UB23.js";import"./chunk-436DNN4Z.js";import"./chunk-J2I56WLK.js";import"./chunk-TQHNFP77.js";import"./chunk-XZDCMDUH.js";import"./chunk-MOVB6H22.js";import"./chunk-VD7AKTGP.js";import{ENTRIES_TAIL_CAPABILITY,INTERACTIVE_USER_CAPABILITY,OBSERVE_READS_CAPABILITY,SESSION_STATUS_CAPABILITY,TUI_OBSERVER_CAPABILITY,describeRpcMethodClasses,engineBuildIdentity,gcHostEndpoints}from"./chunk-622VYTRI.js";import"./chunk-QMRJYMNH.js";import"./chunk-Y7Z7XPUF.js";import"./chunk-54YTJCYZ.js";import"./chunk-26UBFF6N.js";import"./chunk-I5ASHSLZ.js";import{tuiSocketName}from"./chunk-2CNSCMYC.js";import"./chunk-7WYJAYHH.js";import{acquireHostEnsureLock,thisProcessStartTime,writeHostRegistration}from"./chunk-EAEEM2KN.js";import{createDaemonDirectories,createHostDaemonPaths}from"./chunk-YI6KRJDC.js";import"./chunk-DBQBJTMF.js";import{MAX_RPC_LINE_CHARACTERS,attachJsonlLineReader,serializeJsonLine}from"./chunk-SF4MQDKZ.js";import"./chunk-GZVCRV7I.js";import"./chunk-KUPQO7MC.js";import"./chunk-U3VOXCGP.js";import"./chunk-6VWIMHMH.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-RUGTHELO.js";import"./chunk-42XRJQM6.js";import{MAX_SOCKET_PATH_BYTES}from"./chunk-5XHOHZIR.js";import{authenticateSocket,createSocketSecret,resolveSocketTransportAddress,socketSecretPath}from"./chunk-HW6AAS3R.js";import{VERSION}from"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";import{randomUUID as randomUUID2}from"node:crypto";import{rm as rm3}from"node:fs/promises";var ControlAttachments=class{constructor(session,pendingQuestions,presenters){this.writer=new SessionEventWriter(()=>{}),this.roles=new ConnectionRoles,this.receipts=new Map,this.attached=new Set,this.session=session,this.presenters=presenters,this.writer.status.setSource({sessionIds:()=>[this.handle],entryView:id=>id===this.handle?this.entryView():void 0,view:id=>id===this.handle?{entry:this.entryView(),runtime:sessionRuntimeView(session,pendingQuestions())}:void 0}),this.writer.registerConnection(NULL_CONNECTION,{writeRaw:()=>{},waitForBackpressure:async()=>{}}),this.stopRecords=subscribeSessionRecords(session,record=>this.writer.enqueue(this.handle,record))}get handle(){return this.session.sessionId}opened(connection){this.writer.registerConnection(keyOf(connection),connection.transport),this.presenters?.opened(keyOf(connection),connection.transport)}closed(connection){let key=keyOf(connection);this.attached.delete(key)&&this.writer.status.publish(this.handle,"detach","client"),this.roles.release(key),this.presenters?.closed(key),this.writer.unregisterConnection(key)}detach(connection){let key=keyOf(connection);return this.attached.delete(key)?(this.presenters?.detach(key),this.writer.detachConnectionFromSession(key,this.handle),this.writer.status.publish(this.handle,"detach","client"),!0):!1}attach(connection){let key=keyOf(connection);return this.attached.has(key)?!1:(this.attached.add(key),this.presenters?.attach(key),this.writer.attachConnectionToSession(key,this.handle),this.writer.status.publish(this.handle,"attach","client"),!0)}isAttached(connection){return this.attached.has(keyOf(connection))}run(connection,task){return this.writer.withConnection(keyOf(connection),task)}respond(connection,answer2){this.writer.enqueueControl(answer2,keyOf(connection)).catch(()=>connection.transport.close?.())}dispose(){this.stopRecords()}entryView(){let manager=this.session.sessionManager,path=this.session.sessionFile,name=manager.getSessionName();return{state:"open",kind:"interactive",cwd:manager.getCwd(),attachments:1+this.attached.size,durableSessionId:this.session.sessionId,...path!==void 0?{sessionPath:path}:{},...name!==void 0?{name}:{},context:{}}}},NULL_CONNECTION="tui-null";function keyOf(connection){return`tui-${connection.id}`}import{realpathSync}from"node:fs";import{resolve}from"node:path";import{randomUUID}from"node:crypto";function idOf(command){return typeof command.id=="string"?command.id:void 0}function answered(id,command,data){return{...id===void 0?{}:{id},type:"response",command,success:!0,data}}function admitPrompt(context,command){let behavior=command.streamingBehavior;return behavior===void 0&&context.session.isStreaming?refusal(idOf(command),"prompt","session_busy",{reason:"a turn is running and the prompt names no streamingBehavior",action:'send it with streamingBehavior "steer" or "followUp", or as a steer/follow_up'}):admitInput(context,command,behavior==="followUp"?"followUp":"steer","start")}var UNSERVED_INPUT_FIELDS=["images","thinkingLevel","expandPromptTemplates","unknownCommandAsText","sessionTitlePrompt","enqueueOrder","chainCount"];function admitInput(context,command,deliverAs,whenIdle){let id=idOf(command),unserved=UNSERVED_INPUT_FIELDS.filter(field=>command[field]!==void 0);if(unserved.length>0)return refusal(id,command.type,"unsupported_field",{reason:`a terminal delivers input through its admission, which carries text only, not ${unserved.join(", ")}`,action:"send the message without those fields, or send it to a host session"});let message=command.message;if(typeof message!="string"||message.trim()==="")return refusal(id,command.type,"invalid_message",{reason:"message is empty",action:"send a non-empty message"});if(whenIdle!==void 0&&whenIdle!=="queue"&&whenIdle!=="start")return refusal(id,command.type,"invalid_when_idle",{reason:`whenIdle must be "queue" or "start", not ${JSON.stringify(whenIdle)}`,action:'send whenIdle: "queue" (the default) or "start"'});let admission=context.session.externalAdmission,clientMessageId=typeof command.clientMessageId=="string"?command.clientMessageId:void 0,fingerprint=JSON.stringify([command.type,message,deliverAs,whenIdle??null]),prior=clientMessageId===void 0?void 0:context.attachments.receipts.get(clientMessageId);if(prior!==void 0)return prior.fingerprint!==fingerprint?refusal(id,command.type,"client_message_id_conflict",{reason:`clientMessageId ${clientMessageId} was already used for different input`,action:"send new input with a new clientMessageId"}):answered(id,command.type,{disposition:prior.disposition,clientMessageId,replayed:!0,duplicate:!0,admission:prior.admission});let expected=typeof command.expected_turn_id=="number"?command.expected_turn_id:admission.turnEpoch,result=admission.admit({delivery_id:clientMessageId??`tui-rpc-${randomUUID()}`,text:message,sender:{kind:"external",platform:"rpc"},deliverAs,expected_turn_id:expected,whenIdle:whenIdle==="start"?"start":"queue"}),identity=clientMessageId===void 0?{}:{clientMessageId},admitted=disposition=>{if(clientMessageId===void 0)return answered(id,command.type,{disposition});let receipt={fingerprint,disposition,admission:{clientMessageId,durableSessionId:context.session.sessionId,disposition}};return context.attachments.receipts.set(clientMessageId,receipt),answered(id,command.type,{disposition,clientMessageId,admission:receipt.admission})};switch(result.kind){case"started":return admitted("started");case"steered":case"queued":return admitted("queued");case"already_admitted":return answered(id,command.type,{disposition:"queued",duplicate:!0,...identity});case"held_draft":return refusal(id,command.type,"held_draft",{reason:"the user is composing in this terminal, so nothing was delivered",action:"retry after the draft is sent or cleared"});case"turn_conflict":return refusal(id,command.type,"turn_conflict",{reason:`the turn moved on (now ${result.turn_epoch}); this steer named an earlier one`,action:"read get_state's turn_epoch and send it again"})}}import{chmod}from"node:fs/promises";import{createServer}from"node:net";async function listenControlSocket(socketPath,secret,handlers){let clients=new Set,nextConnection=0,server=createServer(socket=>{clients.add(socket),socket.once("close",()=>clients.delete(socket)),socket.on("error",()=>socket.destroy()),authenticateSocket(socket,secret,()=>acceptConnection(socket,++nextConnection,handlers))});return await new Promise((resolve2,reject)=>{server.once("error",reject),server.listen(resolveSocketTransportAddress(socketPath,process.platform,secret),()=>{server.off("error",reject),resolve2()})}),server.on("error",error=>handlers.listenerError(error)),process.platform!=="win32"&&await chmod(socketPath,384),{close:()=>closeServer(server,clients)}}function acceptConnection(socket,id,handlers){let connection={id,send:record=>{handlers.respond!==void 0?handlers.respond(connection,record):socket.destroyed||socket.write(serializeJsonLine(record))},transport:socketSink(socket)};handlers.opened?.(connection);let detach=attachJsonlLineReader(socket,line=>{answer(connection,line,handlers)},{maxLineLength:MAX_RPC_LINE_CHARACTERS,onOversizedLine:()=>connection.send(failure(void 0,"parse","RPC line exceeds the size limit."))});socket.once("close",()=>{detach(),handlers.closed(connection)})}async function answer(connection,line,handlers){let parsed;try{parsed=JSON.parse(line)}catch{connection.send(failure(void 0,"parse","Invalid JSON."));return}let shapeError=rpcCommandShapeError(parsed);if(shapeError!==void 0||!isCommand(parsed)){connection.send(failure(void 0,"parse",shapeError??"RPC command needs a string `type`."));return}let answer2=await handlers.command(connection,parsed);answer2!==null&&connection.send(answer2)}function isCommand(value){return typeof value=="object"&&value!==null&&"type"in value&&typeof value.type=="string"}function failure(id,command,error){return{...id===void 0?{}:{id},type:"response",command,success:!1,error}}function success(id,command,data){return{...id===void 0?{}:{id},type:"response",command,success:!0,...data===void 0?{}:{data}}}function closeServer(server,clients){for(let client of clients)client.destroy();return new Promise(resolve2=>server.close(()=>resolve2()))}import{rm}from"node:fs/promises";var TERMINAL_PRESENTER_COMMANDS=["mcp_presenter_context","mcp_form_presented","mcp_form_response","mcp_form_sync","mcp_presenter_secret_answer"];async function startTerminalPresenters(presenter){let surface=new TerminalPresenterSurface(presenter.local),started=await startMcpPresenterControl(surface,{enforcement:!0,account:presenter.account});return{surface,dispose:async()=>{started?.control.dispose(),started?.dir&&await rm(started.dir,{recursive:!0,force:!0})}}}function presents(capabilities){return capabilities.includes("interactive_user")&&capabilities.includes("mcp_form_presenter_v1")}function writePrivate(transport,record){try{return transport.writeRaw(serializeJsonLine(record)),!0}catch{return!1}}var TerminalPresenterSurface=class{constructor(local){this.sharedAuthority=!0,this.peers=new Map,this.local=local,this.authority=local.authority,this.binding=local.binding,this.sessionId=local.sessionId}attachSealedSecrets(source){let sealed=new TerminalSealedSecrets(source,this.sessionId,this.local.admit);return this.local.sealed=sealed,()=>{this.local.sealed===sealed&&(this.local.sealed=void 0),sealed.dispose()}}getMcpFormBinding(sessionId){return sessionId===this.sessionId?this.binding:void 0}findMcpPresenterConnection(nonce){for(let peer of this.peers.values())if(peer.sender?.nonce===nonce)return peer.sender}getConnectionCapabilities(id){return this.peers.get(id)?.capabilities}advertiseMcpPresenterControl(path){this.controlEndpoint=path}withdrawMcpPresenterControl(path){this.controlEndpoint===path&&(this.controlEndpoint=void 0)}opened(id,transport){this.peers.set(id,{transport,capabilities:[],attached:!1})}declare(id,capabilities){let peer=this.peers.get(id);if(peer){if(peer.capabilities=[...capabilities],!presents(capabilities)){peer.sender&&this.authority.withdraw(peer.sender);return}if(!peer.sender){let sender=this.authority.connect(id,frame=>this.peers.get(id)!==peer||!writePrivate(peer.transport,frame)?(this.authority.detach(sender),!1):(peer.transport.waitForBackpressure().catch(()=>this.authority.detach(sender)),!0));peer.sender=sender}peer.attached&&this.authority.attach(peer.sender,this.binding)}}attach(id){let peer=this.peers.get(id);peer&&(peer.attached=!0,peer.sender&&this.authority.attach(peer.sender,this.binding))}detach(id){let peer=this.peers.get(id);peer&&(peer.attached=!1,peer.sender&&this.authority.detach(peer.sender,this.binding))}closed(id){let sender=this.peers.get(id)?.sender;this.peers.delete(id),sender&&this.authority.detach(sender)}receive(id,frame){let peer=this.peers.get(id);if(!peer)return;if(frame.type==="mcp_presenter_secret_answer"){let lineId=typeof frame.id=="string"?{id:frame.id}:{};(this.local.sealed?.receive(id,frame)??Promise.resolve({error:"secret_answer_refused"})).catch(()=>({error:"secret_answer_refused"})).then(reply2=>{!writePrivate(peer.transport,{type:"mcp_presenter_secret_reply",...lineId,...reply2})&&peer.sender&&this.authority.detach(peer.sender)});return}let sender=peer.sender,reply=frame.type==="mcp_presenter_context"?presenterContextReply(this.authority,sender,frame,this.controlEndpoint):sender?this.authority.receive(sender,frame):{error:"presenter_not_authorized"},answer2={type:"mcp_form_reply",...typeof frame.id=="string"?{id:frame.id}:{},...reply};!writePrivate(peer.transport,answer2)&&sender&&this.authority.detach(sender)}};var TUI_RPC_COMMANDS=["open_session","get_snapshot","subscribe_sessions","unsubscribe_sessions","steer","follow_up","prompt","get_effect_status","set_client_info","attach_session","release_attachment","abort",...TERMINAL_PRESENTER_COMMANDS],STOP_REQUIRES_INTERACTIVE_CLIENT="stop_requires_interactive_client: declare interactive_user with set_client_info first";async function runTuiRpcCommand(context,connection,command){switch(command.type){case"get_snapshot":{let{attachments,session}=context;if(command.sessionId!==void 0&&command.sessionId!==attachments.handle)return{id:command.id,type:"response",command:command.type,success:!1,error:"unknown_session"};let snapshot=getSnapshot(session,{tail:command.tail,maxBytes:command.maxBytes},{enqueue:markerId=>attachments.run(connection,()=>attachments.writer.enqueue(attachments.handle,{type:"snapshot_marker",markerId}))});return"error"in snapshot?{id:command.id,type:"response",command:command.type,success:!1,error:snapshot.error}:answered(idOf(command),command.type,snapshot.data)}case"open_session":return openSession(context,connection,command);case"subscribe_sessions":return subscribe(context,connection,command);case"unsubscribe_sessions":return answerUnsubscribeSessions(command,keyOf(connection),context.attachments.writer.status);case"steer":case"follow_up":return admitInput(context,command,command.type==="steer"?"steer":"followUp",command.whenIdle);case"prompt":return admitPrompt(context,command);case"set_client_info":return setClientInfo(context,connection,command);case"attach_session":return attachSession(context,connection,command);case"release_attachment":return releaseAttachment(context,connection,command);case"abort":return abort(context,connection,command);case"mcp_presenter_context":case"mcp_form_presented":case"mcp_form_response":case"mcp_form_sync":case"mcp_presenter_secret_answer":return context.attachments.presenters?(context.attachments.presenters.receive(keyOf(connection),command),null):void 0;case"get_effect_status":return runGetEffectStatus({session:context.session,by:{connectionId:keyOf(connection)},sessionId:context.attachments.handle},command);default:return}}function openSession(context,connection,command){let{session,attachments}=context,ownPath=typeof command.sessionPath=="string"&&samePath(command.sessionPath,session.sessionFile),ownId=command.sessionId!==void 0&&command.sessionId===session.sessionId;return!ownPath&&!ownId?refusal(idOf(command),"open_session","terminal_single_session",{reason:"this terminal hosts one session and the request names another",action:"open it by this terminal's sessionPath, or open the other session on a host"}):(attachments.run(connection,()=>{attachments.attach(connection),attachments.writer.enqueue(attachments.handle,{id:command.id,type:"response",command:"open_session",success:!0,data:{sessionId:attachments.handle,state:buildRpcSessionState(session),attached:!0}})}),null)}function setClientInfo(context,connection,command){let capabilities=command.capabilities;return capabilities===void 0?success(command.id,"set_client_info"):!Array.isArray(capabilities)||!capabilities.every(entry=>typeof entry=="string")?failure(command.id,"set_client_info","capabilities must be an array of strings"):context.attachments.roles.declare(keyOf(connection),capabilities)!=="declared"?failure(command.id,"set_client_info",CONNECTION_ROLE_FIXED):(context.attachments.presenters?.declare(keyOf(connection),capabilities),success(command.id,"set_client_info"))}function attachSession(context,connection,command){let{session,attachments}=context,id=idOf(command);if(command.sessionId!==attachments.handle)return refusal(id,"attach_session","unknown_session",{reason:"this terminal hosts one session and the request names another",action:"attach with this terminal's sessionId from list_sessions"});let instanceMatches=command.expectedHostInstance===void 0||command.expectedHostInstance===context.instanceId;return command.durableSessionId!==session.sessionId||!instanceMatches?refusal(id,"attach_session","session_identity_mismatch",{reason:"durableSessionId or expectedHostInstance does not name this terminal's session",action:"read list_sessions and get_protocol_info again, then attach with their ids"}):command.takeover===!0?refusal(id,"attach_session","takeover_unsupported",{reason:"only a headless engine with a takeover ledger takes sessions over",action:"attach without takeover"}):(attachments.run(connection,()=>{attachments.attach(connection),attachments.writer.enqueue(attachments.handle,{id:command.id,type:"response",command:"attach_session",success:!0,data:{sessionId:attachments.handle,attached:!0}})}),null)}function releaseAttachment(context,connection,command){return command.sessionId!==context.attachments.handle||!context.attachments.detach(connection)?refusal(idOf(command),"release_attachment","session_not_attached",{reason:"this connection is not attached to that session",action:"attach first with attach_session or open_session"}):success(command.id,"release_attachment",{deferred:!1})}async function abort(context,connection,command){let key=keyOf(connection);if(command.intent==="stop"&&!context.attachments.roles.has(key,INTERACTIVE_USER_CAPABILITY))return failure(command.id,"abort",STOP_REQUIRES_INTERACTIVE_CLIENT);let{session}=context;return runAbort({session,by:{connectionId:key},sessionId:context.attachments.handle},command,()=>(command.intent==="stop"?session.stop():session.abort()).catch(cause=>{connection.send({type:"rpc_error",error:String(cause)})}))}function subscribe(context,connection,command){let{writer}=context.attachments,key=keyOf(connection),{answer:answer2,activate}=answerSubscribeSessions(command,key,writer.status);return activate===void 0?answer2:(writer.enqueueControl(answer2,key).then(()=>{writer.hasConnection(key)?writer.status.activate(activate):writer.status.unsubscribe(key,activate)}).catch(()=>writer.status.unsubscribe(key,activate)),null)}function samePath(requested,own){if(own===void 0)return!1;let canonical=path=>{try{return realpathSync(resolve(path))}catch{return resolve(path)}};return canonical(requested)===canonical(own)}var SESSION_CONTROL_COMMANDS=["get_available_models","get_available_thinking_levels","set_model","set_thinking_level","interrupt"];async function runSessionControlCommand(session,controls,command){let{id,type}=command;switch(type){case"get_available_models":return success(id,type,await availableModelsData(session));case"get_available_thinking_levels":return success(id,type,{levels:session.getAvailableThinkingLevels()});case"set_model":return await setModel(session,controls,command);case"set_thinking_level":{let level=session.getAvailableThinkingLevels().find(candidate=>candidate===command.level);return level===void 0?failure(id,type,unsupportedThinkingLevel(command.level)):(controls.selectThinkingLevel(level,command.scope!=="turn"),success(id,type))}case"interrupt":return success(id,type,await interruptRunningTurn(session,command.turnId,()=>controls.interruptTurn()));default:return}}async function setModel(session,controls,command){let{id,type}=command,model=(await session.modelRegistry.getAvailable()).find(candidate=>candidate.provider===command.provider&&candidate.id===command.modelId);if(model===void 0)return failure(id,type,`Model not found: ${String(command.provider)}/${String(command.modelId)}`);try{let change=await controls.selectModel(model);return success(id,type,{...model,systemPromptName:change?.systemPromptName})}catch(error){return failure(id,type,error instanceof Error?error.message:String(error))}}var TUI_CONTROL_CAPABILITY="tui_control",TUI_CONTROL_COMMANDS=["get_protocol_info","list_sessions","get_state","get_messages","get_entries","set_session_name","subscribe","wake","extension_ui_response",...SESSION_CONTROL_COMMANDS,...TUI_RPC_COMMANDS];async function runControlCommand(context,connection,command){let{id,type}=command,{session}=context;switch(type){case"get_protocol_info":{let build=engineBuildIdentity();return success(id,type,{protocolVersion:1,serverVersion:VERSION,capabilities:[TUI_CONTROL_CAPABILITY,SESSION_STATUS_CAPABILITY,TUI_OBSERVER_CAPABILITY,OBSERVE_READS_CAPABILITY,ENTRIES_TAIL_CAPABILITY,"snapshot_cursor","ui_answer_ledger"],mode:"tui",endpoint_kind:"tui",instanceId:context.instanceId,generation:0,engineVersion:build.text,engineOrdinal:build.ordinal,commands:TUI_CONTROL_COMMANDS,method_classes:describeRpcMethodClasses()})}case"list_sessions":return success(id,type,{sessions:[sessionRow(session)]});case"get_state":return success(id,type,{...buildRpcSessionState(session),turn_epoch:session.externalAdmission.turnEpoch,blocking_question:context.surface.blockingQuestion(),compacting:session.isCompacting,editor_has_draft:context.surface.draftHold()!==void 0,state_version:context.feed.stateVersion});case"get_messages":return success(id,type,{messages:session.messages});case"get_entries":return answerGetEntries(session,command);case"set_session_name":{let name=typeof command.name=="string"?command.name.trim():"";return name===""?failure(id,type,"Session name cannot be empty"):(session.setSessionName(name),success(id,type))}case"subscribe":{let cursor=typeof command.cursor=="number"?command.cursor:void 0;return success(id,type,{cursor:context.feed.subscribe(connection.id,cursor,connection.send)})}case"wake":{let ids=Array.isArray(command.delivery_ids)?command.delivery_ids.filter(entry=>typeof entry=="string"):void 0,result=await context.wake(ids);return success(id,type,{admitted:result.admitted??[]})}case"extension_ui_response":return answerQuestion(context,command);default:{let rpc=await runTuiRpcCommand(context,connection,command);return rpc!==void 0?rpc:await runSessionControlCommand(session,context.surface,command)??failure(id,type,"unsupported")}}}function sessionRow(session){let manager=session.sessionManager,created=manager.getHeader()?.timestamp??null,last=manager.getEntries().at(-1);return{sessionId:session.sessionId,sessionPath:session.sessionFile??null,session_file:session.sessionFile??null,kind:"interactive",surface:"tui",cwd:manager.getCwd(),name:session.sessionName??null,created_at:created,updated_at:last?.timestamp??created,attachments:1,retain_on_disconnect:!0}}function answerQuestion(context,command){if(command.secret===!0)return failure(command.id,"extension_ui_response","invalid_secret_response");let{surface,session}=context,ledger=sessionUiAnswerLedger(session),answerId=command.answerId;if(answerId!==void 0&&(typeof answerId!="string"||answerId.length<1||answerId.length>256))return failure(command.id,"extension_ui_response","invalid_answer_id");let frameId=command.id,requestId=answeredUiRequestId(command),receipt=requestId===void 0||answerId===void 0?void 0:ledger.lookup(requestId,answerId);if(receipt==="replay")return{...success(frameId,"extension_ui_response"),disposition:receipt};if(receipt==="already_answered")return{...failure(frameId,"extension_ui_response","already_answered"),disposition:receipt};let request=requestId===void 0?void 0:surface.pendingQuestion(requestId);if(requestId===void 0||request===void 0)return{...failure(frameId,"extension_ui_response",answerId===void 0?"unknown_request":"unknown_extension_ui_request"),disposition:"unknown"};let response=questionResponse(command,request.questions);return response==="question_incomplete"?failure(frameId,"extension_ui_response",response):response===void 0||!surface.answerQuestion(requestId,response)?failure(frameId,"extension_ui_response","invalid_response"):(ledger.record(requestId,answerId),{...success(frameId,"extension_ui_response"),disposition:"applied"})}function questionResponse(command,questions){if(command.cancelled===!0)return{status:"cancelled",cancelOrigin:"user",answers:{},unanswered:[]};let answers=command.answers;if(typeof answers!="object"||answers===null||Array.isArray(answers))return;let parsed={};for(let[question,value]of Object.entries(answers)){if(typeof value!="object"||value===null||!("selected"in value)||!Array.isArray(value.selected))return;let selected=value.selected.filter(entry=>typeof entry=="string"),text="text"in value&&typeof value.text=="string"?value.text:void 0;parsed[question]=text===void 0?{selected}:{selected,text}}let comment=typeof command.comment=="string"?command.comment:void 0,status=settledQuestionStatus(parsed,comment);if(status===void 0)return"question_incomplete";let unanswered=unansweredQuestionIds(questions,parsed);return{status,resolvedBy:"control_endpoint",answers:parsed,unanswered,...comment===void 0?{}:{comment}}}var ControlFeed=class{constructor(){this.seq=0,this.stateVersionValue=0,this.ring=[],this.subscribers=new Map}get stateVersion(){return this.stateVersionValue}publish(kind,data={}){kind==="state"&&(this.stateVersionValue+=1);let event={type:"session_control_event",seq:++this.seq,kind,data:kind==="state"?{...data,state_version:this.stateVersionValue}:data};this.ring.push(event),this.ring.length>256&&this.ring.shift();for(let send of this.subscribers.values())send(event)}subscribe(connection,cursor,send){if(this.subscribers.set(connection,send),cursor!==void 0)for(let event of this.ring)event.seq>cursor&&send(event);return this.seq}unsubscribe(connection){this.subscribers.delete(connection)}clear(){this.subscribers.clear()}};import{createHash}from"node:crypto";import{rmSync}from"node:fs";import{chmod as chmod2,lstat,mkdir,realpath,rm as rm2}from"node:fs/promises";import{tmpdir}from"node:os";import{dirname,join}from"node:path";var PRIVATE_DIRECTORY_MODE=448,REGISTRY_LOCK_WAIT_MS=5e3;async function resolveTuiSocket(agentDir,instanceId){let name=tuiSocketName(instanceId),primary=join(agentDir,"rpc","tui",name);if(process.platform==="win32"||Buffer.byteLength(primary)<=MAX_SOCKET_PATH_BYTES)return await makePrivateDirectory(dirname(primary)),primary;let fallbackName=`senpi-rpc-${createHash("sha256").update(agentDir).digest("hex").slice(0,8)}`,scopedRoot=join(tmpdir(),fallbackName),root=Buffer.byteLength(join(scopedRoot,"tui",name))<=MAX_SOCKET_PATH_BYTES?scopedRoot:join("/tmp",fallbackName),tuiRoot=join(root,"tui");await makePrivateDirectory(tuiRoot);for(let directory of[root,tuiRoot])await assertPrivateDirectory(directory);let fallback=join(tuiRoot,name);if(Buffer.byteLength(fallback)>MAX_SOCKET_PATH_BYTES)throw new Error(`socket path ${fallback} exceeds ${MAX_SOCKET_PATH_BYTES} bytes`);return fallback}async function makePrivateDirectory(directory){await mkdir(directory,{recursive:!0,mode:PRIVATE_DIRECTORY_MODE}),await chmod2(directory,PRIVATE_DIRECTORY_MODE)}async function assertPrivateDirectory(directory){let stat=await lstat(await realpath(directory)),ownedByUs=process.getuid===void 0||stat.uid===process.getuid();if(!stat.isDirectory()||!ownedByUs||(stat.mode&63)!==0)throw new Error(`alt_root_unsafe: ${directory} is not a private directory of this user`)}async function registerTuiEndpoint(options){let paths=createHostDaemonPaths({socket:options.socket,agentDir:options.agentDir}),release=await acquireHostEnsureLock(options.socket,REGISTRY_LOCK_WAIT_MS);try{await writeHostRegistration(paths,{record:{pid:process.pid,processStartTime:await thisProcessStartTime()},socket:options.socket,instanceId:options.instanceId,generation:0,launchProfileId:"tui",build:engineBuildIdentity()},{fresh:!0}),await createDaemonDirectories(paths,{kind:"tui"})}finally{await release()}return{paths,socket:options.socket}}async function unregisterTuiEndpoint(entry){let release=await acquireHostEnsureLock(entry.socket,REGISTRY_LOCK_WAIT_MS).catch(()=>{});try{await rm2(entry.socket,{force:!0}),await rm2(socketSecretPath(entry.socket),{force:!0}),await rm2(entry.paths.dir,{recursive:!0,force:!0})}finally{await release?.()}}function unregisterTuiEndpointSync(entry){rmSync(entry.socket,{force:!0}),rmSync(socketSecretPath(entry.socket),{force:!0}),rmSync(entry.paths.dir,{recursive:!0,force:!0})}var REPORT_TEXT_LIMIT=4e3;function activateControlEndpoint(parts){let{context,feed,wake}=parts,{session,surface}=context;session.externalAdmission.setEditorSource(()=>editorHold(context));let unsubscribeSession=session.subscribe(event=>{event.type==="agent_start"?feed.publish("state"):event.type==="agent_idle"?(feed.publish("completion",{turn_epoch:session.externalAdmission.turnEpoch}),feed.publish("state"),wake("idle")):event.type==="agent_end"||event.type==="queue_update"||event.type==="compaction_start"||event.type==="compaction_end"?feed.publish("state"):event.type==="message_end"&&event.message.role==="assistant"&&feed.publish("report",{text:assistantText(event.message).slice(0,REPORT_TEXT_LIMIT)})}),unsubscribeEmitted=session.externalAdmission.onEmitted(()=>{wake("emitted")}),unsubscribeInputs=session.externalAdmission.onInputsSettled(()=>queueMicrotask(()=>{wake("submission")})),stopContinue=onProcessContinue(()=>{wake("continue")}),exitCleanup=()=>unregisterTuiEndpointSync(parts.entry);process.once("exit",exitCleanup);let disposing,dispose=()=>(disposing??=(async()=>{process.removeListener("exit",exitCleanup),unsubscribeSession(),unsubscribeEmitted(),unsubscribeInputs(),stopContinue(),parts.stopInbox(),parts.scheduler.dispose(),feed.clear(),session.externalAdmission.setEditorSource(void 0),await parts.server.close(),await sessionReferenced(parts.options,surface)||await session.sessionManager.discardHeaderOnlyFile(),await unregisterTuiEndpoint(parts.entry)})(),disposing);return{socket:parts.entry.socket,wake:reason=>{wake(reason)},noteState:()=>feed.publish("state"),noteQuestions:()=>feed.publish("question",{pending:[...surface.pendingQuestionIds()]}),dispose}}function editorHold(context){let hold=context.surface.draftHold(),revision=context.editorRevision();return hold===void 0?{revision}:{hold_reason:hold,revision}}async function sessionReferenced(options,surface){if(options.isSessionReferenced===void 0)return!1;try{return await options.isSessionReferenced()}catch(error){return surface.notice(`control endpoint kept the session file: ${error instanceof Error?error.message:String(error)}`),!0}}function assistantText(message){return message.role!=="assistant"?"":message.content.flatMap(part=>part.type==="text"?[part.text]:[]).join(`
3
3
  `)}async function registerSessionControlEndpoint(context,options){let cleanups=[];try{let endpoint=await openEndpoint(context,options,cleanups);return{registration:{status:"registered",socket:endpoint.socket,dispose:endpoint.dispose},endpoint}}catch(error){for(let cleanup of cleanups.reverse())await Promise.resolve(cleanup()).catch(()=>{});let reason=errorText(error);return context.surface.notice(`control endpoint unavailable: ${reason}`),{registration:{status:"failed",reason}}}}async function openEndpoint(context,options,cleanups){let{session,agentDir,surface}=context;thisProcessStartTime();let headerDurable=session.sessionManager.persistHeaderNow();headerDurable.catch(()=>{});let instanceId=randomUUID2(),socket=await resolveTuiSocket(agentDir,instanceId);cleanups.push(()=>rm3(socket,{force:!0}),()=>rm3(socketSecretPath(socket),{force:!0}));let secret=await createSocketSecret(socketSecretPath(socket)),feed=new ControlFeed,failing,scheduler=new WakeScheduler(async event=>{await session.extensionRunner.emit(event);let result=await options.drain(event)??{admitted:[]};return failing=void 0,result},error=>{let reason=errorText(error);reason!==failing&&(failing=reason,surface.notice(`control endpoint drain failed: ${reason}`))});cleanups.push(()=>scheduler.dispose());let wake=(reason,ids)=>scheduler.request(reason,ids),presenters=context.mcpPresenter?await startTerminalPresenters(context.mcpPresenter):void 0;presenters&&cleanups.push(presenters.dispose);let attachments=new ControlAttachments(session,()=>surface.pendingQuestionIds().length,presenters?.surface);cleanups.push(()=>attachments.dispose());let commandContext={instanceId,session,surface,feed,wake:ids=>wake("command",ids),attachments},server=await listenControlSocket(socket,secret,{command:(connection,command)=>runControlCommand(commandContext,connection,command),opened:connection=>attachments.opened(connection),respond:(connection,answer2)=>attachments.respond(connection,answer2),closed:connection=>{feed.unsubscribe(connection.id),attachments.closed(connection)},listenerError:error=>surface.notice(`control endpoint listener failed: ${error.message}`)});cleanups.push(()=>server.close()),await headerDurable;let entry=await registerTuiEndpoint({agentDir,socket,instanceId});cleanups.push(()=>unregisterTuiEndpoint(entry));let inbox=await watchInbox(options.inboxDir,()=>{wake("inbox")},error=>surface.notice(`control endpoint inbox watch failed: ${errorText(error)}`));cleanups.push(()=>inbox.stop());let endpoint=activateControlEndpoint({context,options,entry,server,scheduler,feed,stopInbox:inbox.stop,wake});return endpoint.wake("inbox"),inbox.armed.then(()=>endpoint.wake("inbox")),setImmediate(()=>{gcHostEndpoints(agentDir,{kinds:["tui"]}).catch(error=>surface.notice(`control endpoint gc of dead terminals failed: ${errorText(error)}`))}),presenters?{...endpoint,dispose:()=>endpoint.dispose().finally(presenters.dispose)}:endpoint}function errorText(error){return error instanceof Error?error.message:String(error)}export{registerSessionControlEndpoint};
@@ -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{SessionSelectorComponent,createStartupTui,startStartupTui}from"./chunk-WGRKM3N6.js";import"./chunk-CF5OGBC4.js";import"./chunk-GTJJ73DE.js";import"./chunk-FEQDJBDL.js";import"./chunk-RQ6CHXQ2.js";import"./chunk-22YXCY7K.js";import{KeybindingsManager}from"./chunk-4GKU755E.js";import"./chunk-436DNN4Z.js";import"./chunk-J2I56WLK.js";import"./chunk-C7HEEBFH.js";import"./chunk-VD7AKTGP.js";import"./chunk-QMRJYMNH.js";import"./chunk-26UBFF6N.js";import"./chunk-SF4MQDKZ.js";import"./chunk-KLAX467B.js";import"./chunk-2EJ4BGBM.js";import"./chunk-GZVCRV7I.js";import"./chunk-U3VOXCGP.js";import"./chunk-7X72IACK.js";import"./chunk-MSDBBOB2.js";import"./chunk-WB4BUHOH.js";import"./chunk-6VWIMHMH.js";import"./chunk-SOMFLLPD.js";import"./chunk-YU2P3CAR.js";import"./chunk-RQFD6LG2.js";import{setKeybindings}from"./chunk-TMXRR3N7.js";import"./chunk-GKAYPJ4E.js";import"./chunk-BPNSOZ2C.js";import"./chunk-DLAY7CIU.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-QTS2XGPQ.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-BMX2U22F.js";import"./chunk-ZOFZRJSL.js";import"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-IKOFCODM.js";async function selectSession(currentSessionsLoader,allSessionsLoader,settingsManager){let ui=await createStartupTui(settingsManager);return new Promise(resolve=>{let keybindings=KeybindingsManager.create();setKeybindings(keybindings);let resolved=!1,selector=new SessionSelectorComponent(currentSessionsLoader,allSessionsLoader,path=>{resolved||(resolved=!0,ui.stop(),resolve(path))},()=>{resolved||(resolved=!0,ui.stop(),resolve(null))},()=>{ui.stop(),process.exit(0)},()=>ui.requestRender(),{showRenameHint:!1,keybindings});ui.addChild(selector),ui.setFocus(selector.getSessionList()),startStartupTui(ui,settingsManager)})}export{selectSession};
2
+ import{SessionSelectorComponent,createStartupTui,startStartupTui}from"./chunk-45MVD7BU.js";import"./chunk-4NYNMAYF.js";import"./chunk-GTJJ73DE.js";import"./chunk-FEQDJBDL.js";import"./chunk-3TZQXZKH.js";import"./chunk-22YXCY7K.js";import{KeybindingsManager}from"./chunk-4GKU755E.js";import"./chunk-436DNN4Z.js";import"./chunk-J2I56WLK.js";import"./chunk-XZDCMDUH.js";import"./chunk-VD7AKTGP.js";import"./chunk-QMRJYMNH.js";import"./chunk-26UBFF6N.js";import"./chunk-SF4MQDKZ.js";import"./chunk-KLAX467B.js";import"./chunk-2EJ4BGBM.js";import"./chunk-GZVCRV7I.js";import"./chunk-U3VOXCGP.js";import"./chunk-7X72IACK.js";import"./chunk-MSDBBOB2.js";import"./chunk-WB4BUHOH.js";import"./chunk-6VWIMHMH.js";import"./chunk-SOMFLLPD.js";import"./chunk-YU2P3CAR.js";import"./chunk-RQFD6LG2.js";import{setKeybindings}from"./chunk-TMXRR3N7.js";import"./chunk-7PROV6BB.js";import"./chunk-BPNSOZ2C.js";import"./chunk-DLAY7CIU.js";import"./chunk-YUVC7SJB.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-ZDHAJROE.js";import"./chunk-GVSBCJFI.js";import"./chunk-QTS2XGPQ.js";import"./chunk-Z6TEQEZO.js";import"./chunk-HJDTYAPV.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-WIOV3AXZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-OKMHSVCA.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-NDNQ23SK.js";import"./chunk-PJ34QVL5.js";import"./chunk-BMX2U22F.js";import"./chunk-ZOFZRJSL.js";import"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-IKOFCODM.js";async function selectSession(currentSessionsLoader,allSessionsLoader,settingsManager){let ui=await createStartupTui(settingsManager);return new Promise(resolve=>{let keybindings=KeybindingsManager.create();setKeybindings(keybindings);let resolved=!1,selector=new SessionSelectorComponent(currentSessionsLoader,allSessionsLoader,path=>{resolved||(resolved=!0,ui.stop(),resolve(path))},()=>{resolved||(resolved=!0,ui.stop(),resolve(null))},()=>{ui.stop(),process.exit(0)},()=>ui.requestRender(),{showRenameHint:!1,keybindings});ui.addChild(selector),ui.setFocus(selector.getSessionList()),startStartupTui(ui,settingsManager)})}export{selectSession};